From e58a63ffd2612f632d4dc53b63d8d236b9a9c2dc Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Wed, 23 Dec 2015 11:01:07 +0100 Subject: [PATCH] updated vpack library --- .../velocypack/include/velocypack/Builder.h | 22 +++++++- 3rdParty/velocypack/src/Builder.cpp | 56 +++++++++++++++++-- 2 files changed, 71 insertions(+), 7 deletions(-) diff --git a/3rdParty/velocypack/include/velocypack/Builder.h b/3rdParty/velocypack/include/velocypack/Builder.h index 1c20ccd77e..7a10a18636 100644 --- a/3rdParty/velocypack/include/velocypack/Builder.h +++ b/3rdParty/velocypack/include/velocypack/Builder.h @@ -45,6 +45,8 @@ namespace arangodb { namespace velocypack { + class ArrayIterator; + class ObjectIterator; class Builder { friend class Parser; // The parser needs access to internals. @@ -289,7 +291,12 @@ class Builder { } // Return a Slice of the result: - Slice slice() const { return Slice(start(), options); } + Slice slice() const { + if (isEmpty()) { + return Slice(); + } + return Slice(start(), options); + } // Compute the actual size here, but only when sealed ValueLength size() const { @@ -327,6 +334,11 @@ class Builder { // Add a subvalue into an object from a ValuePair: uint8_t* add(std::string const& attrName, ValuePair const& sub); + + // Add all subkeys and subvalues into an object from an ObjectIterator + // and leaves open the object intentionally + uint8_t* add(ObjectIterator& sub); + uint8_t* add(ObjectIterator&& sub); // Add a subvalue into an array from a Value: uint8_t* add(Value const& sub); @@ -336,9 +348,14 @@ class Builder { // Add a subvalue into an array from a ValuePair: uint8_t* add(ValuePair const& sub); + + // Add all subvalues into an array from an ArrayIterator + // and leaves open the array intentionally + uint8_t* add(ArrayIterator& sub); + uint8_t* add(ArrayIterator&& sub); // Seal the innermost array or object: - void close(); + Builder& close(); // Remove last subvalue written to an (unclosed) object or array: // Throws if an error occurs. @@ -607,7 +624,6 @@ private: } throw; } - } uint8_t* set(Value const& item); diff --git a/3rdParty/velocypack/src/Builder.cpp b/3rdParty/velocypack/src/Builder.cpp index d9b0175bcd..2be96797bd 100644 --- a/3rdParty/velocypack/src/Builder.cpp +++ b/3rdParty/velocypack/src/Builder.cpp @@ -29,6 +29,7 @@ #include "velocypack/velocypack-common.h" #include "velocypack/Builder.h" #include "velocypack/Dumper.h" +#include "velocypack/Iterator.h" #include "velocypack/Sink.h" using namespace arangodb::velocypack; @@ -168,7 +169,7 @@ void Builder::removeLast() { index.pop_back(); } -void Builder::close() { +Builder& Builder::close() { if (isClosed()) { throw Exception(Exception::BuilderNeedOpenCompound); } @@ -188,7 +189,7 @@ void Builder::close() { _pos -= 8; // no bytelength and number subvalues needed _stack.pop_back(); // Intentionally leave _index[depth] intact to avoid future allocs! - return; + return *this; } // From now on index.size() > 0 @@ -237,7 +238,7 @@ void Builder::close() { _pos += nLen + bLen; _stack.pop_back(); - return; + return *this; } } @@ -379,6 +380,7 @@ void Builder::close() { // off the _stack: _stack.pop_back(); // Intentionally leave _index[depth] intact to avoid future allocs! + return *this; } // checks whether an Object value has a specific key attribute @@ -675,7 +677,6 @@ uint8_t* Builder::set(Value const& item) { } uint8_t* Builder::set(Slice const& item) { - checkKeyIsString(item.isString()); ValueLength const l = item.byteSize(); @@ -788,6 +789,31 @@ uint8_t* Builder::add(std::string const& attrName, ValuePair const& sub) { uint8_t* Builder::add(std::string const& attrName, Slice const& sub) { return addInternal(attrName, sub); } + +// Add all subkeys and subvalues into an object from an ObjectIterator +// and leaves open the object intentionally +uint8_t* Builder::add(ObjectIterator& sub) { + return add(std::move(sub)); +} + +uint8_t* Builder::add(ObjectIterator&& sub) { + if (_stack.empty()) { + throw Exception(Exception::BuilderNeedOpenObject); + } + ValueLength& tos = _stack.back(); + if (_start[tos] != 0x0b && _start[tos] != 0x14) { + throw Exception(Exception::BuilderNeedOpenObject); + } + if (_keyWritten) { + throw Exception(Exception::BuilderKeyAlreadyWritten); + } + auto const oldPos = _start + _pos; + while (sub.valid()) { + add(sub.key().copyString(), sub.value()); + sub.next(); + } + return oldPos; +} uint8_t* Builder::add(Value const& sub) { return addInternal(sub); } @@ -797,4 +823,26 @@ uint8_t* Builder::add(ValuePair const& sub) { uint8_t* Builder::add(Slice const& sub) { return addInternal(sub); } +// Add all subkeys and subvalues into an object from an ArrayIterator +// and leaves open the array intentionally +uint8_t* Builder::add(ArrayIterator& sub) { + return add(std::move(sub)); +} + +uint8_t* Builder::add(ArrayIterator&& sub) { + if (_stack.empty()) { + throw Exception(Exception::BuilderNeedOpenArray); + } + ValueLength& tos = _stack.back(); + if (_start[tos] != 0x06 && _start[tos] != 0x13) { + throw Exception(Exception::BuilderNeedOpenArray); + } + auto const oldPos = _start + _pos; + while (sub.valid()) { + add(sub.value()); + sub.next(); + } + return oldPos; +} + static_assert(sizeof(double) == 8, "double is not 8 bytes");