9 static const char rcsid[] __attribute__((used)) =
"$Id: Vector.cpp 1702 2016-08-13 23:26:06Z sella $";
13 #include "../util/String.h"
14 #include "../util/CommonMacro.h"
19 using namespace sella::variant;
21 Vector::Vector() throw () :
Nullable(std::make_shared<std::vector<
Variant>>()) { }
23 Vector::Vector(
const std::string &value)
throw (TypeCastException) :
Nullable() {
25 this->value = std::make_shared<std::vector<Variant>>();
27 std::vector<std::string> token = this->tokenize(value, Vector::Pattern());
32 it = std::static_pointer_cast<std::vector<Variant>>(this->value)->begin();
35 Vector::Vector(
const std::vector<std::string> &token)
throw (TypeCastException) :
Nullable() {
37 this->value = std::make_shared<std::vector<Variant>>();
42 it = std::static_pointer_cast<std::vector<Variant>>(this->value)->begin();
46 unmsgpack(mpack, offset);
47 it = std::static_pointer_cast<std::vector<Variant>>(this->value)->begin();
50 Vector::Vector(
const std::vector<Variant> &value)
throw () :
Nullable() {
51 this->value = std::make_shared<std::vector<Variant>>(value);
52 it = std::static_pointer_cast<std::vector<Variant>>(this->value)->begin();
55 Vector::Vector(std::vector<Variant> &&value) throw () :
Nullable() {
56 this->value = std::make_shared<std::vector<Variant>>(std::move(value));
57 it = std::static_pointer_cast<std::vector<Variant>>(this->value)->begin();
61 if (LIKELY(
this != &other)) {
62 if (LIKELY(!other.isNull())) {
63 if (UNLIKELY(isNull())) {
64 this->value = std::make_shared<std::vector<Variant>>(other.get());
66 *std::static_pointer_cast<std::vector<Variant>>(this->value) = *std::static_pointer_cast<std::vector<Variant>>(other.value);
76 if (LIKELY(!other.isNull())) {
77 this->value = std::move(other.value);
78 this->it = std::move(other.it);
84 Vector::~Vector() throw () { }
86 bool Vector::operator==(
const Vector &other)
const throw () {
87 return (*std::static_pointer_cast<std::vector<Variant>>(this->value) == *std::static_pointer_cast<std::vector<Variant>>(other.value));
90 bool Vector::operator!=(
const Vector &other)
const throw () {
91 return !(*
this == other);
94 Vector& Vector::operator=(
const Vector &other)
throw () {
95 if (LIKELY(
this != &other)) {
96 if (LIKELY(!other.isNull())) {
97 if (UNLIKELY(isNull())) {
98 this->value = std::make_shared<std::vector<Variant>>(other.get());
100 *std::static_pointer_cast<std::vector<Variant>>(this->value) = *std::static_pointer_cast<std::vector<Variant>>(other.value);
111 if (LIKELY(
this != &other)) {
112 if (LIKELY(!other.isNull())) {
113 this->value = std::move(other.value);
114 this->it = std::move(other.it);
124 if (UNLIKELY(isNull())) {
125 this->value = std::make_shared<std::vector<Variant>>();
128 if (UNLIKELY(
this == &(other.get<
Vector>()))) {
132 auto &v = *std::static_pointer_cast<std::vector<Variant>>(this->value);
134 if (other.getType() == Variant::TypeVector) {
135 auto &v2 = other.get<
Vector>().
get();
137 v.insert(v.end(), v2.begin(), v2.end());
146 if (UNLIKELY(isNull())) {
147 this->value = std::make_shared<std::vector<Variant>>();
150 if (UNLIKELY(
this == &(other.get<
Vector>()))) {
154 auto &v = *std::static_pointer_cast<std::vector<Variant>>(this->value);
156 if (other.getType() == Variant::TypeVector) {
157 auto &v2 = other.get<
Vector>().
get();
159 std::move(v2.begin(), v2.end(), std::back_inserter(v));
161 v.push_back(std::move(other));
167 const Variant& Vector::operator[](
size_t index)
const throw (RangeException) {
168 if (UNLIKELY(isNull())) {
169 THROW(RangeException,
"index out of bounds");
172 std::vector<Variant> &v = *std::static_pointer_cast<std::vector<Variant>>(this->value);
174 if (UNLIKELY(index >= v.size())) {
175 THROW(RangeException,
"index out of bounds");
181 Variant& Vector::operator[](
size_t index)
throw () {
182 if (UNLIKELY(isNull())) {
183 this->value = std::make_shared<std::vector<Variant>>();
186 std::vector<Variant> &v = *std::static_pointer_cast<std::vector<Variant>>(this->value);
188 if (index >= v.size()) {
195 Vector::iterator Vector::begin() throw () {
196 return get().begin();
199 Vector::iterator Vector::end() throw () {
203 Vector::const_iterator Vector::cbegin()
const throw () {
204 return get().cbegin();
207 Vector::const_iterator Vector::cend()
const throw () {
211 const std::vector<Variant>& Vector::get()
const throw (UnsupportedOperatorException) {
212 if (UNLIKELY(isNull())) {
213 THROW(UnsupportedOperatorException,
"unable to take reference of null value");
216 return *std::static_pointer_cast<std::vector<Variant>>(this->value);
219 std::vector<Variant>& Vector::get() throw (UnsupportedOperatorException) {
220 if (UNLIKELY(isNull())) {
221 THROW(UnsupportedOperatorException,
"unable to take reference of null value");
224 return *std::static_pointer_cast<std::vector<Variant>>(this->value);
227 size_t Vector::size()
const throw () {
228 if (UNLIKELY(isNull())) {
235 bool Vector::empty()
const throw () {
236 if (UNLIKELY(isNull())) {
240 return get().empty();
243 void Vector::clear() throw() {
244 if (UNLIKELY(isNull())) {
245 this->value = std::make_shared<std::vector<Variant>>();
251 bool Vector::erase(
const std::string &v,
int type)
throw () {
257 bool Vector::erase(
const Variant &value)
throw () {
258 auto &v = *std::static_pointer_cast<std::vector<Variant>>(this->value);
261 v.erase(std::remove(v.begin(), v.end(), value), v.end());
263 return (s != v.size());
266 bool Vector::erase(
size_t index)
throw () {
267 auto &v = *std::static_pointer_cast<std::vector<Variant>>(this->value);
269 if ((
size_t) index < v.size()) {
270 v.erase(v.begin() + index) != v.end();
280 void Vector::shrink_to_fit() throw () {
281 auto &v = *std::static_pointer_cast<std::vector<Variant>>(this->value);
283 std::vector<Variant>(v.begin(), v.end()).swap(v);
286 std::string Vector::str(
int type)
const throw () {
314 if (UNLIKELY(isNull())) {
315 c = mpack.append(offset);
319 if (UNLIKELY(c == 0)) {
320 THROW(TypeCastException,
"Failed to append vector '%s' at offset %d (buffer length: %d)", str(JSON).c_str(), offset, mpack.length());
323 const std::vector<Variant> &data = *std::static_pointer_cast<std::vector<Variant>>(this->value);
324 size_t size = data.size();
327 PREFETCH(&data[0].value, PREFETCH_RO, PREFETCH_LOCALITY_MEDIUM);
330 c = mpack.append_vector(offset, size);
334 if (UNLIKELY(c == 0)) {
335 THROW(TypeCastException,
"Failed to append vector '%s' at offset %d (buffer length: %d)", str(JSON).c_str(), offset, mpack.length());
338 for (
size_t i = 0; i < size; i++) {
340 PREFETCH(&data[i + 1].value, PREFETCH_RO, PREFETCH_LOCALITY_MEDIUM);
343 data[i].value->msgpack(mpack, offset);
349 uint32_t c, o = offset;
351 if (UNLIKELY(isNull())) {
352 c = mpack.append(offset);
359 const std::vector<Variant> &data = *std::static_pointer_cast<std::vector<Variant>>(this->value);
361 if (UNLIKELY((c = mpack.append_vector(offset, data.size())) == 0)) {
362 THROW(TypeCastException,
"Failed to append '%s' at offset %d (buffer length: %d)", str(JSON).c_str(), offset, mpack.length());
367 for (
auto it = data.begin(), end = data.end(); it != end; ++it) {
368 if (UNLIKELY(isNull())) {
369 c = mpack.append(offset);
373 int type = it->getType();
377 c = mpack.append(offset, it->get<
Boolean>().get());
381 c = mpack.append(offset, it->get<
Signed>().get());
385 c = mpack.append(offset, it->get<
Unsigned>().get());
389 c = mpack.append(offset, it->get<
Double>().get());
393 c = mpack.append(offset, it->get<
UUID>().get().str());
397 c = mpack.append(offset, it->get<
String>().get());
401 c = it->get<
Binary>().msgpack(mpack, offset);
405 c = mpack.append(offset, (uint64_t) it->get<
Pointer>().get());
408 case IPAddress::Type:
409 c = mpack.append(offset, it->get<
IPAddress>().get().str());
413 c = mpack.append(offset, it->get<
IPPrefix>().get().str());
417 c = mpack.append(offset, it->get<
Interval>().str(JSON));
421 c = mpack.append(offset, it->get<
Time>().str(JSON));
425 c = mpack.append(offset, it->get<
Date>().str(JSON));
428 case TimeStamp::Type:
429 c = mpack.append(offset, it->get<
TimeStamp>().str(JSON));
433 c = it->get<
Vector>().msgpack(mpack, offset);
437 c = it->get<
Object>().msgpack(mpack, offset);
441 if (type != Object::Type && type != Vector::Type && type != Binary::Type) {
446 if (UNLIKELY(c == 0)) {
447 THROW(TypeCastException,
"Failed to append '%s' at offset %d (buffer length: %d)", str(JSON).c_str(), offset, mpack.length());
455 void Vector::msgpackBufferSize(
size_t &size)
const throw () {
456 if (UNLIKELY(isNull())) {
462 const std::vector<Variant> &data = *std::static_pointer_cast<std::vector<Variant>>(this->value);
464 for (
size_t i = 0; i < data.size(); i++) {
465 data[i].value->msgpackBufferSize(size);
471 std::string Vector::json()
const throw () {
472 if (UNLIKELY(isNull())) {
477 const std::vector<Variant> &data = this->
get();
484 for (
auto it = data.begin(), end = data.end(); it != end; ++it) {
485 if ((!it->isScalar() && !it->isNetwork()) || it->isNumeric() || it->isBoolean() || it->isNull()) {
486 output.append(it->value->str(JSON)).append(
", ");
488 output.append(
"\"").append(it->value->str(JSON)).append(
"\", ");
492 output.erase(output.size() - 2);
499 std::string Vector::cjson()
const throw () {
500 if (UNLIKELY(isNull())) {
505 const std::vector<Variant> &data = this->
get();
512 for (
auto it = data.begin(), end = data.end(); it != end; ++it) {
513 if ((!it->isScalar() && !it->isNetwork()) || it->isNumeric() || it->isBoolean() || it->isNull()) {
514 output.append(it->value->str(CJSON)).push_back(
',');
516 output.append(
"\"").append(it->value->str(CJSON)).append(
"\",");
520 output.erase(output.size() - 1);
521 output.push_back(
']');
527 std::string Vector::xml()
const throw () {
528 if (UNLIKELY(isNull())) {
529 return "<root null=\"true\" />";
533 const std::vector<Variant> &data = this->
get();
535 for (
auto it = data.begin(), end = data.end(); it != end; ++it) {
537 output.append(
"<element null=\"true\" />");
539 output.append(
"<element>").append(it->value->str(XML)).append(
"</element>");
546 std::string Vector::csv()
const throw () {
547 if (UNLIKELY(isNull())) {
552 const std::vector<Variant> &data = this->
get();
555 for (
auto it = data.begin(), end = data.end(); it != end; ++it) {
557 output.append(
"\\N");
558 }
else if (it->isScalar()) {
559 output.append(
"\"").append(sella::util::String::escape(it->value->str(CSV))).append(
"\"");
560 }
else if (it->isObject()) {
561 if (!it->empty() && it == data.begin()) {
562 auto &o = it->get<
Object>().
get();
564 for (
auto i = o.begin(); i != o.end(); ++i) {
565 output.append(
"\"").append(i->first).append(
"\",");
567 output.erase(output.size() - 1);
568 output.append(
"\r\n");
571 output.append(it->value->str(CSV));
572 }
else if (it->isVector()) {
573 auto &v = it->get<
Vector>().
get();
576 output.append(
"\\N");
578 for (
auto i = v.begin(), end = v.end(); i != end; ++i) {
580 output.append(
"\\N,");
581 }
else if (i->isScalar()) {
582 output.append(
"\"").append(sella::util::String::escape(i->value->str(CSV))).append(
"\",");
584 output.append(
"\"").append(sella::util::String::escape(i->value->str(JSON))).append(
"\",");
588 output.erase(output.size() - 1);
592 output.append(
"\r\n");
595 output.erase(output.size() - 2);
601 void Vector::parse(
const std::vector<std::string> &token)
throw (TypeCastException) {
602 auto t = token.begin();
603 std::stack<int> type;
604 std::shared_ptr<std::vector<Variant>> v = std::make_shared<std::vector<Variant>>();
606 for (
auto it = token.begin(), end = token.end(); it != end; ++it) {
623 if (UNLIKELY(type.empty() || (type.top() !=
'v'))) {
624 THROW(TypeCastException,
"mismatched vector [ ... ] in text (%s)", t->c_str());
629 v->push_back(
Variant(std::vector<std::string>(t, it)));
634 if (UNLIKELY(type.empty() || (type.top() !=
'o'))) {
635 THROW(TypeCastException,
"mismatched object { ... } in text (%s)", t->c_str());
640 v->push_back(
Variant(std::vector<std::string>(t, it)));
650 std::string value(it->begin() + 1, it->end() - 1);
651 v->push_back(
Variant(value, Variant::TypeQuoted));
657 v->push_back(
Variant(*it, Variant::TypeNonQuoted));
666 std::shared_ptr<std::vector<Variant>> v = std::make_shared<std::vector<Variant>>();
676 v->reserve(mpack.count(offset));
678 mpack.scan(offset, [
this, &mpack, &v, &u](uint32_t i, uint32_t value) {
679 switch (mpack.typeof(value)) {
680 case sella::util::MessagePack::TYPE_NULL:
681 v->push_back(std::move(
Variant()));
684 case sella::util::MessagePack::TYPE_BOOLEAN:
685 if (LIKELY(mpack.decode(u.b, value))) {
686 v->push_back(std::move(
Variant(u.b)));
688 THROW(TypeCastException,
"Failed to decode boolean");
692 case sella::util::MessagePack::TYPE_SIGNED:
693 if (LIKELY(mpack.decode(u.s, value))) {
694 v->push_back(std::move(
Variant(u.s)));
696 THROW(TypeCastException,
"Failed to decode signed");
700 case sella::util::MessagePack::TYPE_UNSIGNED:
701 if (LIKELY(mpack.decode(u.u, value))) {
702 v->push_back(std::move(
Variant(u.u)));
704 THROW(TypeCastException,
"Failed to decode unsigned");
708 case sella::util::MessagePack::TYPE_FLOAT:
709 if (LIKELY(mpack.decode(u.d, value))) {
710 v->push_back(std::move(
Variant(u.d)));
712 THROW(TypeCastException,
"Failed to decode double");
716 case sella::util::MessagePack::TYPE_STRING: {
719 if (LIKELY(mpack.decode(str, value))) {
720 v->push_back(std::move(
Variant(std::move(str))));
722 THROW(TypeCastException,
"Failed to decode string");
727 case sella::util::MessagePack::TYPE_VECTOR:
728 v->push_back(std::move(
Variant(std::move(std::make_shared<Vector>(mpack, value)))));
731 case sella::util::MessagePack::TYPE_OBJECT:
732 v->push_back(std::move(
Variant(std::move(std::make_shared<Object>(mpack, value)))));
736 THROW(TypeCastException,
"Unsupported type %u in input", mpack.typeof(value));
741 }
catch (sella::util::MemoryException &e) {
742 RETHROW(TypeCastException, e);
743 }
catch (TypeCastException &e) {
744 RETHROW(TypeCastException, e);
745 }
catch (std::exception &e) {
746 THROW(TypeCastException,
"%s", e.what());
752 bool Vector::isType(
const char *value,
size_t size)
throw () {
753 return (size > 1 && value[0] ==
'[' && value[size - 1] ==
']');