static CborError advance_recursive(CborValue *it, int nestingLevel) { if (is_fixed_type(it->type)) return advance_internal(it); if (!cbor_value_is_container(it)) { size_t len = SIZE_MAX; return _cbor_value_copy_string(it, NULL, &len, it); } // map or array if (nestingLevel == CBOR_PARSER_MAX_RECURSIONS) return CborErrorNestingTooDeep; CborError err; CborValue recursed; err = cbor_value_enter_container(it, &recursed); if (err) return err; while (!cbor_value_at_end(&recursed)) { err = advance_recursive(&recursed, nestingLevel + 1); if (err) return err; } return cbor_value_leave_container(it, &recursed); }
SOL_API bool sol_oic_map_loop_next(struct sol_oic_repr_field *repr, struct sol_oic_map_reader *iterator, enum sol_oic_map_loop_reason *reason) { CborError err; SOL_NULL_CHECK_GOTO(repr, err); SOL_NULL_CHECK_GOTO(iterator, err); sol_oic_repr_field_clear(repr); if (cbor_value_at_end((CborValue *)iterator)) return false; if (!cbor_value_is_valid((CborValue *)iterator)) goto err; err = sol_oic_cbor_repr_map_get_next_field((CborValue *)iterator, repr); if (err != CborNoError) goto err; return true; err: if (reason) *reason = SOL_OIC_MAP_LOOP_ERROR; return false; }
/** * Attempts to find the value in map \a map that corresponds to the text string * entry \a string. If the item is found, it is stored in \a result. If no item * is found matching the key, then \a result will contain an element of type * \ref CborInvalidType. * * \note This function may be expensive to execute. */ CborError cbor_value_map_find_value(const CborValue *map, const char *string, CborValue *element) { assert(cbor_value_is_map(map)); size_t len = strlen(string); CborError err = cbor_value_enter_container(map, element); if (err) goto error; while (!cbor_value_at_end(element)) { // find the non-tag so we can compare err = cbor_value_skip_tag(element); if (err) goto error; if (cbor_value_is_text_string(element)) { bool equals; size_t dummyLen = len; err = iterate_string_chunks(element, CONST_CAST(char *, string), &dummyLen, &equals, element, iterate_memcmp); if (err) goto error; if (equals) return preparse_value(element); } else { // skip this key err = cbor_value_advance(element); if (err) goto error; } // skip this value err = cbor_value_skip_tag(element); if (err) goto error; err = cbor_value_advance(element); if (err) goto error; }
int cbor_read_array(struct CborValue *value, const struct cbor_array_t *arr) { CborError err = 0; struct CborValue elem; int off, arrcount; size_t len; void *lptr; char *tp; err = cbor_value_enter_container(value, &elem); if (err) { return err; } arrcount = 0; tp = arr->arr.strings.store; for (off = 0; off < arr->maxlen; off++) { switch (arr->element_type) { case CborAttrBooleanType: lptr = &arr->arr.booleans.store[off]; err |= cbor_value_get_boolean(&elem, lptr); break; case CborAttrIntegerType: lptr = &arr->arr.integers.store[off]; err |= cbor_value_get_int64(&elem, lptr); break; case CborAttrUnsignedIntegerType: lptr = &arr->arr.uintegers.store[off]; err |= cbor_value_get_uint64(&elem, lptr); break; #if FLOAT_SUPPORT case CborAttrFloatType: case CborAttrDoubleType: lptr = &arr->arr.reals.store[off]; err |= cbor_value_get_double(&elem, lptr); break; #endif case CborAttrTextStringType: len = arr->arr.strings.storelen - (tp - arr->arr.strings.store); err |= cbor_value_copy_text_string(&elem, tp, &len, NULL); arr->arr.strings.ptrs[off] = tp; tp += len + 1; break; case CborAttrStructObjectType: err |= cbor_internal_read_object(&elem, arr->arr.objects.subtype, arr, off); break; default: err |= CborErrorIllegalType; break; } arrcount++; if (arr->element_type != CborAttrStructObjectType) { err |= cbor_value_advance(&elem); } if (!cbor_value_is_valid(&elem)) { break; } } if (arr->count) { *arr->count = arrcount; } while (!cbor_value_at_end(&elem)) { err |= CborErrorDataTooLarge; cbor_value_advance(&elem); } err |= cbor_value_leave_container(value, &elem); return err; }
/* Parse single property */ static void oc_parse_rep_value(CborValue *value, oc_rep_t **rep, CborError *err) { size_t k, len; CborValue map, array; *rep = _alloc_rep(); oc_rep_t *cur = *rep, **prev = 0; cur->next = 0; cur->value_object_array = 0; /* key */ *err |= cbor_value_calculate_string_length(value, &len); len++; oc_alloc_string(&cur->name, len); *err |= cbor_value_copy_text_string(value, (char *)oc_string(cur->name), &len, NULL); *err |= cbor_value_advance(value); /* value */ switch (value->type) { case CborIntegerType: *err |= cbor_value_get_int64(value, &cur->value_int); cur->type = INT; break; case CborBooleanType: *err |= cbor_value_get_boolean(value, &cur->value_boolean); cur->type = BOOL; break; case CborDoubleType: *err |= cbor_value_get_double(value, &cur->value_double); cur->type = DOUBLE; break; case CborByteStringType: *err |= cbor_value_calculate_string_length(value, &len); len++; oc_alloc_string(&cur->value_string, len); *err |= cbor_value_copy_byte_string( value, oc_cast(cur->value_string, uint8_t), &len, NULL); cur->type = BYTE_STRING; break; case CborTextStringType: *err |= cbor_value_calculate_string_length(value, &len); len++; oc_alloc_string(&cur->value_string, len); *err |= cbor_value_copy_text_string(value, oc_string(cur->value_string), &len, NULL); cur->type = STRING; break; case CborMapType: /* when value is a map/object */ { oc_rep_t **obj = &cur->value_object; // object points to list of properties *err |= cbor_value_enter_container(value, &map); while (!cbor_value_at_end(&map)) { oc_parse_rep_value(&map, obj, err); (*obj)->next = 0; obj = &(*obj)->next; *err |= cbor_value_advance(&map); } cur->type = OBJECT; } break; case CborArrayType: *err |= cbor_value_enter_container(value, &array); len = 0; cbor_value_get_array_length(value, &len); if (len == 0) { CborValue t = array; while (!cbor_value_at_end(&t)) { len++; cbor_value_advance(&t); } } k = 0; while (!cbor_value_at_end(&array)) { switch (array.type) { case CborIntegerType: if (k == 0) { oc_new_int_array(&cur->value_array, len); cur->type = INT | ARRAY; } *err |= cbor_value_get_int64(&array, oc_int_array(cur->value_array) + k); break; case CborDoubleType: if (k == 0) { oc_new_double_array(&cur->value_array, len); cur->type = DOUBLE | ARRAY; } *err |= cbor_value_get_double(&array, oc_double_array(cur->value_array) + k); break; case CborBooleanType: if (k == 0) { oc_new_bool_array(&cur->value_array, len); cur->type = BOOL | ARRAY; } *err |= cbor_value_get_boolean(&array, oc_bool_array(cur->value_array) + k); break; case CborByteStringType: if (k == 0) { oc_new_string_array(&cur->value_array, len); cur->type = BYTE_STRING | ARRAY; } *err |= cbor_value_calculate_string_length(&array, &len); len++; *err |= cbor_value_copy_byte_string( &array, (uint8_t *)oc_string_array_get_item(cur->value_array, k), &len, NULL); break; case CborTextStringType: if (k == 0) { oc_new_string_array(&cur->value_array, len); cur->type = STRING | ARRAY; } *err |= cbor_value_calculate_string_length(&array, &len); len++; *err |= cbor_value_copy_text_string( &array, (char *)oc_string_array_get_item(cur->value_array, k), &len, NULL); break; case CborMapType: if (k == 0) { cur->type = OBJECT | ARRAY; cur->value_object_array = _alloc_rep(); prev = &cur->value_object_array; } else { (*prev)->next = _alloc_rep(); prev = &(*prev)->next; } (*prev)->type = OBJECT; (*prev)->next = 0; oc_rep_t **obj = &(*prev)->value_object; /* Process a series of properties that make up an object of the array */ *err |= cbor_value_enter_container(&array, &map); while (!cbor_value_at_end(&map)) { oc_parse_rep_value(&map, obj, err); obj = &(*obj)->next; *err |= cbor_value_advance(&map); } break; default: break; } k++; *err |= cbor_value_advance(&array); } break; default: break; } }