1
0
Fork 0
arangodb/arangod/VocBase/shaped-json.h

1139 lines
38 KiB
C++

////////////////////////////////////////////////////////////////////////////////
/// @brief shaped JSON objects
///
/// @file
/// Declaration for shaped JSON objects.
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGODB_VOC_BASE_SHAPED_JSON_H
#define ARANGODB_VOC_BASE_SHAPED_JSON_H 1
#include "Basics/Common.h"
#include "Basics/fasthash.h"
#include "Basics/json.h"
////////////////////////////////////////////////////////////////////////////////
/// @page ShapedJson JSON Shapes
///
/// A JSON object is either
///
/// - a scalar type
/// - @c null
/// - a boolean: @c true or @c false
/// - a floating point number
/// - a string
/// - a list (aka array)
/// - a object (aka associative array or hash or document)
///
/// In theory JSON documents are schema-free. They can have any number of
/// attributes and an attribute value can be any JSON object. However, in
/// practice JSON documents often share a common shape. In order to take
/// advantage of this fact, JSON objects can be converted into
/// @ref TRI_shaped_json_t instances together with a shape described by an
/// @ref TRI_shape_t instance.
///
/// A @ref TRI_shape_t describes the layout of the JSON document. Currently,
/// the following shapes are supported:
///
/// - @ref TRI_null_shape_t for the "null" object
/// - @ref TRI_boolean_shape_t for boolean values
/// - @ref TRI_number_shape_t for floating point numbers
/// - @ref TRI_short_string_shape_t for short strings of size less then
/// @ref TRI_SHAPE_SHORT_STRING_CUT, this includes the trailing null
/// - @ref TRI_long_string_shape_t for strings longer than the above limit
/// - @ref TRI_list_shape_t for arbitrary lists
/// - @ref TRI_homogeneous_list_shape_t for lists of objects of the same shape
/// - @ref TRI_homogeneous_sized_list_shape_t for lists of objects of the same
/// shape and size
/// - @ref TRI_array_shape_t for associative arrays
///
/// A shape can be of fixed or arbitrary size. For instance, a
/// @ref TRI_boolean_shape_t is of fixed size, because all boolean JSON
/// objects are of fixed size. The same is true for null, numbers and short
/// strings. A long string is of variable size. Lists are always variable
/// sized. However, a list can be homogeneous or in-homogeneous. A homogeneous
/// list contains only objects of the same shape. For instance, the list
///
/// [ 1, 2, 3, 4, 5 ]
///
/// is homogeneous. In this case it is also homogeneous-sized because all
/// elements of the list have the same size. The list
///
/// [ "Looooooooong String", "Another Looooooooooong String" ]
///
/// is also homogeneous, but not homogeneous-sized as the long strings are
/// variable sized. Note that for a list to be homogeneous-sized the
/// corresponding shape must be fixed sized. Even if in the above example
/// the strings were of equal lengths, that would not imply that the
/// list if homogeneous-sized. It is the shape that matters.
///
/// An array shape can be of fixed or variable size. For instance
///
/// {
/// "a" : 1,
/// "b" : { "c" : 2 }
/// }
///
/// is of fixed size, because all sub-objects are of fixed size. In contrast
/// the object
///
/// {
/// "a" : [ 1 ]
/// }
///
/// is of variable size, because the sub-object stored in "a" is of variable
/// size.
///
/// @section TRI_null_shape_t
///
/// The shape representing the "null" value.
///
/// @copydetails TRI_null_shape_t
///
/// @section TRI_boolean_shape_t
///
/// The shape representing a boolean value.
///
/// @copydetails TRI_boolean_shape_t
///
/// @section TRI_number_shape_t
///
/// The shape representing a number value.
///
/// @copydetails TRI_number_shape_t
///
/// @section TRI_short_string_shape_t
///
/// The shape representing a short string.
///
/// @copydetails TRI_short_string_shape_t
///
/// @section TRI_long_string_shape_t
///
/// The shape representing a string.
///
/// @copydetails TRI_long_string_shape_t
///
/// @section TRI_array_shape_t
///
/// The most complex shape is the shape of an associative array.
///
/// @copydetails TRI_array_shape_t
///
/// @section TRI_list_shape_t
///
/// The shape representing a list.
///
/// @copydetails TRI_list_shape_t
///
/// @section TRI_homogeneous_list_shape_t
///
/// The shape representing a homogeneous list.
///
/// @copydetails TRI_homogeneous_list_shape_t
///
/// @section TRI_homogeneous_sized_list_shape_t
///
/// The shape representing a homogeneous list.
///
/// @copydetails TRI_homogeneous_sized_list_shape_t
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- forward declarations
// -----------------------------------------------------------------------------
struct TRI_memory_zone_s;
struct TRI_string_buffer_s;
class VocShaper;
// -----------------------------------------------------------------------------
// --SECTION-- public constants
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief size of short strings
////////////////////////////////////////////////////////////////////////////////
#define TRI_SHAPE_SHORT_STRING_CUT 7
////////////////////////////////////////////////////////////////////////////////
/// @brief indicator for variable sized data
////////////////////////////////////////////////////////////////////////////////
#define TRI_SHAPE_SIZE_VARIABLE ((TRI_shape_size_t) -1)
// -----------------------------------------------------------------------------
// --SECTION-- JSON SHAPE
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// --SECTION-- public types
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief json storage type of a shape identifier
///
/// @note 0 is not a valid shape identifier.
////////////////////////////////////////////////////////////////////////////////
typedef uint64_t TRI_shape_sid_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief json storage type of an attribute identifier
////////////////////////////////////////////////////////////////////////////////
typedef uint64_t TRI_shape_aid_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief json storage type of a size
////////////////////////////////////////////////////////////////////////////////
typedef uint64_t TRI_shape_size_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief json type of a shape
////////////////////////////////////////////////////////////////////////////////
typedef enum {
TRI_SHAPE_ILLEGAL = 0,
TRI_SHAPE_NULL = 1,
TRI_SHAPE_BOOLEAN = 2,
TRI_SHAPE_NUMBER = 3,
TRI_SHAPE_SHORT_STRING = 4,
TRI_SHAPE_LONG_STRING = 5,
TRI_SHAPE_ARRAY = 6,
TRI_SHAPE_LIST = 7,
TRI_SHAPE_HOMOGENEOUS_LIST = 8,
TRI_SHAPE_HOMOGENEOUS_SIZED_LIST = 9
}
TRI_shape_type_e;
////////////////////////////////////////////////////////////////////////////////
/// @brief json storage type of a TRI_shape_type_e
////////////////////////////////////////////////////////////////////////////////
typedef uint64_t TRI_shape_type_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief json storage type of a boolean
////////////////////////////////////////////////////////////////////////////////
typedef uint32_t TRI_shape_boolean_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief json storage type of a number
////////////////////////////////////////////////////////////////////////////////
typedef double TRI_shape_number_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief json storage type of a length for short strings
////////////////////////////////////////////////////////////////////////////////
typedef uint8_t TRI_shape_length_short_string_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief json storage type of a length for long strings
////////////////////////////////////////////////////////////////////////////////
typedef uint32_t TRI_shape_length_long_string_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief json storage type of a length for lists
////////////////////////////////////////////////////////////////////////////////
typedef uint32_t TRI_shape_length_list_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief base class for json shape
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_shape_s {
TRI_shape_sid_t _sid;
TRI_shape_type_t _type;
TRI_shape_size_t _size; // total size of the shape
TRI_shape_size_t _dataSize; // in case of fixed sized shaped or TRI_SHAPE_SIZE_VARIABLE
}
TRI_shape_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief entry/value structure
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_shape_value_s {
TRI_shape_aid_t _aid; // attribute identifier
TRI_shape_sid_t _sid; // shape identifier of the attribute
TRI_shape_type_t _type; // type of the attribute
bool _fixedSized; // true of all element of this shape have the same size
TRI_shape_size_t _size; // size of the data block
char* _value;
}
TRI_shape_value_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief json shape, null
///
/// A @c TRI_null_shape_t describes the null value. There are no additional
/// attributes.
///
/// <table border>
/// <tr>
/// <td>@c TRI_shape_sid_t</td>
/// <td>_sid</td>
/// <td>shape identifier</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_type_t</td>
/// <td>_type</td>
/// <td>always @c TRI_SHAPE_NULL</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_size</td>
/// <td>total size of the shape, always sizeof(TRI_null_shape_t)</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_dataSize</td>
/// <td>always 0</td>
/// </tr>
/// </table>
///
/// There is no corresponding shaped JSON object.
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_null_shape_s {
TRI_shape_t base;
}
TRI_null_shape_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief json shape, boolean
///
/// A @c TRI_boolean_shape_t describes a boolean value. There are no additional
/// attributes.
///
/// <table border>
/// <tr>
/// <td>@c TRI_shape_sid_t</td>
/// <td>_sid</td>
/// <td>shape identifier</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_type_t</td>
/// <td>_type</td>
/// <td>always @c TRI_SHAPE_BOOLEAN</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_size</td>
/// <td>total size of the shape, always sizeof(TRI_boolean_shape_t)</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_dataSize</td>
/// <td>always sizeof(TRI_shape_boolean_t)</td>
/// </tr>
/// </table>
///
/// The memory layout of the corresponding shaped JSON is as follows
///
/// <table border>
/// <tr>
/// <td>@c TRI_shape_boolean_t</td>
/// <td>_value</td>
/// <td>the boolean value: 0 or 1</td>
/// </tr>
/// </table>
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_boolean_shape_s {
TRI_shape_t base;
}
TRI_boolean_shape_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief json shape, number
///
/// A @c TRI_number_shape_t describes a number value. There are no additional
/// attributes.
///
/// <table border>
/// <tr>
/// <td>@c TRI_shape_sid_t</td>
/// <td>_sid</td>
/// <td>shape identifier</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_type_t</td>
/// <td>_type</td>
/// <td>always @c TRI_SHAPE_NUMBER</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_size</td>
/// <td>total size of the shape, always sizeof(TRI_number_shape_t)</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_dataSize</td>
/// <td>always sizeof(TRI_shape_number_t)</td>
/// </tr>
/// </table>
///
/// The memory layout of the corresponding shaped JSON is as follows
///
/// <table border>
/// <tr>
/// <td>@c TRI_shape_number_t</td>
/// <td>_value</td>
/// <td>the number value</td>
/// </tr>
/// </table>
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_number_shape_s {
TRI_shape_t base;
}
TRI_number_shape_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief json shape, short string
///
/// A @c TRI_short_string_shape_t describes a short string value. There are no
/// additional attributes.
///
/// <table border>
/// <tr>
/// <td>@c TRI_shape_sid_t</td>
/// <td>_sid</td>
/// <td>shape identifier</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_type_t</td>
/// <td>_type</td>
/// <td>always @c TRI_SHAPE_SHORT_STRING</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_size</td>
/// <td>total size of the shape, always sizeof(TRI_short_string_shape_t)</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_dataSize</td>
/// <td>always sizeof(TRI_shape_length_short_string_t) + @c TRI_SHAPE_SHORT_STRING_CUT</td>
/// </tr>
/// </table>
///
/// The memory layout of the corresponding shaped JSON is as follows
///
/// <table border>
/// <tr>
/// <td>@c TRI_shape_length_short_string_t</td>
/// <td>_length</td>
/// <td>the length of the string including the final '\0'</td>
/// </tr>
/// <tr>
/// <td>@c char</td>
/// <td>_value[TRI_SHAPE_SHORT_STRING_CUT]</td>
/// <td>the string</td>
/// </tr>
/// </table>
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_short_string_shape_s {
TRI_shape_t base;
}
TRI_short_string_shape_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief json shape, long string
///
/// A @c TRI_long_string_shape_t describes a string value. There are no
/// additional attributes.
///
/// <table border>
/// <tr>
/// <td>@c TRI_shape_sid_t</td>
/// <td>_sid</td>
/// <td>shape identifier</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_type_t</td>
/// <td>_type</td>
/// <td>always @c TRI_SHAPE_LONG_STRING</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_size</td>
/// <td>total size of the shape, always sizeof(TRI_long_string_shape_t)</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_dataSize</td>
/// <td>always @c TRI_SHAPE_SIZE_VARIABLE</td>
/// </tr>
/// </table>
///
/// The memory layout of the corresponding shaped JSON is as follows
///
/// <table border>
/// <tr>
/// <td>@c TRI_shape_length_long_string_t</td>
/// <td>_length</td>
/// <td>the length of the string including the final '\0'</td>
/// </tr>
/// <tr>
/// <td>@c char</td>
/// <td>_value[_length]</td>
/// <td>the string</td>
/// </tr>
/// </table>
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_long_string_shape_s {
TRI_shape_t base;
}
TRI_long_string_shape_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief json shape, array
///
/// A @c TRI_array_shape_t describes a JSON associative array. Such an array
/// consists of keys (aka attributes) and values. The values themself are
/// again described by @c TRI_shape_t instances. The keys are divided into
/// keys belonging to fixed sized values and into keys belonging to variable
/// sized values. The offsets into the data array of an @c TRI_shaped_json_t
/// for the fixed sized values are stored inside the shape. The offsets for the
/// variable sized values are store inside the shaped JSON. The offsets
/// are measured from the beginning of the shaped JSON. The memory
/// layout of a array shape is as follows:
///
/// <table border>
/// <tr>
/// <td>@c TRI_shape_sid_t</td>
/// <td>_sid</td>
/// <td>shape identifier</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_type_t</td>
/// <td>_type</td>
/// <td>always @c TRI_SHAPE_ARRAY</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_size</td>
/// <td>total size of the shape</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_dataSize</td>
/// <td>eitder @c TRI_SHAPE_SIZE_VARIABLE or tde size of tde data for fixed sized arrays</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_fixedEntries</td>
/// <td>number of fixed attributes</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_variableEntries</td>
/// <td>number of variable attributes</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_sid_t</td>
/// <td>_sids[_fixedEntries + _variableEntries]</td>
/// <td>shape identifier of the corresponding attribute</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_aid_t</td>
/// <td>_aids[_fixedEntries + _variableEntries]</td>
/// <td>attribute identifier of the corresponding attribute</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_offsets[_fixedEntries + 1]</td>
/// <td>offsets into the @c TRI_shaped_json_t object</td>
/// </tr>
/// </table>
///
/// Note that the data block for the n.the fixed sized attribute is between
/// offset _offsets[n] (inclusive) and _offsets[n + 1] (exclusive).
///
/// The memory layout of the corresponding shaped JSON is as follows
///
/// <table border>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_offsets[_variableEntries + 1]</td>
/// <td>offsets into myself</td>
/// </tr>
/// <tr>
/// <td>byte[size1]</td>
/// <td>_attribute1</td>
/// <td>memory block of the value of the first attribute</td>
/// </tr>
/// <tr>
/// <td>byte[size2]</td>
/// <td>_attribute2</td>
/// <td>memory block of the value of the second attribute</td>
/// </tr>
/// <tr>
/// <td>...</td>
/// <td>...</td>
/// <td>...</td>
/// </tr>
/// </table>
///
/// The first variable sized attributes is stored between offset _offsets[0]
/// (inclusive) and _offsets[1] (exclusive).
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_array_shape_s {
TRI_shape_t base;
TRI_shape_size_t _fixedEntries;
TRI_shape_size_t _variableEntries;
// TRI_shape_sid_t _sids[_fixedEntries + _variableEntries]
// TRI_shape_aid_t _aids[_fixedEntries + _variableEntries]
// TRI_shape_size_t _offsets[_fixedEntries + 1]
}
TRI_array_shape_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief json shape, in-homogeneous list
///
/// A @c TRI_list_shape_t describes a list value. There are no additional
/// attributes.
///
/// <table border>
/// <tr>
/// <td>@c TRI_shape_sid_t</td>
/// <td>_sid</td>
/// <td>shape identifier</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_type_t</td>
/// <td>_type</td>
/// <td>always @c TRI_SHAPE_LIST</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_size</td>
/// <td>total size of the shape, always sizeof(TRI_list_shape_t)</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_dataSize</td>
/// <td>always @c TRI_SHAPE_SIZE_VARIABLE</td>
/// </tr>
/// </table>
///
/// The memory layout of the corresponding shaped JSON is as follows
///
/// <table border>
/// <tr>
/// <td>@c TRI_shape_length_list_t</td>
/// <td>_length</td>
/// <td>the length of the list</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_sid_t</td>
/// <td>_sids[_length]</td>
/// <td>the shape identifiers for the list entries</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_offsets[_length + 1]</td>
/// <td>offsets into the @c TRI_shaped_json_t object</td>
/// </tr>
/// <tr>
/// <td>byte[size1]</td>
/// <td>_attribute1</td>
/// <td>memory block of the value of the first attribute</td>
/// </tr>
/// <tr>
/// <td>byte[size2]</td>
/// <td>_attribute2</td>
/// <td>memory block of the value of the second attribute</td>
/// </tr>
/// <tr>
/// <td>...</td>
/// <td>...</td>
/// <td>...</td>
/// </tr>
/// </table>
///
/// The first variable list element is stored between offset _offsets[0]
/// (inclusive) and _offsets[1] (exclusive). Offsets are measured from
/// the beginning of the shaped JSON.
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_list_shape_s {
TRI_shape_t base;
}
TRI_list_shape_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief json shape, homogeneous list, in-homogeneous size
///
/// A @c TRI_homogeneous_list_shape_t describes a homogeneous list value. That is
/// to say, all list elements have the same shape, but possible different sizes.
///
/// <table border>
/// <tr>
/// <td>@c TRI_shape_sid_t</td>
/// <td>_sid</td>
/// <td>shape identifier</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_type_t</td>
/// <td>_type</td>
/// <td>always @c TRI_SHAPE_LIST</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_size</td>
/// <td>total size of the shape, always sizeof(TRI_list_shape_t)</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_dataSize</td>
/// <td>always @c TRI_SHAPE_SIZE_VARIABLE</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_sid_t</td>
/// <td>_sidEntry</td>
/// <td>the shape identifier of all list entries</td>
/// </tr>
/// </table>
///
/// The memory layout of the corresponding shaped JSON is as follows
///
/// <table border>
/// <tr>
/// <td>@c TRI_shape_length_list_t</td>
/// <td>_length</td>
/// <td>the length of the list</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_offsets[_length + 1]</td>
/// <td>offsets into the @c TRI_shaped_json_t object</td>
/// </tr>
/// <tr>
/// <td>byte[size1]</td>
/// <td>_attribute1</td>
/// <td>memory block of the value of the first attribute</td>
/// </tr>
/// <tr>
/// <td>byte[size2]</td>
/// <td>_attribute2</td>
/// <td>memory block of the value of the second attribute</td>
/// </tr>
/// <tr>
/// <td>...</td>
/// <td>...</td>
/// <td>...</td>
/// </tr>
/// </table>
///
/// The first variable list element is stored between offset _offsets[0]
/// (inclusive) and _offsets[1] (exclusive).
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_homogeneous_list_shape_s {
TRI_shape_t base;
TRI_shape_sid_t _sidEntry;
}
TRI_homogeneous_list_shape_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief json shape, homogeneous list, homogeneous size
///
/// A @c TRI_homogeneous_sized_list_shape_t describes a homogeneous, equally
/// sized list value. That is to say, all list elements have the same shape and
/// the same size.
///
/// <table border>
/// <tr>
/// <td>@c TRI_shape_sid_t</td>
/// <td>_sid</td>
/// <td>shape identifier</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_type_t</td>
/// <td>_type</td>
/// <td>always @c TRI_SHAPE_LIST</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_size</td>
/// <td>total size of the shape, always sizeof(TRI_list_shape_t)</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_dataSize</td>
/// <td>always @c TRI_SHAPE_SIZE_VARIABLE</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_sid_t</td>
/// <td>_sidEntry</td>
/// <td>the shape identifier of all list entries</td>
/// </tr>
/// <tr>
/// <td>@c TRI_shape_size_t</td>
/// <td>_sizeEntry</td>
/// <td>the common size of all list entries</td>
/// </tr>
/// </table>
///
/// The memory layout of the corresponding shaped JSON is as follows
///
/// <table border>
/// <tr>
/// <td>@c TRI_shape_length_list_t</td>
/// <td>_length</td>
/// <td>the length of the list</td>
/// </tr>
/// <tr>
/// <td>byte[size1]</td>
/// <td>_attribute1</td>
/// <td>memory block of the value of the first attribute</td>
/// </tr>
/// <tr>
/// <td>byte[size2]</td>
/// <td>_attribute2</td>
/// <td>memory block of the value of the second attribute</td>
/// </tr>
/// <tr>
/// <td>...</td>
/// <td>...</td>
/// <td>...</td>
/// </tr>
/// </table>
///
/// The first variable list element is stored between offset 0 (inclusive) and
/// _sizeEntry (exclusive).
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_homogeneous_sized_list_shape_s {
TRI_shape_t base;
TRI_shape_sid_t _sidEntry;
TRI_shape_size_t _sizeEntry;
}
TRI_homogeneous_sized_list_shape_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief shaped json
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_shaped_json_s {
TRI_shape_sid_t _sid;
TRI_blob_t _data;
}
TRI_shaped_json_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief Hash and Equal comparison for a vector of TRI_shaped_json_t
////////////////////////////////////////////////////////////////////////////////
namespace std {
template<> struct hash<std::vector<TRI_shaped_json_t>> {
size_t operator () (std::vector<TRI_shaped_json_t> const& x) const {
std::hash<TRI_shape_sid_t> sidHash;
size_t res = 0xdeadbeef;
for (auto& el : x) {
res ^= sidHash(el._sid);
if (el._data.data != nullptr) {
res ^= fasthash64(el._data.data, el._data.length, 0xdeadbeef);
}
}
return res;
}
};
template<> struct equal_to<std::vector<TRI_shaped_json_t>> {
bool operator () (std::vector<TRI_shaped_json_t> const& a,
std::vector<TRI_shaped_json_t> const& b) const {
size_t size = a.size();
if (size != b.size()) {
return false;
}
for (size_t i = 0; i < size; ++i) {
if (a[i]._sid != b[i]._sid) {
return false;
}
if (a[i]._data.data == nullptr || b[i]._data.data == nullptr) {
// TODO FIXME
return false;
}
if (a[i]._data.length != b[i]._data.length) {
return false;
}
if (memcmp(a[i]._data.data, b[i]._data.data, a[i]._data.length) != 0) {
return false;
}
}
return true;
}
};
} //closes namespace std
////////////////////////////////////////////////////////////////////////////////
/// @brief shaped json sub-object
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_shaped_sub_s {
TRI_shape_sid_t _sid;
union {
char _data[8];
struct {
uint32_t _offset;
uint32_t _length;
}
_position;
}
_value;
}
TRI_shaped_sub_t;
// -----------------------------------------------------------------------------
// --SECTION-- ATTRIBUTE PATH
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// --SECTION-- public types
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief json storage type of an attribute path
////////////////////////////////////////////////////////////////////////////////
typedef uint64_t TRI_shape_pid_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief json attribute path
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_shape_path_s {
TRI_shape_pid_t _pid;
uint64_t _aidLength;
uint32_t _nameLength; // include trailing '\0'
// TRI_shape_aid_t _aids[];
// char _name[];
}
TRI_shape_path_t;
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief performs a deep copy of a shaped json object
////////////////////////////////////////////////////////////////////////////////
TRI_shaped_json_t* TRI_CopyShapedJson (VocShaper*, TRI_shaped_json_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief destroys a json object, but does not free the pointer
////////////////////////////////////////////////////////////////////////////////
void TRI_DestroyShapedJson (struct TRI_memory_zone_s*, TRI_shaped_json_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief destroys a json object and frees the pointer
////////////////////////////////////////////////////////////////////////////////
void TRI_FreeShapedJson (struct TRI_memory_zone_s*,
TRI_shaped_json_t*);
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief sorts a list of TRI_shape_value_t
////////////////////////////////////////////////////////////////////////////////
void TRI_SortShapeValues (TRI_shape_value_t* values,
size_t n);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts a json object into a shaped json object
////////////////////////////////////////////////////////////////////////////////
TRI_shaped_json_t* TRI_ShapedJsonJson (VocShaper*,
TRI_json_t const*,
bool);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts a shaped json object into a json object
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* TRI_JsonShapedJson (VocShaper*,
TRI_shaped_json_t const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief prints a shaped json to a string buffer, without the outer braces
/// this can only be used to stringify shapes of type array
////////////////////////////////////////////////////////////////////////////////
template<typename T>
bool TRI_StringifyArrayShapedJson (T*,
struct TRI_string_buffer_s*,
TRI_shaped_json_t const*,
bool);
////////////////////////////////////////////////////////////////////////////////
/// @brief prints a shaped json to a string buffer
////////////////////////////////////////////////////////////////////////////////
bool TRI_StringifyAugmentedShapedJson (VocShaper*,
struct TRI_string_buffer_s*,
TRI_shaped_json_t const*,
TRI_json_t const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the length of a list
////////////////////////////////////////////////////////////////////////////////
size_t TRI_LengthListShapedJson (TRI_list_shape_t const*,
TRI_shaped_json_t const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the n.th element of a list
////////////////////////////////////////////////////////////////////////////////
bool TRI_AtListShapedJson (TRI_list_shape_t const* shape,
TRI_shaped_json_t const* json,
size_t position,
TRI_shaped_json_t* result);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the length of a homogeneous list
////////////////////////////////////////////////////////////////////////////////
size_t TRI_LengthHomogeneousListShapedJson (TRI_homogeneous_list_shape_t const* shape,
TRI_shaped_json_t const* json);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the n.th element of a homogeneous list
////////////////////////////////////////////////////////////////////////////////
bool TRI_AtHomogeneousListShapedJson (TRI_homogeneous_list_shape_t const* shape,
TRI_shaped_json_t const* json,
size_t position,
TRI_shaped_json_t* result);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the length of a homogeneous sized list
////////////////////////////////////////////////////////////////////////////////
size_t TRI_LengthHomogeneousSizedListShapedJson (TRI_homogeneous_sized_list_shape_t const* shape,
TRI_shaped_json_t const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the n.th element of a homogeneous sized list
////////////////////////////////////////////////////////////////////////////////
bool TRI_AtHomogeneousSizedListShapedJson (TRI_homogeneous_sized_list_shape_t const* shape,
TRI_shaped_json_t const*,
size_t position,
TRI_shaped_json_t*);
// -----------------------------------------------------------------------------
// --SECTION-- private functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief prints a TRI_shape_t for debugging
////////////////////////////////////////////////////////////////////////////////
void TRI_PrintShape (VocShaper*,
TRI_shape_t const* shape,
int indent);
////////////////////////////////////////////////////////////////////////////////
/// @brief get the string value encoded in a shaped json
/// this will return the pointer to the string and the string length in the
/// variables passed by reference
////////////////////////////////////////////////////////////////////////////////
bool TRI_StringValueShapedJson (TRI_shape_t const*,
char const*,
char**,
size_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief iterate over a shaped json array, using a callback function
////////////////////////////////////////////////////////////////////////////////
void TRI_IterateShapeDataArray (VocShaper*,
TRI_shape_t const*,
char const*,
bool (*)(VocShaper*, TRI_shape_t const*, char const*, char const*, uint64_t, void*),
void*);
////////////////////////////////////////////////////////////////////////////////
/// @brief iterate over a shaped json list, using a callback function
////////////////////////////////////////////////////////////////////////////////
void TRI_IterateShapeDataList (VocShaper*,
TRI_shape_t const*,
char const*,
bool (*)(VocShaper*, TRI_shape_t const*, char const*, uint64_t, void*),
void*);
////////////////////////////////////////////////////////////////////////////////
/// @brief prints a list of TRI_shape_value_t for debugging
////////////////////////////////////////////////////////////////////////////////
void TRI_PrintShapeValues (TRI_shape_value_t*,
size_t);
#endif
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End: