bool mapping_contains(const node *mapping, uint8_t *scalar, size_t length) { PRECOND_NONNULL_ELSE_FALSE(mapping, scalar); PRECOND_ELSE_FALSE(MAPPING == node_kind(mapping), 0 < length); node *key = make_scalar_node(scalar, length, SCALAR_STRING); bool result = hashtable_contains(mapping->content.mapping, key); node_free(key); return result; }
bool path_iterate(const jsonpath *path, path_iterator iterator, void *context) { PRECOND_NONNULL_ELSE_FALSE(path, iterator); for(size_t i = 0; i < path_length(path); i++) { if(!iterator(path->steps[i], context)) { return false; } } return true; }
bool sequence_iterate(const node *sequence, sequence_iterator iterator, void *context) { PRECOND_NONNULL_ELSE_FALSE(sequence, iterator); PRECOND_ELSE_FALSE(SEQUENCE == node_kind(sequence)); context_adapter adapter = {.iterator.sequence=iterator, .context=context }; return vector_iterate(sequence->content.sequence, sequence_iterator_adpater, &adapter); } node *mapping_get(const node *mapping, uint8_t *scalar, size_t length) { PRECOND_NONNULL_ELSE_NULL(mapping, scalar); PRECOND_ELSE_NULL(MAPPING == node_kind(mapping)); PRECOND_ELSE_NULL(0 < length); node *key = make_scalar_node(scalar, length, SCALAR_STRING); node *result = hashtable_get(mapping->content.mapping, key); node_free(key); return result; }
static bool slice_predicate_has(const predicate *value, enum slice_specifiers specifier) { PRECOND_NONNULL_ELSE_FALSE(value); PRECOND_ELSE_FALSE(SLICE == value->kind); return value->slice.specified & specifier; }
bool step_has_predicate(const step *value) { PRECOND_NONNULL_ELSE_FALSE(value); return NULL != value->predicate; }
bool mapping_iterate(const node *mapping, mapping_iterator iterator, void *context) { PRECOND_NONNULL_ELSE_FALSE(mapping, iterator); PRECOND_ELSE_FALSE(MAPPING == node_kind(mapping)); context_adapter adapter = {.iterator.mapping=iterator, .context=context}; return hashtable_iterate(mapping->content.mapping, mapping_iterator_adpater, &adapter); } bool node_equals(const node *one, const node *two) { if(one == two) { return true; } if((NULL == one && NULL != two) || (NULL != one && NULL == two)) { return false; } bool result = node_kind(one) == node_kind(two) && tag_equals(node_name(one), node_name(two)) && node_size(one) == node_size(two); if(!result) { return result; } switch(node_kind(one)) { case DOCUMENT: result &= node_equals(document_root(one), document_root(two)); break; case SCALAR: result &= scalar_equals(one, two); break; case SEQUENCE: result &= sequence_equals(one, two); break; case MAPPING: result &= mapping_equals(one, two); break; case ALIAS: result &= node_equals(alias_target(one), alias_target(two)); break; } return result; } static bool scalar_equals(const node *one, const node *two) { size_t n1 = node_size(one); size_t n2 = node_size(two); if(n1 != n2) { return false; } return memcmp(scalar_value(one), scalar_value(two), n1) == 0; }
bool nodelist_iterate(const nodelist *list, nodelist_iterator iterator, void *context) { PRECOND_NONNULL_ELSE_FALSE(list, iterator); return vector_iterate(list, nodelist_iterator_adpater, &(context_adapter){.iterator.foreach=iterator, context});