00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef RAUL_ATOM_HPP
00019 #define RAUL_ATOM_HPP
00020
00021 #include <stdint.h>
00022 #include <cstdlib>
00023 #include <cassert>
00024 #include <cstring>
00025 #include <string>
00026 #include <sstream>
00027 #include <iostream>
00028
00029 #include CONFIG_H_PATH
00030
00031 #define CUC(x) ((const unsigned char*)(x))
00032
00033 namespace Raul {
00034
00035
00040 class Atom {
00041 public:
00042 enum Type {
00043 NIL,
00044 INT,
00045 FLOAT,
00046 BOOL,
00047 STRING,
00048 BLOB
00049 };
00050
00051 Atom() : _type(NIL), _blob_val(0) {}
00052 Atom(int32_t val) : _type(INT), _int_val(val) {}
00053 Atom(float val) : _type(FLOAT), _float_val(val) {}
00054 Atom(bool val) : _type(BOOL), _bool_val(val) {}
00055 Atom(const char* val) : _type(STRING), _string_val(strdup(val)) {}
00056 Atom(const std::string& val) : _type(STRING), _string_val(strdup(val.c_str())) {}
00057
00058 Atom(const char* type_uri, size_t size, void* val) : _type(BLOB) {
00059 _blob_type_length = strlen(type_uri) + 1;
00060 _blob_size = size;
00061 _blob_val = malloc(_blob_type_length + _blob_size);
00062 memcpy(_blob_val, type_uri, _blob_type_length);
00063 memcpy((char*)_blob_val + _blob_type_length, val, size);
00064 }
00065
00066 ~Atom() {
00067 if (_type == STRING)
00068 free(_string_val);
00069 else if (_type == BLOB)
00070 free(_blob_val);
00071 }
00072
00073
00074
00075 Atom(const Atom& copy)
00076 : _type(copy._type)
00077 {
00078 switch (_type) {
00079 case NIL: _blob_val = 0; break;
00080 case INT: _int_val = copy._int_val; break;
00081 case FLOAT: _float_val = copy._float_val; break;
00082 case BOOL: _bool_val = copy._bool_val; break;
00083 case STRING: _string_val = strdup(copy._string_val); break;
00084 case BLOB: _blob_size = copy._blob_size;
00085 _blob_type_length = copy._blob_type_length;
00086 _blob_val = malloc(_blob_type_length + _blob_size);
00087 memcpy(_blob_val, copy._blob_val, _blob_type_length + _blob_size);
00088 break;
00089 }
00090 }
00091
00092 Atom& operator=(const Atom& other) {
00093 if (_type == BLOB)
00094 free(_blob_val);
00095 else if (_type == STRING)
00096 free(_string_val);
00097
00098 _type = other._type;
00099
00100 switch (_type) {
00101 case NIL: _blob_val = 0; break;
00102 case INT: _int_val = other._int_val; break;
00103 case FLOAT: _float_val = other._float_val; break;
00104 case BOOL: _bool_val = other._bool_val; break;
00105 case STRING: _string_val = strdup(other._string_val); break;
00106 case BLOB: _blob_size = other._blob_size;
00107 _blob_type_length = other._blob_type_length;
00108 _blob_val = malloc(_blob_type_length + _blob_size);
00109 memcpy(_blob_val, other._blob_val, _blob_type_length + _blob_size);
00110 break;
00111 }
00112 return *this;
00113 }
00114
00115 inline bool operator==(const Atom& other) const {
00116 if (_type == other.type()) {
00117 switch (_type) {
00118 case NIL: return true;
00119 case INT: return _int_val == other._int_val;
00120 case FLOAT: return _float_val == other._float_val;
00121 case BOOL: return _bool_val == other._bool_val;
00122 case STRING: return strcmp(_string_val, other._string_val) == 0;
00123 case BLOB: return _blob_val == other._blob_val;
00124 }
00125 }
00126 return false;
00127 }
00128
00129 inline bool operator!=(const Atom& other) const { return ! operator==(other); }
00130
00131 inline bool operator<(const Atom& other) const {
00132 if (_type == other.type()) {
00133 switch (_type) {
00134 case NIL: return true;
00135 case INT: return _int_val < other._int_val;
00136 case FLOAT: return _float_val < other._float_val;
00137 case BOOL: return _bool_val < other._bool_val;
00138 case STRING: return strcmp(_string_val, other._string_val) < 0;
00139 case BLOB: return _blob_val < other._blob_val;
00140 }
00141 }
00142 return _type < other.type();
00143 }
00144
00145 inline size_t data_size() const {
00146 switch (_type) {
00147 case NIL: return 0;
00148 case INT: return sizeof(uint32_t);
00149 case FLOAT: return sizeof(float);
00150 case BOOL: return sizeof(bool);
00151 case STRING: return strlen(_string_val);
00152 case BLOB: return _blob_size;
00153 }
00154 return 0;
00155 }
00156
00157 inline bool is_valid() const { return (_type != NIL); }
00158
00162 Type type() const { return _type; }
00163
00164 inline int32_t get_int32() const { assert(_type == INT); return _int_val; }
00165 inline float get_float() const { assert(_type == FLOAT); return _float_val; }
00166 inline bool get_bool() const { assert(_type == BOOL); return _bool_val; }
00167 inline const char* get_string() const { assert(_type == STRING); return _string_val; }
00168
00169 inline const char* get_blob_type() const { assert(_type == BLOB); return (const char*)_blob_val; }
00170 inline const void* get_blob() const { assert(_type == BLOB); return (const char*)_blob_val + _blob_type_length; }
00171
00172 private:
00173 Type _type;
00174
00175 union {
00176 int32_t _int_val;
00177 float _float_val;
00178 bool _bool_val;
00179 char* _string_val;
00180 struct {
00181 size_t _blob_type_length;
00182 size_t _blob_size;
00183 void* _blob_val;
00184 };
00185 };
00186 };
00187
00188
00189 }
00190
00191 #endif // RAUL_ATOM_HPP