1
0
Fork 0

updated vpack library

This commit is contained in:
Jan Steemann 2015-11-24 10:32:58 +01:00
parent e4a3c462c7
commit d24b46bb71
35 changed files with 3807 additions and 3820 deletions

View File

@ -39,30 +39,21 @@ namespace arangodb {
class Builder;
class AttributeTranslator {
public:
AttributeTranslator(AttributeTranslator const&) = delete;
AttributeTranslator& operator=(AttributeTranslator const&) = delete;
AttributeTranslator ()
: _builder(), _count(0) {
}
AttributeTranslator() : _builder(), _count(0) {}
~AttributeTranslator () {
}
~AttributeTranslator() {}
size_t count () const {
return _count;
}
size_t count() const { return _count; }
void add(std::string const& key, uint64_t id);
void seal();
Builder* builder () {
return _builder.get();
}
Builder* builder() { return _builder.get(); }
// translate from string to id
uint8_t const* translate(std::string const& key) const;
@ -74,7 +65,6 @@ namespace arangodb {
uint8_t const* translate(uint64_t id) const;
private:
std::unique_ptr<Builder> _builder;
std::unordered_map<std::string, uint8_t const*> _keyToId;
std::unordered_map<uint64_t, uint8_t const*> _idToKey;

View File

@ -37,27 +37,19 @@ namespace arangodb {
template <typename T>
class Buffer {
public:
Buffer ()
: _buffer(_local),
_alloc(sizeof(_local)),
_pos(0) {
Buffer() : _buffer(_local), _alloc(sizeof(_local)), _pos(0) {
#ifdef VELOCYPACK_DEBUG
// poison memory
memset(_buffer, 0xa5, _alloc);
#endif
}
explicit Buffer (ValueLength expectedLength)
: Buffer() {
explicit Buffer(ValueLength expectedLength) : Buffer() {
reserve(expectedLength);
}
Buffer (Buffer const& that)
: Buffer() {
Buffer(Buffer const& that) : Buffer() {
if (that._pos > 0) {
if (that._pos > sizeof(_local)) {
_buffer = new T[that._pos];
@ -84,15 +76,12 @@ namespace arangodb {
return *this;
}
Buffer (Buffer&& that)
: Buffer() {
Buffer(Buffer&& that) : Buffer() {
if (that._buffer == that._local) {
memcpy(_buffer, that._buffer, that._pos);
_pos = that._pos;
that._pos = 0;
}
else {
} else {
_buffer = that._buffer;
_alloc = that._alloc;
_pos = that._pos;
@ -102,34 +91,22 @@ namespace arangodb {
}
}
~Buffer () {
reset();
}
~Buffer() { reset(); }
inline T* data () {
return _buffer;
}
inline T* data() { return _buffer; }
inline T const* data () const {
return _buffer;
}
inline T const* data() const { return _buffer; }
inline ValueLength size () const {
return _pos;
}
inline ValueLength size() const { return _pos; }
inline ValueLength length () const {
return _pos;
}
inline ValueLength length() const { return _pos; }
std::string toString() const {
std::string result(reinterpret_cast<char const*>(_buffer), _pos);
return std::move(result);
}
void clear () {
reset();
}
void clear() { reset(); }
void reset() {
if (_buffer != _local) {
@ -199,11 +176,7 @@ namespace arangodb {
}
private:
inline ValueLength capacity () const {
return _alloc;
}
inline ValueLength capacity() const { return _alloc; }
T* _buffer;
ValueLength _alloc;
@ -211,7 +184,6 @@ namespace arangodb {
// an already initialized space for small values
T _local[192];
};
typedef Buffer<char> CharBuffer;

View File

@ -46,7 +46,6 @@ namespace arangodb {
namespace velocypack {
class Builder {
friend class Parser; // The parser needs access to internals.
public:
@ -57,12 +56,9 @@ namespace arangodb {
uint64_t offset;
};
void reserve (ValueLength len) {
reserveSpace(len);
}
void reserve(ValueLength len) { reserveSpace(len); }
private:
std::shared_ptr<Buffer<uint8_t>> _buffer; // Here we collect the result
uint8_t* _start; // Always points to the start of _buffer
ValueLength _size; // Always contains the size of _buffer
@ -126,33 +122,28 @@ namespace arangodb {
std::vector<ValueLength>& offsets);
public:
Options const* options;
// Constructor and destructor:
explicit Builder (std::shared_ptr<Buffer<uint8_t>>& buffer, Options const* options = &Options::Defaults)
: _buffer(buffer),
_pos(0),
options(options) {
explicit Builder(std::shared_ptr<Buffer<uint8_t>>& buffer,
Options const* options = &Options::Defaults)
: _buffer(buffer), _pos(0), options(options) {
if (_buffer.get() == nullptr) {
throw Exception(Exception::InternalError, "Buffer cannot be a nullptr");
}
_start = _buffer->data();
_size = _buffer->size();
VELOCYPACK_ASSERT(options != nullptr);
if (options == nullptr) {
throw Exception(Exception::InternalError, "Options cannot be a nullptr");
}
}
explicit Builder(Options const* options = &Options::Defaults)
: _buffer(new Buffer<uint8_t>()),
_pos(0),
options(options) {
: _buffer(new Buffer<uint8_t>()), _pos(0), options(options) {
_start = _buffer->data();
_size = _buffer->size();
VELOCYPACK_ASSERT(options != nullptr);
if (options == nullptr) {
throw Exception(Exception::InternalError, "Options cannot be a nullptr");
}
@ -160,21 +151,26 @@ namespace arangodb {
// The rule of five:
~Builder () {
}
~Builder() {}
Builder(Builder const& that)
: _buffer(that._buffer), _start(_buffer->data()), _size(_buffer->size()), _pos(that._pos),
_stack(that._stack), _index(that._index), options(that.options) {
VELOCYPACK_ASSERT(options != nullptr);
: _buffer(that._buffer),
_start(_buffer->data()),
_size(_buffer->size()),
_pos(that._pos),
_stack(that._stack),
_index(that._index),
options(that.options) {
if (that._buffer == nullptr) {
throw Exception(Exception::InternalError, "Buffer of Builder is already gone");
throw Exception(Exception::InternalError,
"Buffer of Builder is already gone");
}
}
Builder& operator=(Builder const& that) {
if (that._buffer == nullptr) {
throw Exception(Exception::InternalError, "Buffer of Builder is already gone");
throw Exception(Exception::InternalError,
"Buffer of Builder is already gone");
}
_buffer = that._buffer;
_start = _buffer->data();
@ -183,13 +179,13 @@ namespace arangodb {
_stack = that._stack;
_index = that._index;
options = that.options;
VELOCYPACK_ASSERT(options != nullptr);
return *this;
}
Builder(Builder&& that) {
if (that._buffer == nullptr) {
throw Exception(Exception::InternalError, "Buffer of Builder is already gone");
throw Exception(Exception::InternalError,
"Buffer of Builder is already gone");
}
_buffer = that._buffer;
that._buffer.reset();
@ -201,7 +197,6 @@ namespace arangodb {
_index.clear();
_index.swap(that._index);
options = that.options;
VELOCYPACK_ASSERT(options != nullptr);
that._start = nullptr;
that._size = 0;
that._pos = 0;
@ -209,7 +204,8 @@ namespace arangodb {
Builder& operator=(Builder&& that) {
if (that._buffer == nullptr) {
throw Exception(Exception::InternalError, "Buffer of Builder is already gone");
throw Exception(Exception::InternalError,
"Buffer of Builder is already gone");
}
_buffer = that._buffer;
that._buffer.reset();
@ -221,7 +217,6 @@ namespace arangodb {
_index.clear();
_index.swap(that._index);
options = that.options;
VELOCYPACK_ASSERT(options != nullptr);
that._start = nullptr;
that._size = 0;
that._pos = 0;
@ -229,13 +224,12 @@ namespace arangodb {
}
// get a const reference to the Builder's Buffer object
std::shared_ptr<Buffer<uint8_t>> const& buffer () const {
return _buffer;
}
std::shared_ptr<Buffer<uint8_t>> const& buffer() const { return _buffer; }
uint8_t const* data() const {
if (_buffer == nullptr) {
throw Exception(Exception::InternalError, "Buffer of Builder is already gone");
throw Exception(Exception::InternalError,
"Buffer of Builder is already gone");
}
return _buffer.get()->data();
@ -244,12 +238,13 @@ namespace arangodb {
std::string toString() const;
// get a non-const reference to the Builder's Buffer object
std::shared_ptr<Buffer<uint8_t>>& buffer () {
return _buffer;
}
std::shared_ptr<Buffer<uint8_t>>& buffer() { return _buffer; }
static Builder clone (Slice const& slice, Options const* options = &Options::Defaults) {
VELOCYPACK_ASSERT(options != nullptr);
static Builder clone(Slice const& slice,
Options const* options = &Options::Defaults) {
if (options == nullptr) {
throw Exception(Exception::InternalError, "Options cannot be a nullptr");
}
Builder b(options);
b.add(slice);
@ -271,9 +266,7 @@ namespace arangodb {
}
// Return a Slice of the result:
Slice slice () const {
return Slice(start(), options);
}
Slice slice() const { return Slice(start(), options); }
// Compute the actual size here, but only when sealed
ValueLength size() const {
@ -283,9 +276,7 @@ namespace arangodb {
return _pos;
}
bool isClosed () const throw() {
return _stack.empty();
}
bool isClosed() const throw() { return _stack.empty(); }
// Add a subvalue into an object from a Value:
uint8_t* add(std::string const& attrName, Value const& sub);
@ -391,12 +382,10 @@ namespace arangodb {
if (v >= 0 && v <= 9) {
reserveSpace(1);
_start[_pos++] = static_cast<uint8_t>(0x30 + v);
}
else if (v < 0 && v >= -6) {
} else if (v < 0 && v >= -6) {
reserveSpace(1);
_start[_pos++] = static_cast<uint8_t>(0x40 + v);
}
else {
} else {
appendInt(v, 0x1f);
}
}
@ -405,8 +394,7 @@ namespace arangodb {
if (v <= 9) {
reserveSpace(1);
_start[_pos++] = static_cast<uint8_t>(0x30 + v);
}
else {
} else {
appendUInt(v, 0x27);
}
}
@ -426,8 +414,7 @@ namespace arangodb {
_start[_pos++] = 0xbf;
// write string length
appendLength(strLen, 8);
}
else {
} else {
// short string
_start[_pos++] = static_cast<uint8_t>(0x40 + strLen);
}
@ -440,40 +427,64 @@ namespace arangodb {
addCompoundValue(unindexed ? 0x13 : 0x06);
}
// this is an alias for addArray()
inline void openArray(bool unindexed = false) {
addCompoundValue(unindexed ? 0x13 : 0x06);
}
inline void addObject(bool unindexed = false) {
addCompoundValue(unindexed ? 0x14 : 0x0b);
}
private:
// this is an alias for addObject()
inline void openObject(bool unindexed = false) {
addCompoundValue(unindexed ? 0x14 : 0x0b);
}
private:
template <typename T>
uint8_t* addInternal(T const& sub) {
bool haveReported = false;
if (!_stack.empty()) {
ValueLength& tos = _stack.back();
if (_start[tos] != 0x06 && _start[tos] != 0x13) {
throw Exception(Exception::BuilderNeedOpenArray);
}
reportAdd(tos);
haveReported = true;
}
try {
return set(sub);
} catch (...) {
// clean up in case of an exception
if (haveReported) {
cleanupAdd();
}
throw;
}
}
template <typename T>
uint8_t* addInternal(std::string const& attrName, T const& sub) {
bool haveReported = false;
if (!_stack.empty()) {
ValueLength& tos = _stack.back();
if (_start[tos] != 0x0b && _start[tos] != 0x14) {
throw Exception(Exception::BuilderNeedOpenObject);
}
reportAdd(tos);
haveReported = true;
}
try {
if (options->attributeTranslator != nullptr) {
// check if a translation for the attribute name exists
uint8_t const* translated = options->attributeTranslator->translate(attrName);
uint8_t const* translated =
options->attributeTranslator->translate(attrName);
if (translated != nullptr) {
set(Slice(options->attributeTranslator->translate(attrName), options));
set(Slice(options->attributeTranslator->translate(attrName),
options));
return set(sub);
}
// otherwise fall through to regular behavior
@ -481,6 +492,13 @@ namespace arangodb {
set(Value(attrName, ValueType::String));
return set(sub);
} catch (...) {
// clean up in case of an exception
if (haveReported) {
cleanupAdd();
}
throw;
}
}
void addCompoundValue(uint8_t type) {
@ -502,6 +520,11 @@ namespace arangodb {
uint8_t* set(Slice const& item);
void cleanupAdd() {
size_t depth = _stack.size() - 1;
_index[depth].pop_back();
}
void reportAdd(ValueLength base) {
size_t depth = _stack.size() - 1;
_index[depth].push_back(_pos - base);
@ -523,8 +546,7 @@ namespace arangodb {
vSize++;
_start[_pos++] = static_cast<uint8_t>(v & 0xff);
v >>= 8;
}
while (v != 0);
} while (v != 0);
_start[save] = base + vSize;
}
@ -540,8 +562,7 @@ namespace arangodb {
do {
xSize++;
x >>= 8;
}
while (x >= 0x80);
} while (x >= 0x80);
return xSize + 1;
}
@ -550,8 +571,7 @@ namespace arangodb {
uint64_t x;
if (vSize == 8) {
x = toUInt64(v);
}
else {
} else {
int64_t shift = 1LL << (vSize * 8 - 1); // will never overflow!
x = v >= 0 ? static_cast<uint64_t>(v)
: static_cast<uint64_t>(v + shift) + shift;

View File

@ -40,51 +40,63 @@ namespace arangodb {
namespace velocypack {
class Collection {
public:
enum VisitationOrder {
PreOrder = 1,
PostOrder = 2
};
enum VisitationOrder { PreOrder = 1, PostOrder = 2 };
Collection() = delete;
Collection(Collection const&) = delete;
Collection& operator=(Collection const&) = 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);
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);
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 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);
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);
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);
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);
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);
}
@ -102,49 +114,60 @@ namespace arangodb {
static void keys(Slice const& slice, std::unordered_set<std::string>& 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);
}
static Builder values(Slice const& slice);
static Builder values (Slice const* slice) {
return values(*slice);
}
static Builder values(Slice const* slice) { return values(*slice); }
static Builder keep(Slice const& slice, std::vector<std::string> const& keys);
static Builder keep (Slice const& slice, std::unordered_set<std::string> const& keys);
static Builder keep(Slice const& slice,
std::unordered_set<std::string> const& keys);
static Builder keep (Slice const* slice, std::vector<std::string> const& keys) {
static Builder keep(Slice const* slice,
std::vector<std::string> const& keys) {
return keep(*slice, keys);
}
static Builder keep (Slice const* slice, std::unordered_set<std::string> const& keys) {
static Builder keep(Slice const* slice,
std::unordered_set<std::string> const& keys) {
return keep(*slice, keys);
}
static Builder remove (Slice const& slice, std::vector<std::string> const& keys);
static Builder remove(Slice const& slice,
std::vector<std::string> const& keys);
static Builder remove (Slice const& slice, std::unordered_set<std::string> const& keys);
static Builder remove(Slice const& slice,
std::unordered_set<std::string> const& keys);
static Builder remove (Slice const* slice, std::vector<std::string> const& keys) {
static Builder remove(Slice const* slice,
std::vector<std::string> const& keys) {
return remove(*slice, keys);
}
static Builder remove (Slice const* slice, std::unordered_set<std::string> const& keys) {
static Builder remove(Slice const* slice,
std::unordered_set<std::string> const& keys) {
return remove(*slice, keys);
}
static Builder merge(Slice const& left, Slice const& right, bool mergeValues);
static Builder merge (Slice const* left, Slice const* right, bool mergeValues) {
static Builder merge(Slice const* left, Slice const* right,
bool mergeValues) {
return merge(*left, *right, mergeValues);
}
static void visitRecursive (Slice const& slice, VisitationOrder order, std::function<bool(Slice const&, Slice const&)> const& func);
static void visitRecursive(
Slice const& slice, VisitationOrder order,
std::function<bool(Slice const&, Slice const&)> const& func);
static void visitRecursive (Slice const* slice, VisitationOrder order, std::function<bool(Slice const&, Slice const&)> const& func) {
static void visitRecursive(
Slice const* slice, VisitationOrder order,
std::function<bool(Slice const&, Slice const&)> const& func) {
visitRecursive(*slice, order, func);
}
};

View File

@ -40,9 +40,7 @@ namespace arangodb {
// Dumps VPack into a JSON output string
class Dumper {
public:
Options const* options;
Dumper(Dumper const&) = delete;
@ -50,18 +48,17 @@ namespace arangodb {
Dumper(Sink* sink, Options const* options = &Options::Defaults)
: options(options), _sink(sink), _indentation(0) {
if (sink == nullptr) {
throw Exception(Exception::InternalError, "Sink cannot be a nullptr");
}
if (options == nullptr) {
throw Exception(Exception::InternalError, "Options cannot be a nullptr");
}
}
~Dumper () {
}
~Dumper() {}
Sink* sink () const {
return _sink;
}
Sink* sink() const { return _sink; }
void dump(Slice const& slice) {
_indentation = 0;
@ -69,37 +66,35 @@ namespace arangodb {
dumpValue(&slice);
}
void dump (Slice const* slice) {
dump(*slice);
}
void dump(Slice const* slice) { dump(*slice); }
static void dump (Slice const& slice, Sink* sink, Options const* options = &Options::Defaults) {
static void dump(Slice const& slice, Sink* sink,
Options const* options = &Options::Defaults) {
Dumper dumper(sink, options);
dumper.dump(slice);
}
static void dump (Slice const* slice, Sink* sink, Options const* options = &Options::Defaults) {
static void dump(Slice const* slice, Sink* sink,
Options const* options = &Options::Defaults) {
dump(*slice, sink, options);
}
static std::string toString (Slice const& slice, Options const* options = &Options::Defaults) {
static std::string toString(Slice const& slice,
Options const* options = &Options::Defaults) {
std::string buffer;
StringSink sink(&buffer);
dump(slice, &sink, options);
return std::move(buffer);
}
static std::string toString (Slice const* slice, Options const* options = &Options::Defaults) {
static std::string toString(Slice const* slice,
Options const* options = &Options::Defaults) {
return std::move(toString(*slice, options));
}
void append (Slice const& slice) {
dumpValue(&slice);
}
void append(Slice const& slice) { dumpValue(&slice); }
void append (Slice const* slice) {
dumpValue(slice);
}
void append(Slice const* slice) { dumpValue(slice); }
void appendString(char const* src, ValueLength len) {
_sink->reserve(2 + len);
@ -118,7 +113,6 @@ namespace arangodb {
void appendUInt(uint64_t);
private:
void dumpInteger(Slice const*);
void dumpString(char const*, ValueLength);
@ -147,11 +141,9 @@ namespace arangodb {
}
private:
Sink* _sink;
int _indentation;
};
} // namespace arangodb::velocypack

View File

@ -64,6 +64,7 @@ namespace arangodb {
BuilderUnexpectedType = 34,
BuilderUnexpectedValue = 35,
BuilderNeedSubvalue = 36,
BuilderExternalsDisallowed = 37,
UnknownError = 999
};
@ -73,23 +74,16 @@ namespace arangodb {
std::string _msg;
public:
Exception(ExceptionType type, std::string const& msg)
: _type(type), _msg(msg) {}
Exception (ExceptionType type, std::string const& msg) : _type(type), _msg(msg) {
}
Exception(ExceptionType type, char const* msg) : _type(type), _msg(msg) {}
Exception (ExceptionType type, char const* msg) : _type(type), _msg(msg) {
}
explicit Exception(ExceptionType type) : Exception(type, message(type)) {}
explicit Exception (ExceptionType type) : Exception(type, message(type)) {
}
char const* what() const throw() { return _msg.c_str(); }
char const* what() const throw() {
return _msg.c_str();
}
ExceptionType errorCode () const throw() {
return _type;
}
ExceptionType errorCode() const throw() { return _type; }
static char const* message(ExceptionType type) throw() {
switch (type) {
@ -137,13 +131,14 @@ namespace arangodb {
return "Unexpected type";
case BuilderUnexpectedValue:
return "Unexpected value";
case BuilderExternalsDisallowed:
return "Externals are not allowed in this configuration";
case UnknownError:
default:
return "Unknown error";
}
}
};
} // namespace arangodb::velocypack

View File

@ -40,13 +40,13 @@ namespace arangodb {
struct HexDump {
HexDump() = delete;
HexDump (Slice const& slice, int valuesPerLine = 16, std::string const& separator = " ")
: slice(slice), valuesPerLine(valuesPerLine), separator(separator) {
}
HexDump(Slice const& slice, int valuesPerLine = 16,
std::string const& separator = " ")
: slice(slice), valuesPerLine(valuesPerLine), separator(separator) {}
HexDump (Slice const* slice, int valuesPerLine = 16, std::string const& separator = " ")
: HexDump(*slice, valuesPerLine, separator) {
}
HexDump(Slice const* slice, int valuesPerLine = 16,
std::string const& separator = " ")
: HexDump(*slice, valuesPerLine, separator) {}
static std::string toHex(uint8_t value);

View File

@ -39,14 +39,11 @@ namespace arangodb {
namespace velocypack {
class ArrayIterator {
public:
ArrayIterator() = delete;
ArrayIterator(Slice const& slice)
: _slice(slice), _size(_slice.length()), _position(0), _current(nullptr) {
if (slice.type() != ValueType::Array) {
throw Exception(Exception::InvalidValueType, "Expecting Array slice");
}
@ -57,8 +54,10 @@ namespace arangodb {
}
ArrayIterator(ArrayIterator const& other)
: _slice(other._slice), _size(other._size), _position(other._position), _current(other._current) {
}
: _slice(other._slice),
_size(other._size),
_position(other._position),
_current(other._current) {}
ArrayIterator& operator=(ArrayIterator const& other) {
_slice = other._slice;
@ -73,8 +72,7 @@ namespace arangodb {
++_position;
if (_position <= _size && _current != nullptr) {
_current += Slice(_current, _slice.options).byteSize();
}
else {
} else {
_current = nullptr;
}
return *this;
@ -98,13 +96,9 @@ namespace arangodb {
return _slice.at(_position);
}
ArrayIterator begin () {
return ArrayIterator(_slice);
}
ArrayIterator begin() { return ArrayIterator(_slice); }
ArrayIterator begin () const {
return ArrayIterator(_slice);
}
ArrayIterator begin() const { return ArrayIterator(_slice); }
ArrayIterator end() {
auto it = ArrayIterator(_slice);
@ -118,9 +112,7 @@ namespace arangodb {
return it;
}
inline bool valid () const throw() {
return (_position < _size);
}
inline bool valid() const throw() { return (_position < _size); }
inline Slice value() const {
if (_position >= _size) {
@ -134,24 +126,15 @@ namespace arangodb {
return valid();
}
inline ValueLength index () const throw() {
return _position;
}
inline ValueLength index() const throw() { return _position; }
inline ValueLength size () const throw() {
return _size;
}
inline ValueLength size() const throw() { return _size; }
inline bool isFirst () const throw() {
return (_position == 0);
}
inline bool isFirst() const throw() { return (_position == 0); }
inline bool isLast () const throw() {
return (_position + 1 >= _size);
}
inline bool isLast() const throw() { return (_position + 1 >= _size); }
private:
Slice _slice;
ValueLength _size;
ValueLength _position;
@ -159,13 +142,9 @@ namespace arangodb {
};
class ObjectIterator {
public:
struct ObjectPair {
ObjectPair (Slice const& key, Slice const& value)
: key(key), value(value) {
}
ObjectPair(Slice const& key, Slice const& value) : key(key), value(value) {}
Slice const key;
Slice const value;
};
@ -174,7 +153,6 @@ namespace arangodb {
ObjectIterator(Slice const& slice)
: _slice(slice), _size(_slice.length()), _position(0), _current(nullptr) {
if (slice.type() != ValueType::Object) {
throw Exception(Exception::InvalidValueType, "Expecting Object slice");
}
@ -185,8 +163,10 @@ namespace arangodb {
}
ObjectIterator(ObjectIterator const& other)
: _slice(other._slice), _size(other._size), _position(other._position), _current(other._current) {
}
: _slice(other._slice),
_size(other._size),
_position(other._position),
_current(other._current) {}
ObjectIterator& operator=(ObjectIterator const& other) {
_slice = other._slice;
@ -204,8 +184,7 @@ namespace arangodb {
_current += Slice(_current, _slice.options).byteSize();
// skip over value
_current += Slice(_current, _slice.options).byteSize();
}
else {
} else {
_current = nullptr;
}
return *this;
@ -230,13 +209,9 @@ namespace arangodb {
return ObjectPair(_slice.keyAt(_position), _slice.valueAt(_position));
}
ObjectIterator begin () {
return ObjectIterator(_slice);
}
ObjectIterator begin() { return ObjectIterator(_slice); }
ObjectIterator begin () const {
return ObjectIterator(_slice);
}
ObjectIterator begin() const { return ObjectIterator(_slice); }
ObjectIterator end() {
auto it = ObjectIterator(_slice);
@ -250,9 +225,7 @@ namespace arangodb {
return it;
}
inline bool valid () const throw() {
return (_position < _size);
}
inline bool valid() const throw() { return (_position < _size); }
inline Slice key() const {
if (_position >= _size) {
@ -280,24 +253,15 @@ namespace arangodb {
return valid();
}
inline ValueLength index () const throw() {
return _position;
}
inline ValueLength index() const throw() { return _position; }
inline ValueLength size () const throw() {
return _size;
}
inline ValueLength size() const throw() { return _size; }
inline bool isFirst () const throw() {
return (_position == 0);
}
inline bool isFirst() const throw() { return (_position == 0); }
inline bool isLast () const throw() {
return (_position + 1 >= _size);
}
inline bool isLast() const throw() { return (_position + 1 >= _size); }
private:
Slice _slice;
ValueLength _size;
ValueLength _position;
@ -307,12 +271,16 @@ namespace arangodb {
} // namespace arangodb::velocypack
} // namespace arangodb
std::ostream& operator<< (std::ostream&, arangodb::velocypack::ArrayIterator const*);
std::ostream& operator<<(std::ostream&,
arangodb::velocypack::ArrayIterator const*);
std::ostream& operator<< (std::ostream&, arangodb::velocypack::ArrayIterator const&);
std::ostream& operator<<(std::ostream&,
arangodb::velocypack::ArrayIterator const&);
std::ostream& operator<< (std::ostream&, arangodb::velocypack::ObjectIterator const*);
std::ostream& operator<<(std::ostream&,
arangodb::velocypack::ObjectIterator const*);
std::ostream& operator<< (std::ostream&, arangodb::velocypack::ObjectIterator const&);
std::ostream& operator<<(std::ostream&,
arangodb::velocypack::ObjectIterator const&);
#endif

View File

@ -39,17 +39,16 @@ namespace arangodb {
class Slice;
struct AttributeExcludeHandler {
virtual ~AttributeExcludeHandler () {
}
virtual ~AttributeExcludeHandler() {}
virtual bool shouldExclude(Slice const& key, int nesting) = 0;
};
struct CustomTypeHandler {
virtual ~CustomTypeHandler () {
}
virtual ~CustomTypeHandler() {}
virtual void toJson (Slice const& value, Dumper* dumper, Slice const& base) = 0;
virtual void toJson(Slice const& value, Dumper* dumper,
Slice const& base) = 0;
virtual ValueLength byteSize(Slice const& value) = 0;
};
@ -59,8 +58,7 @@ namespace arangodb {
FailOnUnsupportedType
};
Options () {
}
Options() {}
// Dumper behavior when a VPack value is serialized to JSON that
// has no JSON equivalent
@ -103,6 +101,10 @@ namespace arangodb {
// JSON with a Dumper
bool escapeForwardSlashes = false;
// disallow using type External (to prevent injection of arbitrary pointer
// values as a security precaution)
bool disallowExternals = false;
// default options with the above settings
static Options Defaults;
};

View File

@ -41,16 +41,11 @@ namespace arangodb {
namespace velocypack {
class Parser {
// This class can parse JSON very rapidly, but only from contiguous
// blocks of memory. It builds the result using the Builder.
struct ParsedNumber {
ParsedNumber ()
: intValue(0),
doubleValue(0.0),
isInteger(true) {
}
ParsedNumber() : intValue(0), doubleValue(0.0), isInteger(true) {}
void addDigit(int i) {
if (isInteger) {
@ -91,7 +86,6 @@ namespace arangodb {
int _nesting;
public:
Options const* options;
Parser(Parser const&) = delete;
@ -99,7 +93,6 @@ namespace arangodb {
Parser(Options const* options = &Options::Defaults)
: _start(nullptr), _size(0), _pos(0), _nesting(0), options(options) {
VELOCYPACK_ASSERT(options != nullptr);
if (options == nullptr) {
@ -108,29 +101,30 @@ namespace arangodb {
_b.options = options;
}
static Builder fromJson (std::string const& json, Options const* options = &Options::Defaults) {
static Builder fromJson(std::string const& json,
Options const* options = &Options::Defaults) {
Parser parser(options);
parser.parse(json);
return parser.steal();
}
static Builder fromJson (uint8_t const* start, size_t size, Options const* options = &Options::Defaults) {
static Builder fromJson(uint8_t const* start, size_t size,
Options const* options = &Options::Defaults) {
Parser parser(options);
parser.parse(start, size);
return parser.steal();
}
ValueLength parse(std::string const& json, bool multi = false) {
return parse(reinterpret_cast<uint8_t const*>(json.c_str()), json.size(), multi);
return parse(reinterpret_cast<uint8_t const*>(json.c_str()), json.size(),
multi);
}
ValueLength parse (char const* start, size_t size,
bool multi = false) {
ValueLength parse(char const* start, size_t size, bool multi = false) {
return parse(reinterpret_cast<uint8_t const*>(start), size, multi);
}
ValueLength parse (uint8_t const* start, size_t size,
bool multi = false) {
ValueLength parse(uint8_t const* start, size_t size, bool multi = false) {
_start = start;
_size = size;
_pos = 0;
@ -144,29 +138,23 @@ namespace arangodb {
Builder&& steal() {
if (_b._buffer == nullptr) {
throw Exception(Exception::InternalError, "Buffer of Builder is already gone");
throw Exception(Exception::InternalError,
"Buffer of Builder is already gone");
}
return std::move(_b);
}
// Beware, only valid as long as you do not parse more, use steal
// to move the data out!
uint8_t const* start () {
return _b.start();
}
uint8_t const* start() { return _b.start(); }
// Returns the position at the time when the just reported error
// occurred, only use when handling an exception.
size_t errorPos () const {
return _pos > 0 ? _pos - 1 : _pos;
}
size_t errorPos() const { return _pos > 0 ? _pos - 1 : _pos; }
void clear () {
_b.clear();
}
void clear() { _b.clear(); }
private:
inline int peek() const {
if (_pos >= _size) {
return -1;
@ -181,13 +169,9 @@ namespace arangodb {
return static_cast<int>(_start[_pos++]);
}
inline void unconsume () {
--_pos;
}
inline void unconsume() { --_pos; }
inline void reset () {
_pos = 0;
}
inline void reset() { _pos = 0; }
ValueLength parseInternal(bool multi);
@ -263,13 +247,9 @@ namespace arangodb {
return i;
}
inline void increaseNesting () {
++_nesting;
}
inline void increaseNesting() { ++_nesting; }
inline void decreaseNesting () {
--_nesting;
}
inline void decreaseNesting() { --_nesting; }
void parseNumber();
@ -280,7 +260,6 @@ namespace arangodb {
void parseObject();
void parseJson();
};
} // namespace arangodb::velocypack

View File

@ -38,13 +38,11 @@ namespace arangodb {
namespace velocypack {
struct Sink {
Sink () {
}
Sink() {}
Sink(Sink const&) = delete;
Sink& operator=(Sink const&) = delete;
virtual ~Sink () {
}
virtual ~Sink() {}
virtual void push_back(char c) = 0;
virtual void append(std::string const& p) = 0;
virtual void append(char const* p) = 0;
@ -54,29 +52,21 @@ namespace arangodb {
template <typename T>
struct ByteBufferSinkImpl final : public Sink {
explicit ByteBufferSinkImpl (Buffer<T>* buffer)
: buffer(buffer) {
}
explicit ByteBufferSinkImpl(Buffer<T>* buffer) : buffer(buffer) {}
void push_back (char c) override final {
buffer->push_back(c);
}
void push_back(char c) override final { buffer->push_back(c); }
void append(std::string const& p) override final {
buffer->append(p.c_str(), p.size());
}
void append (char const* p) override final {
buffer->append(p, strlen(p));
}
void append(char const* p) override final { buffer->append(p, strlen(p)); }
void append(char const* p, ValueLength len) override final {
buffer->append(p, len);
}
void reserve (ValueLength len) override final {
buffer->reserve(len);
}
void reserve(ValueLength len) override final { buffer->reserve(len); }
Buffer<T>* buffer;
};
@ -85,29 +75,19 @@ namespace arangodb {
template <typename T>
struct StringSinkImpl final : public Sink {
explicit StringSinkImpl (T* buffer)
: buffer(buffer) {
}
explicit StringSinkImpl(T* buffer) : buffer(buffer) {}
void push_back (char c) override final {
buffer->push_back(c);
}
void push_back(char c) override final { buffer->push_back(c); }
void append (std::string const& p) override final {
buffer->append(p);
}
void append(std::string const& p) override final { buffer->append(p); }
void append (char const* p) override final {
buffer->append(p, strlen(p));
}
void append(char const* p) override final { buffer->append(p, strlen(p)); }
void append(char const* p, ValueLength len) override final {
buffer->append(p, len);
}
void reserve (ValueLength len) override final {
buffer->reserve(len);
}
void reserve(ValueLength len) override final { buffer->reserve(len); }
T* buffer;
};
@ -116,17 +96,11 @@ namespace arangodb {
template <typename T>
struct StreamSinkImpl final : public Sink {
explicit StreamSinkImpl (T* stream)
: stream(stream) {
}
explicit StreamSinkImpl(T* stream) : stream(stream) {}
void push_back (char c) override final {
*stream << c;
}
void push_back(char c) override final { *stream << c; }
void append (std::string const& p) override final {
*stream << p;
}
void append(std::string const& p) override final { *stream << p; }
void append(char const* p) override final {
stream->write(p, static_cast<std::streamsize>(strlen(p)));
@ -136,8 +110,7 @@ namespace arangodb {
stream->write(p, static_cast<std::streamsize>(len));
}
void reserve (ValueLength) override final {
}
void reserve(ValueLength) override final {}
T* stream;
};

View File

@ -48,7 +48,6 @@ namespace arangodb {
uint64_t fasthash64(void const*, size_t, uint64_t);
class Slice {
// This class provides read only access to a VPack value, it is
// intentionally light-weight (only one pointer value), such that
// it can easily be used to traverse larger VPack values.
@ -58,15 +57,13 @@ namespace arangodb {
uint8_t const* _start;
public:
Options const* options;
// constructor for an empty Value of type None
Slice ()
: Slice("\x00", &Options::Defaults) {
}
Slice() : Slice("\x00", &Options::Defaults) {}
explicit Slice (uint8_t const* start, Options const* options = &Options::Defaults)
explicit Slice(uint8_t const* start,
Options const* options = &Options::Defaults)
: _start(start), options(options) {
VELOCYPACK_ASSERT(options != nullptr);
}
@ -76,13 +73,11 @@ namespace arangodb {
VELOCYPACK_ASSERT(options != nullptr);
}
Slice (Slice const& other)
: _start(other._start), options(other.options) {
Slice(Slice const& other) : _start(other._start), options(other.options) {
VELOCYPACK_ASSERT(options != nullptr);
}
Slice (Slice&& other)
: _start(other._start), options(other.options) {
Slice(Slice&& other) : _start(other._start), options(other.options) {
VELOCYPACK_ASSERT(options != nullptr);
}
@ -100,37 +95,23 @@ namespace arangodb {
return *this;
}
uint8_t const* begin () {
return _start;
}
uint8_t const* begin() { return _start; }
uint8_t const* begin () const {
return _start;
}
uint8_t const* begin() const { return _start; }
uint8_t const* end () {
return _start + byteSize();
}
uint8_t const* end() { return _start + byteSize(); }
uint8_t const* end () const {
return _start + byteSize();
}
uint8_t const* end() const { return _start + byteSize(); }
// No destructor, does not take part in memory management,
// get the type for the slice
inline ValueType type () const {
return TypeMap[head()];
}
inline ValueType type() const { return TypeMap[head()]; }
char const* typeName () const {
return valueTypeName(type());
}
char const* typeName() const { return valueTypeName(type()); }
// pointer to the head byte
uint8_t const* start () const {
return _start;
}
uint8_t const* start() const { return _start; }
// pointer to the head byte
template <typename T>
@ -139,118 +120,83 @@ namespace arangodb {
}
// value of the head byte
inline uint8_t head () const {
return *_start;
}
inline uint8_t head() const { return *_start; }
inline uint64_t hash() const {
return fasthash64(start(), byteSize(), 0xdeadbeef);
}
// check if slice is of the specified type
inline bool isType (ValueType t) const {
return type() == t;
}
inline bool isType(ValueType t) const { return type() == t; }
// check if slice is a None object
bool isNone () const {
return isType(ValueType::None);
}
bool isNone() const { return isType(ValueType::None); }
// check if slice is a Null object
bool isNull () const {
return isType(ValueType::Null);
}
bool isNull() const { return isType(ValueType::Null); }
// check if slice is a Bool object
bool isBool () const {
return isType(ValueType::Bool);
}
bool isBool() const { return isType(ValueType::Bool); }
// check if slice is a Bool object - this is an alias for isBool()
bool isBoolean () const {
return isBool();
}
bool isBoolean() const { return isBool(); }
// check if slice is the Boolean value true
bool isTrue() const { return head() == 0x1a; }
// check if slice is the Boolean value false
bool isFalse() const { return head() == 0x19; }
// check if slice is an Array object
bool isArray () const {
return isType(ValueType::Array);
}
bool isArray() const { return isType(ValueType::Array); }
// check if slice is an Object object
bool isObject () const {
return isType(ValueType::Object);
}
bool isObject() const { return isType(ValueType::Object); }
// check if slice is a Double object
bool isDouble () const {
return isType(ValueType::Double);
}
bool isDouble() const { return isType(ValueType::Double); }
// check if slice is a UTCDate object
bool isUTCDate () const {
return isType(ValueType::UTCDate);
}
bool isUTCDate() const { return isType(ValueType::UTCDate); }
// check if slice is an External object
bool isExternal () const {
return isType(ValueType::External);
}
bool isExternal() const { return isType(ValueType::External); }
// check if slice is a MinKey object
bool isMinKey () const {
return isType(ValueType::MinKey);
}
bool isMinKey() const { return isType(ValueType::MinKey); }
// check if slice is a MaxKey object
bool isMaxKey () const {
return isType(ValueType::MaxKey);
}
bool isMaxKey() const { return isType(ValueType::MaxKey); }
// check if slice is an Int object
bool isInt () const {
return isType(ValueType::Int);
}
bool isInt() const { return isType(ValueType::Int); }
// check if slice is a UInt object
bool isUInt () const {
return isType(ValueType::UInt);
}
bool isUInt() const { return isType(ValueType::UInt); }
// check if slice is a SmallInt object
bool isSmallInt () const {
return isType(ValueType::SmallInt);
}
bool isSmallInt() const { return isType(ValueType::SmallInt); }
// check if slice is a String object
bool isString () const {
return isType(ValueType::String);
}
bool isString() const { return isType(ValueType::String); }
// check if slice is a Binary object
bool isBinary () const {
return isType(ValueType::Binary);
}
bool isBinary() const { return isType(ValueType::Binary); }
// check if slice is a BCD
bool isBCD () const {
return isType(ValueType::BCD);
}
bool isBCD() const { return isType(ValueType::BCD); }
// check if slice is a Custom type
bool isCustom () const {
return isType(ValueType::Custom);
}
bool isCustom() const { return isType(ValueType::Custom); }
// check if a slice is any number type
bool isInteger() const {
return isType(ValueType::Int) || isType(ValueType::UInt) || isType(ValueType::SmallInt);
return isType(ValueType::Int) || isType(ValueType::UInt) ||
isType(ValueType::SmallInt);
}
// check if slice is any Number-type object
bool isNumber () const {
return isInteger() || isDouble();
}
bool isNumber() const { return isInteger() || isDouble(); }
bool isSorted() const {
auto const h = head();
@ -259,18 +205,20 @@ namespace arangodb {
// return the value for a Bool object
bool getBool() const {
assertType(ValueType::Bool);
if (type() != ValueType::Bool) {
throw Exception(Exception::InvalidValueType, "Expecting type Bool");
}
return (head() == 0x1a); // 0x19 == false, 0x1a == true
}
// return the value for a Bool object - this is an alias for getBool()
bool getBoolean () const {
return getBool();
}
bool getBoolean() const { return getBool(); }
// return the value for a Double object
double getDouble() const {
assertType(ValueType::Double);
if (type() != ValueType::Double) {
throw Exception(Exception::InvalidValueType, "Expecting type Double");
}
union {
uint64_t dv;
double d;
@ -294,20 +242,19 @@ namespace arangodb {
// - 0x09 : array with 8-byte index table entries
Slice at(ValueLength index) const {
if (!isType(ValueType::Array)) {
throw Exception(Exception::InvalidValueType, "Expecting Array");
throw Exception(Exception::InvalidValueType, "Expecting type Array");
}
return getNth(index);
}
Slice operator[] (ValueLength index) const {
return at(index);
}
Slice operator[](ValueLength index) const { return at(index); }
// return the number of members for an Array or Object object
ValueLength length() const {
if (type() != ValueType::Array && type() != ValueType::Object) {
throw Exception(Exception::InvalidValueType, "Expecting Array or Object");
throw Exception(Exception::InvalidValueType,
"Expecting type Array or Object");
}
auto const h = head();
@ -330,8 +277,7 @@ namespace arangodb {
ValueLength firstSubOffset = findDataOffset(h);
Slice first(_start + firstSubOffset, options);
return (end - firstSubOffset) / first.byteSize();
}
else if (offsetSize < 8) {
} else if (offsetSize < 8) {
return readInteger<ValueLength>(_start + offsetSize + 1, offsetSize);
}
@ -340,17 +286,25 @@ namespace arangodb {
// extract a key from an Object at the specified index
// - 0x0a : empty object
// - 0x0b : object with 1-byte index table entries, sorted by attribute name
// - 0x0c : object with 2-byte index table entries, sorted by attribute name
// - 0x0d : object with 4-byte index table entries, sorted by attribute name
// - 0x0e : object with 8-byte index table entries, sorted by attribute name
// - 0x0f : object with 1-byte index table entries, not sorted by attribute name
// - 0x10 : object with 2-byte index table entries, not sorted by attribute name
// - 0x11 : object with 4-byte index table entries, not sorted by attribute name
// - 0x12 : object with 8-byte index table entries, not sorted by attribute name
// - 0x0b : object with 1-byte index table entries, sorted by attribute
// name
// - 0x0c : object with 2-byte index table entries, sorted by attribute
// name
// - 0x0d : object with 4-byte index table entries, sorted by attribute
// name
// - 0x0e : object with 8-byte index table entries, sorted by attribute
// name
// - 0x0f : object with 1-byte index table entries, not sorted by
// attribute name
// - 0x10 : object with 2-byte index table entries, not sorted by
// attribute name
// - 0x11 : object with 4-byte index table entries, not sorted by
// attribute name
// - 0x12 : object with 8-byte index table entries, not sorted by
// attribute name
Slice keyAt(ValueLength index) const {
if (!isType(ValueType::Object)) {
throw Exception(Exception::InvalidValueType, "Expecting Object");
throw Exception(Exception::InvalidValueType, "Expecting type Object");
}
return getNthKey(index, true);
@ -358,7 +312,7 @@ namespace arangodb {
Slice valueAt(ValueLength index) const {
if (!isType(ValueType::Object)) {
throw Exception(Exception::InvalidValueType, "Expecting Object");
throw Exception(Exception::InvalidValueType, "Expecting type Object");
}
Slice key = getNthKey(index, false);
@ -408,7 +362,9 @@ namespace arangodb {
// return the pointer to the data for an External object
char const* getExternal() const {
assertType(ValueType::External);
if (type() != ValueType::External) {
throw Exception(Exception::InvalidValueType, "Expecting type External");
}
return extractValue<char const*>();
}
@ -444,13 +400,11 @@ namespace arangodb {
throw Exception(Exception::NumberOutOfRange);
}
return static_cast<T>(v);
}
else {
} else {
// unsigned integral type
if (isDouble()) {
auto v = getDouble();
if (v < 0.0 ||
v > static_cast<double>(UINT64_MAX) ||
if (v < 0.0 || v > static_cast<double>(UINT64_MAX) ||
v > static_cast<double>(std::numeric_limits<T>::max())) {
throw Exception(Exception::NumberOutOfRange);
}
@ -488,6 +442,9 @@ namespace arangodb {
// return the value for a UTCDate object
int64_t getUTCDate() const {
if (type() != ValueType::UTCDate) {
throw Exception(Exception::InvalidValueType, "Expecting type UTCDate");
}
assertType(ValueType::UTCDate);
uint64_t v = readInteger<uint64_t>(_start + 1, sizeof(uint64_t));
return toInt64(v);
@ -518,7 +475,8 @@ namespace arangodb {
if (h >= 0x40 && h <= 0xbe) {
// short UTF-8 String
ValueLength length = h - 0x40;
return std::string(reinterpret_cast<char const*>(_start + 1), static_cast<size_t>(length));
return std::string(reinterpret_cast<char const*>(_start + 1),
static_cast<size_t>(length));
}
if (h == 0xbf) {
@ -532,7 +490,9 @@ namespace arangodb {
// return the value for a Binary object
uint8_t const* getBinary(ValueLength& length) const {
assertType(ValueType::Binary);
if (type() != ValueType::Binary) {
throw Exception(Exception::InvalidValueType, "Expecting type Binary");
}
uint8_t const h = head();
if (h >= 0xc0 && h <= 0xc7) {
@ -546,7 +506,9 @@ namespace arangodb {
// return a copy of the value for a Binary object
std::vector<uint8_t> copyBinary() const {
assertType(ValueType::Binary);
if (type() != ValueType::Binary) {
throw Exception(Exception::InvalidValueType, "Expecting type Binary");
}
uint8_t const h = head();
if (h >= 0xc0 && h <= 0xc7) {
@ -554,8 +516,9 @@ namespace arangodb {
ValueLength length = readInteger<ValueLength>(_start + 1, h - 0xbf);
checkValueLength(length);
out.reserve(static_cast<size_t>(length));
out.insert(out.end(), _start + 1 + h - 0xbf, _start + 1 + h - 0xbf + length);
return out;
out.insert(out.end(), _start + 1 + h - 0xbf,
_start + 1 + h - 0xbf + length);
return std::move(out);
}
throw Exception(Exception::InvalidValueType, "Expecting type Binary");
@ -614,7 +577,8 @@ namespace arangodb {
auto const h = head();
if (h == 0xbf) {
// long UTF-8 String
return static_cast<ValueLength>(1 + 8 + readInteger<ValueLength>(_start + 1, 8));
return static_cast<ValueLength>(
1 + 8 + readInteger<ValueLength>(_start + 1, 8));
}
// short UTF-8 String
@ -623,18 +587,21 @@ namespace arangodb {
case ValueType::Binary: {
auto const h = head();
return static_cast<ValueLength>(1 + h - 0xbf + readInteger<ValueLength>(_start + 1, h - 0xbf));
return static_cast<ValueLength>(
1 + h - 0xbf + readInteger<ValueLength>(_start + 1, h - 0xbf));
}
case ValueType::BCD: {
auto const h = head();
if (h <= 0xcf) {
// positive BCD
return static_cast<ValueLength>(1 + h - 0xc7 + readInteger<ValueLength>(_start + 1, h - 0xc7));
return static_cast<ValueLength>(
1 + h - 0xc7 + readInteger<ValueLength>(_start + 1, h - 0xc7));
}
// negative BCD
return static_cast<ValueLength>(1 + h - 0xcf + readInteger<ValueLength>(_start + 1, h - 0xcf));
return static_cast<ValueLength>(
1 + h - 0xcf + readInteger<ValueLength>(_start + 1, h - 0xcf));
}
case ValueType::Custom: {
@ -660,7 +627,6 @@ namespace arangodb {
std::string hexType() const;
private:
Slice getFromCompactObject(std::string const& attribute) const;
ValueLength findDataOffset(uint8_t head) const {
@ -705,22 +671,17 @@ namespace arangodb {
}
// perform a linear search for the specified attribute inside an Object
Slice searchObjectKeyLinear (std::string const& attribute,
ValueLength ieBase,
ValueLength offsetSize,
ValueLength n) const;
Slice searchObjectKeyLinear(std::string const& attribute, ValueLength ieBase,
ValueLength offsetSize, ValueLength n) const;
// perform a binary search for the specified attribute inside an Object
Slice searchObjectKeyBinary (std::string const& attribute,
ValueLength ieBase,
ValueLength offsetSize,
ValueLength n) const;
Slice searchObjectKeyBinary(std::string const& attribute, ValueLength ieBase,
ValueLength offsetSize, ValueLength n) const;
// assert that the slice is of a specific type
// can be used for debugging and removed in production
#ifdef VELOCYPACK_ASSERT
inline void assertType (ValueType) const {
}
inline void assertType(ValueType) const {}
#else
inline void assertType(ValueType type) const {
VELOCYPACK_ASSERT(this->type() == type);
@ -729,7 +690,8 @@ namespace arangodb {
// extracts a value from the slice and converts it into a
// built-in type
template<typename T> T extractValue () const {
template <typename T>
T extractValue() const {
union {
T value;
char binary[sizeof(T)];
@ -739,7 +701,6 @@ namespace arangodb {
}
private:
static ValueType const TypeMap[256];
static unsigned int const WidthMap[32];
static unsigned int const FirstSubMap[32];
@ -749,13 +710,15 @@ namespace arangodb {
} // namespace arangodb
namespace std {
template<> struct hash<arangodb::velocypack::Slice> {
template <>
struct hash<arangodb::velocypack::Slice> {
size_t operator()(arangodb::velocypack::Slice const& slice) const {
return slice.hash();
}
};
template<> struct equal_to<arangodb::velocypack::Slice> {
template <>
struct equal_to<arangodb::velocypack::Slice> {
bool operator()(arangodb::velocypack::Slice const& a,
arangodb::velocypack::Slice const& b) const {
if (*a.start() != *b.start()) {

View File

@ -42,7 +42,6 @@ namespace arangodb {
friend class Builder;
public:
enum class CType {
None = 0,
Bool = 1,
@ -55,7 +54,6 @@ namespace arangodb {
};
private:
ValueType _valueType;
CType _cType; // denotes variant used, 0: none
@ -67,17 +65,14 @@ namespace arangodb {
std::string const* s; // 5: std::string
char const* c; // 6: char const*
void const* e; // external
}
_value;
} _value;
bool _unindexed;
public:
#ifdef SWIG
Value () : _valueType(ValueType::None), _cType(CType::None),
_unindexed(false) {
}
Value()
: _valueType(ValueType::None), _cType(CType::None), _unindexed(false) {}
#else
Value() = delete;
#endif
@ -85,7 +80,6 @@ namespace arangodb {
// creates a Value with the specified type Array or Object
explicit Value(ValueType t, bool allowUnindexed = false)
: _valueType(t), _cType(CType::None), _unindexed(allowUnindexed) {
if (allowUnindexed &&
(_valueType != ValueType::Array && _valueType != ValueType::Object)) {
throw Exception(Exception::InvalidValueType, "Expecting compound type");
@ -153,17 +147,11 @@ namespace arangodb {
_value.s = &s;
}
ValueType valueType () const {
return _valueType;
}
ValueType valueType() const { return _valueType; }
CType cType () const {
return _cType;
}
CType cType() const { return _cType; }
bool isString () const {
return _valueType == ValueType::String;
}
bool isString() const { return _valueType == ValueType::String; }
bool getBool() const {
VELOCYPACK_ASSERT(_cType == CType::Bool);
@ -199,7 +187,6 @@ namespace arangodb {
VELOCYPACK_ASSERT(_cType == CType::CharPtr);
return _value.c;
}
};
class ValuePair {
@ -208,38 +195,26 @@ namespace arangodb {
ValueType _type;
public:
ValuePair(uint8_t const* start, uint64_t size,
ValueType type = ValueType::Binary)
: _start(start), _size(size), _type(type) {
}
: _start(start), _size(size), _type(type) {}
ValuePair(char const* start, uint64_t size,
ValueType type = ValueType::Binary)
: _start(reinterpret_cast<uint8_t const*>(start)),
_size(size), _type(type) {
}
_size(size),
_type(type) {}
explicit ValuePair (uint64_t size,
ValueType type = ValueType::Binary)
: _start(nullptr), _size(size), _type(type) {
}
explicit ValuePair(uint64_t size, ValueType type = ValueType::Binary)
: _start(nullptr), _size(size), _type(type) {}
uint8_t const* getStart () const {
return _start;
}
uint8_t const* getStart() const { return _start; }
uint64_t getSize () const {
return _size;
}
uint64_t getSize() const { return _size; }
ValueType valueType () const {
return _type;
}
ValueType valueType() const { return _type; }
bool isString () const {
return _type == ValueType::String;
}
bool isString() const { return _type == ValueType::String; }
};
} // namespace arangodb::velocypack

View File

@ -40,8 +40,9 @@ namespace arangodb {
Version& operator=(Version const&) = delete;
Version(int majorValue, int minorValue, int patchValue)
: majorValue(majorValue), minorValue(minorValue), patchValue(patchValue) {
}
: majorValue(majorValue),
minorValue(minorValue),
patchValue(patchValue) {}
std::string toString() const;

View File

@ -35,7 +35,8 @@ namespace {
using VPackValueLength = arangodb::velocypack::ValueLength;
#endif
// conditional typedefs, only used when the respective headers are already included
// conditional typedefs, only used when the respective headers are already
// included
#ifdef VELOCYPACK_ITERATOR_H
#ifndef VELOCYPACK_ALIAS_ITERATOR
@ -108,7 +109,8 @@ namespace {
#ifndef VELOCYPACK_ALIAS_OPTIONS
#define VELOCYPACK_ALIAS_OPTIONS
using VPackOptions = arangodb::velocypack::Options;
using VPackAttributeExcludeHandler = arangodb::velocypack::AttributeExcludeHandler;
using VPackAttributeExcludeHandler =
arangodb::velocypack::AttributeExcludeHandler;
using VPackCustomTypeHandler = arangodb::velocypack::CustomTypeHandler;
#endif
#endif
@ -149,4 +151,3 @@ namespace {
#endif
#endif
}

View File

@ -104,12 +104,10 @@ namespace arangodb {
p += 7;
if (reverse) {
--source;
}
else {
} else {
++source;
}
}
while (v & 0x80);
} while (v & 0x80);
return len;
}
@ -124,8 +122,7 @@ namespace arangodb {
value >>= 7;
}
*dst-- = static_cast<uint8_t>(value & 0x7f);
}
else {
} else {
while (value >= 0x80) {
*dst++ = static_cast<uint8_t>(value | 0x80);
value >>= 7;
@ -166,8 +163,7 @@ namespace arangodb {
do {
value += static_cast<T>(*start++) << x;
x += 8;
}
while (start < end);
} while (start < end);
return value;
}
@ -180,8 +176,7 @@ namespace arangodb {
do {
*start++ = static_cast<uint8_t>(value & 0xff);
value >>= 8;
}
while (start < end);
} while (start < end);
}
} // namespace arangodb::velocypack

View File

@ -73,7 +73,8 @@ uint8_t const* AttributeTranslator::translate (std::string const& key) const {
}
// translate from string to id
uint8_t const* AttributeTranslator::translate (char const* key, ValueLength length) const {
uint8_t const* AttributeTranslator::translate(char const* key,
ValueLength length) const {
auto it = _keyToId.find(std::string(key, length));
if (it == _keyToId.end()) {
@ -93,4 +94,3 @@ uint8_t const* AttributeTranslator::translate (uint64_t id) const {
return (*it).second;
}

View File

@ -49,8 +49,7 @@ void Builder::doActualSort (std::vector<SortEntry>& entries) {
uint64_t sizea = a.nameSize;
uint8_t const* pb = b.nameStart;
uint64_t sizeb = b.nameSize;
size_t const compareLength
= static_cast<size_t>((std::min)(sizea, sizeb));
size_t const compareLength = static_cast<size_t>((std::min)(sizea, sizeb));
int res = memcmp(pa, pb, compareLength);
return (res < 0 || (res == 0 && sizea < sizeb));
@ -81,14 +80,12 @@ void Builder::sortObjectIndexShort (uint8_t* objBase,
auto cmp = [&](ValueLength a, ValueLength b) -> bool {
uint8_t const* aa = objBase + a;
uint8_t const* bb = objBase + b;
if (*aa >= 0x40 && *aa <= 0xbe &&
*bb >= 0x40 && *bb <= 0xbe) {
if (*aa >= 0x40 && *aa <= 0xbe && *bb >= 0x40 && *bb <= 0xbe) {
// The fast path, short strings:
uint8_t m = (std::min)(*aa - 0x40, *bb - 0x40);
int c = memcmp(aa + 1, bb + 1, static_cast<size_t>(m));
return (c < 0 || (c == 0 && *aa < *bb));
}
else {
} else {
uint64_t lena;
uint64_t lenb;
aa = findAttrName(aa, lena);
@ -103,7 +100,6 @@ void Builder::sortObjectIndexShort (uint8_t* objBase,
void Builder::sortObjectIndexLong(uint8_t* objBase,
std::vector<ValueLength>& offsets) {
// on some platforms we can use a thread-local vector
#if __llvm__ == 1
// nono thread local
@ -136,8 +132,7 @@ void Builder::sortObjectIndex (uint8_t* objBase,
std::vector<ValueLength>& offsets) {
if (offsets.size() > 32) {
sortObjectIndexLong(objBase, offsets);
}
else {
} else {
sortObjectIndexShort(objBase, offsets);
}
}
@ -182,12 +177,12 @@ void Builder::close () {
VELOCYPACK_ASSERT(index.size() > 0);
// check if we can use the compact Array / Object format
if (index.size() > 1 &&
((head == 0x13 || head == 0x14) ||
if (index.size() > 1 && ((head == 0x13 || head == 0x14) ||
(head == 0x06 && options->buildUnindexedArrays) ||
(head == 0x0b && options->buildUnindexedObjects))) {
// use compact notation
ValueLength nLen = getVariableValueLength(static_cast<ValueLength>(index.size()));
ValueLength nLen =
getVariableValueLength(static_cast<ValueLength>(index.size()));
VELOCYPACK_ASSERT(nLen > 0);
ValueLength byteSize = _pos - (tos + 8) + nLen;
VELOCYPACK_ASSERT(byteSize > 0);
@ -199,13 +194,13 @@ void Builder::close () {
}
if (bLen < 9) {
// can only use compact notation if total byte length is at most 8 bytes long
// can only use compact notation if total byte length is at most 8 bytes
// long
_start[tos] = (isArray ? 0x13 : 0x14);
ValueLength targetPos = 1 + bLen;
if (_pos > (tos + 9)) {
memmove(_start + tos + targetPos, _start + tos + 9,
_pos - (tos + 9));
memmove(_start + tos + targetPos, _start + tos + 9, _pos - (tos + 9));
}
// store byte length
@ -216,7 +211,8 @@ void Builder::close () {
if (nLen > 8 - bLen) {
reserveSpace(nLen);
}
storeVariableValueLength<true>(_start + tos + byteSize - 1, static_cast<ValueLength>(index.size()));
storeVariableValueLength<true>(_start + tos + byteSize - 1,
static_cast<ValueLength>(index.size()));
_pos -= 8;
_pos += nLen + bLen;
@ -237,8 +233,7 @@ void Builder::close () {
needNrSubs = false;
}
// For objects we leave needNrSubs at true here!
}
else if (_start[tos] == 0x06 && // an Array
} else if (_start[tos] == 0x06 && // an Array
(_pos - tos) - index[0] == index.size() * (index[1] - index[0])) {
// In this case it could be that all entries have the same length
// and we do not need an offset table at all:
@ -246,8 +241,7 @@ void Builder::close () {
ValueLength const subLen = index[1] - index[0];
if ((_pos - tos) - index[index.size() - 1] != subLen) {
noTable = false;
}
else {
} else {
for (size_t i = 1; i < index.size() - 1; i++) {
if (index[i + 1] - index[i] != subLen) {
noTable = false;
@ -265,21 +259,19 @@ void Builder::close () {
unsigned int offsetSize;
// can be 1, 2, 4 or 8 for the byte width of the offsets,
// the byte length and the number of subvalues:
if (_pos - tos + (needIndexTable ? index.size() : 0)
- (needNrSubs ? 6 : 7) <= 0xff) {
if (_pos - tos + (needIndexTable ? index.size() : 0) - (needNrSubs ? 6 : 7) <=
0xff) {
// We have so far used _pos - tos bytes, including the reserved 8
// bytes for byte length and number of subvalues. In the 1-byte number
// case we would win back 6 bytes but would need one byte per subvalue
// for the index table
offsetSize = 1;
}
else if (_pos - tos + (needIndexTable ? 2 * index.size() : 0) <= 0xffff) {
} else if (_pos - tos + (needIndexTable ? 2 * index.size() : 0) <= 0xffff) {
offsetSize = 2;
}
else if (_pos - tos + (needIndexTable ? 4 * index.size() : 0) <= 0xffffffffu) {
} else if (_pos - tos + (needIndexTable ? 4 * index.size() : 0) <=
0xffffffffu) {
offsetSize = 4;
}
else {
} else {
offsetSize = 8;
}
@ -290,8 +282,7 @@ void Builder::close () {
targetPos = 2;
}
if (_pos > (tos + 9)) {
memmove(_start + tos + targetPos, _start + tos + 9,
_pos - (tos + 9));
memmove(_start + tos + targetPos, _start + tos + 9, _pos - (tos + 9));
}
_pos -= (9 - targetPos);
for (size_t i = 0; i < index.size(); i++) {
@ -312,9 +303,7 @@ void Builder::close () {
// Object
if (!options->sortAttributeNames) {
_start[tos] = 0x0f; // unsorted
}
else if (index.size() >= 2 &&
options->sortAttributeNames) {
} else if (index.size() >= 2 && options->sortAttributeNames) {
sortObjectIndex(_start + tos, index);
}
}
@ -325,8 +314,7 @@ void Builder::close () {
x >>= 8;
}
}
}
else { // no index table
} else { // no index table
if (_start[tos] == 0x06) {
_start[tos] = 0x02;
}
@ -335,11 +323,9 @@ void Builder::close () {
if (offsetSize > 1) {
if (offsetSize == 2) {
_start[tos] += 1;
}
else if (offsetSize == 4) {
} else if (offsetSize == 4) {
_start[tos] += 2;
}
else { // offsetSize == 8
} else { // offsetSize == 8
_start[tos] += 3;
if (needNrSubs) {
appendLength(index.size(), 8);
@ -397,7 +383,7 @@ bool Builder::hasKey (std::string const& key) const {
return false;
}
// return an attribute from an Object value
// return the value for a specific key of an Object value
Slice Builder::getKey(std::string const& key) const {
if (_stack.empty()) {
throw Exception(Exception::BuilderNeedOpenObject);
@ -412,8 +398,11 @@ Slice Builder::getKey (std::string const& key) const {
}
for (size_t i = 0; i < index.size(); ++i) {
Slice s(_start + tos + index[i], options);
if (!s.isString()) {
s = s.makeKey();
}
if (s.isString() && s.isEqualString(key)) {
return s;
return Slice(s.start() + s.byteSize(), options);
}
}
return Slice();
@ -428,7 +417,8 @@ uint8_t* Builder::set (Value const& item) {
// table is created and a new ValueLength is pushed onto the stack.
switch (item.valueType()) {
case ValueType::None: {
throw Exception(Exception::BuilderUnexpectedType, "Cannot set a ValueType::None");
throw Exception(Exception::BuilderUnexpectedType,
"Cannot set a ValueType::None");
}
case ValueType::Null: {
reserveSpace(1);
@ -437,13 +427,13 @@ uint8_t* Builder::set (Value const& item) {
}
case ValueType::Bool: {
if (ctype != Value::CType::Bool) {
throw Exception(Exception::BuilderUnexpectedValue, "Must give bool for ValueType::Bool");
throw Exception(Exception::BuilderUnexpectedValue,
"Must give bool for ValueType::Bool");
}
reserveSpace(1);
if (item.getBool()) {
_start[_pos++] = 0x1a;
}
else {
} else {
_start[_pos++] = 0x19;
}
break;
@ -464,7 +454,8 @@ uint8_t* Builder::set (Value const& item) {
v = static_cast<double>(item.getUInt64());
break;
default:
throw Exception(Exception::BuilderUnexpectedValue, "Must give number for ValueType::Double");
throw Exception(Exception::BuilderUnexpectedValue,
"Must give number for ValueType::Double");
}
reserveSpace(1 + sizeof(double));
_start[_pos++] = 0x1b;
@ -473,8 +464,14 @@ uint8_t* Builder::set (Value const& item) {
break;
}
case ValueType::External: {
if (options->disallowExternals) {
// External values explicitly disallowed as a security
// precaution
throw Exception(Exception::BuilderExternalsDisallowed);
}
if (ctype != Value::CType::VoidPtr) {
throw Exception(Exception::BuilderUnexpectedValue, "Must give void pointer for ValueType::External");
throw Exception(Exception::BuilderUnexpectedValue,
"Must give void pointer for ValueType::External");
}
reserveSpace(1 + sizeof(void*));
// store pointer. this doesn't need to be portable
@ -497,16 +494,17 @@ uint8_t* Builder::set (Value const& item) {
vv = static_cast<int64_t>(item.getUInt64());
break;
default:
throw Exception(Exception::BuilderUnexpectedValue, "Must give number for ValueType::SmallInt");
throw Exception(Exception::BuilderUnexpectedValue,
"Must give number for ValueType::SmallInt");
}
if (vv < -6 || vv > 9) {
throw Exception(Exception::NumberOutOfRange, "Number out of range of ValueType::SmallInt");
throw Exception(Exception::NumberOutOfRange,
"Number out of range of ValueType::SmallInt");
}
reserveSpace(1);
if (vv >= 0) {
_start[_pos++] = static_cast<uint8_t>(vv + 0x30);
}
else {
} else {
_start[_pos++] = static_cast<uint8_t>(vv + 0x40);
}
break;
@ -524,7 +522,8 @@ uint8_t* Builder::set (Value const& item) {
v = toInt64(item.getUInt64());
break;
default:
throw Exception(Exception::BuilderUnexpectedValue, "Must give number for ValueType::Int");
throw Exception(Exception::BuilderUnexpectedValue,
"Must give number for ValueType::Int");
}
addInt(v);
break;
@ -534,13 +533,17 @@ uint8_t* Builder::set (Value const& item) {
switch (ctype) {
case Value::CType::Double:
if (item.getDouble() < 0.0) {
throw Exception(Exception::BuilderUnexpectedValue, "Must give non-negative number for ValueType::UInt");
throw Exception(
Exception::BuilderUnexpectedValue,
"Must give non-negative number for ValueType::UInt");
}
v = static_cast<uint64_t>(item.getDouble());
break;
case Value::CType::Int64:
if (item.getInt64() < 0) {
throw Exception(Exception::BuilderUnexpectedValue, "Must give non-negative number for ValueType::UInt");
throw Exception(
Exception::BuilderUnexpectedValue,
"Must give non-negative number for ValueType::UInt");
}
v = static_cast<uint64_t>(item.getInt64());
break;
@ -548,7 +551,8 @@ uint8_t* Builder::set (Value const& item) {
v = item.getUInt64();
break;
default:
throw Exception(Exception::BuilderUnexpectedValue, "Must give number for ValueType::UInt");
throw Exception(Exception::BuilderUnexpectedValue,
"Must give number for ValueType::UInt");
}
addUInt(v);
break;
@ -566,22 +570,23 @@ uint8_t* Builder::set (Value const& item) {
v = toInt64(item.getUInt64());
break;
default:
throw Exception(Exception::BuilderUnexpectedValue, "Must give number for ValueType::UTCDate");
throw Exception(Exception::BuilderUnexpectedValue,
"Must give number for ValueType::UTCDate");
}
addUTCDate(v);
break;
}
case ValueType::String: {
if (ctype != Value::CType::String &&
ctype != Value::CType::CharPtr) {
throw Exception(Exception::BuilderUnexpectedValue, "Must give a string or char const* for ValueType::String");
if (ctype != Value::CType::String && ctype != Value::CType::CharPtr) {
throw Exception(
Exception::BuilderUnexpectedValue,
"Must give a string or char const* for ValueType::String");
}
std::string const* s;
std::string value;
if (ctype == Value::CType::String) {
s = item.getString();
}
else {
} else {
value = item.getCharPtr();
s = &value;
}
@ -591,8 +596,7 @@ uint8_t* Builder::set (Value const& item) {
reserveSpace(1 + size);
_start[_pos++] = static_cast<uint8_t>(0x40 + size);
memcpy(_start + _pos, s->c_str(), size);
}
else {
} else {
// long string
reserveSpace(1 + 8 + size);
_start[_pos++] = 0xbf;
@ -611,16 +615,16 @@ uint8_t* Builder::set (Value const& item) {
break;
}
case ValueType::Binary: {
if (ctype != Value::CType::String &&
ctype != Value::CType::CharPtr) {
throw Exception(Exception::BuilderUnexpectedValue, "Must provide std::string or char const* for ValueType::Binary");
if (ctype != Value::CType::String && ctype != Value::CType::CharPtr) {
throw Exception(
Exception::BuilderUnexpectedValue,
"Must provide std::string or char const* for ValueType::Binary");
}
std::string const* s;
std::string value;
if (ctype == Value::CType::String) {
s = item.getString();
}
else {
} else {
value = item.getCharPtr();
s = &value;
}
@ -644,7 +648,8 @@ uint8_t* Builder::set (Value const& item) {
throw Exception(Exception::NotImplemented);
}
case ValueType::Custom: {
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;
@ -669,8 +674,7 @@ uint8_t* Builder::set (ValuePair const& pair) {
memcpy(_start + _pos, pair.getStart(), v);
_pos += v;
return nullptr; // unused here
}
else if (pair.valueType() == ValueType::String) {
} else if (pair.valueType() == ValueType::String) {
uint64_t size = pair.getSize();
if (size > 126) {
// long string
@ -678,8 +682,7 @@ uint8_t* Builder::set (ValuePair const& pair) {
_start[_pos++] = 0xbf;
appendLength(size, 8);
_pos += size;
}
else {
} else {
// short string
reserveSpace(1 + size);
_start[_pos++] = static_cast<uint8_t>(0x40 + size);
@ -690,8 +693,7 @@ uint8_t* Builder::set (ValuePair const& pair) {
// _start + _pos - size .. _start + _pos - 1
// with valid UTF-8!
return _start + _pos - size;
}
else if (pair.valueType() == ValueType::Custom) {
} else if (pair.valueType() == ValueType::Custom) {
// We only reserve space here, the caller has to fill in the custom type
uint64_t size = pair.getSize();
reserveSpace(size);
@ -702,7 +704,9 @@ uint8_t* Builder::set (ValuePair const& pair) {
_pos += size;
return _start + _pos - size;
}
throw Exception(Exception::BuilderUnexpectedType, "Only ValueType::Binary, ValueType::String and ValueType::Custom are valid for ValuePair argument");
throw Exception(Exception::BuilderUnexpectedType,
"Only ValueType::Binary, ValueType::String and "
"ValueType::Custom are valid for ValuePair argument");
}
void Builder::checkAttributeUniqueness(Slice const& obj) const {
@ -719,7 +723,8 @@ void Builder::checkAttributeUniqueness (Slice const& obj) const {
for (ValueLength i = 1; i < n; ++i) {
Slice current = obj.keyAt(i);
if (!current.isString()) {
throw Exception(Exception::BuilderUnexpectedType, "Expecting String key");
throw Exception(Exception::BuilderUnexpectedType,
"Expecting String key");
}
ValueLength len2;
@ -733,14 +738,14 @@ void Builder::checkAttributeUniqueness (Slice const& obj) const {
len = len2;
p = q;
}
}
else {
} else {
std::unordered_set<std::string> keys;
for (size_t i = 0; i < n; ++i) {
Slice key = obj.keyAt(i);
if (!key.isString()) {
throw Exception(Exception::BuilderUnexpectedType, "Expecting String key");
throw Exception(Exception::BuilderUnexpectedType,
"Expecting String key");
}
if (!keys.emplace(key.copyString()).second) {
@ -762,17 +767,12 @@ uint8_t* Builder::add (std::string const& attrName, Slice const& sub) {
return addInternal<Slice>(attrName, sub);
}
uint8_t* Builder::add (Value const& sub) {
return addInternal<Value>(sub);
}
uint8_t* Builder::add(Value const& sub) { return addInternal<Value>(sub); }
uint8_t* Builder::add(ValuePair const& sub) {
return addInternal<ValuePair>(sub);
}
uint8_t* Builder::add (Slice const& sub) {
return addInternal<Slice>(sub);
}
uint8_t* Builder::add(Slice const& sub) { return addInternal<Slice>(sub); }
static_assert(sizeof(double) == 8, "double is not 8 bytes");

View File

@ -36,7 +36,8 @@
using namespace arangodb::velocypack;
// convert a vector of strings into an unordered_set of strings
static inline std::unordered_set<std::string> ToSet (std::vector<std::string> const& keys) {
static inline std::unordered_set<std::string> ToSet(
std::vector<std::string> const& keys) {
std::unordered_set<std::string> s;
for (auto const& it : keys) {
s.emplace(it);
@ -44,7 +45,9 @@ static inline std::unordered_set<std::string> ToSet (std::vector<std::string> co
return s;
}
void Collection::forEach (Slice const& slice, std::function<bool(Slice const&, ValueLength)> const& cb) {
void Collection::forEach(
Slice const& slice,
std::function<bool(Slice const&, ValueLength)> const& cb) {
ArrayIterator it(slice);
ValueLength index = 0;
@ -58,7 +61,9 @@ void Collection::forEach (Slice const& slice, std::function<bool(Slice const&, V
}
}
Builder Collection::filter (Slice const& slice, std::function<bool(Slice const&, ValueLength)> const& cb) {
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));
@ -78,7 +83,9 @@ Builder Collection::filter (Slice const& slice, std::function<bool(Slice const&,
return b;
}
Slice Collection::find (Slice const& slice, std::function<bool(Slice const&, ValueLength)> const& cb) {
Slice Collection::find(
Slice const& slice,
std::function<bool(Slice const&, ValueLength)> const& cb) {
ArrayIterator it(slice);
ValueLength index = 0;
@ -94,7 +101,9 @@ Slice Collection::find (Slice const& slice, std::function<bool(Slice const&, Val
return Slice();
}
bool Collection::contains (Slice const& slice, std::function<bool(Slice const&, ValueLength)> const& cb) {
bool Collection::contains(
Slice const& slice,
std::function<bool(Slice const&, ValueLength)> const& cb) {
ArrayIterator it(slice);
ValueLength index = 0;
@ -110,7 +119,8 @@ bool Collection::contains (Slice const& slice, std::function<bool(Slice const&,
return false;
}
bool Collection::all (Slice const& slice, std::function<bool(Slice const&, ValueLength)> const& cb) {
bool Collection::all(Slice const& slice,
std::function<bool(Slice const&, ValueLength)> const& cb) {
ArrayIterator it(slice);
ValueLength index = 0;
@ -126,7 +136,8 @@ bool Collection::all (Slice const& slice, std::function<bool(Slice const&, Value
return true;
}
bool Collection::any (Slice const& slice, std::function<bool(Slice const&, ValueLength)> const& cb) {
bool Collection::any(Slice const& slice,
std::function<bool(Slice const&, ValueLength)> const& cb) {
ArrayIterator it(slice);
ValueLength index = 0;
@ -162,7 +173,8 @@ void Collection::keys (Slice const& slice, std::vector<std::string>& result) {
}
}
void Collection::keys (Slice const& slice, std::unordered_set<std::string>& result) {
void Collection::keys(Slice const& slice,
std::unordered_set<std::string>& result) {
ObjectIterator it(slice);
while (it.valid()) {
@ -186,7 +198,8 @@ Builder Collection::values (Slice const& slice) {
return b;
}
Builder Collection::keep (Slice const& slice, std::vector<std::string> const& keys) {
Builder Collection::keep(Slice const& slice,
std::vector<std::string> const& keys) {
// check if there are so many keys that we want to use the hash-based version
// cut-off values are arbitrary...
if (keys.size() >= 4 && slice.length() > 10) {
@ -210,7 +223,8 @@ Builder Collection::keep (Slice const& slice, std::vector<std::string> const& ke
return b;
}
Builder Collection::keep (Slice const& slice, std::unordered_set<std::string> const& keys) {
Builder Collection::keep(Slice const& slice,
std::unordered_set<std::string> const& keys) {
Builder b;
b.add(Value(ValueType::Object));
@ -228,7 +242,8 @@ Builder Collection::keep (Slice const& slice, std::unordered_set<std::string> co
return b;
}
Builder Collection::remove (Slice const& slice, std::vector<std::string> const& keys) {
Builder Collection::remove(Slice const& slice,
std::vector<std::string> const& keys) {
// check if there are so many keys that we want to use the hash-based version
// cut-off values are arbitrary...
if (keys.size() >= 4 && slice.length() > 10) {
@ -252,7 +267,8 @@ Builder Collection::remove (Slice const& slice, std::vector<std::string> const&
return b;
}
Builder Collection::remove (Slice const& slice, std::unordered_set<std::string> const& keys) {
Builder Collection::remove(Slice const& slice,
std::unordered_set<std::string> const& keys) {
Builder b;
b.add(Value(ValueType::Object));
@ -270,7 +286,8 @@ Builder Collection::remove (Slice const& slice, std::unordered_set<std::string>
return b;
}
Builder Collection::merge (Slice const& left, Slice const& right, bool mergeValues) {
Builder Collection::merge(Slice const& left, Slice const& right,
bool mergeValues) {
if (!left.isObject() || !right.isObject()) {
throw Exception(Exception::InvalidValueType, "Expecting type Object");
}
@ -297,13 +314,12 @@ Builder Collection::merge (Slice const& left, Slice const& right, bool mergeValu
if (found == rightValues.end()) {
// use left value
b.add(key, it.value());
}
else if (mergeValues && it.value().isObject() && (*found).second.isObject()) {
} else if (mergeValues && it.value().isObject() &&
(*found).second.isObject()) {
// merge both values
Builder sub = Collection::merge(it.value(), (*found).second, true);
b.add(key, sub.slice());
}
else {
} else {
// use right value
b.add(key, (*found).second);
// clear the value in the map so its not added again
@ -326,10 +342,14 @@ Builder Collection::merge (Slice const& left, Slice const& right, bool mergeValu
}
template <Collection::VisitationOrder order>
static bool doVisit (Slice const& slice, std::function<bool(Slice const& key, Slice const& value)> const& func);
static bool doVisit(
Slice const& slice,
std::function<bool(Slice const& key, Slice const& value)> const& func);
template <Collection::VisitationOrder order>
static bool visitObject (Slice const& value, std::function<bool(Slice const& key, Slice const& value)> const& func) {
static bool visitObject(
Slice const& value,
std::function<bool(Slice const& key, Slice const& value)> const& func) {
ObjectIterator it(value);
while (it.valid()) {
@ -359,7 +379,9 @@ static bool visitObject (Slice const& value, std::function<bool(Slice const& key
}
template <Collection::VisitationOrder order>
static bool visitArray (Slice const& value, std::function<bool(Slice const& key, Slice const& value)> const& func) {
static bool visitArray(
Slice const& value,
std::function<bool(Slice const& key, Slice const& value)> const& func) {
ArrayIterator it(value);
while (it.valid()) {
@ -390,7 +412,9 @@ static bool visitArray (Slice const& value, std::function<bool(Slice const& key,
}
template <Collection::VisitationOrder order>
static bool doVisit (Slice const& slice, std::function<bool(Slice const& key, Slice const& value)> const& func) {
static bool doVisit(
Slice const& slice,
std::function<bool(Slice const& key, Slice const& value)> const& func) {
if (slice.isObject()) {
return visitObject<order>(slice, func);
}
@ -398,15 +422,16 @@ static bool doVisit (Slice const& slice, std::function<bool(Slice const& key, Sl
return visitArray<order>(slice, func);
}
throw Exception(Exception::InvalidValueType, "Expecting type Object or Array");
throw Exception(Exception::InvalidValueType,
"Expecting type Object or Array");
}
void Collection::visitRecursive (Slice const& slice, Collection::VisitationOrder order, std::function<bool(Slice const&, Slice const&)> const& func) {
void Collection::visitRecursive(
Slice const& slice, Collection::VisitationOrder order,
std::function<bool(Slice const&, Slice const&)> const& func) {
if (order == Collection::PreOrder) {
doVisit<Collection::PreOrder>(slice, func);
}
else {
} else {
doVisit<Collection::PostOrder>(slice, func);
}
}

View File

@ -41,25 +41,63 @@ namespace arangodb {
};
void Dumper::appendUInt(uint64_t v) {
if (10000000000000000000ULL <= v) { _sink->push_back('0' + (v / 10000000000000000000ULL) % 10); }
if ( 1000000000000000000ULL <= v) { _sink->push_back('0' + (v / 1000000000000000000ULL) % 10); }
if ( 100000000000000000ULL <= v) { _sink->push_back('0' + (v / 100000000000000000ULL) % 10); }
if ( 10000000000000000ULL <= v) { _sink->push_back('0' + (v / 10000000000000000ULL) % 10); }
if ( 1000000000000000ULL <= v) { _sink->push_back('0' + (v / 1000000000000000ULL) % 10); }
if ( 100000000000000ULL <= v) { _sink->push_back('0' + (v / 100000000000000ULL) % 10); }
if ( 10000000000000ULL <= v) { _sink->push_back('0' + (v / 10000000000000ULL) % 10); }
if ( 1000000000000ULL <= v) { _sink->push_back('0' + (v / 1000000000000ULL) % 10); }
if ( 100000000000ULL <= v) { _sink->push_back('0' + (v / 100000000000ULL) % 10); }
if ( 10000000000ULL <= v) { _sink->push_back('0' + (v / 10000000000ULL) % 10); }
if ( 1000000000ULL <= v) { _sink->push_back('0' + (v / 1000000000ULL) % 10); }
if ( 100000000ULL <= v) { _sink->push_back('0' + (v / 100000000ULL) % 10); }
if ( 10000000ULL <= v) { _sink->push_back('0' + (v / 10000000ULL) % 10); }
if ( 1000000ULL <= v) { _sink->push_back('0' + (v / 1000000ULL) % 10); }
if ( 100000ULL <= v) { _sink->push_back('0' + (v / 100000ULL) % 10); }
if ( 10000ULL <= v) { _sink->push_back('0' + (v / 10000ULL) % 10); }
if ( 1000ULL <= v) { _sink->push_back('0' + (v / 1000ULL) % 10); }
if ( 100ULL <= v) { _sink->push_back('0' + (v / 100ULL) % 10); }
if ( 10ULL <= v) { _sink->push_back('0' + (v / 10ULL) % 10); }
if (10000000000000000000ULL <= v) {
_sink->push_back('0' + (v / 10000000000000000000ULL) % 10);
}
if (1000000000000000000ULL <= v) {
_sink->push_back('0' + (v / 1000000000000000000ULL) % 10);
}
if (100000000000000000ULL <= v) {
_sink->push_back('0' + (v / 100000000000000000ULL) % 10);
}
if (10000000000000000ULL <= v) {
_sink->push_back('0' + (v / 10000000000000000ULL) % 10);
}
if (1000000000000000ULL <= v) {
_sink->push_back('0' + (v / 1000000000000000ULL) % 10);
}
if (100000000000000ULL <= v) {
_sink->push_back('0' + (v / 100000000000000ULL) % 10);
}
if (10000000000000ULL <= v) {
_sink->push_back('0' + (v / 10000000000000ULL) % 10);
}
if (1000000000000ULL <= v) {
_sink->push_back('0' + (v / 1000000000000ULL) % 10);
}
if (100000000000ULL <= v) {
_sink->push_back('0' + (v / 100000000000ULL) % 10);
}
if (10000000000ULL <= v) {
_sink->push_back('0' + (v / 10000000000ULL) % 10);
}
if (1000000000ULL <= v) {
_sink->push_back('0' + (v / 1000000000ULL) % 10);
}
if (100000000ULL <= v) {
_sink->push_back('0' + (v / 100000000ULL) % 10);
}
if (10000000ULL <= v) {
_sink->push_back('0' + (v / 10000000ULL) % 10);
}
if (1000000ULL <= v) {
_sink->push_back('0' + (v / 1000000ULL) % 10);
}
if (100000ULL <= v) {
_sink->push_back('0' + (v / 100000ULL) % 10);
}
if (10000ULL <= v) {
_sink->push_back('0' + (v / 10000ULL) % 10);
}
if (1000ULL <= v) {
_sink->push_back('0' + (v / 1000ULL) % 10);
}
if (100ULL <= v) {
_sink->push_back('0' + (v / 100ULL) % 10);
}
if (10ULL <= v) {
_sink->push_back('0' + (v / 10ULL) % 10);
}
_sink->push_back('0' + (v % 10));
}
@ -69,8 +107,7 @@ void Dumper::dumpInteger (Slice const* slice) {
uint64_t v = slice->getUInt();
appendUInt(v);
}
else if (slice->isType(ValueType::Int)) {
} else if (slice->isType(ValueType::Int)) {
int64_t v = slice->getInt();
if (v == INT64_MIN) {
_sink->append("-9223372036854775808", 20);
@ -81,60 +118,108 @@ void Dumper::dumpInteger (Slice const* slice) {
v = -v;
}
if (1000000000000000000LL <= v) { _sink->push_back('0' + (v / 1000000000000000000LL) % 10); }
if ( 100000000000000000LL <= v) { _sink->push_back('0' + (v / 100000000000000000LL) % 10); }
if ( 10000000000000000LL <= v) { _sink->push_back('0' + (v / 10000000000000000LL) % 10); }
if ( 1000000000000000LL <= v) { _sink->push_back('0' + (v / 1000000000000000LL) % 10); }
if ( 100000000000000LL <= v) { _sink->push_back('0' + (v / 100000000000000LL) % 10); }
if ( 10000000000000LL <= v) { _sink->push_back('0' + (v / 10000000000000LL) % 10); }
if ( 1000000000000LL <= v) { _sink->push_back('0' + (v / 1000000000000LL) % 10); }
if ( 100000000000LL <= v) { _sink->push_back('0' + (v / 100000000000LL) % 10); }
if ( 10000000000LL <= v) { _sink->push_back('0' + (v / 10000000000LL) % 10); }
if ( 1000000000LL <= v) { _sink->push_back('0' + (v / 1000000000LL) % 10); }
if ( 100000000LL <= v) { _sink->push_back('0' + (v / 100000000LL) % 10); }
if ( 10000000LL <= v) { _sink->push_back('0' + (v / 10000000LL) % 10); }
if ( 1000000LL <= v) { _sink->push_back('0' + (v / 1000000LL) % 10); }
if ( 100000LL <= v) { _sink->push_back('0' + (v / 100000LL) % 10); }
if ( 10000LL <= v) { _sink->push_back('0' + (v / 10000LL) % 10); }
if ( 1000LL <= v) { _sink->push_back('0' + (v / 1000LL) % 10); }
if ( 100LL <= v) { _sink->push_back('0' + (v / 100LL) % 10); }
if ( 10LL <= v) { _sink->push_back('0' + (v / 10LL) % 10); }
if (1000000000000000000LL <= v) {
_sink->push_back('0' + (v / 1000000000000000000LL) % 10);
}
if (100000000000000000LL <= v) {
_sink->push_back('0' + (v / 100000000000000000LL) % 10);
}
if (10000000000000000LL <= v) {
_sink->push_back('0' + (v / 10000000000000000LL) % 10);
}
if (1000000000000000LL <= v) {
_sink->push_back('0' + (v / 1000000000000000LL) % 10);
}
if (100000000000000LL <= v) {
_sink->push_back('0' + (v / 100000000000000LL) % 10);
}
if (10000000000000LL <= v) {
_sink->push_back('0' + (v / 10000000000000LL) % 10);
}
if (1000000000000LL <= v) {
_sink->push_back('0' + (v / 1000000000000LL) % 10);
}
if (100000000000LL <= v) {
_sink->push_back('0' + (v / 100000000000LL) % 10);
}
if (10000000000LL <= v) {
_sink->push_back('0' + (v / 10000000000LL) % 10);
}
if (1000000000LL <= v) {
_sink->push_back('0' + (v / 1000000000LL) % 10);
}
if (100000000LL <= v) {
_sink->push_back('0' + (v / 100000000LL) % 10);
}
if (10000000LL <= v) {
_sink->push_back('0' + (v / 10000000LL) % 10);
}
if (1000000LL <= v) {
_sink->push_back('0' + (v / 1000000LL) % 10);
}
if (100000LL <= v) {
_sink->push_back('0' + (v / 100000LL) % 10);
}
if (10000LL <= v) {
_sink->push_back('0' + (v / 10000LL) % 10);
}
if (1000LL <= v) {
_sink->push_back('0' + (v / 1000LL) % 10);
}
if (100LL <= v) {
_sink->push_back('0' + (v / 100LL) % 10);
}
if (10LL <= v) {
_sink->push_back('0' + (v / 10LL) % 10);
}
_sink->push_back('0' + (v % 10));
}
else if (slice->isType(ValueType::SmallInt)) {
} else if (slice->isType(ValueType::SmallInt)) {
int64_t v = slice->getSmallInt();
if (v < 0) {
_sink->push_back('-');
v = -v;
}
_sink->push_back('0' + static_cast<char>(v));
}
else {
throw Exception(Exception::InternalError, "Unexpected number type");
} else {
// we should never get here
throw Exception(Exception::InvalidValueType, "Unexpected number type");
}
}
void Dumper::dumpString(char const* src, ValueLength len) {
static char const EscapeTable[256] = {
//0 1 2 3 4 5 6 7 8 9 A B C D E F
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10
0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '/', // 20
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 30~4F
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60~FF
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
// 0 1 2 3 4 5 6 7 8 9 A B C D E
// F
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r',
'u',
'u', // 00
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
'u',
'u', // 10
0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
'/', // 20
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
0, // 30~4F
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'\\', 0, 0, 0, // 50
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
0, // 60~FF
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0};
uint8_t const* p = reinterpret_cast<uint8_t const*>(src);
uint8_t const* e = p + len;
@ -157,15 +242,15 @@ void Dumper::dumpString (char const* src, ValueLength len) {
uint16_t i2 = (((uint16_t)c) & 0x0f);
_sink->append("00", 2);
_sink->push_back(static_cast<char>((i1 < 10) ? ('0' + i1) : ('A' + i1 - 10)));
_sink->push_back(static_cast<char>((i2 < 10) ? ('0' + i2) : ('A' + i2 - 10)));
_sink->push_back(
static_cast<char>((i1 < 10) ? ('0' + i1) : ('A' + i1 - 10)));
_sink->push_back(
static_cast<char>((i2 < 10) ? ('0' + i2) : ('A' + i2 - 10)));
}
}
else {
} else {
_sink->push_back(static_cast<char>(c));
}
}
else if ((c & 0xe0) == 0xc0) {
} else if ((c & 0xe0) == 0xc0) {
// two-byte sequence
if (p + 1 >= e) {
throw Exception(Exception::InvalidUtf8Sequence);
@ -173,8 +258,7 @@ void Dumper::dumpString (char const* src, ValueLength len) {
_sink->append(reinterpret_cast<char const*>(p), 2);
++p;
}
else if ((c & 0xf0) == 0xe0) {
} else if ((c & 0xf0) == 0xe0) {
// three-byte sequence
if (p + 2 >= e) {
throw Exception(Exception::InvalidUtf8Sequence);
@ -182,8 +266,7 @@ void Dumper::dumpString (char const* src, ValueLength len) {
_sink->append(reinterpret_cast<char const*>(p), 3);
p += 2;
}
else if ((c & 0xf8) == 0xf0) {
} else if ((c & 0xf8) == 0xf0) {
// four-byte sequence
if (p + 3 >= e) {
throw Exception(Exception::InvalidUtf8Sequence);
@ -217,8 +300,7 @@ void Dumper::dumpValue (Slice const* slice, Slice const* base) {
case ValueType::Bool: {
if (slice->getBool()) {
_sink->append("true", 4);
}
else {
} else {
_sink->append("false", 5);
}
break;
@ -241,8 +323,7 @@ void Dumper::dumpValue (Slice const* slice, Slice const* base) {
}
--_indentation;
indent();
}
else {
} else {
while (it.valid()) {
if (!it.isFirst()) {
_sink->push_back(',');
@ -274,8 +355,7 @@ void Dumper::dumpValue (Slice const* slice, Slice const* base) {
}
--_indentation;
indent();
}
else {
} else {
while (it.valid()) {
if (!it.isFirst()) {
_sink->push_back(',');
@ -294,8 +374,7 @@ void Dumper::dumpValue (Slice const* slice, Slice const* base) {
double const v = slice->getDouble();
if (std::isnan(v) || !std::isfinite(v)) {
handleUnsupportedType(slice);
}
else {
} else {
char temp[24];
int len = fpconv_dtoa(v, &temp[0]);
_sink->append(&temp[0], static_cast<ValueLength>(len));
@ -350,8 +429,7 @@ void Dumper::dumpValue (Slice const* slice, Slice const* base) {
case ValueType::Custom: {
if (options->customTypeHandler == nullptr) {
handleUnsupportedType(slice);
}
else {
} else {
options->customTypeHandler->toJson(*slice, this, *base);
}
break;

View File

@ -39,4 +39,3 @@ std::ostream& operator<< (std::ostream& stream, Exception const* ex) {
std::ostream& operator<<(std::ostream& stream, Exception const& ex) {
return operator<<(stream, &ex);
}

View File

@ -65,4 +65,3 @@ std::ostream& operator<< (std::ostream& stream, HexDump const* hexdump) {
std::ostream& operator<<(std::ostream& stream, HexDump const& hexdump) {
return operator<<(stream, &hexdump);
}

View File

@ -48,4 +48,3 @@ std::ostream& operator<< (std::ostream& stream, ObjectIterator const* it) {
std::ostream& operator<<(std::ostream& stream, ObjectIterator const& it) {
return operator<<(stream, &it);
}

View File

@ -31,4 +31,3 @@ using namespace arangodb::velocypack;
// default options instance
Options Options::Defaults;

View File

@ -41,9 +41,7 @@ ValueLength Parser::parseInternal (bool multi) {
_b.options = options; // copy over options
// skip over optional BOM
if (_size >= 3 &&
_start[0] == 0xef &&
_start[1] == 0xbb &&
if (_size >= 3 && _start[0] == 0xef && _start[1] == 0xbb &&
_start[2] == 0xbf) {
// found UTF-8 BOM. simply skip over it
_pos += 3;
@ -53,16 +51,14 @@ ValueLength Parser::parseInternal (bool multi) {
do {
parseJson();
nr++;
while (_pos < _size &&
isWhiteSpace(_start[_pos])) {
while (_pos < _size && isWhiteSpace(_start[_pos])) {
++_pos;
}
if (!multi && _pos != _size) {
consume(); // to get error reporting right
throw Exception(Exception::ParseError, "Expecting EOF");
}
}
while (multi && _pos < _size);
} while (multi && _pos < _size);
return nr;
}
@ -123,23 +119,18 @@ void Parser::parseNumber () {
if (!numberValue.isInteger) {
if (negative) {
_b.addDouble(-numberValue.doubleValue);
}
else {
} else {
_b.addDouble(numberValue.doubleValue);
}
}
else if (negative) {
} else if (negative) {
if (numberValue.intValue <= static_cast<uint64_t>(INT64_MAX)) {
_b.addInt(-static_cast<int64_t>(numberValue.intValue));
}
else if (numberValue.intValue == toUInt64(INT64_MIN)) {
} else if (numberValue.intValue == toUInt64(INT64_MIN)) {
_b.addInt(INT64_MIN);
}
else {
} else {
_b.addDouble(-static_cast<double>(numberValue.intValue));
}
}
else {
} else {
_b.addUInt(numberValue.intValue);
}
return;
@ -156,8 +147,7 @@ void Parser::parseNumber () {
fractionalPart = scanDigitsFractional();
if (negative) {
fractionalPart = -numberValue.asDouble() - fractionalPart;
}
else {
} else {
fractionalPart = numberValue.asDouble() + fractionalPart;
}
i = consume();
@ -165,12 +155,10 @@ void Parser::parseNumber () {
_b.addDouble(fractionalPart);
return;
}
}
else {
} else {
if (negative) {
fractionalPart = -numberValue.asDouble();
}
else {
} else {
fractionalPart = numberValue.asDouble();
}
}
@ -193,8 +181,7 @@ void Parser::parseNumber () {
scanDigits(exponent);
if (negative) {
fractionalPart *= pow(10, -exponent.asDouble());
}
else {
} else {
fractionalPart *= pow(10, exponent.asDouble());
}
if (std::isnan(fractionalPart) || !std::isfinite(fractionalPart)) {
@ -225,8 +212,7 @@ void Parser::parseString () {
if (options->validateUtf8Strings) {
count = JSONStringCopyCheckUtf8(_b._start + _b._pos, _start + _pos,
remainder);
}
else {
} else {
count = JSONStringCopy(_b._start + _b._pos, _start + _pos, remainder);
}
_pos += count;
@ -236,8 +222,7 @@ void Parser::parseString () {
if (!large && _b._pos - (base + 1) > 126) {
large = true;
_b.reserveSpace(8);
memmove(_b._start + base + 9, _b._start + base + 1,
_b._pos - (base + 1));
memmove(_b._start + base + 9, _b._start + base + 1, _b._pos - (base + 1));
_b._pos += 8;
}
switch (i) {
@ -247,8 +232,7 @@ void Parser::parseString () {
len = _b._pos - (base + 1);
_b._start[base] = 0x40 + static_cast<uint8_t>(len);
// String is ready
}
else {
} else {
len = _b._pos - (base + 9);
_b._start[base] = 0xbf;
for (ValueLength i = 1; i <= 8; i++) {
@ -301,37 +285,32 @@ void Parser::parseString () {
for (int j = 0; j < 4; j++) {
i = consume();
if (i < 0) {
throw Exception(Exception::ParseError, "Unfinished \\uXXXX escape sequence");
throw Exception(Exception::ParseError,
"Unfinished \\uXXXX escape sequence");
}
if (i >= '0' && i <= '9') {
v = (v << 4) + i - '0';
}
else if (i >= 'a' && i <= 'f') {
} else if (i >= 'a' && i <= 'f') {
v = (v << 4) + i - 'a' + 10;
}
else if (i >= 'A' && i <= 'F') {
} else if (i >= 'A' && i <= 'F') {
v = (v << 4) + i - 'A' + 10;
}
else {
throw Exception(Exception::ParseError, "Illegal \\uXXXX escape sequence");
} else {
throw Exception(Exception::ParseError,
"Illegal \\uXXXX escape sequence");
}
}
if (v < 0x80) {
_b.reserveSpace(1);
_b._start[_b._pos++] = static_cast<uint8_t>(v);
highSurrogate = 0;
}
else if (v < 0x800) {
} else if (v < 0x800) {
_b.reserveSpace(2);
_b._start[_b._pos++] = 0xc0 + (v >> 6);
_b._start[_b._pos++] = 0x80 + (v & 0x3f);
highSurrogate = 0;
}
else if (v >= 0xdc00 && v < 0xe000 &&
highSurrogate != 0) {
} else if (v >= 0xdc00 && v < 0xe000 && highSurrogate != 0) {
// Low surrogate, put the two together:
v = 0x10000 + ((highSurrogate - 0xd800) << 10)
+ v - 0xdc00;
v = 0x10000 + ((highSurrogate - 0xd800) << 10) + v - 0xdc00;
_b._pos -= 3;
_b.reserveSpace(4);
_b._start[_b._pos++] = 0xf0 + (v >> 18);
@ -339,13 +318,11 @@ void Parser::parseString () {
_b._start[_b._pos++] = 0x80 + ((v >> 6) & 0x3f);
_b._start[_b._pos++] = 0x80 + (v & 0x3f);
highSurrogate = 0;
}
else {
} else {
if (v >= 0xd800 && v < 0xdc00) {
// High surrogate:
highSurrogate = v;
}
else {
} else {
highSurrogate = 0;
}
_b.reserveSpace(3);
@ -369,32 +346,26 @@ void Parser::parseString () {
highSurrogate = 0;
_b.reserveSpace(1);
_b._start[_b._pos++] = static_cast<uint8_t>(i);
}
else {
} else {
if (!options->validateUtf8Strings) {
highSurrogate = 0;
_b.reserveSpace(1);
_b._start[_b._pos++] = static_cast<uint8_t>(i);
}
else {
} else {
// multi-byte UTF-8 sequence!
int follow = 0;
if ((i & 0xe0) == 0x80) {
throw Exception(Exception::InvalidUtf8Sequence);
}
else if ((i & 0xe0) == 0xc0) {
} else if ((i & 0xe0) == 0xc0) {
// two-byte sequence
follow = 1;
}
else if ((i & 0xf0) == 0xe0) {
} else if ((i & 0xf0) == 0xe0) {
// three-byte sequence
follow = 2;
}
else if ((i & 0xf8) == 0xf0) {
} else if ((i & 0xf8) == 0xf0) {
// four-byte sequence
follow = 3;
}
else {
} else {
throw Exception(Exception::InvalidUtf8Sequence);
}
@ -483,10 +454,10 @@ void Parser::parseObject () {
auto const lastPos = _b._pos;
if (options->attributeExcludeHandler == nullptr) {
parseString();
}
else {
} else {
parseString();
if (options->attributeExcludeHandler->shouldExclude(Slice(_b._start + lastPos, options), _nesting)) {
if (options->attributeExcludeHandler->shouldExclude(
Slice(_b._start + lastPos, options), _nesting)) {
excludeAttribute = true;
}
}
@ -498,11 +469,13 @@ void Parser::parseObject () {
if (key.isString()) {
ValueLength keyLength;
char const* p = key.getString(keyLength);
uint8_t const* translated = options->attributeTranslator->translate(p, keyLength);
uint8_t const* translated =
options->attributeTranslator->translate(p, keyLength);
if (translated != nullptr) {
// found translation... now reset position to old key position
// and simply overwrite the existing key with the numeric translation id
// and simply overwrite the existing key with the numeric translation
// id
_b._pos = lastPos;
_b.addUInt(Slice(translated, options).getUInt());
}
@ -581,4 +554,3 @@ void Parser::parseJson () {
}
}
}

View File

@ -39,71 +39,134 @@ using namespace arangodb::velocypack;
using VT = arangodb::velocypack::ValueType;
VT const Slice::TypeMap[256] = {
/* 0x00 */ VT::None, /* 0x01 */ VT::Array, /* 0x02 */ VT::Array, /* 0x03 */ VT::Array,
/* 0x04 */ VT::Array, /* 0x05 */ VT::Array, /* 0x06 */ VT::Array, /* 0x07 */ VT::Array,
/* 0x08 */ VT::Array, /* 0x09 */ VT::Array, /* 0x0a */ VT::Object, /* 0x0b */ VT::Object,
/* 0x0c */ VT::Object, /* 0x0d */ VT::Object, /* 0x0e */ VT::Object, /* 0x0f */ VT::Object,
/* 0x10 */ VT::Object, /* 0x11 */ VT::Object, /* 0x12 */ VT::Object, /* 0x13 */ VT::Array,
/* 0x14 */ VT::Object, /* 0x15 */ VT::None, /* 0x16 */ VT::None, /* 0x17 */ VT::None,
/* 0x18 */ VT::Null, /* 0x19 */ VT::Bool, /* 0x1a */ VT::Bool, /* 0x1b */ VT::Double,
/* 0x1c */ VT::UTCDate, /* 0x1d */ VT::External, /* 0x1e */ VT::MinKey, /* 0x1f */ VT::MaxKey,
/* 0x20 */ VT::Int, /* 0x21 */ VT::Int, /* 0x22 */ VT::Int, /* 0x23 */ VT::Int,
/* 0x24 */ VT::Int, /* 0x25 */ VT::Int, /* 0x26 */ VT::Int, /* 0x27 */ VT::Int,
/* 0x28 */ VT::UInt, /* 0x29 */ VT::UInt, /* 0x2a */ VT::UInt, /* 0x2b */ VT::UInt,
/* 0x2c */ VT::UInt, /* 0x2d */ VT::UInt, /* 0x2e */ VT::UInt, /* 0x2f */ VT::UInt,
/* 0x30 */ VT::SmallInt, /* 0x31 */ VT::SmallInt, /* 0x32 */ VT::SmallInt, /* 0x33 */ VT::SmallInt,
/* 0x34 */ VT::SmallInt, /* 0x35 */ VT::SmallInt, /* 0x36 */ VT::SmallInt, /* 0x37 */ VT::SmallInt,
/* 0x38 */ VT::SmallInt, /* 0x39 */ VT::SmallInt, /* 0x3a */ VT::SmallInt, /* 0x3b */ VT::SmallInt,
/* 0x3c */ VT::SmallInt, /* 0x3d */ VT::SmallInt, /* 0x3e */ VT::SmallInt, /* 0x3f */ VT::SmallInt,
/* 0x40 */ VT::String, /* 0x41 */ VT::String, /* 0x42 */ VT::String, /* 0x43 */ VT::String,
/* 0x44 */ VT::String, /* 0x45 */ VT::String, /* 0x46 */ VT::String, /* 0x47 */ VT::String,
/* 0x48 */ VT::String, /* 0x49 */ VT::String, /* 0x4a */ VT::String, /* 0x4b */ VT::String,
/* 0x4c */ VT::String, /* 0x4d */ VT::String, /* 0x4e */ VT::String, /* 0x4f */ VT::String,
/* 0x50 */ VT::String, /* 0x51 */ VT::String, /* 0x52 */ VT::String, /* 0x53 */ VT::String,
/* 0x54 */ VT::String, /* 0x55 */ VT::String, /* 0x56 */ VT::String, /* 0x57 */ VT::String,
/* 0x58 */ VT::String, /* 0x59 */ VT::String, /* 0x5a */ VT::String, /* 0x5b */ VT::String,
/* 0x5c */ VT::String, /* 0x5d */ VT::String, /* 0x5e */ VT::String, /* 0x5f */ VT::String,
/* 0x60 */ VT::String, /* 0x61 */ VT::String, /* 0x62 */ VT::String, /* 0x63 */ VT::String,
/* 0x64 */ VT::String, /* 0x65 */ VT::String, /* 0x66 */ VT::String, /* 0x67 */ VT::String,
/* 0x68 */ VT::String, /* 0x69 */ VT::String, /* 0x6a */ VT::String, /* 0x6b */ VT::String,
/* 0x6c */ VT::String, /* 0x6d */ VT::String, /* 0x6e */ VT::String, /* 0x6f */ VT::String,
/* 0x70 */ VT::String, /* 0x71 */ VT::String, /* 0x72 */ VT::String, /* 0x73 */ VT::String,
/* 0x74 */ VT::String, /* 0x75 */ VT::String, /* 0x76 */ VT::String, /* 0x77 */ VT::String,
/* 0x78 */ VT::String, /* 0x79 */ VT::String, /* 0x7a */ VT::String, /* 0x7b */ VT::String,
/* 0x7c */ VT::String, /* 0x7d */ VT::String, /* 0x7e */ VT::String, /* 0x7f */ VT::String,
/* 0x80 */ VT::String, /* 0x81 */ VT::String, /* 0x82 */ VT::String, /* 0x83 */ VT::String,
/* 0x84 */ VT::String, /* 0x85 */ VT::String, /* 0x86 */ VT::String, /* 0x87 */ VT::String,
/* 0x88 */ VT::String, /* 0x89 */ VT::String, /* 0x8a */ VT::String, /* 0x8b */ VT::String,
/* 0x8c */ VT::String, /* 0x8d */ VT::String, /* 0x8e */ VT::String, /* 0x8f */ VT::String,
/* 0x90 */ VT::String, /* 0x91 */ VT::String, /* 0x92 */ VT::String, /* 0x93 */ VT::String,
/* 0x94 */ VT::String, /* 0x95 */ VT::String, /* 0x96 */ VT::String, /* 0x97 */ VT::String,
/* 0x98 */ VT::String, /* 0x99 */ VT::String, /* 0x9a */ VT::String, /* 0x9b */ VT::String,
/* 0x9c */ VT::String, /* 0x9d */ VT::String, /* 0x9e */ VT::String, /* 0x9f */ VT::String,
/* 0xa0 */ VT::String, /* 0xa1 */ VT::String, /* 0xa2 */ VT::String, /* 0xa3 */ VT::String,
/* 0xa4 */ VT::String, /* 0xa5 */ VT::String, /* 0xa6 */ VT::String, /* 0xa7 */ VT::String,
/* 0xa8 */ VT::String, /* 0xa9 */ VT::String, /* 0xaa */ VT::String, /* 0xab */ VT::String,
/* 0xac */ VT::String, /* 0xad */ VT::String, /* 0xae */ VT::String, /* 0xaf */ VT::String,
/* 0xb0 */ VT::String, /* 0xb1 */ VT::String, /* 0xb2 */ VT::String, /* 0xb3 */ VT::String,
/* 0xb4 */ VT::String, /* 0xb5 */ VT::String, /* 0xb6 */ VT::String, /* 0xb7 */ VT::String,
/* 0xb8 */ VT::String, /* 0xb9 */ VT::String, /* 0xba */ VT::String, /* 0xbb */ VT::String,
/* 0xbc */ VT::String, /* 0xbd */ VT::String, /* 0xbe */ VT::String, /* 0xbf */ VT::String,
/* 0xc0 */ VT::Binary, /* 0xc1 */ VT::Binary, /* 0xc2 */ VT::Binary, /* 0xc3 */ VT::Binary,
/* 0xc4 */ VT::Binary, /* 0xc5 */ VT::Binary, /* 0xc6 */ VT::Binary, /* 0xc7 */ VT::Binary,
/* 0xc8 */ VT::BCD, /* 0xc9 */ VT::BCD, /* 0xca */ VT::BCD, /* 0xcb */ VT::BCD,
/* 0xcc */ VT::BCD, /* 0xcd */ VT::BCD, /* 0xce */ VT::BCD, /* 0xcf */ VT::BCD,
/* 0xd0 */ VT::BCD, /* 0xd1 */ VT::BCD, /* 0xd2 */ VT::BCD, /* 0xd3 */ VT::BCD,
/* 0xd4 */ VT::BCD, /* 0xd5 */ VT::BCD, /* 0xd6 */ VT::BCD, /* 0xd7 */ VT::BCD,
/* 0xd8 */ VT::None, /* 0xd9 */ VT::None, /* 0xda */ VT::None, /* 0xdb */ VT::None,
/* 0xdc */ VT::None, /* 0xdd */ VT::None, /* 0xde */ VT::None, /* 0xdf */ VT::None,
/* 0xe0 */ VT::None, /* 0xe1 */ VT::None, /* 0xe2 */ VT::None, /* 0xe3 */ VT::None,
/* 0xe4 */ VT::None, /* 0xe5 */ VT::None, /* 0xe6 */ VT::None, /* 0xe7 */ VT::None,
/* 0xe8 */ VT::None, /* 0xe9 */ VT::None, /* 0xea */ VT::None, /* 0xeb */ VT::None,
/* 0xec */ VT::None, /* 0xed */ VT::None, /* 0xee */ VT::None, /* 0xef */ VT::None,
/* 0xf0 */ VT::Custom, /* 0xf1 */ VT::Custom, /* 0xf2 */ VT::Custom, /* 0xf3 */ VT::Custom,
/* 0xf4 */ VT::Custom, /* 0xf5 */ VT::Custom, /* 0xf6 */ VT::Custom, /* 0xf7 */ VT::Custom,
/* 0xf8 */ VT::Custom, /* 0xf9 */ VT::Custom, /* 0xfa */ VT::Custom, /* 0xfb */ VT::Custom,
/* 0xfc */ VT::Custom, /* 0xfd */ VT::Custom, /* 0xfe */ VT::Custom, /* 0xff */ VT::Custom
};
/* 0x00 */ VT::None, /* 0x01 */ VT::Array,
/* 0x02 */ VT::Array, /* 0x03 */ VT::Array,
/* 0x04 */ VT::Array, /* 0x05 */ VT::Array,
/* 0x06 */ VT::Array, /* 0x07 */ VT::Array,
/* 0x08 */ VT::Array, /* 0x09 */ VT::Array,
/* 0x0a */ VT::Object, /* 0x0b */ VT::Object,
/* 0x0c */ VT::Object, /* 0x0d */ VT::Object,
/* 0x0e */ VT::Object, /* 0x0f */ VT::Object,
/* 0x10 */ VT::Object, /* 0x11 */ VT::Object,
/* 0x12 */ VT::Object, /* 0x13 */ VT::Array,
/* 0x14 */ VT::Object, /* 0x15 */ VT::None,
/* 0x16 */ VT::None, /* 0x17 */ VT::None,
/* 0x18 */ VT::Null, /* 0x19 */ VT::Bool,
/* 0x1a */ VT::Bool, /* 0x1b */ VT::Double,
/* 0x1c */ VT::UTCDate, /* 0x1d */ VT::External,
/* 0x1e */ VT::MinKey, /* 0x1f */ VT::MaxKey,
/* 0x20 */ VT::Int, /* 0x21 */ VT::Int,
/* 0x22 */ VT::Int, /* 0x23 */ VT::Int,
/* 0x24 */ VT::Int, /* 0x25 */ VT::Int,
/* 0x26 */ VT::Int, /* 0x27 */ VT::Int,
/* 0x28 */ VT::UInt, /* 0x29 */ VT::UInt,
/* 0x2a */ VT::UInt, /* 0x2b */ VT::UInt,
/* 0x2c */ VT::UInt, /* 0x2d */ VT::UInt,
/* 0x2e */ VT::UInt, /* 0x2f */ VT::UInt,
/* 0x30 */ VT::SmallInt, /* 0x31 */ VT::SmallInt,
/* 0x32 */ VT::SmallInt, /* 0x33 */ VT::SmallInt,
/* 0x34 */ VT::SmallInt, /* 0x35 */ VT::SmallInt,
/* 0x36 */ VT::SmallInt, /* 0x37 */ VT::SmallInt,
/* 0x38 */ VT::SmallInt, /* 0x39 */ VT::SmallInt,
/* 0x3a */ VT::SmallInt, /* 0x3b */ VT::SmallInt,
/* 0x3c */ VT::SmallInt, /* 0x3d */ VT::SmallInt,
/* 0x3e */ VT::SmallInt, /* 0x3f */ VT::SmallInt,
/* 0x40 */ VT::String, /* 0x41 */ VT::String,
/* 0x42 */ VT::String, /* 0x43 */ VT::String,
/* 0x44 */ VT::String, /* 0x45 */ VT::String,
/* 0x46 */ VT::String, /* 0x47 */ VT::String,
/* 0x48 */ VT::String, /* 0x49 */ VT::String,
/* 0x4a */ VT::String, /* 0x4b */ VT::String,
/* 0x4c */ VT::String, /* 0x4d */ VT::String,
/* 0x4e */ VT::String, /* 0x4f */ VT::String,
/* 0x50 */ VT::String, /* 0x51 */ VT::String,
/* 0x52 */ VT::String, /* 0x53 */ VT::String,
/* 0x54 */ VT::String, /* 0x55 */ VT::String,
/* 0x56 */ VT::String, /* 0x57 */ VT::String,
/* 0x58 */ VT::String, /* 0x59 */ VT::String,
/* 0x5a */ VT::String, /* 0x5b */ VT::String,
/* 0x5c */ VT::String, /* 0x5d */ VT::String,
/* 0x5e */ VT::String, /* 0x5f */ VT::String,
/* 0x60 */ VT::String, /* 0x61 */ VT::String,
/* 0x62 */ VT::String, /* 0x63 */ VT::String,
/* 0x64 */ VT::String, /* 0x65 */ VT::String,
/* 0x66 */ VT::String, /* 0x67 */ VT::String,
/* 0x68 */ VT::String, /* 0x69 */ VT::String,
/* 0x6a */ VT::String, /* 0x6b */ VT::String,
/* 0x6c */ VT::String, /* 0x6d */ VT::String,
/* 0x6e */ VT::String, /* 0x6f */ VT::String,
/* 0x70 */ VT::String, /* 0x71 */ VT::String,
/* 0x72 */ VT::String, /* 0x73 */ VT::String,
/* 0x74 */ VT::String, /* 0x75 */ VT::String,
/* 0x76 */ VT::String, /* 0x77 */ VT::String,
/* 0x78 */ VT::String, /* 0x79 */ VT::String,
/* 0x7a */ VT::String, /* 0x7b */ VT::String,
/* 0x7c */ VT::String, /* 0x7d */ VT::String,
/* 0x7e */ VT::String, /* 0x7f */ VT::String,
/* 0x80 */ VT::String, /* 0x81 */ VT::String,
/* 0x82 */ VT::String, /* 0x83 */ VT::String,
/* 0x84 */ VT::String, /* 0x85 */ VT::String,
/* 0x86 */ VT::String, /* 0x87 */ VT::String,
/* 0x88 */ VT::String, /* 0x89 */ VT::String,
/* 0x8a */ VT::String, /* 0x8b */ VT::String,
/* 0x8c */ VT::String, /* 0x8d */ VT::String,
/* 0x8e */ VT::String, /* 0x8f */ VT::String,
/* 0x90 */ VT::String, /* 0x91 */ VT::String,
/* 0x92 */ VT::String, /* 0x93 */ VT::String,
/* 0x94 */ VT::String, /* 0x95 */ VT::String,
/* 0x96 */ VT::String, /* 0x97 */ VT::String,
/* 0x98 */ VT::String, /* 0x99 */ VT::String,
/* 0x9a */ VT::String, /* 0x9b */ VT::String,
/* 0x9c */ VT::String, /* 0x9d */ VT::String,
/* 0x9e */ VT::String, /* 0x9f */ VT::String,
/* 0xa0 */ VT::String, /* 0xa1 */ VT::String,
/* 0xa2 */ VT::String, /* 0xa3 */ VT::String,
/* 0xa4 */ VT::String, /* 0xa5 */ VT::String,
/* 0xa6 */ VT::String, /* 0xa7 */ VT::String,
/* 0xa8 */ VT::String, /* 0xa9 */ VT::String,
/* 0xaa */ VT::String, /* 0xab */ VT::String,
/* 0xac */ VT::String, /* 0xad */ VT::String,
/* 0xae */ VT::String, /* 0xaf */ VT::String,
/* 0xb0 */ VT::String, /* 0xb1 */ VT::String,
/* 0xb2 */ VT::String, /* 0xb3 */ VT::String,
/* 0xb4 */ VT::String, /* 0xb5 */ VT::String,
/* 0xb6 */ VT::String, /* 0xb7 */ VT::String,
/* 0xb8 */ VT::String, /* 0xb9 */ VT::String,
/* 0xba */ VT::String, /* 0xbb */ VT::String,
/* 0xbc */ VT::String, /* 0xbd */ VT::String,
/* 0xbe */ VT::String, /* 0xbf */ VT::String,
/* 0xc0 */ VT::Binary, /* 0xc1 */ VT::Binary,
/* 0xc2 */ VT::Binary, /* 0xc3 */ VT::Binary,
/* 0xc4 */ VT::Binary, /* 0xc5 */ VT::Binary,
/* 0xc6 */ VT::Binary, /* 0xc7 */ VT::Binary,
/* 0xc8 */ VT::BCD, /* 0xc9 */ VT::BCD,
/* 0xca */ VT::BCD, /* 0xcb */ VT::BCD,
/* 0xcc */ VT::BCD, /* 0xcd */ VT::BCD,
/* 0xce */ VT::BCD, /* 0xcf */ VT::BCD,
/* 0xd0 */ VT::BCD, /* 0xd1 */ VT::BCD,
/* 0xd2 */ VT::BCD, /* 0xd3 */ VT::BCD,
/* 0xd4 */ VT::BCD, /* 0xd5 */ VT::BCD,
/* 0xd6 */ VT::BCD, /* 0xd7 */ VT::BCD,
/* 0xd8 */ VT::None, /* 0xd9 */ VT::None,
/* 0xda */ VT::None, /* 0xdb */ VT::None,
/* 0xdc */ VT::None, /* 0xdd */ VT::None,
/* 0xde */ VT::None, /* 0xdf */ VT::None,
/* 0xe0 */ VT::None, /* 0xe1 */ VT::None,
/* 0xe2 */ VT::None, /* 0xe3 */ VT::None,
/* 0xe4 */ VT::None, /* 0xe5 */ VT::None,
/* 0xe6 */ VT::None, /* 0xe7 */ VT::None,
/* 0xe8 */ VT::None, /* 0xe9 */ VT::None,
/* 0xea */ VT::None, /* 0xeb */ VT::None,
/* 0xec */ VT::None, /* 0xed */ VT::None,
/* 0xee */ VT::None, /* 0xef */ VT::None,
/* 0xf0 */ VT::Custom, /* 0xf1 */ VT::Custom,
/* 0xf2 */ VT::Custom, /* 0xf3 */ VT::Custom,
/* 0xf4 */ VT::Custom, /* 0xf5 */ VT::Custom,
/* 0xf6 */ VT::Custom, /* 0xf7 */ VT::Custom,
/* 0xf8 */ VT::Custom, /* 0xf9 */ VT::Custom,
/* 0xfa */ VT::Custom, /* 0xfb */ VT::Custom,
/* 0xfc */ VT::Custom, /* 0xfd */ VT::Custom,
/* 0xfe */ VT::Custom, /* 0xff */ VT::Custom};
unsigned int const Slice::WidthMap[32] = {
0, // 0x00, None
@ -125,8 +188,7 @@ unsigned int const Slice::WidthMap[32] = {
2, // 0x10, object with unsorted index table
4, // 0x11, object with unsorted index table
8, // 0x12, object with unsorted index table
0
};
0};
unsigned int const Slice::FirstSubMap[32] = {
0, // 0x00, None
@ -148,8 +210,7 @@ unsigned int const Slice::FirstSubMap[32] = {
5, // 0x10, object with unsorted index table
8, // 0x11, object with unsorted index table
8, // 0x12, object with unsorted index table
0
};
0};
// translates an integer key into a string
Slice Slice::translate() const {
@ -182,9 +243,7 @@ std::string Slice::toString () const {
return std::move(buffer);
}
std::string Slice::hexType () const {
return std::move(HexDump::toHex(head()));
}
std::string Slice::hexType() const { return std::move(HexDump::toHex(head())); }
// look for the specified attribute inside an Object
// returns a Slice(ValueType::None) if not found
@ -210,15 +269,9 @@ Slice Slice::get (std::string const& attribute) const {
// read number of items
ValueLength n;
if (h <= 0x05) { // No offset table or length, need to compute:
dataOffset = findDataOffset(h);
Slice first(_start + dataOffset, options);
n = (end - dataOffset) / first.byteSize();
}
else if (offsetSize < 8) {
if (offsetSize < 8) {
n = readInteger<ValueLength>(_start + 1 + offsetSize, offsetSize);
}
else {
} else {
n = readInteger<ValueLength>(_start + end - offsetSize, offsetSize);
}
@ -234,14 +287,12 @@ Slice Slice::get (std::string const& attribute) const {
if (!key.isEqualString(attribute)) {
return Slice();
}
}
else if (key.isInteger()) {
} else if (key.isInteger()) {
// translate key
if (!key.translate().isEqualString(attribute)) {
return Slice();
}
}
else {
} else {
// invalid key
return Slice();
}
@ -249,8 +300,8 @@ Slice Slice::get (std::string const& attribute) const {
return Slice(key.start() + key.byteSize(), options);
}
ValueLength const ieBase = end - n * offsetSize
- (offsetSize == 8 ? offsetSize : 0);
ValueLength const ieBase =
end - n * offsetSize - (offsetSize == 8 ? offsetSize : 0);
// only use binary search for attributes if we have at least this many entries
// otherwise we'll always use the linear search
@ -273,8 +324,7 @@ int64_t Slice::getInt () const {
uint64_t v = readInteger<uint64_t>(_start + 1, h - 0x1f);
if (h == 0x27) {
return toInt64(v);
}
else {
} else {
int64_t vv = static_cast<int64_t>(v);
int64_t shift = 1LL << ((h - 0x1f) * 8 - 1);
return vv < shift ? vv : vv - (shift << 1);
@ -342,10 +392,10 @@ int64_t Slice::getSmallInt () const {
return static_cast<int64_t>(h - 0x3a) - 6;
}
if ((h >= 0x20 && h <= 0x27) ||
(h >= 0x28 && h <= 0x2f)) {
if ((h >= 0x20 && h <= 0x27) || (h >= 0x28 && h <= 0x2f)) {
// Int and UInt
// we'll leave it to the compiler to detect the two ranges above are adjacent
// we'll leave it to the compiler to detect the two ranges above are
// adjacent
return getInt();
}
@ -356,7 +406,8 @@ int Slice::compareString (std::string const& attribute) const {
ValueLength keyLength;
char const* k = getString(keyLength);
size_t const attributeLength = attribute.size();
size_t const compareLength = (std::min)(static_cast<size_t>(keyLength), attributeLength);
size_t const compareLength =
(std::min)(static_cast<size_t>(keyLength), attributeLength);
int res = memcmp(k, attribute.c_str(), compareLength);
if (res == 0) {
@ -384,8 +435,7 @@ Slice Slice::getFromCompactObject (std::string const& attribute) const {
if (key.isEqualString(attribute)) {
return Slice(key.start() + key.byteSize(), options);
}
}
else if (key.isInteger()) {
} else if (key.isInteger()) {
if (key.translate().isEqualString(attribute)) {
return Slice(key.start() + key.byteSize(), options);
}
@ -422,11 +472,9 @@ ValueLength Slice::getNthOffset (ValueLength index) const {
if (h <= 0x05) { // No offset table or length, need to compute:
Slice first(_start + dataOffset, options);
n = (end - dataOffset) / first.byteSize();
}
else if (offsetSize < 8) {
} else if (offsetSize < 8) {
n = readInteger<ValueLength>(_start + 1 + offsetSize, offsetSize);
}
else {
} else {
n = readInteger<ValueLength>(_start + end - offsetSize, offsetSize);
}
@ -447,8 +495,8 @@ ValueLength Slice::getNthOffset (ValueLength index) const {
return dataOffset + index * firstItem.byteSize();
}
ValueLength const ieBase = end - n * offsetSize + index * offsetSize
- (offsetSize == 8 ? 8 : 0);
ValueLength const ieBase =
end - n * offsetSize + index * offsetSize - (offsetSize == 8 ? 8 : 0);
return readInteger<ValueLength>(_start + ieBase, offsetSize);
}
@ -521,25 +569,23 @@ ValueLength Slice::getNthOffsetFromCompact (ValueLength index) const {
// perform a linear search for the specified attribute inside an Object
Slice Slice::searchObjectKeyLinear(std::string const& attribute,
ValueLength ieBase,
ValueLength offsetSize,
ValueLength ieBase, ValueLength offsetSize,
ValueLength n) const {
for (ValueLength index = 0; index < n; ++index) {
ValueLength offset = ieBase + index * offsetSize;
Slice key(_start + readInteger<ValueLength>(_start + offset, offsetSize), options);
Slice key(_start + readInteger<ValueLength>(_start + offset, offsetSize),
options);
if (key.isString()) {
if (!key.isEqualString(attribute)) {
continue;
}
}
else if (key.isInteger()) {
} else if (key.isInteger()) {
// translate key
if (!key.translate().isEqualString(attribute)) {
continue;
}
}
else {
} else {
// invalid key type
return Slice();
}
@ -554,8 +600,7 @@ Slice Slice::searchObjectKeyLinear (std::string const& attribute,
// perform a binary search for the specified attribute inside an Object
Slice Slice::searchObjectKeyBinary(std::string const& attribute,
ValueLength ieBase,
ValueLength offsetSize,
ValueLength ieBase, ValueLength offsetSize,
ValueLength n) const {
VELOCYPACK_ASSERT(n > 0);
@ -567,17 +612,16 @@ Slice Slice::searchObjectKeyBinary (std::string const& attribute,
ValueLength index = l + ((r - l) / 2);
ValueLength offset = ieBase + index * offsetSize;
Slice key(_start + readInteger<ValueLength>(_start + offset, offsetSize), options);
Slice key(_start + readInteger<ValueLength>(_start + offset, offsetSize),
options);
int res;
if (key.isString()) {
res = key.compareString(attribute);
}
else if (key.isInteger()) {
} else if (key.isInteger()) {
// translate key
res = key.translate().compareString(attribute);
}
else {
} else {
// invalid key
return Slice();
}
@ -592,8 +636,7 @@ Slice Slice::searchObjectKeyBinary (std::string const& attribute,
return Slice();
}
r = index - 1;
}
else {
} else {
l = index + 1;
}
if (r < l) {
@ -603,7 +646,8 @@ Slice Slice::searchObjectKeyBinary (std::string const& attribute,
}
std::ostream& operator<<(std::ostream& stream, Slice const* slice) {
stream << "[Slice " << valueTypeName(slice->type()) << " (" << slice->hexType() << "), byteSize: " << slice->byteSize() << "]";
stream << "[Slice " << valueTypeName(slice->type()) << " ("
<< slice->hexType() << "), byteSize: " << slice->byteSize() << "]";
return stream;
}
@ -611,5 +655,6 @@ std::ostream& operator<< (std::ostream& stream, Slice const& slice) {
return operator<<(stream, &slice);
}
static_assert(sizeof(arangodb::velocypack::Slice) == sizeof(void*) + sizeof(void*),
static_assert(sizeof(arangodb::velocypack::Slice) ==
sizeof(void*) + sizeof(void*),
"Slice has an unexpected size");

View File

@ -32,23 +32,40 @@ using namespace arangodb::velocypack;
char const* arangodb::velocypack::valueTypeName(ValueType type) {
switch (type) {
case ValueType::None: return "none";
case ValueType::Null: return "null";
case ValueType::Bool: return "bool";
case ValueType::Array: return "array";
case ValueType::Object: return "object";
case ValueType::Double: return "double";
case ValueType::UTCDate: return "utc-date";
case ValueType::External: return "external";
case ValueType::MinKey: return "min-key";
case ValueType::MaxKey: return "max-key";
case ValueType::Int: return "int";
case ValueType::UInt: return "uint";
case ValueType::SmallInt: return "smallint";
case ValueType::String: return "string";
case ValueType::Binary: return "binary";
case ValueType::BCD: return "bcd";
case ValueType::Custom: return "custom";
case ValueType::None:
return "none";
case ValueType::Null:
return "null";
case ValueType::Bool:
return "bool";
case ValueType::Array:
return "array";
case ValueType::Object:
return "object";
case ValueType::Double:
return "double";
case ValueType::UTCDate:
return "utc-date";
case ValueType::External:
return "external";
case ValueType::MinKey:
return "min-key";
case ValueType::MaxKey:
return "max-key";
case ValueType::Int:
return "int";
case ValueType::UInt:
return "uint";
case ValueType::SmallInt:
return "smallint";
case ValueType::String:
return "string";
case ValueType::Binary:
return "binary";
case ValueType::BCD:
return "bcd";
case ValueType::Custom:
return "custom";
}
return "unknown";

View File

@ -55,4 +55,3 @@ int Version::compare (Version const& other) const {
int Version::compare(Version const& lhs, Version const& rhs) {
return lhs.compare(rhs);
}

View File

@ -53,19 +53,18 @@ static bool HasSSE42 () {
if (__get_cpuid(1, &eax, &ebx, &ecx, &edx)) {
if ((ecx & 0x100000) != 0) {
return true;
}
else {
} else {
return false;
}
}
else {
} else {
return false;
}
}
static size_t JSONStringCopySSE42 (uint8_t* dst, uint8_t const* src, size_t limit) {
alignas(16) static char const ranges[17]
= "\x20\x21\x23\x5b\x5d\xff ";
static size_t JSONStringCopySSE42(uint8_t* dst, uint8_t const* src,
size_t limit) {
alignas(16) static char const ranges[17] =
"\x20\x21\x23\x5b\x5d\xff ";
//= "\x01\x1f\"\"\\\\\"\"\"\"\"\"\"\"\"\"";
__m128i const r = _mm_load_si128(reinterpret_cast<__m128i const*>(ranges));
size_t count = 0;
@ -74,8 +73,7 @@ static size_t JSONStringCopySSE42 (uint8_t* dst, uint8_t const* src, size_t limi
__m128i const s = _mm_loadu_si128(reinterpret_cast<__m128i const*>(src));
x = _mm_cmpistri(r, /* 6, */ s, /* 16, */
_SIDD_UBYTE_OPS | _SIDD_CMP_RANGES |
_SIDD_NEGATIVE_POLARITY |
_SIDD_LEAST_SIGNIFICANT);
_SIDD_NEGATIVE_POLARITY | _SIDD_LEAST_SIGNIFICANT);
if (x < 16) {
memcpy(dst, src, x);
dst += x;
@ -95,8 +93,7 @@ static size_t JSONStringCopySSE42 (uint8_t* dst, uint8_t const* src, size_t limi
__m128i const s = _mm_loadu_si128(reinterpret_cast<__m128i const*>(src));
x = _mm_cmpistri(r, /* 6, */ s, /* limit, */
_SIDD_UBYTE_OPS | _SIDD_CMP_RANGES |
_SIDD_NEGATIVE_POLARITY |
_SIDD_LEAST_SIGNIFICANT);
_SIDD_NEGATIVE_POLARITY | _SIDD_LEAST_SIGNIFICANT);
if (x > static_cast<int>(limit)) {
x = static_cast<int>(limit);
}
@ -110,18 +107,16 @@ static size_t JSONStringCopySSE42 (uint8_t* dst, uint8_t const* src, size_t limi
static size_t DoInitCopy(uint8_t* dst, uint8_t const* src, size_t limit) {
if (HasSSE42()) {
JSONStringCopy = JSONStringCopySSE42;
}
else {
} else {
JSONStringCopy = JSONStringCopyC;
}
return (*JSONStringCopy)(dst, src, limit);
}
static size_t JSONStringCopyCheckUtf8SSE42 (uint8_t* dst,
uint8_t const* src,
static size_t JSONStringCopyCheckUtf8SSE42(uint8_t* dst, uint8_t const* src,
size_t limit) {
alignas(16) static unsigned char const ranges[17]
= "\x20\x21\x23\x5b\x5d\x7f ";
alignas(16) static unsigned char const ranges[17] =
"\x20\x21\x23\x5b\x5d\x7f ";
//= "\x01\x1f\x80\xff\"\"\\\\\"\"\"\"\"\"\"\"";
__m128i const r = _mm_load_si128(reinterpret_cast<__m128i const*>(ranges));
size_t count = 0;
@ -130,8 +125,7 @@ static size_t JSONStringCopyCheckUtf8SSE42 (uint8_t* dst,
__m128i const s = _mm_loadu_si128(reinterpret_cast<__m128i const*>(src));
x = _mm_cmpistri(r, /* 8, */ s, /* 16, */
_SIDD_UBYTE_OPS | _SIDD_CMP_RANGES |
_SIDD_NEGATIVE_POLARITY |
_SIDD_LEAST_SIGNIFICANT);
_SIDD_NEGATIVE_POLARITY | _SIDD_LEAST_SIGNIFICANT);
if (x < 16) {
memcpy(dst, src, x);
dst += x;
@ -151,8 +145,7 @@ static size_t JSONStringCopyCheckUtf8SSE42 (uint8_t* dst,
__m128i const s = _mm_loadu_si128(reinterpret_cast<__m128i const*>(src));
x = _mm_cmpistri(r, /* 8, */ s, /* limit, */
_SIDD_UBYTE_OPS | _SIDD_CMP_RANGES |
_SIDD_NEGATIVE_POLARITY |
_SIDD_LEAST_SIGNIFICANT);
_SIDD_NEGATIVE_POLARITY | _SIDD_LEAST_SIGNIFICANT);
if (x > static_cast<int>(limit)) {
x = static_cast<int>(limit);
}
@ -167,8 +160,7 @@ static size_t DoInitCopyCheckUtf8 (uint8_t* dst, uint8_t const* src,
size_t limit) {
if (HasSSE42()) {
JSONStringCopyCheckUtf8 = JSONStringCopyCheckUtf8SSE42;
}
else {
} else {
JSONStringCopyCheckUtf8 = JSONStringCopyCheckUtf8C;
}
return (*JSONStringCopyCheckUtf8)(dst, src, limit);
@ -183,8 +175,7 @@ static size_t JSONSkipWhiteSpaceSSE42 (uint8_t const* ptr, size_t limit) {
__m128i const s = _mm_loadu_si128(reinterpret_cast<__m128i const*>(ptr));
x = _mm_cmpistri(w, /* 4, */ s, /* 16, */
_SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY |
_SIDD_NEGATIVE_POLARITY |
_SIDD_LEAST_SIGNIFICANT);
_SIDD_NEGATIVE_POLARITY | _SIDD_LEAST_SIGNIFICANT);
if (x < 16) {
ptr += x;
count += x;
@ -200,8 +191,7 @@ static size_t JSONSkipWhiteSpaceSSE42 (uint8_t const* ptr, size_t limit) {
__m128i const s = _mm_loadu_si128(reinterpret_cast<__m128i const*>(ptr));
x = _mm_cmpistri(w, /* 4, */ s, /* limit, */
_SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY |
_SIDD_NEGATIVE_POLARITY |
_SIDD_LEAST_SIGNIFICANT);
_SIDD_NEGATIVE_POLARITY | _SIDD_LEAST_SIGNIFICANT);
if (static_cast<size_t>(x) > limit) {
x = static_cast<int>(limit);
}
@ -213,8 +203,7 @@ static size_t JSONSkipWhiteSpaceSSE42 (uint8_t const* ptr, size_t limit) {
static size_t DoInitSkip(uint8_t const* ptr, size_t limit) {
if (HasSSE42()) {
JSONSkipWhiteSpace = JSONSkipWhiteSpaceSSE42;
}
else {
} else {
JSONSkipWhiteSpace = JSONSkipWhiteSpaceC;
}
return (*JSONSkipWhiteSpace)(ptr, limit);
@ -240,19 +229,18 @@ static size_t DoInitSkip (uint8_t const* ptr, size_t limit) {
#endif
size_t (*JSONStringCopy)(uint8_t*, uint8_t const*, size_t) = DoInitCopy;
size_t (*JSONStringCopyCheckUtf8)(uint8_t*, uint8_t const*, size_t)
= DoInitCopyCheckUtf8;
size_t (*JSONStringCopyCheckUtf8)(uint8_t*, uint8_t const*,
size_t) = DoInitCopyCheckUtf8;
size_t (*JSONSkipWhiteSpace)(uint8_t const*, size_t) = DoInitSkip;
#if defined(COMPILE_VELOCYPACK_ASM_UNITTESTS)
int testPositions[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 23, 31, 32, 67, 103, 178, 210, 234, 247, 254, 255,
-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12,
-13, -14, -15, -16, -23, -31, -32, -67, -103, -178,
-210, -234, -247, -254, -255 };
int testPositions[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 23, 31, 32, 67, 103, 178, 210, 234, 247, 254, 255,
-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14,
-15, -16, -23, -31, -32, -67, -103, -178, -210, -234, -247, -254, -255};
void TestStringCopyCorrectness(uint8_t* src, uint8_t* dst, size_t size) {
size_t copied;
@ -272,8 +260,7 @@ void TestStringCopyCorrectness (uint8_t* src, uint8_t* dst, size_t size) {
size_t pos;
if (off >= 0) {
pos = off;
}
else {
} else {
pos = size - static_cast<size_t>(-off);
}
if (pos >= size) {
@ -281,11 +268,12 @@ void TestStringCopyCorrectness (uint8_t* src, uint8_t* dst, size_t size) {
}
// Test a quote character:
merk = src[pos]; src[pos] = '"';
merk = src[pos];
src[pos] = '"';
copied = JSONStringCopy(dst, src, size);
if (copied != pos || memcmp(dst, src, copied) != 0) {
std::cout << "Error: " << salign << " " << dalign << " "
<< i << " " << pos << " " << copied << std::endl;
std::cout << "Error: " << salign << " " << dalign << " " << i << " "
<< pos << " " << copied << std::endl;
}
src[pos] = merk;
@ -293,8 +281,8 @@ void TestStringCopyCorrectness (uint8_t* src, uint8_t* dst, size_t size) {
src[pos] = '\\';
copied = JSONStringCopy(dst, src, size);
if (copied != pos || memcmp(dst, src, copied) != 0) {
std::cout << "Error: " << salign << " " << dalign << " "
<< i << " " << pos << " " << copied << std::endl;
std::cout << "Error: " << salign << " " << dalign << " " << i << " "
<< pos << " " << copied << std::endl;
}
src[pos] = merk;
@ -302,8 +290,8 @@ void TestStringCopyCorrectness (uint8_t* src, uint8_t* dst, size_t size) {
src[pos] = 1;
copied = JSONStringCopy(dst, src, size);
if (copied != pos || memcmp(dst, src, copied) != 0) {
std::cout << "Error: " << salign << " " << dalign << " "
<< i << " " << pos << " " << copied << std::endl;
std::cout << "Error: " << salign << " " << dalign << " " << i << " "
<< pos << " " << copied << std::endl;
}
src[pos] = merk;
@ -311,8 +299,8 @@ void TestStringCopyCorrectness (uint8_t* src, uint8_t* dst, size_t size) {
src[pos] = 31;
copied = JSONStringCopy(dst, src, size);
if (copied != pos || memcmp(dst, src, copied) != 0) {
std::cout << "Error: " << salign << " " << dalign << " "
<< i << " " << pos << " " << copied << std::endl;
std::cout << "Error: " << salign << " " << dalign << " " << i << " "
<< pos << " " << copied << std::endl;
}
src[pos] = merk;
}
@ -322,8 +310,8 @@ void TestStringCopyCorrectness (uint8_t* src, uint8_t* dst, size_t size) {
}
auto now = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> totalTime
= std::chrono::duration_cast<std::chrono::duration<double>>(now - start);
std::chrono::duration<double> totalTime =
std::chrono::duration_cast<std::chrono::duration<double>>(now - start);
std::cout << "Tests took altogether " << totalTime.count() << " seconds."
<< std::endl;
}
@ -340,15 +328,14 @@ void TestStringCopyCorrectnessCheckUtf8 (uint8_t* src, uint8_t* dst,
src += salign;
for (int dalign = 0; dalign < 16; dalign++) {
dst += dalign;
for (int i = 0;
i < static_cast<int>(sizeof(testPositions) / sizeof(int)); i++) {
for (int i = 0; i < static_cast<int>(sizeof(testPositions) / sizeof(int));
i++) {
uint8_t merk;
int off = testPositions[i];
size_t pos;
if (off >= 0) {
pos = off;
}
else {
} else {
pos = size - static_cast<size_t>(-off);
}
if (pos >= size) {
@ -356,11 +343,12 @@ void TestStringCopyCorrectnessCheckUtf8 (uint8_t* src, uint8_t* dst,
}
// Test a quote character:
merk = src[pos]; src[pos] = '"';
merk = src[pos];
src[pos] = '"';
copied = JSONStringCopyCheckUtf8(dst, src, size);
if (copied != pos || memcmp(dst, src, copied) != 0) {
std::cout << "Error: " << salign << " " << dalign << " "
<< i << " " << pos << " " << copied << std::endl;
std::cout << "Error: " << salign << " " << dalign << " " << i << " "
<< pos << " " << copied << std::endl;
}
src[pos] = merk;
@ -368,8 +356,8 @@ void TestStringCopyCorrectnessCheckUtf8 (uint8_t* src, uint8_t* dst,
src[pos] = '\\';
copied = JSONStringCopyCheckUtf8(dst, src, size);
if (copied != pos || memcmp(dst, src, copied) != 0) {
std::cout << "Error: " << salign << " " << dalign << " "
<< i << " " << pos << " " << copied << std::endl;
std::cout << "Error: " << salign << " " << dalign << " " << i << " "
<< pos << " " << copied << std::endl;
}
src[pos] = merk;
@ -377,8 +365,8 @@ void TestStringCopyCorrectnessCheckUtf8 (uint8_t* src, uint8_t* dst,
src[pos] = 1;
copied = JSONStringCopyCheckUtf8(dst, src, size);
if (copied != pos || memcmp(dst, src, copied) != 0) {
std::cout << "Error: " << salign << " " << dalign << " "
<< i << " " << pos << " " << copied << std::endl;
std::cout << "Error: " << salign << " " << dalign << " " << i << " "
<< pos << " " << copied << std::endl;
}
src[pos] = merk;
@ -386,8 +374,8 @@ void TestStringCopyCorrectnessCheckUtf8 (uint8_t* src, uint8_t* dst,
src[pos] = 31;
copied = JSONStringCopyCheckUtf8(dst, src, size);
if (copied != pos || memcmp(dst, src, copied) != 0) {
std::cout << "Error: " << salign << " " << dalign << " "
<< i << " " << pos << " " << copied << std::endl;
std::cout << "Error: " << salign << " " << dalign << " " << i << " "
<< pos << " " << copied << std::endl;
}
src[pos] = merk;
@ -395,8 +383,8 @@ void TestStringCopyCorrectnessCheckUtf8 (uint8_t* src, uint8_t* dst,
src[pos] = 0x80;
copied = JSONStringCopyCheckUtf8(dst, src, size);
if (copied != pos || memcmp(dst, src, copied) != 0) {
std::cout << "Error: " << salign << " " << dalign << " "
<< i << " " << pos << " " << copied << std::endl;
std::cout << "Error: " << salign << " " << dalign << " " << i << " "
<< pos << " " << copied << std::endl;
}
src[pos] = merk;
}
@ -406,8 +394,8 @@ void TestStringCopyCorrectnessCheckUtf8 (uint8_t* src, uint8_t* dst,
}
auto now = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> totalTime
= std::chrono::duration_cast<std::chrono::duration<double>>(now - start);
std::chrono::duration<double> totalTime =
std::chrono::duration_cast<std::chrono::duration<double>>(now - start);
std::cout << "Tests took altogether " << totalTime.count() << " seconds."
<< std::endl;
}
@ -422,15 +410,14 @@ void TestSkipWhiteSpaceCorrectness (uint8_t* src, size_t size) {
for (int salign = 0; salign < 16; salign++) {
src += salign;
for (int i = 0;
i < static_cast<int>(sizeof(testPositions) / sizeof(int)); i++) {
for (int i = 0; i < static_cast<int>(sizeof(testPositions) / sizeof(int));
i++) {
uint8_t merk;
int off = testPositions[i];
size_t pos;
if (off >= 0) {
pos = off;
}
else {
} else {
pos = size - static_cast<size_t>(-off);
}
if (pos >= size) {
@ -438,11 +425,12 @@ void TestSkipWhiteSpaceCorrectness (uint8_t* src, size_t size) {
}
// Test a non-whitespace character:
merk = src[pos]; src[pos] = 'x';
merk = src[pos];
src[pos] = 'x';
copied = JSONSkipWhiteSpace(src, size);
if (copied != pos) {
std::cout << "Error: " << salign << " "
<< i << " " << pos << " " << copied << std::endl;
std::cout << "Error: " << salign << " " << i << " " << pos << " "
<< copied << std::endl;
}
src[pos] = merk;
}
@ -450,13 +438,14 @@ void TestSkipWhiteSpaceCorrectness (uint8_t* src, size_t size) {
}
auto now = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> totalTime
= std::chrono::duration_cast<std::chrono::duration<double>>(now-start);
std::chrono::duration<double> totalTime =
std::chrono::duration_cast<std::chrono::duration<double>>(now - start);
std::cout << "Whitespace tests took altogether " << totalTime.count()
<< " seconds." << std::endl;
}
void RaceStringCopy (uint8_t* dst, uint8_t* src, size_t size, int repeat, int&akku) {
void RaceStringCopy(uint8_t* dst, uint8_t* src, size_t size, int repeat,
int& akku) {
size_t copied;
std::cout << "\nNow racing for the repeated full string, "
@ -471,8 +460,8 @@ void RaceStringCopy (uint8_t* dst, uint8_t* src, size_t size, int repeat, int&ak
auto now = std::chrono::high_resolution_clock::now();
src[size] = 'a' + (size % 26);
auto totalTime
= std::chrono::duration_cast<std::chrono::duration<double>>(now - start);
auto totalTime =
std::chrono::duration_cast<std::chrono::duration<double>>(now - start);
std::cout << "Race took altogether " << totalTime.count() << " seconds."
<< std::endl;
@ -480,8 +469,7 @@ void RaceStringCopy (uint8_t* dst, uint8_t* src, size_t size, int repeat, int&ak
<< " on average is: " << totalTime.count() / repeat << "."
<< std::endl;
std::cout << "Bytes copied per second: "
<< (double) size * (double) repeat / totalTime.count()
<< std::endl;
<< (double)size * (double)repeat / totalTime.count() << std::endl;
std::cout << "\nNow racing for the repeated full string, "
<< "now unaligned target...\n" << std::endl;
@ -495,8 +483,8 @@ void RaceStringCopy (uint8_t* dst, uint8_t* src, size_t size, int repeat, int&ak
now = std::chrono::high_resolution_clock::now();
dst--;
totalTime
= std::chrono::duration_cast<std::chrono::duration<double>>(now - start);
totalTime =
std::chrono::duration_cast<std::chrono::duration<double>>(now - start);
std::cout << "Race took altogether " << totalTime.count() << " seconds."
<< std::endl;
@ -504,12 +492,11 @@ void RaceStringCopy (uint8_t* dst, uint8_t* src, size_t size, int repeat, int&ak
<< " on average is: " << totalTime.count() / repeat << "."
<< std::endl;
std::cout << "Bytes copied per second: "
<< (double) size * (double) repeat / totalTime.count()
<< std::endl;
<< (double)size * (double)repeat / totalTime.count() << std::endl;
}
void RaceStringCopyCheckUtf8 (uint8_t* dst, uint8_t* src,
size_t size, int repeat, int& akku) {
void RaceStringCopyCheckUtf8(uint8_t* dst, uint8_t* src, size_t size,
int repeat, int& akku) {
size_t copied;
std::cout << "\nNow racing for the repeated (check UTF8) full string, "
@ -524,8 +511,8 @@ void RaceStringCopyCheckUtf8 (uint8_t* dst, uint8_t* src,
auto now = std::chrono::high_resolution_clock::now();
src[size] = 'a' + (size % 26);
auto totalTime
= std::chrono::duration_cast<std::chrono::duration<double>>(now - start);
auto totalTime =
std::chrono::duration_cast<std::chrono::duration<double>>(now - start);
std::cout << "Race took altogether " << totalTime.count() << " seconds."
<< std::endl;
@ -533,10 +520,11 @@ void RaceStringCopyCheckUtf8 (uint8_t* dst, uint8_t* src,
<< " on average is: " << totalTime.count() / repeat << "."
<< std::endl;
std::cout << "Bytes copied per second: "
<< (double) size * (double) repeat / totalTime.count()
<< std::endl;
<< (double)size * (double)repeat / totalTime.count() << std::endl;
std::cout << "\nNow racing for the repeated full string, now unaligned target...\n" << std::endl;
std::cout
<< "\nNow racing for the repeated full string, now unaligned target...\n"
<< std::endl;
dst++;
start = std::chrono::high_resolution_clock::now();
@ -547,8 +535,8 @@ void RaceStringCopyCheckUtf8 (uint8_t* dst, uint8_t* src,
now = std::chrono::high_resolution_clock::now();
dst--;
totalTime
= std::chrono::duration_cast<std::chrono::duration<double>>(now - start);
totalTime =
std::chrono::duration_cast<std::chrono::duration<double>>(now - start);
std::cout << "Race took altogether " << totalTime.count() << " seconds."
<< std::endl;
@ -556,8 +544,7 @@ void RaceStringCopyCheckUtf8 (uint8_t* dst, uint8_t* src,
<< " on average is: " << totalTime.count() / repeat << "."
<< std::endl;
std::cout << "Bytes copied per second: "
<< (double) size * (double) repeat / totalTime.count()
<< std::endl;
<< (double)size * (double)repeat / totalTime.count() << std::endl;
std::cout << "\nNow comparing with strcpy...\n" << std::endl;
@ -565,12 +552,11 @@ void RaceStringCopyCheckUtf8 (uint8_t* dst, uint8_t* src,
for (int j = 0; j < repeat; j++) {
// strcpy((char*) dst, (char*) src);
memcpy((char*)dst, (char*)src, size);
}
now = std::chrono::high_resolution_clock::now();
totalTime
= std::chrono::duration_cast<std::chrono::duration<double>>(now - start);
totalTime =
std::chrono::duration_cast<std::chrono::duration<double>>(now - start);
std::cout << "Race took altogether " << totalTime.count() << " seconds."
<< std::endl;
@ -578,8 +564,7 @@ void RaceStringCopyCheckUtf8 (uint8_t* dst, uint8_t* src,
<< " on average is: " << totalTime.count() / repeat << "."
<< std::endl;
std::cout << "Bytes copied per second: "
<< (double) size * (double) repeat / totalTime.count()
<< std::endl;
<< (double)size * (double)repeat / totalTime.count() << std::endl;
}
void RaceSkipWhiteSpace(uint8_t* src, size_t size, int repeat, int& akku) {
@ -596,8 +581,8 @@ void RaceSkipWhiteSpace (uint8_t* src, size_t size, int repeat, int& akku) {
}
auto now = std::chrono::high_resolution_clock::now();
auto totalTime
= std::chrono::duration_cast<std::chrono::duration<double>>(now-start);
auto totalTime =
std::chrono::duration_cast<std::chrono::duration<double>>(now - start);
std::cout << "Race took altogether " << totalTime.count() << " seconds."
<< std::endl;
@ -605,8 +590,7 @@ void RaceSkipWhiteSpace (uint8_t* src, size_t size, int repeat, int& akku) {
<< " on average is: " << totalTime.count() / repeat << "."
<< std::endl;
std::cout << "Bytes skipped per second: "
<< (double) size * (double) repeat / totalTime.count()
<< std::endl;
<< (double)size * (double)repeat / totalTime.count() << std::endl;
std::cout << "\nNow comparing with strlen...\n" << std::endl;
@ -619,8 +603,8 @@ void RaceSkipWhiteSpace (uint8_t* src, size_t size, int repeat, int& akku) {
}
now = std::chrono::high_resolution_clock::now();
totalTime
= std::chrono::duration_cast<std::chrono::duration<double>>(now - start);
totalTime =
std::chrono::duration_cast<std::chrono::duration<double>>(now - start);
std::cout << "Race took altogether " << totalTime.count() << " seconds."
<< std::endl;
@ -628,13 +612,13 @@ void RaceSkipWhiteSpace (uint8_t* src, size_t size, int repeat, int& akku) {
<< " on average is: " << totalTime.count() / repeat << "."
<< std::endl;
std::cout << "Bytes scanned per second: "
<< (double) size * (double) repeat / totalTime.count()
<< std::endl;
<< (double)size * (double)repeat / totalTime.count() << std::endl;
}
int main(int argc, char* argv[]) {
if (argc < 4) {
std::cout << "Usage: " << argv[0] << " SIZE REPEAT CORRECTNESS" << std::endl;
std::cout << "Usage: " << argv[0] << " SIZE REPEAT CORRECTNESS"
<< std::endl;
return 0;
}

View File

@ -37,10 +37,7 @@ static inline size_t JSONStringCopyInline (uint8_t* dst, uint8_t const* src,
// Report the number of bytes copied. May copy less bytes, for example
// for alignment reasons.
size_t count = limit;
while (count > 0 &&
*src >= 32 &&
*src != '\\' &&
*src != '"') {
while (count > 0 && *src >= 32 && *src != '\\' && *src != '"') {
*dst++ = *src++;
count--;
}
@ -61,10 +58,7 @@ static inline size_t JSONStringCopyCheckUtf8Inline (uint8_t* dst,
// Report the number of bytes copied. May copy less bytes, for example
// for alignment reasons.
size_t count = limit;
while (count > 0 &&
*src >= 32 &&
*src != '\\' &&
*src != '"' &&
while (count > 0 && *src >= 32 && *src != '\\' && *src != '"' &&
*src < 0x80) {
*dst++ = *src++;
count--;
@ -72,8 +66,7 @@ static inline size_t JSONStringCopyCheckUtf8Inline (uint8_t* dst,
return limit - count;
}
size_t JSONStringCopyCheckUtf8C (uint8_t* dst, uint8_t const* src,
size_t limit);
size_t JSONStringCopyCheckUtf8C(uint8_t* dst, uint8_t const* src, size_t limit);
extern size_t (*JSONStringCopyCheckUtf8)(uint8_t*, uint8_t const*, size_t);
// White space skipping:
@ -84,10 +77,7 @@ static inline size_t JSONSkipWhiteSpaceInline (uint8_t const* ptr,
// Advance ptr and return the number of skipped bytes.
size_t count = limit;
while (count > 0 &&
(*ptr == ' ' ||
*ptr == '\t' ||
*ptr == '\n' ||
*ptr == '\r')) {
(*ptr == ' ' || *ptr == '\t' || *ptr == '\n' || *ptr == '\r')) {
ptr++;
count--;
}

View File

@ -39,8 +39,7 @@ namespace arangodb {
return h;
}
uint64_t fasthash64(const void *buf, size_t len, uint64_t seed)
{
uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) {
const uint64_t m = 0x880355f21e6d1965ULL;
const uint64_t *pos = (const uint64_t *)buf;
const uint64_t *end = pos + (len / 8);
@ -58,13 +57,20 @@ namespace arangodb {
v = 0;
switch (len & 7) {
case 7: v ^= (uint64_t)pos2[6] << 48;
case 6: v ^= (uint64_t)pos2[5] << 40;
case 5: v ^= (uint64_t)pos2[4] << 32;
case 4: v ^= (uint64_t)pos2[3] << 24;
case 3: v ^= (uint64_t)pos2[2] << 16;
case 2: v ^= (uint64_t)pos2[1] << 8;
case 1: v ^= (uint64_t)pos2[0];
case 7:
v ^= (uint64_t)pos2[6] << 48;
case 6:
v ^= (uint64_t)pos2[5] << 40;
case 5:
v ^= (uint64_t)pos2[4] << 32;
case 4:
v ^= (uint64_t)pos2[3] << 24;
case 3:
v ^= (uint64_t)pos2[2] << 16;
case 2:
v ^= (uint64_t)pos2[1] << 8;
case 1:
v ^= (uint64_t)pos2[0];
h ^= mix(v);
h *= m;
}
@ -74,4 +80,3 @@ namespace arangodb {
} // namespace arangodb::velocypack
} // namespace arangodb

View File

@ -52,11 +52,9 @@ static uint64_t tens[] = {
10000000000U, 1000000000U, 100000000U,
10000000U, 1000000U, 100000U,
10000U, 1000U, 100U,
10U, 1U
};
10U, 1U};
static inline uint64_t get_dbits(double d)
{
static inline uint64_t get_dbits(double d) {
union {
double dbl;
uint64_t i;
@ -65,8 +63,7 @@ static inline uint64_t get_dbits(double d)
return dbl_bits.i;
}
static Fp build_fp(double d)
{
static Fp build_fp(double d) {
uint64_t bits = get_dbits(d);
Fp fp;
@ -84,8 +81,7 @@ static Fp build_fp(double d)
return fp;
}
static void normalize(Fp* fp)
{
static void normalize(Fp* fp) {
while ((fp->frac & hiddenbit) == 0) {
fp->frac <<= 1;
fp->exp--;
@ -96,8 +92,7 @@ static void normalize(Fp* fp)
fp->exp -= shift;
}
static void get_normalized_boundaries(Fp* fp, Fp* lower, Fp* upper)
{
static void get_normalized_boundaries(Fp* fp, Fp* lower, Fp* upper) {
upper->frac = (fp->frac << 1) + 1;
upper->exp = fp->exp - 1;
@ -111,19 +106,16 @@ static void get_normalized_boundaries(Fp* fp, Fp* lower, Fp* upper)
upper->frac <<= u_shift;
upper->exp = upper->exp - u_shift;
int l_shift = fp->frac == hiddenbit ? 2 : 1;
lower->frac = (fp->frac << l_shift) - 1;
lower->exp = fp->exp - l_shift;
lower->frac <<= lower->exp - upper->exp;
lower->exp = upper->exp;
}
static Fp multiply(Fp* a, Fp* b)
{
static Fp multiply(Fp* a, Fp* b) {
const uint64_t lomask = 0x00000000FFFFFFFF;
uint64_t ah_bl = (a->frac >> 32) * (b->frac & lomask);
@ -135,26 +127,22 @@ static Fp multiply(Fp* a, Fp* b)
/* round up */
tmp += 1U << 31;
Fp fp = {
ah_bh + (ah_bl >> 32) + (al_bh >> 32) + (tmp >> 32),
a->exp + b->exp + 64
};
Fp fp = {ah_bh + (ah_bl >> 32) + (al_bh >> 32) + (tmp >> 32),
a->exp + b->exp + 64};
return fp;
}
static void round_digit(char* digits, int ndigits, uint64_t delta, uint64_t rem, uint64_t kappa, uint64_t frac)
{
static void round_digit(char* digits, int ndigits, uint64_t delta, uint64_t rem,
uint64_t kappa, uint64_t frac) {
while (rem < frac && delta - rem >= kappa &&
(rem + kappa < frac || frac - rem > rem + kappa - frac)) {
digits[ndigits - 1]--;
rem += kappa;
}
}
static int generate_digits(Fp* fp, Fp* upper, Fp* lower, char* digits, int* K)
{
static int generate_digits(Fp* fp, Fp* upper, Fp* lower, char* digits, int* K) {
uint64_t wfrac = upper->frac - fp->frac;
uint64_t delta = upper->frac - lower->frac;
@ -169,7 +157,6 @@ static int generate_digits(Fp* fp, Fp* upper, Fp* lower, char* digits, int* K)
uint64_t* divp;
/* 1000000000 */
for (divp = tens + 10; kappa > 0; divp++) {
uint64_t div = *divp;
unsigned digit = static_cast<unsigned>(part1 / div);
@ -214,8 +201,7 @@ static int generate_digits(Fp* fp, Fp* upper, Fp* lower, char* digits, int* K)
}
}
static int grisu2(double d, char* digits, int* K)
{
static int grisu2(double d, char* digits, int* K) {
Fp w = build_fp(d);
Fp lower, upper;
@ -238,8 +224,7 @@ static int grisu2(double d, char* digits, int* K)
return generate_digits(&w, &upper, &lower, digits, K);
}
static int emit_digits(char* digits, int ndigits, char* dest, int K, bool neg)
{
static int emit_digits(char* digits, int ndigits, char* dest, int K, bool neg) {
int exp = absv(K + ndigits - 1);
/* write plain integer */
@ -311,8 +296,7 @@ static int emit_digits(char* digits, int ndigits, char* dest, int K, bool neg)
return idx;
}
static int filter_special(double fp, char* dest)
{
static int filter_special(double fp, char* dest) {
if (fp == 0.0) {
dest[0] = '0';
return 1;
@ -327,17 +311,20 @@ static int filter_special(double fp, char* dest)
}
if (bits & fracmask) {
dest[0] = 'N'; dest[1] = 'a'; dest[2] = 'N';
dest[0] = 'N';
dest[1] = 'a';
dest[2] = 'N';
} else {
dest[0] = 'i'; dest[1] = 'n'; dest[2] = 'f';
dest[0] = 'i';
dest[1] = 'n';
dest[2] = 'f';
}
return 3;
}
int arangodb::velocypack::fpconv_dtoa (double d, char dest[24])
{
int arangodb::velocypack::fpconv_dtoa(double d, char dest[24]) {
char digits[18];
int str_len = 0;

View File

@ -12,61 +12,100 @@
#define expmax -32
#define expmin -60
typedef struct Fp {
uint64_t frac;
int exp;
} Fp;
static Fp powers_ten[] = {
{ 18054884314459144840U, -1220 }, { 13451937075301367670U, -1193 },
{ 10022474136428063862U, -1166 }, { 14934650266808366570U, -1140 },
{ 11127181549972568877U, -1113 }, { 16580792590934885855U, -1087 },
{ 12353653155963782858U, -1060 }, { 18408377700990114895U, -1034 },
{ 13715310171984221708U, -1007 }, { 10218702384817765436U, -980 },
{ 15227053142812498563U, -954 }, { 11345038669416679861U, -927 },
{ 16905424996341287883U, -901 }, { 12595523146049147757U, -874 },
{ 9384396036005875287U, -847 }, { 13983839803942852151U, -821 },
{ 10418772551374772303U, -794 }, { 15525180923007089351U, -768 },
{ 11567161174868858868U, -741 }, { 17236413322193710309U, -715 },
{ 12842128665889583758U, -688 }, { 9568131466127621947U, -661 },
{ 14257626930069360058U, -635 }, { 10622759856335341974U, -608 },
{ 15829145694278690180U, -582 }, { 11793632577567316726U, -555 },
{ 17573882009934360870U, -529 }, { 13093562431584567480U, -502 },
{ 9755464219737475723U, -475 }, { 14536774485912137811U, -449 },
{ 10830740992659433045U, -422 }, { 16139061738043178685U, -396 },
{ 12024538023802026127U, -369 }, { 17917957937422433684U, -343 },
{ 13349918974505688015U, -316 }, { 9946464728195732843U, -289 },
{ 14821387422376473014U, -263 }, { 11042794154864902060U, -236 },
{ 16455045573212060422U, -210 }, { 12259964326927110867U, -183 },
{ 18268770466636286478U, -157 }, { 13611294676837538539U, -130 },
{ 10141204801825835212U, -103 }, { 15111572745182864684U, -77 },
{ 11258999068426240000U, -50 }, { 16777216000000000000U, -24 },
{ 12500000000000000000U, 3 }, { 9313225746154785156U, 30 },
{ 13877787807814456755U, 56 }, { 10339757656912845936U, 83 },
{ 15407439555097886824U, 109 }, { 11479437019748901445U, 136 },
{ 17105694144590052135U, 162 }, { 12744735289059618216U, 189 },
{ 9495567745759798747U, 216 }, { 14149498560666738074U, 242 },
{ 10542197943230523224U, 269 }, { 15709099088952724970U, 295 },
{ 11704190886730495818U, 322 }, { 17440603504673385349U, 348 },
{ 12994262207056124023U, 375 }, { 9681479787123295682U, 402 },
{ 14426529090290212157U, 428 }, { 10748601772107342003U, 455 },
{ 16016664761464807395U, 481 }, { 11933345169920330789U, 508 },
{ 17782069995880619868U, 534 }, { 13248674568444952270U, 561 },
{ 9871031767461413346U, 588 }, { 14708983551653345445U, 614 },
{ 10959046745042015199U, 641 }, { 16330252207878254650U, 667 },
{ 12166986024289022870U, 694 }, { 18130221999122236476U, 720 },
{ 13508068024458167312U, 747 }, { 10064294952495520794U, 774 },
{ 14996968138956309548U, 800 }, { 11173611982879273257U, 827 },
{ 16649979327439178909U, 853 }, { 12405201291620119593U, 880 },
{ 9242595204427927429U, 907 }, { 13772540099066387757U, 933 },
{ 10261342003245940623U, 960 }, { 15290591125556738113U, 986 },
{ 11392378155556871081U, 1013 }, { 16975966327722178521U, 1039 },
{ 12648080533535911531U, 1066 }
};
static Fp powers_ten[] = {{18054884314459144840U, -1220},
{13451937075301367670U, -1193},
{10022474136428063862U, -1166},
{14934650266808366570U, -1140},
{11127181549972568877U, -1113},
{16580792590934885855U, -1087},
{12353653155963782858U, -1060},
{18408377700990114895U, -1034},
{13715310171984221708U, -1007},
{10218702384817765436U, -980},
{15227053142812498563U, -954},
{11345038669416679861U, -927},
{16905424996341287883U, -901},
{12595523146049147757U, -874},
{9384396036005875287U, -847},
{13983839803942852151U, -821},
{10418772551374772303U, -794},
{15525180923007089351U, -768},
{11567161174868858868U, -741},
{17236413322193710309U, -715},
{12842128665889583758U, -688},
{9568131466127621947U, -661},
{14257626930069360058U, -635},
{10622759856335341974U, -608},
{15829145694278690180U, -582},
{11793632577567316726U, -555},
{17573882009934360870U, -529},
{13093562431584567480U, -502},
{9755464219737475723U, -475},
{14536774485912137811U, -449},
{10830740992659433045U, -422},
{16139061738043178685U, -396},
{12024538023802026127U, -369},
{17917957937422433684U, -343},
{13349918974505688015U, -316},
{9946464728195732843U, -289},
{14821387422376473014U, -263},
{11042794154864902060U, -236},
{16455045573212060422U, -210},
{12259964326927110867U, -183},
{18268770466636286478U, -157},
{13611294676837538539U, -130},
{10141204801825835212U, -103},
{15111572745182864684U, -77},
{11258999068426240000U, -50},
{16777216000000000000U, -24},
{12500000000000000000U, 3},
{9313225746154785156U, 30},
{13877787807814456755U, 56},
{10339757656912845936U, 83},
{15407439555097886824U, 109},
{11479437019748901445U, 136},
{17105694144590052135U, 162},
{12744735289059618216U, 189},
{9495567745759798747U, 216},
{14149498560666738074U, 242},
{10542197943230523224U, 269},
{15709099088952724970U, 295},
{11704190886730495818U, 322},
{17440603504673385349U, 348},
{12994262207056124023U, 375},
{9681479787123295682U, 402},
{14426529090290212157U, 428},
{10748601772107342003U, 455},
{16016664761464807395U, 481},
{11933345169920330789U, 508},
{17782069995880619868U, 534},
{13248674568444952270U, 561},
{9871031767461413346U, 588},
{14708983551653345445U, 614},
{10959046745042015199U, 641},
{16330252207878254650U, 667},
{12166986024289022870U, 694},
{18130221999122236476U, 720},
{13508068024458167312U, 747},
{10064294952495520794U, 774},
{14996968138956309548U, 800},
{11173611982879273257U, 827},
{16649979327439178909U, 853},
{12405201291620119593U, 880},
{9242595204427927429U, 907},
{13772540099066387757U, 933},
{10261342003245940623U, 960},
{15290591125556738113U, 986},
{11392378155556871081U, 1013},
{16975966327722178521U, 1039},
{12648080533535911531U, 1066}};
static Fp find_cachedpow10(int exp, int* k)
{
static Fp find_cachedpow10(int exp, int* k) {
const double one_log_ten = 0.30102999566398114;
int approx = static_cast<int>(-(exp + npowers) * one_log_ten);

View File

@ -41,9 +41,10 @@ void checkValueLength (ValueLength length) {
#endif
int64_t arangodb::velocypack::currentUTCDateValue() {
return static_cast<int64_t>(std::chrono::system_clock::now().time_since_epoch().count() / std::chrono::milliseconds(1).count());
return static_cast<int64_t>(
std::chrono::system_clock::now().time_since_epoch().count() /
std::chrono::milliseconds(1).count());
}
static_assert(sizeof(arangodb::velocypack::ValueLength) >= sizeof(SIZE_MAX),
"invalid value for SIZE_MAX");