56 Atom() : _type(NIL), _blob_val(0) {}
57 Atom(int32_t val) : _type(INT), _int_val(val) {}
58 Atom(
float val) : _type(FLOAT), _float_val(val) {}
59 Atom(
bool val) : _type(BOOL), _bool_val(val) {}
60 Atom(
const char* val) : _type(STRING), _string_val(strdup(val)) {}
62 Atom(
const std::string& val) : _type(STRING), _string_val(strdup(val.c_str())) {}
65 Atom(Type t,
const std::string& val) : _type(t), _string_val(g_intern_string(val.c_str())) {
69 Atom(
const char* type_uri,
size_t size,
void* val)
70 : _type(BLOB), _blob_val(new BlobValue(type_uri, size, val)) {}
72 typedef std::map<Raul::Atom, Raul::Atom> DictValue;
73 Atom(
const DictValue& dict) : _type(DICT), _dict_val(new DictValue(dict)) {}
75 ~Atom() { dealloc(); }
77 Atom(
const Atom& copy)
81 case NIL: _blob_val = 0;
break;
82 case INT: _int_val = copy._int_val;
break;
83 case FLOAT: _float_val = copy._float_val;
break;
84 case BOOL: _bool_val = copy._bool_val;
break;
85 case URI: _string_val = copy._string_val;
break;
86 case STRING: _string_val = strdup(copy._string_val);
break;
87 case BLOB: _blob_val =
new BlobValue(*copy._blob_val);
break;
88 case DICT: _dict_val =
new DictValue(*copy._dict_val);
break;
92 Atom& operator=(
const Atom& other) {
97 case NIL: _blob_val = 0;
break;
98 case INT: _int_val = other._int_val;
break;
99 case FLOAT: _float_val = other._float_val;
break;
100 case BOOL: _bool_val = other._bool_val;
break;
101 case URI: _string_val = other._string_val;
break;
102 case STRING: _string_val = strdup(other._string_val);
break;
103 case BLOB: _blob_val =
new BlobValue(*other._blob_val);
break;
104 case DICT: _dict_val =
new DictValue(*other._dict_val);
break;
109 inline bool operator==(
const Atom& other)
const {
110 if (_type == other.type()) {
112 case NIL:
return true;
113 case INT:
return _int_val == other._int_val;
114 case FLOAT:
return _float_val == other._float_val;
115 case BOOL:
return _bool_val == other._bool_val;
116 case URI:
return _string_val == other._string_val;
117 case STRING:
return strcmp(_string_val, other._string_val) == 0;
118 case BLOB:
return _blob_val == other._blob_val;
119 case DICT:
return *_dict_val == *other._dict_val;
125 inline bool operator!=(
const Atom& other)
const {
return ! operator==(other); }
127 inline bool operator<(
const Atom& other)
const {
128 if (_type == other.type()) {
130 case NIL:
return true;
131 case INT:
return _int_val < other._int_val;
132 case FLOAT:
return _float_val < other._float_val;
133 case BOOL:
return _bool_val < other._bool_val;
135 if (_string_val == other._string_val) {
138 case STRING:
return strcmp(_string_val, other._string_val) < 0;
139 case BLOB:
return _blob_val < other._blob_val;
140 case DICT:
return *_dict_val < *other._dict_val;
143 return _type < other.type();
146 inline size_t data_size()
const {
149 case INT:
return sizeof(uint32_t);
150 case FLOAT:
return sizeof(float);
151 case BOOL:
return sizeof(bool);
153 case STRING:
return strlen(_string_val) + 1;
154 case BLOB:
return _blob_val->size();
160 inline bool is_valid()
const {
return (_type != NIL); }
165 Type
type()
const {
return _type; }
167 inline int32_t get_int32()
const { assert(_type == INT);
return _int_val; }
168 inline float get_float()
const { assert(_type == FLOAT);
return _float_val; }
169 inline bool get_bool()
const { assert(_type == BOOL);
return _bool_val; }
170 inline const char* get_string()
const { assert(_type == STRING);
return _string_val; }
171 inline const char* get_uri()
const { assert(_type == URI);
return _string_val; }
173 inline const char* get_blob_type()
const { assert(_type == BLOB);
return _blob_val->type(); }
174 inline const void* get_blob()
const { assert(_type == BLOB);
return _blob_val->data(); }
176 inline const DictValue& get_dict()
const { assert(_type == DICT);
return *_dict_val; }
182 Atom(
const char* str, uint32_t magic) : _type(
URI), _string_val(str) {
183 assert(magic == 12345);
184 assert(g_intern_string(str) == str);
187 inline void dealloc() {
190 free(const_cast<char*>(_string_val));
201 BlobValue(
const char*
type,
size_t size,
void* data)
202 : _type_length(strlen(type) + 1)
204 , _buf(malloc(_type_length + _size))
206 memcpy(_buf, type, _type_length);
207 memcpy(static_cast<char*>(_buf) + _type_length, data, size);
210 BlobValue(
const BlobValue& copy)
211 : _type_length(copy._type_length)
213 , _buf(malloc(_type_length + _size))
215 _type_length = copy._type_length;
216 memcpy(_buf, copy._buf, _type_length + _size);
219 ~BlobValue() { free(_buf); }
221 inline const char*
type()
const {
return static_cast<const char*
>(_buf); }
222 inline const void* data()
const {
return static_cast<const char*
>(_buf) + _type_length; }
223 inline size_t size()
const {
return _size; }
234 const char* _string_val;
235 BlobValue* _blob_val;
236 const DictValue* _dict_val;
243 static inline std::ostream& operator<<(std::ostream& os,
const Raul::Atom& atom)
245 switch (atom.
type()) {
246 case Raul::Atom::NIL:
return os <<
"(nil)";
247 case Raul::Atom::INT:
return os << atom.get_int32();
248 case Raul::Atom::FLOAT:
return os << atom.get_float();
249 case Raul::Atom::BOOL:
return os << (atom.get_bool() ?
"true" :
"false");
250 case Raul::Atom::URI:
return os <<
"<" << atom.get_uri() <<
">";
251 case Raul::Atom::STRING:
return os << atom.get_string();
252 case Raul::Atom::BLOB:
return os << atom.get_blob();
253 case Raul::Atom::DICT:
255 for (Raul::Atom::DictValue::const_iterator i = atom.get_dict().begin();
256 i != atom.get_dict().end(); ++i) {
257 os <<
" " << i->first <<
" " << i->second <<
";";
265 static inline std::ostream& operator<<(std::ostream& os, Raul::Atom::Type type)
268 case Raul::Atom::NIL:
return os <<
"Nil";
269 case Raul::Atom::INT:
return os <<
"Int";
270 case Raul::Atom::FLOAT:
return os <<
"Float";
271 case Raul::Atom::BOOL:
return os <<
"Bool";
272 case Raul::Atom::URI:
return os <<
"URI";
273 case Raul::Atom::STRING:
return os <<
"String";
274 case Raul::Atom::BLOB:
return os <<
"Blob";
275 case Raul::Atom::DICT:
return os <<
"Dict";
280 #endif // RAUL_ATOM_HPP