9 static const char rcsid[] __attribute__((used)) =
"$Id: Variant.cpp 1892 2017-06-23 17:23:36Z sella $";
13 #include "../util/String.h"
14 #include "../util/MessagePack.h"
15 #include "../util/CommonMacro.h"
17 using namespace sella::variant;
19 const int Variant::TypeAuto;
20 const int Variant::TypeNull;
21 const int Variant::TypeBoolean;
22 const int Variant::TypeSigned;
23 const int Variant::TypeUnsigned;
24 const int Variant::TypeDouble;
25 const int Variant::TypeString;
26 const int Variant::TypeUUID;
27 const int Variant::TypeBinary;
28 const int Variant::TypePointer;
29 const int Variant::TypeIPAddress;
30 const int Variant::TypeIPPrefix;
31 const int Variant::TypeInterval;
32 const int Variant::TypeTime;
33 const int Variant::TypeDate;
34 const int Variant::TypeTimeStamp ;
35 const int Variant::TypeVector;
36 const int Variant::TypeObject;
37 const int Variant::TypeJSON;
38 const int Variant::TypeQuoted;
39 const int Variant::TypeNonQuoted;
40 const int Variant::JSON;
41 const int Variant::CJSON;
42 const int Variant::MSGPACK;
43 const int Variant::XML;
44 const int Variant::CSV;
45 const int Variant::IterScalar;
46 const int Variant::IterVector;
47 const int Variant::IterObject;
49 Variant::Variant() throw () :
54 Variant::Variant(
const std::shared_ptr<Nullable> &value)
throw (TypeCastException) :
56 type(this->value->getType())
59 Variant::Variant(std::shared_ptr<Nullable> &&value) throw (TypeCastException) :
60 value(std::move(value)),
61 type(this->value->getType())
64 Variant::Variant(
const std::string &value,
int type)
throw (TypeCastException) {
65 if (type == TypeString) {
66 this->value = std::make_shared<String>(value);
67 this->type = TypeString;
73 Variant::Variant(std::string &&value,
int type)
throw (TypeCastException) {
74 if (type == TypeString) {
75 this->value = std::make_shared<String>(std::move(value));
76 this->type = TypeString;
82 Variant::Variant(
const char *value,
int type)
throw (TypeCastException) {
83 if (type == TypeString) {
84 this->value = std::make_shared<String>(value);
85 this->type = TypeString;
91 Variant::Variant(uint32_t size, uint8_t *buffer)
throw (TypeCastException) {
92 this->unmsgpack(buffer, size);
96 value(std::make_shared<UUID>(value)),
101 value(std::make_shared<
UUID>(std::move(value))),
107 Variant::Variant(uuid_t &value)
throw () :
108 value(std::make_shared<UUID>(value)),
112 Variant::Variant(
void *ptr)
throw () :
113 value(std::make_shared<Pointer>(ptr)),
118 value(std::make_shared<IPAddress>(value)),
123 value(std::make_shared<
IPAddress>(std::move(value))),
130 value(std::make_shared<IPPrefix>(value)),
135 value(std::make_shared<
IPPrefix>(std::move(value))),
141 Variant::Variant(
bool value)
throw () :
142 value(std::make_shared<Boolean>(value)),
146 Variant::Variant(uint8_t value)
throw () :
147 value(std::make_shared<Unsigned>(value)),
151 Variant::Variant(uint16_t value)
throw () :
152 value(std::make_shared<Unsigned>(value)),
156 Variant::Variant(
unsigned int value)
throw () :
157 value(std::make_shared<Unsigned>(value)),
161 Variant::Variant(uint64_t value)
throw () :
162 value(std::make_shared<Unsigned>(value)),
166 Variant::Variant(int8_t value)
throw () :
167 value(std::make_shared<Signed>(value)),
171 Variant::Variant(int16_t value)
throw () :
172 value(std::make_shared<Signed>(value)),
176 Variant::Variant(
int value)
throw () :
177 value(std::make_shared<Signed>(value)),
181 Variant::Variant(int64_t value)
throw () :
182 value(std::make_shared<Signed>(value)),
186 Variant::Variant(
float value)
throw () :
187 value(std::make_shared<Double>(value)),
191 Variant::Variant(
double value)
throw () :
192 value(std::make_shared<Double>(value)),
196 Variant::Variant(
const std::vector<std::string> &token)
throw (TypeCastException) {
198 THROW(TypeCastException,
"empty token stream passed to variant");
201 switch (token.front().at(0)) {
203 this->value = std::make_shared<Vector>(std::vector<std::string>(token.begin() + 1, token.end()));
204 this->type = TypeVector;
209 this->value = std::make_shared<Object>(std::vector<std::string>(token.begin() + 1, token.end()));
210 this->type = TypeObject;
215 THROW(TypeCastException,
"unknown token stream passed to variant (first token: %s)", token.front().c_str());
220 Variant::Variant(
unsigned long long value)
throw () :
221 value(std::make_shared<Unsigned>(value)),
225 Variant::Variant(
long long value)
throw () :
226 value(std::make_shared<Unsigned>(value)),
230 Variant::Variant(
unsigned long value)
throw () :
231 value(std::make_shared<Unsigned>(value)),
235 Variant::Variant(
long value)
throw () :
236 value(std::make_shared<Unsigned>(value)),
241 Variant::Variant(
const Variant &other)
throw () :
245 switch (other.type) {
247 this->value = null();
252 this->value = std::make_shared<Boolean>(other.get<
Boolean>());
257 this->value = std::make_shared<Signed>(other.get<
Signed>());
262 this->value = std::make_shared<Unsigned>(other.get<
Unsigned>());
267 this->value = std::make_shared<Double>(other.get<
Double>());
272 this->value = std::make_shared<String>(other.get<
String>());
277 this->value = std::make_shared<UUID>(other.get<
UUID>());
282 this->value = std::make_shared<Binary>(other.get<
Binary>());
287 this->value = std::make_shared<Pointer>(other.get<
Pointer>());
292 this->value = std::make_shared<IPAddress>(other.get<
IPAddress>());
297 this->value = std::make_shared<IPPrefix>(other.get<
IPPrefix>());
302 this->value = std::make_shared<Interval>(other.get<
Interval>());
307 this->value = std::make_shared<Time>(other.get<
Time>());
312 this->value = std::make_shared<Date>(other.get<
Date>());
317 this->value = std::make_shared<TimeStamp>(other.get<
TimeStamp>());
322 this->value = std::make_shared<Vector>(other.get<
Vector>());
327 this->value = std::make_shared<Object>(other.get<
Object>());
332 fprintf(stderr,
"DEBUG: Missing Type in switch statements.\n");
337 Variant::Variant(
Variant &&other) throw () {
341 Variant::~Variant() throw () { }
347 if (this->type == TypeObject) {
348 it.type = IterObject;
349 it.oit = get<Object>().begin();
350 }
else if (this->type == TypeVector) {
351 it.type = IterVector;
352 it.vit = get<Vector>().begin();
354 it.type = IterScalar;
365 if (this->type == TypeObject) {
366 it.type = IterObject;
367 it.oit = get<Object>().end();
368 }
else if (this->type == TypeVector) {
369 it.type = IterVector;
370 it.vit = get<Vector>().end();
372 it.type = IterScalar;
379 int Variant::getType()
const throw () {
383 void Variant::setType(
int type)
throw (TypeCastException) {
384 if (this->type != type) {
388 this->value = null();
392 this->value = (isNull()) ? std::make_shared<Boolean>() : std::make_shared<Boolean>((bool) *
this);
396 this->value = (isNull()) ? std::make_shared<Signed>() : std::make_shared<Signed>((int64_t) *
this);
400 this->value = (isNull()) ? std::make_shared<Unsigned>() : std::make_shared<Unsigned>((uint64_t) *
this);
404 this->value = (isNull()) ? std::make_shared<Double>() : std::make_shared<Double>((double) *
this);
409 this->value = (isNull()) ? std::make_shared<UUID>() : std::make_shared<UUID>(str());
411 this->value = std::make_shared<UUID>(
"");
416 this->value = (isNull()) ? std::make_shared<String>() : std::make_shared<String>(str());
420 this->value = (isNull()) ? std::make_shared<Binary>() : std::make_shared<Binary>(str());
424 this->value = (isNull()) ? std::make_shared<Pointer>() : std::make_shared<Pointer>(str());
428 this->value = (isNull()) ? std::make_shared<IPAddress>() : std::make_shared<IPAddress>(str());
432 this->value = (isNull()) ? std::make_shared<IPPrefix>() : std::make_shared<IPPrefix>(str());
436 this->value = (isNull()) ? std::make_shared<Interval>() : std::make_shared<Interval>(str());
440 this->value = (isNull()) ? std::make_shared<Time>() : std::make_shared<Time>(str());
444 this->value = (isNull()) ? std::make_shared<Date>() : std::make_shared<Date>(str());
448 this->value = (isNull()) ? std::make_shared<TimeStamp>() : std::make_shared<TimeStamp>(str());
452 this->value = std::make_shared<Vector>(
"");
457 this->value = std::make_shared<Object>(
"");
461 THROW(TypeCastException,
"unable to change type to %s(%d)", getTypeName(type), type);
468 const char* Variant::getTypeName(
int type)
const throw () {
529 fprintf(stderr,
"DEBUG: Missing Type %d in switch statements.\n", type);
534 Variant& Variant::parse(
const std::string &value,
int type)
throw (TypeCastException) {
535 if (type == TypeAuto || type == TypeJSON || type == TypeQuoted || type == TypeNonQuoted) {
538 }
else if (::isspace(value.front()) != 0 || ::isspace(value.back()) != 0) {
539 std::string trimmed = sella::util::String::trim(value);
541 if (!trimmed.empty()) {
542 return parse(trimmed, type);
549 if (Signed::isType(value)) {
552 }
else if (Unsigned::isType(value)) {
555 }
else if (Boolean::isType(value)) {
557 }
else if (Double::isType(value)) {
559 }
else if (Null::isType(value)) {
561 }
else if (UUID::isType(value)) {
563 }
else if (IPPrefix::isType(value)) {
565 }
else if (IPAddress::isType(value)) {
566 type = TypeIPAddress;
567 }
else if (Vector::isType(value)) {
569 }
else if (Object::isType(value)) {
571 }
else if (Binary::isType(value)) {
574 }
else if (Pointer::isType(value)) {
577 }
else if (Interval::isType(value)) {
579 }
else if (Time::isType(value)) {
581 }
else if (Date::isType(value)) {
583 }
else if (TimeStamp::isType(value)) {
584 type = TypeTimeStamp;
591 if (Object::isType(value)) {
593 }
else if (Vector::isType(value)) {
601 if (UUID::isType(value)) {
603 }
else if (IPPrefix::isType(value)) {
605 }
else if (IPAddress::isType(value)) {
606 type = TypeIPAddress;
613 if (Signed::isType(value)) {
615 }
else if (Boolean::isType(value)) {
617 }
else if (Double::isType(value)) {
619 }
else if (Null::isType(value)) {
631 this->value = null();
632 this->type = TypeNull;
636 this->value = std::make_shared<Boolean>(value);
637 this->type = TypeBoolean;
642 this->value = std::make_shared<Signed>(value);
643 this->type = TypeSigned;
646 }
catch (TypeCastException &e) { }
649 this->value = std::make_shared<Unsigned>(value);
650 this->type = TypeUnsigned;
654 this->value = std::make_shared<Double>(value);
655 this->type = TypeDouble;
659 this->value = std::make_shared<UUID>(value);
660 this->type = TypeUUID;
665 this->value = std::make_shared<String>(value);
666 this->type = TypeString;
670 this->value = std::make_shared<Binary>(value);
671 this->type = TypeBinary;
675 this->value = std::make_shared<Pointer>(value);
676 this->type = TypePointer;
680 this->value = std::make_shared<IPAddress>(value);
681 this->type = TypeIPAddress;
685 this->value = std::make_shared<IPPrefix>(value);
686 this->type = TypeIPPrefix;
690 this->value = std::make_shared<Interval>(value);
691 this->type = TypeInterval;
695 this->value = std::make_shared<Time>(value);
696 this->type = TypeTime;
700 this->value = std::make_shared<Date>(value);
701 this->type = TypeDate;
705 this->value = std::make_shared<TimeStamp>(value);
706 this->type = TypeTimeStamp;
710 this->value = std::make_shared<Vector>(value);
711 this->type = TypeVector;
715 this->value = std::make_shared<Object>(value);
716 this->type = TypeObject;
720 this->unmsgpack(value);
724 THROW(TypeCastException,
"unknown scalar type %d supplied", type);
730 bool Variant::erase(
const Variant &value)
throw () {
731 if (this->type == TypeObject && !isNull()) {
732 return get<Object>().erase(value.str());
733 }
else if (this->type == TypeVector && !isNull()) {
734 return get<Vector>().erase(value);
740 bool Variant::erase(
const std::string &value)
throw () {
741 if (this->type == TypeObject && !isNull()) {
742 return get<Object>().erase(value);
743 }
else if (this->type == TypeVector && !isNull()) {
744 return get<Vector>().erase(
Variant(value));
750 bool Variant::erase(
unsigned int index)
throw () {
751 if (this->type == TypeVector && !isNull()) {
752 return get<Vector>().erase(index);
758 void Variant::shrink_to_fit() throw () {
759 switch (this->type) {
761 return get<UUID>().shrink_to_fit();
764 return get<String>().shrink_to_fit();
767 return get<Vector>().shrink_to_fit();
770 return get<Nullable>().shrink_to_fit();
774 void Variant::sort(
void) throw (UnsupportedOperatorException) {
775 if (this->type != TypeVector) {
776 THROW(TypeCastException,
"operation only supported with type vector");
779 std::vector<Variant> &v = get<Vector>().
get();
781 std::sort(v.begin(), v.end());
784 void Variant::unique(
void) throw (UnsupportedOperatorException) {
785 if (this->type != TypeVector) {
786 THROW(TypeCastException,
"operation only supported with type vector");
789 std::vector<Variant> &v = get<Vector>().
get();
791 v.erase(std::unique(v.begin(), v.end()), v.end());
794 void Variant::zero() throw () {
795 switch (this->type) {
797 get<Boolean>() =
false;
817 get<String>().clear();
821 get<Binary>().clear();
825 get<Pointer>() = 0x0;
829 get<IPAddress>().clear();
833 get<IPPrefix>().clear();
849 get<TimeStamp>() = 0;
853 get<Vector>().clear();
857 get<Object>().clear();
862 void Variant::clear() throw () {
868 size_t Variant::size()
const throw () {
869 switch (this->type) {
871 return get<Object>().size();
873 return get<Vector>().size();
875 return get<String>().size();
877 return get<Binary>().size();
883 bool Variant::empty()
const throw () {
884 switch (this->type) {
886 return get<Object>().empty();
888 return get<Vector>().empty();
890 return get<String>().empty();
892 return get<Binary>().empty();
900 bool Variant::isScalar()
const throw () {
901 return !(isVector() || isObject());
904 bool Variant::isNumeric()
const throw () {
905 return (isSigned() || isUnsigned() || isDouble());
908 bool Variant::isTemporal()
const throw () {
909 return (isInterval() || isTime() || isDate() || isTimeStamp());
912 bool Variant::isNetwork()
const throw () {
913 return (isIPAddress() || isIPPrefix());
916 bool Variant::isNull()
const throw () {
917 return (this->value == NULL || this->value->isNull());
920 bool Variant::isBoolean()
const throw () {
921 return (this->type == TypeBoolean);
924 bool Variant::isSigned()
const throw () {
925 return (this->type == TypeSigned);
928 bool Variant::isUnsigned()
const throw () {
929 return (this->type == TypeUnsigned);
932 bool Variant::isDouble()
const throw () {
933 return (this->type == TypeDouble);
936 bool Variant::isString()
const throw () {
937 return (this->type == TypeString);
940 bool Variant::isUUID()
const throw () {
941 return (this->type == TypeUUID);
944 bool Variant::isBinary()
const throw () {
945 return (this->type == TypeBinary);
948 bool Variant::isPointer()
const throw () {
949 return (this->type == TypePointer);
952 bool Variant::isIPAddress()
const throw () {
953 return (this->type == TypeIPAddress);
956 bool Variant::isIPPrefix()
const throw () {
957 return (this->type == TypeIPPrefix);
960 bool Variant::isInterval()
const throw () {
961 return (this->type == TypeInterval);
964 bool Variant::isTime()
const throw () {
965 return (this->type == TypeTime);
968 bool Variant::isDate()
const throw () {
969 return (this->type == TypeDate);
972 bool Variant::isTimeStamp()
const throw () {
973 return (this->type == TypeTimeStamp);
976 bool Variant::isVector()
const throw () {
977 return (this->type == TypeVector);
980 bool Variant::isObject()
const throw () {
981 return (this->type == TypeObject);
984 const std::vector<Variant>& Variant::asVector(
void)
const throw (TypeCastException) {
985 return this->cast<const std::vector<Variant>&>();
988 std::vector<Variant>& Variant::asVector(
void) throw (TypeCastException) {
989 return this->cast<std::vector<Variant>&>();
992 const std::map<std::string, Variant>& Variant::asMap(
void)
const throw (TypeCastException) {
993 return this->cast<const std::map<std::string, Variant>&>();
996 std::map<std::string, Variant>& Variant::asMap(
void) throw (TypeCastException) {
997 return this->cast<std::map<std::string, Variant>&>();
1000 Variant& Variant::unjson(
const std::string &json)
throw (TypeCastException) {
1001 return parse(json, TypeJSON);
1004 const std::string& Variant::str(
int type)
const throw () {
1009 if (this->type == TypeString) {
1010 return this->get<sella::variant::String>().
get();
1013 buf = this->value->str(JSON);
1017 buf = this->value->str(CJSON);
1026 buf.append(
"<root>").append(this->value->str(XML)).append(
"</root>");
1030 buf = this->value->str(CSV);
1039 const char* Variant::c_str(
int type)
const throw () {
1040 return str(type).c_str();
1043 size_t Variant::msgpack(std::string &buffer, uint32_t size)
const throw (TypeCastException) {
1047 uint8_t buf[(512 * 1024)];
1049 if ((c = msgpack(buf, (uint32_t)
sizeof(buf))) > 0) {
1050 buffer.assign((
const char*) buf, c);
1053 uint8_t *buf = (uint8_t*) malloc(size);
1056 if ((c = msgpack(buf, size)) > 0) {
1057 buffer.assign((
const char*) buf, c);
1062 RETHROW(TypeCastException, e);
1071 size_t Variant::msgpack(uint8_t *buffer, uint32_t size)
const throw (TypeCastException) {
1073 uint32_t offset = 0;
1077 this->value->msgpack(mpack, offset);
1081 uint32_t offset = 0, c = 0;
1085 if (UNLIKELY(this->isNull())) {
1086 return mpack.append(offset);
1089 switch (this->type) {
1091 c = mpack.append(offset, get<Boolean>().
get());
1095 c = mpack.append(offset, get<Signed>().
get());
1099 c = mpack.append(offset, get<Unsigned>().
get());
1103 c = mpack.append(offset, get<Double>().
get());
1107 c = mpack.append(offset, get<UUID>().
get().str());
1111 c = mpack.append(offset, get<String>().
get());
1115 c = get<Binary>().msgpack(mpack, offset);
1119 c = mpack.append(offset, (uint64_t) get<Pointer>().
get());
1123 c = mpack.append(offset, get<IPAddress>().
get().str());
1127 c = mpack.append(offset, get<IPPrefix>().
get().str());
1131 c = mpack.append(offset, get<Interval>().str(JSON));
1135 c = mpack.append(offset, get<Time>().str(JSON));
1139 c = mpack.append(offset, get<Date>().str(JSON));
1143 c = mpack.append(offset, get<TimeStamp>().str(JSON));
1147 c = get<Vector>().msgpack(mpack, offset);
1151 c = get<Object>().msgpack(mpack, offset);
1155 if (this->type != TypeObject && this->type != TypeVector && this->type != TypeBinary) {
1159 if (UNLIKELY(c == 0)) {
1160 THROW(TypeCastException,
"Failed to append '%s' at offset %d (buffer length: %d)", str(JSON).c_str(), offset, mpack.length());
1167 Variant& Variant::unmsgpack(
const std::string &msgpack)
throw (TypeCastException) {
1168 return unmsgpack((uint8_t*) msgpack.data(), msgpack.size());
1171 Variant& Variant::unmsgpack(uint8_t *buffer, uint32_t size)
throw (TypeCastException) {
1172 uint32_t offset = 0;
1174 if (UNLIKELY(size < 1)) {
1190 switch (mpack.typeof(offset)) {
1191 case sella::util::MessagePack::TYPE_NULL:
1192 this->value = null();
1193 this->type = TypeNull;
1196 case sella::util::MessagePack::TYPE_BOOLEAN:
1197 if (mpack.decode(u.b, offset)) {
1198 this->value = std::make_shared<Boolean>(u.b);
1199 this->type = TypeBoolean;
1201 THROW(TypeCastException,
"Failed to decode boolean");
1205 case sella::util::MessagePack::TYPE_SIGNED:
1206 if (mpack.decode(u.s, offset)) {
1207 this->value = std::make_shared<Signed>(u.s);
1208 this->type = TypeSigned;
1210 THROW(TypeCastException,
"Failed to decode signed");
1214 case sella::util::MessagePack::TYPE_UNSIGNED:
1215 if (mpack.decode(u.u, offset)) {
1216 this->value = std::make_shared<Unsigned>(u.u);
1217 this->type = TypeUnsigned;
1219 THROW(TypeCastException,
"Failed to decode unsigned");
1223 case sella::util::MessagePack::TYPE_FLOAT:
1224 if (mpack.decode(u.d, offset)) {
1225 this->value = std::make_shared<Double>(u.d);
1226 this->type = TypeDouble;
1228 THROW(TypeCastException,
"Failed to decode double");
1232 case sella::util::MessagePack::TYPE_STRING: {
1235 if (mpack.decode(str, offset)) {
1236 this->value = std::make_shared<String>(std::move(str));
1237 this->type = TypeString;
1239 THROW(TypeCastException,
"Failed to decode string");
1244 case sella::util::MessagePack::TYPE_VECTOR:
1245 this->value = std::make_shared<Vector>(mpack, offset);
1246 this->type = TypeVector;
1249 case sella::util::MessagePack::TYPE_OBJECT:
1250 this->value = std::make_shared<Object>(mpack, offset);
1251 this->type = TypeObject;
1255 THROW(TypeCastException,
"Unsupported type %u in input", mpack.typeof(offset));
1257 }
catch (sella::util::MemoryException &e) {
1258 RETHROW(TypeCastException, e);
1264 size_t Variant::msgpackBufferSize(
void)
const throw () {
1268 this->value->msgpackBufferSize(size);
1276 void Variant::swap(
Variant& other) {
1277 int type = other.type;
1278 other.type = this->type;
1281 this->value.swap(other.value);
1282 this->cache.swap(other.cache);