static TRI_json_t* GetMergedKeyList (const TRI_json_t* const lhs, const TRI_json_t* const rhs) { TRI_json_t* keys; TRI_json_t* unique; size_t i, n; TRI_ASSERT(lhs->_type == TRI_JSON_ARRAY); TRI_ASSERT(rhs->_type == TRI_JSON_ARRAY); keys = TRI_CreateList2Json(TRI_UNKNOWN_MEM_ZONE, lhs->_value._objects._length + rhs->_value._objects._length); if (keys == NULL) { return NULL; } n = lhs->_value._objects._length; for (i = 0 ; i < n; i += 2) { TRI_json_t* key = TRI_AtVector(&lhs->_value._objects, i); TRI_ASSERT(TRI_IsStringJson(key)); TRI_PushBackListJson(TRI_UNKNOWN_MEM_ZONE, keys, key); } n = rhs->_value._objects._length; for (i = 0 ; i < n; i += 2) { TRI_json_t* key = TRI_AtVector(&rhs->_value._objects, i); TRI_ASSERT(TRI_IsStringJson(key)); TRI_PushBackListJson(TRI_UNKNOWN_MEM_ZONE, keys, key); } // sort the key list in place TRI_SortListJson(keys); // list is now sorted unique = TRI_UniquifyListJson(keys); TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, keys); return unique; // might be NULL }
TRI_json_t* TRI_CreateListJson (TRI_memory_zone_t* zone) { return TRI_CreateList2Json(zone, 0); }
TRI_json_t* TRI_IntersectListsJson (const TRI_json_t* const list1, const TRI_json_t* const list2, const bool unique) { TRI_json_t* last = NULL; TRI_json_t* result; size_t i1, i2; size_t n1, n2; TRI_ASSERT(list1); TRI_ASSERT(list1->_type == TRI_JSON_LIST); TRI_ASSERT(list2); TRI_ASSERT(list2->_type == TRI_JSON_LIST); n1 = list1->_value._objects._length; n2 = list2->_value._objects._length; // create result list result = TRI_CreateList2Json(TRI_UNKNOWN_MEM_ZONE, n1 > n2 ? n1 : n2); if (result == NULL) { return NULL; } // special case for empty lists if (n1 == 0 || n2 == 0) { return result; } // reset positions i1 = 0; i2 = 0; // iterate over lists while (i1 < n1 && i2 < n2) { // pointers to elements in both lists TRI_json_t* p1 = TRI_AtVector(&list1->_value._objects, i1); TRI_json_t* p2 = TRI_AtVector(&list2->_value._objects, i2); int compareResult = TRI_CompareValuesJson(p1, p2); if (compareResult < 0) { // left element is smaller ++i1; } else if (compareResult > 0) { // right element is smaller ++i2; } else { // both elements are equal if (! unique || last == NULL || TRI_CompareValuesJson(p1, last) > 0) { TRI_PushBackListJson(TRI_UNKNOWN_MEM_ZONE, result, p1); last = p1; if (! unique) { TRI_PushBackListJson(TRI_UNKNOWN_MEM_ZONE, result, p2); } } ++i1; ++i2; } } return result; }
TRI_json_t* TRI_NodeJsonAql (TRI_aql_context_t* const context, const TRI_aql_node_t* const node) { switch (node->_type) { case TRI_AQL_NODE_VALUE: { switch (node->_value._type) { case TRI_AQL_TYPE_FAIL: case TRI_AQL_TYPE_NULL: return TRI_CreateNullJson(TRI_UNKNOWN_MEM_ZONE); case TRI_AQL_TYPE_BOOL: return TRI_CreateBooleanJson(TRI_UNKNOWN_MEM_ZONE, node->_value._value._bool); case TRI_AQL_TYPE_INT: return TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, (double) node->_value._value._int); case TRI_AQL_TYPE_DOUBLE: return TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, node->_value._value._double); case TRI_AQL_TYPE_STRING: return TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, node->_value._value._string); } assert(false); return NULL; } case TRI_AQL_NODE_LIST: { const size_t n = node->_members._length; TRI_json_t* result = TRI_CreateList2Json(TRI_UNKNOWN_MEM_ZONE, n); if (result != NULL) { size_t i; for (i = 0; i < n; ++i) { TRI_json_t* subValue = TRI_NodeJsonAql(context, TRI_AQL_NODE_MEMBER(node, i)); if (subValue != NULL) { TRI_PushBack3ListJson(TRI_UNKNOWN_MEM_ZONE, result, subValue); } } } return result; } case TRI_AQL_NODE_ARRAY: { const size_t n = node->_members._length; TRI_json_t* result = TRI_CreateArray2Json(TRI_UNKNOWN_MEM_ZONE, n); if (result != NULL) { size_t i; for (i = 0; i < n; ++i) { TRI_aql_node_t* element = TRI_AQL_NODE_MEMBER(node, i); TRI_json_t* subValue = TRI_NodeJsonAql(context, TRI_AQL_NODE_MEMBER(element, 0)); if (subValue) { TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, result, TRI_AQL_NODE_STRING(element), subValue); } } } return result; } default: { return NULL; } } }