29
29
#include " velocypack/velocypack-common.h"
30
30
#include " velocypack/Builder.h"
31
31
#include " velocypack/Dumper.h"
32
+ #include " velocypack/Iterator.h"
32
33
#include " velocypack/Sink.h"
33
34
34
35
using namespace arangodb ::velocypack;
@@ -168,7 +169,7 @@ void Builder::removeLast() {
168
169
index.pop_back ();
169
170
}
170
171
171
- void Builder::close () {
172
+ Builder& Builder::close () {
172
173
if (isClosed ()) {
173
174
throw Exception (Exception::BuilderNeedOpenCompound);
174
175
}
@@ -188,7 +189,7 @@ void Builder::close() {
188
189
_pos -= 8 ; // no bytelength and number subvalues needed
189
190
_stack.pop_back ();
190
191
// Intentionally leave _index[depth] intact to avoid future allocs!
191
- return ;
192
+ return * this ;
192
193
}
193
194
194
195
// From now on index.size() > 0
@@ -237,7 +238,7 @@ void Builder::close() {
237
238
_pos += nLen + bLen;
238
239
239
240
_stack.pop_back ();
240
- return ;
241
+ return * this ;
241
242
}
242
243
}
243
244
@@ -379,6 +380,7 @@ void Builder::close() {
379
380
// off the _stack:
380
381
_stack.pop_back ();
381
382
// Intentionally leave _index[depth] intact to avoid future allocs!
383
+ return *this ;
382
384
}
383
385
384
386
// checks whether an Object value has a specific key attribute
@@ -675,7 +677,6 @@ uint8_t* Builder::set(Value const& item) {
675
677
}
676
678
677
679
uint8_t * Builder::set (Slice const & item) {
678
-
679
680
checkKeyIsString (item.isString ());
680
681
681
682
ValueLength const l = item.byteSize ();
@@ -788,6 +789,31 @@ uint8_t* Builder::add(std::string const& attrName, ValuePair const& sub) {
788
789
uint8_t * Builder::add (std::string const & attrName, Slice const & sub) {
789
790
return addInternal<Slice>(attrName, sub);
790
791
}
792
+
793
+ // Add all subkeys and subvalues into an object from an ObjectIterator
794
+ // and leaves open the object intentionally
795
+ uint8_t * Builder::add (ObjectIterator& sub) {
796
+ return add (std::move (sub));
797
+ }
798
+
799
+ uint8_t * Builder::add (ObjectIterator&& sub) {
800
+ if (_stack.empty ()) {
801
+ throw Exception (Exception::BuilderNeedOpenObject);
802
+ }
803
+ ValueLength& tos = _stack.back ();
804
+ if (_start[tos] != 0x0b && _start[tos] != 0x14 ) {
805
+ throw Exception (Exception::BuilderNeedOpenObject);
806
+ }
807
+ if (_keyWritten) {
808
+ throw Exception (Exception::BuilderKeyAlreadyWritten);
809
+ }
810
+ auto const oldPos = _start + _pos;
811
+ while (sub.valid ()) {
812
+ add (sub.key ().copyString (), sub.value ());
813
+ sub.next ();
814
+ }
815
+ return oldPos;
816
+ }
791
817
792
818
uint8_t * Builder::add (Value const & sub) { return addInternal<Value>(sub); }
793
819
@@ -797,4 +823,26 @@ uint8_t* Builder::add(ValuePair const& sub) {
797
823
798
824
uint8_t * Builder::add (Slice const & sub) { return addInternal<Slice>(sub); }
799
825
826
+ // Add all subkeys and subvalues into an object from an ArrayIterator
827
+ // and leaves open the array intentionally
828
+ uint8_t * Builder::add (ArrayIterator& sub) {
829
+ return add (std::move (sub));
830
+ }
831
+
832
+ uint8_t * Builder::add (ArrayIterator&& sub) {
833
+ if (_stack.empty ()) {
834
+ throw Exception (Exception::BuilderNeedOpenArray);
835
+ }
836
+ ValueLength& tos = _stack.back ();
837
+ if (_start[tos] != 0x06 && _start[tos] != 0x13 ) {
838
+ throw Exception (Exception::BuilderNeedOpenArray);
839
+ }
840
+ auto const oldPos = _start + _pos;
841
+ while (sub.valid ()) {
842
+ add (sub.value ());
843
+ sub.next ();
844
+ }
845
+ return oldPos;
846
+ }
847
+
800
848
static_assert (sizeof (double ) == 8, "double is not 8 bytes");
0 commit comments