1
0
Fork 0

vpack library update

This commit is contained in:
Jan Steemann 2015-11-06 16:28:48 +01:00
parent 746c1a2573
commit 02fc1e4d20
16 changed files with 569 additions and 122 deletions

View File

@ -63,11 +63,11 @@ namespace arangodb {
private: private:
Buffer<uint8_t> _buffer; // Here we collect the result Buffer<uint8_t> _buffer; // Here we collect the result
uint8_t* _start; // Always points to the start of _buffer uint8_t* _start; // Always points to the start of _buffer
ValueLength _size; // Always contains the size of _buffer ValueLength _size; // Always contains the size of _buffer
ValueLength _pos; // the append position, always <= _size ValueLength _pos; // the append position, always <= _size
bool _attrWritten; // indicates that an attribute name bool _attrWritten; // indicates that an attribute name
// in an object has been written // in an object has been written
std::vector<ValueLength> _stack; // Start positions of std::vector<ValueLength> _stack; // Start positions of
// open objects/arrays // open objects/arrays
std::vector<std::vector<ValueLength>> _index; // Indices for starts std::vector<std::vector<ValueLength>> _index; // Indices for starts
@ -92,7 +92,7 @@ namespace arangodb {
// allocations. In the beginning, the _stack is empty, which // allocations. In the beginning, the _stack is empty, which
// allows to build a sequence of unrelated VPack objects in the // allows to build a sequence of unrelated VPack objects in the
// buffer. Whenever the stack is empty, one can use the start, // 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). // object(s).
void reserveSpace (ValueLength len) { void reserveSpace (ValueLength len) {
@ -145,15 +145,9 @@ namespace arangodb {
~Builder () { ~Builder () {
} }
Builder (Builder const& that) { Builder (Builder const& that)
_buffer = that._buffer; : _buffer(that._buffer), _start(_buffer.data()), _size(_buffer.size()), _pos(that._pos),
_start = _buffer.data(); _attrWritten(that._attrWritten), _stack(that._stack), _index(that._index), options(that.options) {
_size = _buffer.size();
_pos = that._pos;
_attrWritten = that._attrWritten;
_stack = that._stack;
_index = that._index;
options = that.options;
} }
Builder& operator= (Builder const& that) { Builder& operator= (Builder const& that) {
@ -233,13 +227,19 @@ namespace arangodb {
} }
// Add a subvalue into an object from a Value: // 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: // Add a subvalue into an object from a ValuePair:
uint8_t* add (std::string const& attrName, ValuePair const& sub); uint8_t* add (std::string const& attrName, ValuePair const& sub);
// Add a subvalue into an array from a Value: // 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: // Add a subvalue into an array from a ValuePair:
uint8_t* add (ValuePair const& sub); uint8_t* add (ValuePair const& sub);
@ -365,6 +365,46 @@ namespace arangodb {
private: private:
template<typename T>
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<typename T>
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) { void addCompoundValue (uint8_t type) {
reserveSpace(9); reserveSpace(9);
// an array is started: // an array is started:
@ -378,10 +418,12 @@ namespace arangodb {
_pos += 8; // Will be filled later with bytelength and nr subs _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 (ValuePair const& pair);
uint8_t* set (Slice const& item);
void reportAdd (ValueLength base) { void reportAdd (ValueLength base) {
size_t depth = _stack.size() - 1; size_t depth = _stack.size() - 1;
_index[depth].push_back(_pos - base); _index[depth].push_back(_pos - base);

View File

@ -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 <functional>
#include <string>
#include <unordered_set>
#include <vector>
#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<bool(Slice const&, ValueLength)> const& cb);
static void forEach (Slice const* slice, std::function<bool(Slice const&, ValueLength)> const& cb) {
return forEach(*slice, cb);
}
static Builder filter (Slice const& slice, std::function<bool(Slice const&, ValueLength)> const& cb);
static Builder filter (Slice const* slice, std::function<bool(Slice const&, ValueLength)> const& cb) {
return filter(*slice, cb);
}
static Builder map (Slice const& slice, std::function<Value(Slice const&, ValueLength)> const& cb);
static Builder map (Slice const* slice, std::function<Value(Slice const&, ValueLength)> const& cb) {
return map(*slice, cb);
}
static Slice find (Slice const& slice, std::function<bool(Slice const&, ValueLength)> const& cb);
static Slice find (Slice const* slice, std::function<bool(Slice const&, ValueLength)> const& cb) {
return find(*slice, cb);
}
static bool contains (Slice const& slice, std::function<bool(Slice const&, ValueLength)> const& cb);
static bool contains (Slice const* slice, std::function<bool(Slice const&, ValueLength)> const& cb) {
return contains(*slice, cb);
}
static bool all (Slice const& slice, std::function<bool(Slice const&, ValueLength)> const& cb);
static bool all (Slice const* slice, std::function<bool(Slice const&, ValueLength)> const& cb) {
return all(*slice, cb);
}
static bool any (Slice const& slice, std::function<bool(Slice const&, ValueLength)> const& cb);
static bool any (Slice const* slice, std::function<bool(Slice const&, ValueLength)> const& cb) {
return any(*slice, cb);
}
static std::vector<std::string> keys (Slice const& slice);
static std::vector<std::string> keys (Slice const* slice) {
return keys(*slice);
}
static void keys (Slice const& slice, std::vector<std::string>& result);
static void keys (Slice const* slice, std::vector<std::string>& result) {
return keys(*slice, result);
}
static void keys (Slice const& slice, std::unordered_set<std::string>& result);
static void keys (Slice const* slice, std::unordered_set<std::string>& result) {
return keys(*slice, result);
}
};
} // namespace arangodb::velocypack
} // namespace arangodb
#endif

View File

@ -55,15 +55,15 @@ namespace arangodb {
Options options; Options options;
enum UnsupportedTypeStrategy { enum UnsupportedTypeStrategy {
StrategyNullify, StrategyNullifyUnsupportedType,
StrategyFail StrategyFailOnUnsupportedType
}; };
Dumper (Dumper const&) = delete; Dumper (Dumper const&) = delete;
Dumper& operator= (Dumper const&) = delete; Dumper& operator= (Dumper const&) = delete;
Dumper (T& buffer, UnsupportedTypeStrategy strategy = StrategyFail) Dumper (T& buffer, UnsupportedTypeStrategy strategy = StrategyFailOnUnsupportedType)
: _buffer(&buffer), _strategy(strategy), _indentation(0) { : strategy(strategy), _buffer(&buffer), _indentation(0) {
} }
~Dumper () { ~Dumper () {
@ -99,24 +99,24 @@ namespace arangodb {
internalDump(slice, nullptr); 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 dumper(buffer, strategy);
dumper.dump(slice); 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 dumper(buffer, strategy);
dumper.dump(slice); dumper.dump(slice);
} }
static T Dump (Slice const& slice, UnsupportedTypeStrategy strategy = StrategyFail) { static T Dump (Slice const& slice, UnsupportedTypeStrategy strategy = StrategyFailOnUnsupportedType) {
T buffer; T buffer;
Dumper dumper(buffer, strategy); Dumper dumper(buffer, strategy);
dumper.dump(slice); dumper.dump(slice);
return buffer; return buffer;
} }
static T Dump (Slice const* slice, UnsupportedTypeStrategy strategy = StrategyFail) { static T Dump (Slice const* slice, UnsupportedTypeStrategy strategy = StrategyFailOnUnsupportedType) {
T buffer; T buffer;
Dumper dumper(buffer, strategy); Dumper dumper(buffer, strategy);
dumper.dump(slice); dumper.dump(slice);
@ -473,7 +473,7 @@ namespace arangodb {
} }
void handleUnsupportedType (Slice const*) { void handleUnsupportedType (Slice const*) {
if (_strategy == StrategyNullify) { if (strategy == StrategyNullifyUnsupportedType) {
_buffer->append("null", 4); _buffer->append("null", 4);
return; return;
} }
@ -481,14 +481,15 @@ namespace arangodb {
throw Exception(Exception::NoJsonEquivalent); throw Exception(Exception::NoJsonEquivalent);
} }
public:
UnsupportedTypeStrategy strategy;
private: private:
T* _buffer; T* _buffer;
std::function<bool(T*, Slice const*, Slice const*)> _callback; std::function<bool(T*, Slice const*, Slice const*)> _callback;
UnsupportedTypeStrategy _strategy;
int _indentation; int _indentation;
}; };

View File

@ -109,7 +109,7 @@ namespace arangodb {
case BuilderObjectNotSealed: case BuilderObjectNotSealed:
return "Object not sealed"; return "Object not sealed";
case BuilderNeedOpenObject: case BuilderNeedOpenObject:
return "Need open array or object for close() call"; return "Need open Array or Object for close() call";
case BuilderUnexpectedType: case BuilderUnexpectedType:
return "Unexpected type"; return "Unexpected type";
case BuilderUnexpectedValue: case BuilderUnexpectedValue:

View File

@ -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

View File

@ -30,6 +30,7 @@
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
#include <string> #include <string>
#include <unordered_set>
#include <vector> #include <vector>
#include <ostream> #include <ostream>
#include <functional> #include <functional>
@ -411,27 +412,6 @@ namespace arangodb {
} }
} }
std::vector<std::string> keys () const {
std::vector<std::string> 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<std::string>& 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 // return the pointer to the data for an External object
char const* getExternal () const { char const* getExternal () const {
return extractValue<char const*>(); return extractValue<char const*>();

View File

@ -106,6 +106,21 @@ namespace arangodb {
: _valueType(t), _cType(CType::UInt64) { : _valueType(t), _cType(CType::UInt64) {
_value.u = u; _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<uint64_t>(i);
}
#endif
explicit Value (std::string const& s, ValueType t = ValueType::String) explicit Value (std::string const& s, ValueType t = ValueType::String)
: _valueType(t), _cType(CType::String) { : _valueType(t), _cType(CType::String) {
_value.s = &s; _value.s = &s;

View File

@ -27,6 +27,8 @@
#ifndef VELOCYPACK_VALUETYPE_H #ifndef VELOCYPACK_VALUETYPE_H
#define VELOCYPACK_VALUETYPE_H #define VELOCYPACK_VALUETYPE_H
#include <ostream>
#include "velocypack-common.h" #include "velocypack-common.h"
namespace arangodb { namespace arangodb {
@ -57,4 +59,6 @@ namespace arangodb {
} // namespace arangodb::velocypack } // namespace arangodb::velocypack
} // namespace arangodb } // namespace arangodb
std::ostream& operator<< (std::ostream&, arangodb::velocypack::ValueType);
#endif #endif

View File

@ -29,10 +29,13 @@
#include "velocypack/vpack.h" #include "velocypack/vpack.h"
using VPackArrayIterator = arangodb::velocypack::ArrayIterator;
using VPackBufferDumper = arangodb::velocypack::BufferDumper; using VPackBufferDumper = arangodb::velocypack::BufferDumper;
using VPackBuilder = arangodb::velocypack::Builder; using VPackBuilder = arangodb::velocypack::Builder;
using VPackCharBuffer = arangodb::velocypack::CharBuffer; using VPackCharBuffer = arangodb::velocypack::CharBuffer;
using VPackCollection = arangodb::velocypack::Collection;
using VPackException = arangodb::velocypack::Exception; using VPackException = arangodb::velocypack::Exception;
using VPackObjectIterator = arangodb::velocypack::ObjectIterator;
using VPackOptions = arangodb::velocypack::Options; using VPackOptions = arangodb::velocypack::Options;
using VPackParser = arangodb::velocypack::Parser; using VPackParser = arangodb::velocypack::Parser;
using VPackStringDumper = arangodb::velocypack::StringDumper; using VPackStringDumper = arangodb::velocypack::StringDumper;

View File

@ -29,8 +29,10 @@
#include "velocypack/velocypack-common.h" #include "velocypack/velocypack-common.h"
#include "velocypack/Builder.h" #include "velocypack/Builder.h"
#include "velocypack/Collection.h"
#include "velocypack/Dump.h" #include "velocypack/Dump.h"
#include "velocypack/Exception.h" #include "velocypack/Exception.h"
#include "velocypack/Iterator.h"
#include "velocypack/Options.h" #include "velocypack/Options.h"
#include "velocypack/Parser.h" #include "velocypack/Parser.h"
#include "velocypack/Slice.h" #include "velocypack/Slice.h"

View File

@ -295,7 +295,8 @@ void Builder::close () {
// Intentionally leave _index[depth] intact to avoid future allocs! // 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(); auto ctype = item.cType();
// This method builds a single further VPack item at the current // 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"); 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) { 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) { uint8_t* Builder::add (std::string const& attrName, Value const& sub) {
if (_attrWritten) { return addInternal<Value>(attrName, sub);
throw Exception(Exception::InternalError, "Attribute name already written"); }
}
if (! _stack.empty()) { uint8_t* Builder::add (std::string const& attrName, Slice const& sub) {
ValueLength& tos = _stack.back(); return addInternal<Slice>(attrName, sub);
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, ValuePair const& sub) { uint8_t* Builder::add (std::string const& attrName, ValuePair const& sub) {
if (_attrWritten) { return addInternal<ValuePair>(attrName, sub);
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 Builder::add (Value const& sub) { uint8_t* Builder::add (Value const& sub) {
if (! _stack.empty()) { return addInternal<Value>(sub);
ValueLength& tos = _stack.back(); }
if (_start[tos] != 0x06 && _start[tos] != 0x0b) {
// no array or object uint8_t* Builder::add (Slice const& sub) {
throw Exception(Exception::BuilderNeedOpenObject); return addInternal<Slice>(sub);
}
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 (ValuePair const& sub) { uint8_t* Builder::add (ValuePair const& sub) {
if (! _stack.empty()) { return addInternal<ValuePair>(sub);
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);
} }

179
3rdParty/velocypack/src/Collection.cpp vendored Normal file
View File

@ -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<bool(Slice const&, ValueLength)> 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<bool(Slice const&, ValueLength)> 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<Value(Slice const&, ValueLength)> 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<bool(Slice const&, ValueLength)> 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<bool(Slice const&, ValueLength)> 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<bool(Slice const&, ValueLength)> 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<bool(Slice const&, ValueLength)> 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<std::string> Collection::keys (Slice const& slice) {
std::vector<std::string> result;
keys(slice, result);
return result;
}
void Collection::keys (Slice const& slice, std::vector<std::string>& 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<std::string>& result) {
ObjectIterator it(slice);
while (it.valid()) {
result.emplace(it.key().copyString());
it.next();
}
}

View File

@ -25,6 +25,7 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include "velocypack/velocypack-common.h" #include "velocypack/velocypack-common.h"
#include "velocypack/Builder.h"
#include "velocypack/Dump.h" #include "velocypack/Dump.h"
#include "velocypack/Slice.h" #include "velocypack/Slice.h"
#include "velocypack/ValueType.h" #include "velocypack/ValueType.h"

View File

@ -51,3 +51,8 @@ char const* arangodb::velocypack::ValueTypeName (ValueType type) {
return "unknown"; return "unknown";
} }
std::ostream& operator<< (std::ostream& stream, ValueType type) {
stream << ValueTypeName(type);
return stream;
}

View File

@ -53,6 +53,7 @@ include_directories(../3rdParty/velocypack/include)
SET(LIB_ARANGO_VPACK SET(LIB_ARANGO_VPACK
../3rdParty/velocypack/src/Builder.cpp ../3rdParty/velocypack/src/Builder.cpp
../3rdParty/velocypack/src/Collection.cpp
../3rdParty/velocypack/src/Exception.cpp ../3rdParty/velocypack/src/Exception.cpp
../3rdParty/velocypack/src/Parser.cpp ../3rdParty/velocypack/src/Parser.cpp
../3rdParty/velocypack/src/Slice.cpp ../3rdParty/velocypack/src/Slice.cpp

View File

@ -59,7 +59,7 @@ lib_libarango_a_SOURCES = \
lib/Basics/SpinLocker.cpp \ lib/Basics/SpinLocker.cpp \
lib/Basics/ssl-helper.cpp \ lib/Basics/ssl-helper.cpp \
lib/Basics/string-buffer.cpp \ lib/Basics/string-buffer.cpp \
lib/Basics/stringBufferAdapter.cpp \ lib/Basics/StringBufferAdapter.cpp \
lib/Basics/StringUtils.cpp \ lib/Basics/StringUtils.cpp \
lib/Basics/structures.cpp \ lib/Basics/structures.cpp \
lib/Basics/system-functions.cpp \ lib/Basics/system-functions.cpp \
@ -110,6 +110,7 @@ endif
lib_libarango_a_SOURCES += \ lib_libarango_a_SOURCES += \
3rdParty/velocypack/src/Builder.cpp \ 3rdParty/velocypack/src/Builder.cpp \
3rdParty/velocypack/src/Collection.cpp \
3rdParty/velocypack/src/Exception.cpp \ 3rdParty/velocypack/src/Exception.cpp \
3rdParty/velocypack/src/Parser.cpp \ 3rdParty/velocypack/src/Parser.cpp \
3rdParty/velocypack/src/Slice.cpp \ 3rdParty/velocypack/src/Slice.cpp \