Decoding
=============================

libcbor provides two decoding interfaces:

.. rst-class:: fixed-table

.. list-table::
   :header-rows: 1
   :widths: 20 40 40

   * -
     - Default
     - Streaming
   * - **Function**
     - :func:`cbor_load`
     - :func:`cbor_stream_decode`
   * - **Returns**
     - A fully-built ``cbor_item_t`` tree.
     - Nothing. Fires a callback for each decoded value.
   * - **Callbacks**
     - None. Results available after the call returns.
     - One callback per primitive, string chunk, or
       collection boundary (e.g. ``array_start``,
       ``uint8``, ``string_chunk``).
   * - **Nesting**
     - Handled by the library.
     - Caller's responsibility. Nested structures
       (e.g. arrays containing maps) require the
       caller to maintain an explicit stack to track
       the current depth and accumulate children.
   * - **Memory**
     - Allocates the ``cbor_item_t`` tree.
       Free with :func:`cbor_decref`.
     - No library allocations.
   * - **Best for**
     - - Trusted or size-bounded inputs.
       - General data manipulation and inspection.
       - Simple use cases.
     - - Large or unbounded inputs.
       - Memory-constrained environments.
       - Mapping to custom data structures.
       - Known, restricted schemas.

:func:`cbor_load` is implemented on top of :func:`cbor_stream_decode` — it
installs its own internal callbacks that build the ``cbor_item_t`` tree as
events arrive.

.. graphviz::
   :align: center

   digraph decoding {
       graph [rankdir=TB, nodesep=1.4, ranksep=0.8, fontname="Helvetica"]
       node  [shape=box, style="filled,rounded", fontname="Helvetica", margin="0.3,0.15"]
       edge  [color="#555555", fontname="Helvetica", fontsize=10]

       client    [label="Client application",                   fillcolor="#AED6F1"]
       cbor_load [label="cbor_load",                            fillcolor="#FAD7A0"]
       streaming [label="cbor_stream_decode",                   fillcolor="#FAD7A0"]
       item      [label="cbor_item_t",                          fillcolor="#A9DFBF"]
       manip     [label="Manipulation routines\n(cbor_item_t API)", fillcolor="#D2B4DE"]

       { rank=same; cbor_load; streaming }
       { rank=same; item; manip }

       client -> cbor_load [label=" bytes "]
       client -> streaming [label=" bytes + callbacks "]

       cbor_load -> streaming [label=" internal callbacks ",
                               style=dashed, constraint=false]
       cbor_load -> item

       item:e -> manip:w [style=dashed, dir=both, constraint=false,
                          label=" use items "]
   }

This section covers the **Default driver** — :func:`cbor_load` and related
routines that decode a complete CBOR input into a ``cbor_item_t`` tree in one
call.

.. warning::

   ``cbor_load`` allocates memory sized by lengths declared in the CBOR header
   before reading the corresponding data:

   - **Definite-length arrays and maps** — storage for the declared element count.
   - **Definite-length strings and bytestrings** — a buffer for the declared byte length.

   All of these lengths are encoded as a 64-bit integer, so ``cbor_load`` may
   attempt an allocation of up to 2\ :sup:`64`\−1 bytes before any payload data
   is read. ``malloc`` will normally refuse such a request and ``cbor_load``
   will return ``CBOR_ERR_MEMERROR``, but on platforms with memory overcommit
   (Linux by default) the allocation may silently appear to succeed.

   Mitigations:

   - Install a capping allocator via :func:`cbor_set_allocs` to bound total
     memory consumption (see ``examples/capped_alloc.c`` for a self-contained
     example).
   - Use the streaming decoder (:doc:`streaming_decoding`), which gives the
     application full control over memory allocation for each decoded item.

.. doxygenfunction:: cbor_load

Associated data structures
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. doxygenenum:: cbor_error_code

.. doxygenstruct:: cbor_load_result
    :members:

.. doxygenstruct:: cbor_error
    :members:

