diff --git a/3rdParty/velocypack/include/velocypack/Builder.h b/3rdParty/velocypack/include/velocypack/Builder.h index 9429b585d4..a209056d8f 100644 --- a/3rdParty/velocypack/include/velocypack/Builder.h +++ b/3rdParty/velocypack/include/velocypack/Builder.h @@ -63,11 +63,11 @@ namespace arangodb { private: Buffer _buffer; // Here we collect the result - uint8_t* _start; // Always points to the start of _buffer - ValueLength _size; // Always contains the size of _buffer - ValueLength _pos; // the append position, always <= _size - bool _attrWritten; // indicates that an attribute name - // in an object has been written + uint8_t* _start; // Always points to the start of _buffer + ValueLength _size; // Always contains the size of _buffer + ValueLength _pos; // the append position, always <= _size + bool _attrWritten; // indicates that an attribute name + // in an object has been written std::vector _stack; // Start positions of // open objects/arrays std::vector> _index; // Indices for starts @@ -92,7 +92,7 @@ namespace arangodb { // allocations. In the beginning, the _stack is empty, which // allows to build a sequence of unrelated VPack objects in the // buffer. Whenever the stack is empty, one can use the start, - // size and stealTo methods to get out the ready built VPack + // size and slice methods to get out the ready built VPack // object(s). void reserveSpace (ValueLength len) { @@ -145,15 +145,9 @@ namespace arangodb { ~Builder () { } - Builder (Builder const& that) { - _buffer = that._buffer; - _start = _buffer.data(); - _size = _buffer.size(); - _pos = that._pos; - _attrWritten = that._attrWritten; - _stack = that._stack; - _index = that._index; - options = that.options; + Builder (Builder const& that) + : _buffer(that._buffer), _start(_buffer.data()), _size(_buffer.size()), _pos(that._pos), + _attrWritten(that._attrWritten), _stack(that._stack), _index(that._index), options(that.options) { } Builder& operator= (Builder const& that) { @@ -233,17 +227,23 @@ namespace arangodb { } // Add a subvalue into an object from a Value: - void add (std::string const& attrName, Value const& sub); + uint8_t* add (std::string const& attrName, Value const& sub); + + // Add a subvalue into an object from a Slice: + uint8_t* add (std::string const& attrName, Slice const& sub); // Add a subvalue into an object from a ValuePair: uint8_t* add (std::string const& attrName, ValuePair const& sub); // Add a subvalue into an array from a Value: - void add (Value const& sub); + uint8_t* add (Value const& sub); + + // Add a slice to an array + uint8_t* add (Slice const& sub); // Add a subvalue into an array from a ValuePair: uint8_t* add (ValuePair const& sub); - + // Seal the innermost array or object: void close (); @@ -365,6 +365,46 @@ namespace arangodb { private: + template + uint8_t* addInternal (T const& sub) { + if (! _stack.empty()) { + ValueLength& tos = _stack.back(); + if (_start[tos] != 0x06 && _start[tos] != 0x0b) { + throw Exception(Exception::BuilderNeedOpenObject); + } + if (_start[tos] == 0x0b) { // Object + if (! _attrWritten && ! sub.isString()) { + throw Exception(Exception::BuilderNeedOpenObject); + } + if (! _attrWritten) { + reportAdd(tos); + } + _attrWritten = ! _attrWritten; + } + else { // Array + reportAdd(tos); + } + } + return set(sub); + } + + template + uint8_t* addInternal (std::string const& attrName, T const& sub) { + if (_attrWritten) { + throw Exception(Exception::InternalError, "Attribute name already written"); + } + if (! _stack.empty()) { + ValueLength& tos = _stack.back(); + if (_start[tos] != 0x06 && + _start[tos] != 0x0b) { + throw Exception(Exception::BuilderNeedOpenObject); + } + reportAdd(tos); + } + set(Value(attrName, ValueType::String)); + return set(sub); + } + void addCompoundValue (uint8_t type) { reserveSpace(9); // an array is started: @@ -378,10 +418,12 @@ namespace arangodb { _pos += 8; // Will be filled later with bytelength and nr subs } - void set (Value const& item); + uint8_t* set (Value const& item); uint8_t* set (ValuePair const& pair); + uint8_t* set (Slice const& item); + void reportAdd (ValueLength base) { size_t depth = _stack.size() - 1; _index[depth].push_back(_pos - base); diff --git a/3rdParty/velocypack/include/velocypack/Collection.h b/3rdParty/velocypack/include/velocypack/Collection.h new file mode 100644 index 0000000000..8c690fc449 --- /dev/null +++ b/3rdParty/velocypack/include/velocypack/Collection.h @@ -0,0 +1,112 @@ +//////////////////////////////////////////////////////////////////////////////// +/// @brief Library to build up VPack documents. +/// +/// DISCLAIMER +/// +/// Copyright 2015 ArangoDB GmbH, Cologne, Germany +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// +/// Copyright holder is ArangoDB GmbH, Cologne, Germany +/// +/// @author Max Neunhoeffer +/// @author Jan Steemann +/// @author Copyright 2015, ArangoDB GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +#ifndef VELOCYPACK_COLLECTION_H +#define VELOCYPACK_COLLECTION_H 1 + +#include +#include +#include +#include + +#include "velocypack/velocypack-common.h" +#include "velocypack/Builder.h" +#include "velocypack/Slice.h" + +namespace arangodb { + namespace velocypack { + + class Collection { + + public: + + Collection () = delete; + + static void forEach (Slice const& slice, std::function const& cb); + + static void forEach (Slice const* slice, std::function const& cb) { + return forEach(*slice, cb); + } + + static Builder filter (Slice const& slice, std::function const& cb); + + static Builder filter (Slice const* slice, std::function const& cb) { + return filter(*slice, cb); + } + + static Builder map (Slice const& slice, std::function const& cb); + + static Builder map (Slice const* slice, std::function const& cb) { + return map(*slice, cb); + } + + static Slice find (Slice const& slice, std::function const& cb); + + static Slice find (Slice const* slice, std::function const& cb) { + return find(*slice, cb); + } + + static bool contains (Slice const& slice, std::function const& cb); + + static bool contains (Slice const* slice, std::function const& cb) { + return contains(*slice, cb); + } + + static bool all (Slice const& slice, std::function const& cb); + + static bool all (Slice const* slice, std::function const& cb) { + return all(*slice, cb); + } + + static bool any (Slice const& slice, std::function const& cb); + + static bool any (Slice const* slice, std::function const& cb) { + return any(*slice, cb); + } + + static std::vector keys (Slice const& slice); + + static std::vector keys (Slice const* slice) { + return keys(*slice); + } + + static void keys (Slice const& slice, std::vector& result); + + static void keys (Slice const* slice, std::vector& result) { + return keys(*slice, result); + } + + static void keys (Slice const& slice, std::unordered_set& result); + + static void keys (Slice const* slice, std::unordered_set& result) { + return keys(*slice, result); + } + }; + + } // namespace arangodb::velocypack +} // namespace arangodb + +#endif diff --git a/3rdParty/velocypack/include/velocypack/Dumper.h b/3rdParty/velocypack/include/velocypack/Dumper.h index 9817856f3e..0dd685204a 100644 --- a/3rdParty/velocypack/include/velocypack/Dumper.h +++ b/3rdParty/velocypack/include/velocypack/Dumper.h @@ -55,15 +55,15 @@ namespace arangodb { Options options; enum UnsupportedTypeStrategy { - StrategyNullify, - StrategyFail + StrategyNullifyUnsupportedType, + StrategyFailOnUnsupportedType }; Dumper (Dumper const&) = delete; Dumper& operator= (Dumper const&) = delete; - Dumper (T& buffer, UnsupportedTypeStrategy strategy = StrategyFail) - : _buffer(&buffer), _strategy(strategy), _indentation(0) { + Dumper (T& buffer, UnsupportedTypeStrategy strategy = StrategyFailOnUnsupportedType) + : strategy(strategy), _buffer(&buffer), _indentation(0) { } ~Dumper () { @@ -99,24 +99,24 @@ namespace arangodb { internalDump(slice, nullptr); } - static void Dump (Slice const& slice, T& buffer, UnsupportedTypeStrategy strategy = StrategyFail) { + static void Dump (Slice const& slice, T& buffer, UnsupportedTypeStrategy strategy = StrategyFailOnUnsupportedType) { Dumper dumper(buffer, strategy); dumper.dump(slice); } - static void Dump (Slice const* slice, T& buffer, UnsupportedTypeStrategy strategy = StrategyFail) { + static void Dump (Slice const* slice, T& buffer, UnsupportedTypeStrategy strategy = StrategyFailOnUnsupportedType) { Dumper dumper(buffer, strategy); dumper.dump(slice); } - static T Dump (Slice const& slice, UnsupportedTypeStrategy strategy = StrategyFail) { + static T Dump (Slice const& slice, UnsupportedTypeStrategy strategy = StrategyFailOnUnsupportedType) { T buffer; Dumper dumper(buffer, strategy); dumper.dump(slice); return buffer; } - static T Dump (Slice const* slice, UnsupportedTypeStrategy strategy = StrategyFail) { + static T Dump (Slice const* slice, UnsupportedTypeStrategy strategy = StrategyFailOnUnsupportedType) { T buffer; Dumper dumper(buffer, strategy); dumper.dump(slice); @@ -473,13 +473,16 @@ namespace arangodb { } void handleUnsupportedType (Slice const*) { - if (_strategy == StrategyNullify) { + if (strategy == StrategyNullifyUnsupportedType) { _buffer->append("null", 4); return; } throw Exception(Exception::NoJsonEquivalent); } + + public: + UnsupportedTypeStrategy strategy; private: @@ -487,8 +490,6 @@ namespace arangodb { std::function _callback; - UnsupportedTypeStrategy _strategy; - int _indentation; }; diff --git a/3rdParty/velocypack/include/velocypack/Exception.h b/3rdParty/velocypack/include/velocypack/Exception.h index 982d447581..0b28929721 100644 --- a/3rdParty/velocypack/include/velocypack/Exception.h +++ b/3rdParty/velocypack/include/velocypack/Exception.h @@ -109,7 +109,7 @@ namespace arangodb { case BuilderObjectNotSealed: return "Object not sealed"; case BuilderNeedOpenObject: - return "Need open array or object for close() call"; + return "Need open Array or Object for close() call"; case BuilderUnexpectedType: return "Unexpected type"; case BuilderUnexpectedValue: diff --git a/3rdParty/velocypack/include/velocypack/Iterator.h b/3rdParty/velocypack/include/velocypack/Iterator.h new file mode 100644 index 0000000000..c3f883bd29 --- /dev/null +++ b/3rdParty/velocypack/include/velocypack/Iterator.h @@ -0,0 +1,144 @@ +//////////////////////////////////////////////////////////////////////////////// +/// @brief Library to build up VPack documents. +/// +/// DISCLAIMER +/// +/// Copyright 2015 ArangoDB GmbH, Cologne, Germany +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// +/// Copyright holder is ArangoDB GmbH, Cologne, Germany +/// +/// @author Max Neunhoeffer +/// @author Jan Steemann +/// @author Copyright 2015, ArangoDB GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +#ifndef VELOCYPACK_ITERATOR_H +#define VELOCYPACK_ITERATOR_H 1 + +#include "velocypack/velocypack-common.h" +#include "velocypack/Exception.h" +#include "velocypack/Slice.h" +#include "velocypack/ValueType.h" + +namespace arangodb { + namespace velocypack { + + class ArrayIterator { + + public: + + ArrayIterator () = delete; + + ArrayIterator (Slice const& slice) + : _slice(slice), _size(_slice.length()), _position(0) { + + if (slice.type() != ValueType::Array) { + throw Exception(Exception::InvalidValueType, "Expecting Array slice"); + } + } + + ArrayIterator (ArrayIterator const& other) + : _slice(other._slice), _size(other._size), _position(0) { + } + + ArrayIterator& operator= (ArrayIterator const& other) { + _slice = other._slice; + _size = other._size; + _position = 0; + return *this; + } + + inline bool valid () const throw() { + return (_position < _size); + } + + inline Slice value () const { + if (_position >= _size) { + throw Exception(Exception::IndexOutOfBounds); + } + return _slice.at(_position); + } + + inline bool next () throw() { + ++_position; + return valid(); + } + + private: + + Slice _slice; + ValueLength _size; + ValueLength _position; + }; + + class ObjectIterator { + + public: + + ObjectIterator () = delete; + + ObjectIterator (Slice const& slice) + : _slice(slice), _size(_slice.length()), _position(0) { + + if (slice.type() != ValueType::Object) { + throw Exception(Exception::InvalidValueType, "Expecting Object slice"); + } + } + + ObjectIterator (ObjectIterator const& other) + : _slice(other._slice), _size(other._size), _position(0) { + } + + ObjectIterator& operator= (ObjectIterator const& other) { + _slice = other._slice; + _size = other._size; + _position = 0; + return *this; + } + + inline bool valid () const throw() { + return (_position < _size); + } + + inline Slice key () const { + if (_position >= _size) { + throw Exception(Exception::IndexOutOfBounds); + } + return _slice.keyAt(_position); + } + + inline Slice value () const { + if (_position >= _size) { + throw Exception(Exception::IndexOutOfBounds); + } + return _slice.valueAt(_position); + } + + inline bool next () throw() { + ++_position; + return valid(); + } + + private: + + Slice _slice; + ValueLength _size; + ValueLength _position; + }; + + } // namespace arangodb::velocypack +} // namespace arangodb + +#endif diff --git a/3rdParty/velocypack/include/velocypack/Slice.h b/3rdParty/velocypack/include/velocypack/Slice.h index fcfb2be152..4dfc467406 100644 --- a/3rdParty/velocypack/include/velocypack/Slice.h +++ b/3rdParty/velocypack/include/velocypack/Slice.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -411,27 +412,6 @@ namespace arangodb { } } - std::vector keys () const { - std::vector keys; - ValueLength const n = length(); - keys.reserve(n); - for (ValueLength i = 0; i < n; ++i) { - keys.emplace_back(keyAt(i).copyString()); - } - return keys; - } - - void keys (std::vector& keys) const { - ValueLength const n = length(); - if (! keys.empty()) { - keys.clear(); - } - keys.reserve(n); - for (ValueLength i = 0; i < n; ++i) { - keys.emplace_back(keyAt(i).copyString()); - } - } - // return the pointer to the data for an External object char const* getExternal () const { return extractValue(); diff --git a/3rdParty/velocypack/include/velocypack/Value.h b/3rdParty/velocypack/include/velocypack/Value.h index dc23032d29..a55dd3863d 100644 --- a/3rdParty/velocypack/include/velocypack/Value.h +++ b/3rdParty/velocypack/include/velocypack/Value.h @@ -106,6 +106,21 @@ namespace arangodb { : _valueType(t), _cType(CType::UInt64) { _value.u = u; } +#ifdef __APPLE__ + // MacOS uses the following typedefs: + // - typedef unsigned int uint32_t; + // - typedef unsigned long long uint64_t; + // - typedef unsigned long size_t; + // not defining the method for type unsigned long will prevent + // users from constructing Value objects with a size_t input + + // however, defining the method on Linux and with MSVC will lead + // to ambiguous overloads, so this is restricted to __APPLE__ only + explicit Value (unsigned long i, ValueType t = ValueType::Int) + : _valueType(t), _cType(CType::UInt64) { + _value.i = static_cast(i); + } +#endif explicit Value (std::string const& s, ValueType t = ValueType::String) : _valueType(t), _cType(CType::String) { _value.s = &s; diff --git a/3rdParty/velocypack/include/velocypack/ValueType.h b/3rdParty/velocypack/include/velocypack/ValueType.h index 08948e6bba..f23a4dc118 100644 --- a/3rdParty/velocypack/include/velocypack/ValueType.h +++ b/3rdParty/velocypack/include/velocypack/ValueType.h @@ -27,6 +27,8 @@ #ifndef VELOCYPACK_VALUETYPE_H #define VELOCYPACK_VALUETYPE_H +#include + #include "velocypack-common.h" namespace arangodb { @@ -57,4 +59,6 @@ namespace arangodb { } // namespace arangodb::velocypack } // namespace arangodb +std::ostream& operator<< (std::ostream&, arangodb::velocypack::ValueType); + #endif diff --git a/3rdParty/velocypack/include/velocypack/velocypack-aliases.h b/3rdParty/velocypack/include/velocypack/velocypack-aliases.h index 58ad2b03e1..7ed745bf8a 100644 --- a/3rdParty/velocypack/include/velocypack/velocypack-aliases.h +++ b/3rdParty/velocypack/include/velocypack/velocypack-aliases.h @@ -29,10 +29,13 @@ #include "velocypack/vpack.h" +using VPackArrayIterator = arangodb::velocypack::ArrayIterator; using VPackBufferDumper = arangodb::velocypack::BufferDumper; using VPackBuilder = arangodb::velocypack::Builder; using VPackCharBuffer = arangodb::velocypack::CharBuffer; +using VPackCollection = arangodb::velocypack::Collection; using VPackException = arangodb::velocypack::Exception; +using VPackObjectIterator = arangodb::velocypack::ObjectIterator; using VPackOptions = arangodb::velocypack::Options; using VPackParser = arangodb::velocypack::Parser; using VPackStringDumper = arangodb::velocypack::StringDumper; diff --git a/3rdParty/velocypack/include/velocypack/vpack.h b/3rdParty/velocypack/include/velocypack/vpack.h index c24297d704..1e1dcffac4 100644 --- a/3rdParty/velocypack/include/velocypack/vpack.h +++ b/3rdParty/velocypack/include/velocypack/vpack.h @@ -29,8 +29,10 @@ #include "velocypack/velocypack-common.h" #include "velocypack/Builder.h" +#include "velocypack/Collection.h" #include "velocypack/Dump.h" #include "velocypack/Exception.h" +#include "velocypack/Iterator.h" #include "velocypack/Options.h" #include "velocypack/Parser.h" #include "velocypack/Slice.h" diff --git a/3rdParty/velocypack/src/Builder.cpp b/3rdParty/velocypack/src/Builder.cpp index 7ebb8e4e23..fcee680f14 100644 --- a/3rdParty/velocypack/src/Builder.cpp +++ b/3rdParty/velocypack/src/Builder.cpp @@ -295,7 +295,8 @@ void Builder::close () { // Intentionally leave _index[depth] intact to avoid future allocs! } -void Builder::set (Value const& item) { +uint8_t* Builder::set (Value const& item) { + auto const oldPos = _start + _pos; auto ctype = item.cType(); // This method builds a single further VPack item at the current @@ -521,6 +522,15 @@ void Builder::set (Value const& item) { throw Exception(Exception::BuilderUnexpectedType, "Cannot set a ValueType::Custom with this method"); } } + return oldPos; +} + +uint8_t* Builder::set (Slice const& item) { + ValueLength const l = item.byteSize(); + reserveSpace(l); + memcpy(_start + _pos, item.start(), l); + _pos += l; + return _start + _pos - l; } uint8_t* Builder::set (ValuePair const& pair) { @@ -615,80 +625,27 @@ void Builder::checkAttributeUniqueness (Slice const obj) const { } } -void Builder::add (std::string const& attrName, Value const& sub) { - if (_attrWritten) { - throw Exception(Exception::InternalError, "Attribute name already written"); - } - if (! _stack.empty()) { - ValueLength& tos = _stack.back(); - if (_start[tos] != 0x06 && - _start[tos] != 0x0b) { - throw Exception(Exception::BuilderNeedOpenObject); - } - reportAdd(tos); - } - set(Value(attrName, ValueType::String)); - set(sub); +uint8_t* Builder::add (std::string const& attrName, Value const& sub) { + return addInternal(attrName, sub); +} + +uint8_t* Builder::add (std::string const& attrName, Slice const& sub) { + return addInternal(attrName, sub); } uint8_t* Builder::add (std::string const& attrName, ValuePair const& sub) { - if (_attrWritten) { - throw Exception(Exception::InternalError, "Attribute name already written"); - } - if (! _stack.empty()) { - ValueLength& tos = _stack.back(); - if (_start[tos] != 0x06 && - _start[tos] != 0x0b) { - throw Exception(Exception::BuilderNeedOpenObject); - } - reportAdd(tos); - } - set(Value(attrName, ValueType::String)); - return set(sub); + return addInternal(attrName, sub); } -void Builder::add (Value const& sub) { - if (! _stack.empty()) { - ValueLength& tos = _stack.back(); - if (_start[tos] != 0x06 && _start[tos] != 0x0b) { - // no array or object - throw Exception(Exception::BuilderNeedOpenObject); - } - if (_start[tos] == 0x0b) { // object - if (! _attrWritten && ! sub.isString()) { - throw Exception(Exception::BuilderNeedOpenObject); - } - if (! _attrWritten) { - reportAdd(tos); - } - _attrWritten = ! _attrWritten; - } - else { - reportAdd(tos); - } - } - set(sub); +uint8_t* Builder::add (Value const& sub) { + return addInternal(sub); +} + +uint8_t* Builder::add (Slice const& sub) { + return addInternal(sub); } uint8_t* Builder::add (ValuePair const& sub) { - if (! _stack.empty()) { - ValueLength& tos = _stack.back(); - if (_start[tos] != 0x06 && _start[tos] != 0x0b) { - throw Exception(Exception::BuilderNeedOpenObject); - } - if (_start[tos] == 0x06) { // object - if (! _attrWritten && ! sub.isString()) { - throw Exception(Exception::BuilderNeedOpenObject); - } - if (! _attrWritten) { - reportAdd(tos); - } - _attrWritten = ! _attrWritten; - } - else { - reportAdd(tos); - } - } - return set(sub); + return addInternal(sub); } diff --git a/3rdParty/velocypack/src/Collection.cpp b/3rdParty/velocypack/src/Collection.cpp new file mode 100644 index 0000000000..3468a86f32 --- /dev/null +++ b/3rdParty/velocypack/src/Collection.cpp @@ -0,0 +1,179 @@ +//////////////////////////////////////////////////////////////////////////////// +/// @brief Library to build up VPack documents. +/// +/// DISCLAIMER +/// +/// Copyright 2015 ArangoDB GmbH, Cologne, Germany +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// +/// Copyright holder is ArangoDB GmbH, Cologne, Germany +/// +/// @author Max Neunhoeffer +/// @author Jan Steemann +/// @author Copyright 2015, ArangoDB GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +#include "velocypack/velocypack-common.h" +#include "velocypack/Collection.h" +#include "velocypack/Iterator.h" +#include "velocypack/Slice.h" +#include "velocypack/Value.h" +#include "velocypack/ValueType.h" + +using namespace arangodb::velocypack; + +void Collection::forEach (Slice const& slice, std::function const& cb) { + ArrayIterator it(slice); + ValueLength index = 0; + + while (it.valid()) { + if (! cb(it.value(), index)) { + // abort + return; + } + it.next(); + ++index; + } +} + +Builder Collection::filter (Slice const& slice, std::function const& cb) { + // construct a new Array + Builder b; + b.add(Value(ValueType::Array)); + + ArrayIterator it(slice); + ValueLength index = 0; + + while (it.valid()) { + Slice s = it.value(); + if (cb(s, index)) { + b.add(s); + } + it.next(); + ++index; + } + b.close(); + return b; +} + +Builder Collection::map (Slice const& slice, std::function const& cb) { + // construct a new Array + Builder b; + b.add(Value(ValueType::Array)); + + ArrayIterator it(slice); + ValueLength index = 0; + + while (it.valid()) { + b.add(cb(it.value(), index)); + it.next(); + ++index; + } + b.close(); + return b; +} + +Slice Collection::find (Slice const& slice, std::function const& cb) { + ArrayIterator it(slice); + ValueLength index = 0; + + while (it.valid()) { + Slice s = it.value(); + if (cb(s, index)) { + return s; + } + it.next(); + ++index; + } + + return Slice(); +} + +bool Collection::contains (Slice const& slice, std::function const& cb) { + ArrayIterator it(slice); + ValueLength index = 0; + + while (it.valid()) { + Slice s = it.value(); + if (cb(s, index)) { + return true; + } + it.next(); + ++index; + } + + return false; +} + +bool Collection::all (Slice const& slice, std::function const& cb) { + ArrayIterator it(slice); + ValueLength index = 0; + + while (it.valid()) { + Slice s = it.value(); + if (! cb(s, index)) { + return false; + } + it.next(); + ++index; + } + + return true; +} + +bool Collection::any (Slice const& slice, std::function const& cb) { + ArrayIterator it(slice); + ValueLength index = 0; + + while (it.valid()) { + Slice s = it.value(); + if (cb(s, index)) { + return true; + } + it.next(); + ++index; + } + + return false; +} + +std::vector Collection::keys (Slice const& slice) { + std::vector result; + + keys(slice, result); + + return result; +} + +void Collection::keys (Slice const& slice, std::vector& result) { + // pre-allocate result vector + result.reserve(slice.length()); + + ObjectIterator it(slice); + + while (it.valid()) { + result.emplace_back(it.key().copyString()); + it.next(); + } +} + +void Collection::keys (Slice const& slice, std::unordered_set& result) { + ObjectIterator it(slice); + + while (it.valid()) { + result.emplace(it.key().copyString()); + it.next(); + } +} + diff --git a/3rdParty/velocypack/src/Slice.cpp b/3rdParty/velocypack/src/Slice.cpp index d7739966c2..5f2f8ce110 100644 --- a/3rdParty/velocypack/src/Slice.cpp +++ b/3rdParty/velocypack/src/Slice.cpp @@ -25,6 +25,7 @@ //////////////////////////////////////////////////////////////////////////////// #include "velocypack/velocypack-common.h" +#include "velocypack/Builder.h" #include "velocypack/Dump.h" #include "velocypack/Slice.h" #include "velocypack/ValueType.h" @@ -144,7 +145,7 @@ unsigned int const Slice::FirstSubMap[256] = { 8, // 0x12, object with unsorted index table 0 }; - + std::string Slice::toString () const { return StringPrettyDumper::Dump(this); } diff --git a/3rdParty/velocypack/src/ValueType.cpp b/3rdParty/velocypack/src/ValueType.cpp index c09986d08e..f0b68bc9ec 100644 --- a/3rdParty/velocypack/src/ValueType.cpp +++ b/3rdParty/velocypack/src/ValueType.cpp @@ -51,3 +51,8 @@ char const* arangodb::velocypack::ValueTypeName (ValueType type) { return "unknown"; } + +std::ostream& operator<< (std::ostream& stream, ValueType type) { + stream << ValueTypeName(type); + return stream; +} diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 55bf5f927f..ab5e05ee98 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -53,6 +53,7 @@ include_directories(../3rdParty/velocypack/include) SET(LIB_ARANGO_VPACK ../3rdParty/velocypack/src/Builder.cpp + ../3rdParty/velocypack/src/Collection.cpp ../3rdParty/velocypack/src/Exception.cpp ../3rdParty/velocypack/src/Parser.cpp ../3rdParty/velocypack/src/Slice.cpp diff --git a/lib/Makefile.files b/lib/Makefile.files index b383087a61..28eaf2dde6 100644 --- a/lib/Makefile.files +++ b/lib/Makefile.files @@ -59,7 +59,7 @@ lib_libarango_a_SOURCES = \ lib/Basics/SpinLocker.cpp \ lib/Basics/ssl-helper.cpp \ lib/Basics/string-buffer.cpp \ - lib/Basics/stringBufferAdapter.cpp \ + lib/Basics/StringBufferAdapter.cpp \ lib/Basics/StringUtils.cpp \ lib/Basics/structures.cpp \ lib/Basics/system-functions.cpp \ @@ -110,6 +110,7 @@ endif lib_libarango_a_SOURCES += \ 3rdParty/velocypack/src/Builder.cpp \ + 3rdParty/velocypack/src/Collection.cpp \ 3rdParty/velocypack/src/Exception.cpp \ 3rdParty/velocypack/src/Parser.cpp \ 3rdParty/velocypack/src/Slice.cpp \