提交 f45f2664 编写于 作者: D Daniel Larimer

remove eosio::string and vector, switch to std

上级 fa95e965
......@@ -7,6 +7,7 @@
#include <eosiolib/memory.h>
#include <eosiolib/vector.hpp>
#include <eosiolib/varint.hpp>
#include <string>
namespace eosio {
......@@ -383,6 +384,24 @@ inline datastream<Stream>& operator>>(datastream<Stream>& ds, uint8_t& d) {
return ds;
}
template<typename DataStream>
DataStream& operator << ( DataStream& ds, const std::string& v ) {
ds << unsigned_int( v.size() );
for( const auto& i : v )
ds << i;
return ds;
}
template<typename DataStream>
DataStream& operator >> ( DataStream& ds, std::string& v ) {
unsigned_int s;
ds >> s;
v.resize(s.value);
for( auto& i : v )
ds >> i;
return ds;
}
template<typename DataStream, typename T>
DataStream& operator << ( DataStream& ds, const vector<T>& v ) {
ds << unsigned_int( v.size() );
......
......@@ -5,9 +5,10 @@
#include <eosiolib/dispatcher.hpp>
#include <eosiolib/serialize.hpp>
#include <eosiolib/action.hpp>
#include <eosiolib/string.hpp>
#include <string>
namespace eosio {
using std::string;
template<typename Token>
class generic_currency {
......@@ -49,7 +50,7 @@ namespace eosio {
struct transfer_memo : public transfer {
transfer_memo(){}
transfer_memo( account_name f, account_name t, token_type q, string m )
:transfer( f, t, q ), memo( move(m) ){}
:transfer( f, t, q ), memo( std::move(m) ){}
string memo;
......
#pragma once
#include <eosiolib/utility.hpp>
#include <eosiolib/preprocessor/seq/for_each.hpp>
#include <eosiolib/preprocessor/seq/enum.hpp>
#include <eosiolib/preprocessor/seq/size.hpp>
......
#pragma once
#include <eosiolib/string.h>
#include <eosiolib/types.hpp>
#include <eosiolib/system.h>
#include <eosiolib/memory.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/varint.hpp>
namespace eosio {
/**
* @brief Count the length of null terminated string (excluding the null terminated symbol)
* Non-null terminated string need to be passed here,
* Otherwise it will not give the right length
* @param cstr - null terminated string
*/
inline size_t cstrlen(const char* cstr) {
size_t len = 0;
while(*cstr != '\0') {
len++;
cstr++;
}
return len;
}
class string {
private:
size_t size = 0; // size of the string
char* data = nullptr; // underlying data
bool own_memory = false; // true if the object is responsible to clean the memory
uint32_t* refcount = nullptr; // shared reference count to the underlying data
// Release data if no more string reference to it
void release_data_if_needed() {
if (own_memory && refcount != nullptr) {
(*refcount)--;
if (*refcount == 0) {
free(data);
}
}
}
public:
/**
* Default constructor
*/
string() : size(0), data(nullptr), own_memory(false), refcount(nullptr) {
}
/**
* Constructor to create string with reserved space
* @param s size to be reserved (in number o)
*/
string(size_t s) : size(s) {
if (s == 0) {
data = nullptr;
own_memory = false;
refcount = nullptr;
} else {
data = (char *)malloc(s * sizeof(char));
own_memory = true;
refcount = (uint32_t*)malloc(sizeof(uint32_t));
*refcount = 1;
}
}
/**
* Constructor to create string with given data and size
* @param d data
* @param s size of the string (in number of bytes)
* @param copy true to have the data copied and owned by the object
*/
string(char* d, size_t s, bool copy) {
assign(d, s, copy);
}
// Copy constructor
string(const string& obj) {
if (this != &obj) {
data = obj.data;
size = obj.size;
own_memory = obj.own_memory;
refcount = obj.refcount;
if (refcount != nullptr) (*refcount)++;
}
}
/**
* @brief Constructor for string literal
* Non-null terminated string need to be passed here,
* Otherwise it will have extraneous data
* @param cstr - null terminated string
*/
string(const char* cstr) {
size = cstrlen(cstr) + 1;
data = (char *)malloc(size * sizeof(char));
memcpy(data, cstr, size * sizeof(char));
own_memory = true;
refcount = (uint32_t*)malloc(sizeof(uint32_t));
*refcount = 1;
}
// Destructor
~string() {
release_data_if_needed();
}
void resize( size_t newsize ) {
if( newsize == 0 ) {
release_data_if_needed();
refcount = nullptr;
own_memory = true;
data = nullptr;
size = 0;
}
else if( newsize < size ) {
size = newsize;
data[newsize] = 0;
}
else if( newsize > size ) {
char* newbuf = (char*)malloc( newsize );
memcpy( newbuf, data, size );
release_data_if_needed();
size = newsize;
data = newbuf;
own_memory = true;
refcount = nullptr;
}
}
// Get size of the string (in number of bytes)
const size_t get_size() const {
return size;
}
// Get the underlying data of the string
const char* get_data() const {
return data;
}
char* get_data() {
return data;
}
// Check if it owns memory
const bool is_own_memory() const {
return own_memory;
}
// Get the ref count
const uint32_t get_refcount() const {
return *refcount;
}
/**
* Assign string with new data and size
* @param d data
* @param s size (in number of bytes)
* @param copy true to have the data copied and owned by the object
* @return the current string
*/
string& assign(char* d, size_t s, bool copy) {
if (s == 0) {
clear();
} else {
release_data_if_needed();
if (copy) {
data = (char *)malloc(s * sizeof(char));
memcpy(data, d, s * sizeof(char));
own_memory = true;
refcount = (uint32_t*)malloc(sizeof(uint32_t));
*refcount = 1;
} else {
data = d;
own_memory = false;
refcount = nullptr;
}
size = s;
}
return *this;
}
/**
* Clear the content of the string
*/
void clear() {
release_data_if_needed();
data = nullptr;
size = 0;
own_memory = false;
refcount = nullptr;
}
/**
* Create substring from current string
* @param offset offset from the current string's data
* @param substr_size size of the substring
* @param copy true to have the data copied and owned by the object
* @return substring of the current string
*/
string substr(size_t offset, size_t substr_size, bool copy) {
eos_assert((offset < size) && (offset + substr_size < size), "out of bound");
return string(data + offset, substr_size, copy);
}
char operator [] (const size_t index) {
eos_assert(index < size, "index out of bound");
return *(data + index);
}
// Assignment operator
string& operator = (const string& obj) {
if (this != &obj) {
release_data_if_needed();
data = obj.data;
size = obj.size;
own_memory = obj.own_memory;
refcount = obj.refcount;
if (refcount != nullptr) (*refcount)++;
}
return *this;
}
/**
* @brief Assignment operator for string literal
* Non-null terminated string need to be passed here,
* Otherwise it will have extraneous data
* @param cstr - null terminated string
*/
string& operator = (const char* cstr) {
release_data_if_needed();
size = cstrlen(cstr) + 1;
data = (char *)malloc(size * sizeof(char));
memcpy(data, cstr, size * sizeof(char));
own_memory = true;
refcount = (uint32_t*)malloc(sizeof(uint32_t));
*refcount = 1;
return *this;
}
string& operator += (const string& str){
eos_assert((size + str.size > size) && (size + str.size > str.size), "overflow");
char* new_data;
size_t new_size;
if (size > 0 && *(data + size - 1) == '\0') {
// Null terminated string, remove the \0 when concatenates
new_size = size - 1 + str.size;
new_data = (char *)malloc(new_size * sizeof(char));
memcpy(new_data, data, (size - 1) * sizeof(char));
memcpy(new_data + size - 1, str.data, str.size * sizeof(char));
} else {
new_size = size + str.size;
new_data = (char *)malloc(new_size * sizeof(char));
memcpy(new_data, data, size * sizeof(char));
memcpy(new_data + size, str.data, str.size * sizeof(char));
}
// Release old data
release_data_if_needed();
// Assign new data
data = new_data;
size = new_size;
own_memory = true;
refcount = (uint32_t*)malloc(sizeof(uint32_t));
*refcount = 1;
return *this;
}
// Compare two strings
// Return an integral value indicating the relationship between strings
// >0 if the first string is greater than the second string
// 0 if both strings are equal
// <0 if the first string is smaller than the second string
// The return value also represents the difference between the first character that doesn't match of the two strings
int32_t compare(const string& str) const {
int32_t result;
if (size == str.size) {
result = memcmp(data, str.data, size);
} else if (size < str.size) {
result = memcmp(data, str.data, size);
if (result == 0) {
// String is equal up to size of the shorter string, return the difference in byte of the next character
result = 0 - (unsigned char)str.data[size];
}
} else if (size > str.size) {
result = memcmp(data, str.data, str.size);
if (result == 0) {
// String is equal up to size of the shorter string, return the difference in byte of the next character
result = (unsigned char)data[str.size];
}
}
return result;
}
friend bool operator < (const string& lhs, const string& rhs) {
return lhs.compare(rhs) < 0;
}
friend bool operator > (const string& lhs, const string& rhs) {
return lhs.compare(rhs) > 0;
}
friend bool operator == (const string& lhs, const string& rhs) {
return lhs.compare(rhs) == 0;
}
friend bool operator != (const string& lhs, const string& rhs) {
return lhs.compare(rhs) != 0;
}
friend string operator + (string lhs, const string& rhs) {
return lhs += rhs;
}
template<typename DataStream>
friend DataStream& operator << ( DataStream& ds, const string& t ){
ds << unsigned_int( t.get_size() );
if( t.get_size() ) ds.write( t.get_data(), t.get_size() );
return ds;
}
template<typename DataStream>
friend DataStream& operator >> ( DataStream& ds, string& t ){
unsigned_int size;
ds >> size;
t.resize( size );
if( size.value )
ds.read( t.get_data(), size.value );
return ds;
}
void print() const {
if (size > 0 && *(data + size - 1) == '\0') {
// Null terminated string
prints(data);
} else {
// Non null terminated string
// We need to specify the size of string so it knows where to stop
prints_l(data, size);
}
}
}; /// class string
}
......@@ -6,7 +6,6 @@
#include <eosiolib/transaction.h>
#include <eosiolib/action.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/string.hpp>
#include <eosiolib/types.hpp>
#include <eosiolib/serialize.hpp>
......
#pragma once
#include <eosiolib/types.hpp>
namespace eosio {
template<typename T, typename U>
inline T&& forward( U&& u ) { return static_cast<T&&>(u); }
template<typename T>
inline typename remove_reference<T>::type&& move( T&& arg ) { return (typename remove_reference<T>::type&&)arg; }
} /// namespace eosio
#pragma once
#include <eosiolib/utility.hpp>
#include <eosiolib/memory.hpp>
#include <eosiolib/stdlib.hpp>
#include <vector>
namespace eosio {
/**
* This class provides an interface similar to std::vector
*/
template<typename T>
class vector {
public:
vector(){}
using std::vector;
vector( size_t s, const T& value ) {
reserve( s );
for( uint32_t i = 0; i < s; ++i )
emplace_back( value );
}
vector( const vector& copy ) {
reserve( copy.size() );
for( uint32_t i = 0; i < copy.size(); ++i ) {
emplace_back( copy[i] );
}
}
vector( vector&& mv ) {
_data = mv._data;
_size = mv._size;
_capacity = mv._capacity;
mv._data = nullptr;
mv._size = 0;
mv._capacity = 0;
}
vector( std::initializer_list<T> init ) {
resize(0);
reserve( init.size() );
int i = 0;
for( auto itr = init.begin(); itr != init.end(); itr++ ) {
emplace_back( *itr );
}
}
~vector() {
for( uint32_t i = 0; i < _size; ++i )
_data[i].~T();
free( _data );
_data = nullptr;
_size = 0;
_capacity = 0;
}
vector& operator = ( const vector& copy ) {
if( this != &copy ) {
resize(0);
reserve( copy.size() );
for( uint32_t i = 0; i < copy.size(); ++i ) {
new (&_data[i]) T( copy[i] );
}
_size = copy.size();
}
return *this;
}
vector& operator = ( vector&& mv ) {
resize( 0 );
_data = mv._data;
_size = mv._size;
_capacity = mv._capacity;
mv._data = nullptr;
mv._size = 0;
mv._capacity = 0;
return *this;
}
T& operator[]( uint32_t index ) { return _data[index]; }
const T& operator[]( uint32_t index )const { return _data[index]; }
T* begin() { return _data; }
T* end() { return _data + _size; }
const T* begin()const { return _data; }
const T* end()const { return _data + _size; }
const T* data()const { return _data; }
T* data() { return _data; }
uint32_t size()const { return _size; }
uint32_t capacity()const { return _capacity; }
void push_back( const T& value ) {
if( _size == _capacity )
reserve( _size + 1 );
new (&_data[_size]) T( value );
++_size;
}
template<typename... Args>
void emplace_back( Args&& ...value ) {
if( _size == _capacity )
reserve( _size + 1 );
new (&_data[_size]) T( forward<Args>(value)... );
++_size;
}
void resize( uint32_t new_size ) {
reserve( new_size );
if( new_size > _size )
{
for( uint32_t i = _size; i < new_size; ++i ) {
new (&_data[i]) T();
}
}
else if ( new_size < _size )
{
for( uint32_t i = new_size; i < _size; ++i ) {
_data[i].~T();
}
}
_size = new_size;
} /// resize
void reserve( uint32_t new_capacity ) {
if( new_capacity > _capacity ) {
T* new_data = (T*)malloc( sizeof(T) * new_capacity );
for( uint32_t i = 0; i < _size; ++i ) {
new (new_data+i) T( move( _data[i] ) );
_data[i].~T();
}
free( _data );
_data = new_data;
_capacity = new_capacity;
}
}
private:
T* _data = nullptr;
uint32_t _size = 0;
uint32_t _capacity = 0;
}; /// class vector
typedef eosio::vector<char> bytes;
typedef std::vector<char> bytes;
} /// namespace eosio
......@@ -5,15 +5,14 @@
#include <eosiolib/singleton.hpp>
#include <eosiolib/table.hpp>
#include <eosiolib/vector.hpp>
#include <eosiolib/string.hpp>
namespace identity {
using eosio::action_meta;
using eosio::table_i64i64i64;
using eosio::table64;
using eosio::singleton;
using eosio::string;
using eosio::vector;
using std::string;
using std::vector;
/**
* This contract maintains a graph database of certified statements about an
......@@ -331,7 +330,7 @@ namespace identity {
row.trusted = is_trusted( cert.certifier );
row.certifier = cert.certifier;
row.confidence = value.confidence;
eos_assert(value.type.get_size() <= 32, "certrow::type should be not longer than 32 bytes");
eos_assert(value.type.size() <= 32, "certrow::type should be not longer than 32 bytes");
row.type = value.type;
row.data = value.data;
......
......@@ -10,8 +10,8 @@ namespace identity_test {
using eosio::action_meta;
using eosio::singleton;
using eosio::string;
using eosio::vector;
using std::string;
using std::vector;
class contract {
public:
......
......@@ -6,18 +6,18 @@
#include <eosiolib/eosio.hpp>
#include <eosiolib/dispatcher.hpp>
#include <eosiolib/string.hpp>
using namespace eosio;
namespace noop {
using std::string;
/**
noop contract
All it does is require sender authorization.
Actions: anyaction
*/
class noop {
public:
......
......@@ -149,7 +149,6 @@
*/
//include <eosiolib/eos.hpp>
#include <eosiolib/token.hpp>
#include <eosiolib/string.hpp>
#include <eosiolib/dispatcher.hpp>
using namespace eosio;
......
......@@ -6,7 +6,6 @@
#include <eosiolib/action.hpp>
#include <eosiolib/types.hpp>
#include <eosiolib/serialize.hpp>
#include <eosiolib/string.hpp>
#include <eosiolib/system.h>
using namespace eosio;
......@@ -42,7 +41,7 @@ namespace testsystem {
struct producer_key {
account_name account;
string public_key;
std::string public_key;
EOSLIB_SERIALIZE( producer_key, (account)(public_key) );
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册