FIDO-Raw

 view release on metacpan or  search on metacpan

deps/libcbor/src/cbor/internal/builder_callbacks.c  view on Meta::CPAN

/*
 * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
 *
 * libcbor is free software; you can redistribute it and/or modify
 * it under the terms of the MIT license. See LICENSE for details.
 */

#include "builder_callbacks.h"
#include <string.h>
#include "../arrays.h"
#include "../bytestrings.h"
#include "../floats_ctrls.h"
#include "../ints.h"
#include "../maps.h"
#include "../strings.h"
#include "../tags.h"
#include "unicode.h"

void _cbor_builder_append(cbor_item_t *item,
                          struct _cbor_decoder_context *ctx) {
  if (ctx->stack->size == 0) {
    /* Top level item */
    ctx->root = item;
  } else {
    /* Part of a bigger structure */
    switch (ctx->stack->top->item->type) {
      case CBOR_TYPE_ARRAY: {
        if (cbor_array_is_definite(ctx->stack->top->item)) {
          /*
           * We don't need an explicit check for whether the item still belongs
           * into this array because if there are extra items, they will cause a
           * syntax error when decoded.
           */
          assert(ctx->stack->top->subitems > 0);
          cbor_array_push(ctx->stack->top->item, item);
          ctx->stack->top->subitems--;
          if (ctx->stack->top->subitems == 0) {
            cbor_item_t *item = ctx->stack->top->item;
            _cbor_stack_pop(ctx->stack);
            _cbor_builder_append(item, ctx);
          }
          cbor_decref(&item);
        } else {
          /* Indefinite array, don't bother with subitems */
          cbor_array_push(ctx->stack->top->item, item);
          cbor_decref(&item);
        }
        break;
      }
      case CBOR_TYPE_MAP: {
        /* We use 0 and 1 subitems to distinguish between keys and values in
         * indefinite items */
        if (ctx->stack->top->subitems % 2) {
          /* Odd record, this is a value */
          _cbor_map_add_value(ctx->stack->top->item, cbor_move(item));
        } else {
          /* Even record, this is a key */
          _cbor_map_add_key(ctx->stack->top->item, cbor_move(item));
        }
        if (cbor_map_is_definite(ctx->stack->top->item)) {
          ctx->stack->top->subitems--;
          if (ctx->stack->top->subitems == 0) {
            cbor_item_t *item = ctx->stack->top->item;
            _cbor_stack_pop(ctx->stack);
            _cbor_builder_append(item, ctx);
          }
        } else {
          ctx->stack->top->subitems ^=
              1; /* Flip the indicator for indefinite items */
        }
        break;
      }
      case CBOR_TYPE_TAG: {
        assert(ctx->stack->top->subitems == 1);
        cbor_tag_set_item(ctx->stack->top->item, item);
        cbor_decref(&item); /* Give up on our reference */
        cbor_item_t *item = ctx->stack->top->item;
        _cbor_stack_pop(ctx->stack);
        _cbor_builder_append(item, ctx);
        break;
      }
      default: {
        cbor_decref(&item);
        ctx->syntax_error = true;
      }
    }
  }
}

#define CHECK_RES(ctx, res)        \
  do {                             \
    if (res == NULL) {             \



( run in 0.616 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )