# `./fio-stl/004 resp3.h`

24 public symbols.

### Macros

#### `FIO_RESP3_MAX_NESTING`

```c
#define FIO_RESP3_MAX_NESTING 32
```



_Symbol type:_ `macro`

#### `FIO_RESP3_STREAM_THRESHOLD`

```c
#define FIO_RESP3_STREAM_THRESHOLD 4096
```



_Symbol type:_ `macro`

#### `FIO_RESP3_SIMPLE_STR`

```c
#define FIO_RESP3_SIMPLE_STR '+'
```

Simple String: `+<string>\r\n`

_Symbol type:_ `macro`

#### `FIO_RESP3_SIMPLE_ERR`

```c
#define FIO_RESP3_SIMPLE_ERR '-'
```

Simple Error: `-<string>\r\n`

_Symbol type:_ `macro`

#### `FIO_RESP3_NUMBER`

```c
#define FIO_RESP3_NUMBER ':'
```

Number: `:<number>\r\n`

_Symbol type:_ `macro`

#### `FIO_RESP3_NULL`

```c
#define FIO_RESP3_NULL '_'
```

Null: `_\r\n`

_Symbol type:_ `macro`

#### `FIO_RESP3_DOUBLE`

```c
#define FIO_RESP3_DOUBLE ','
```

Double: `,<floating-point-number>\r\n`

_Symbol type:_ `macro`

#### `FIO_RESP3_BOOL`

```c
#define FIO_RESP3_BOOL '#'
```

Boolean: `#t\r\n` or `#f\r\n`

_Symbol type:_ `macro`

#### `FIO_RESP3_BIGNUM`

```c
#define FIO_RESP3_BIGNUM '('
```

Big Number: `(<big number>\r\n`

_Symbol type:_ `macro`

#### `FIO_RESP3_BLOB_STR`

```c
#define FIO_RESP3_BLOB_STR '$'
```

Blob String: `$<length>\r\n<bytes>\r\n`

_Symbol type:_ `macro`

#### `FIO_RESP3_BLOB_ERR`

```c
#define FIO_RESP3_BLOB_ERR '!'
```

Blob Error: `!<length>\r\n<bytes>\r\n`

_Symbol type:_ `macro`

#### `FIO_RESP3_VERBATIM`

```c
#define FIO_RESP3_VERBATIM '='
```

Verbatim String: `=<length>\r\n<type:><bytes>\r\n`

_Symbol type:_ `macro`

#### `FIO_RESP3_ARRAY`

```c
#define FIO_RESP3_ARRAY '*'
```

Array: `*<count>\r\n...elements...`

_Symbol type:_ `macro`

#### `FIO_RESP3_MAP`

```c
#define FIO_RESP3_MAP '%'
```

Map: `%<count>\r\n...key-value pairs...`

_Symbol type:_ `macro`

#### `FIO_RESP3_SET`

```c
#define FIO_RESP3_SET '~'
```

Set: `~<count>\r\n...elements...`

_Symbol type:_ `macro`

#### `FIO_RESP3_PUSH`

```c
#define FIO_RESP3_PUSH '>'
```

Push: `><count>\r\n...elements...`

_Symbol type:_ `macro`

#### `FIO_RESP3_ATTR`

```c
#define FIO_RESP3_ATTR '|'
```

Attribute: `|<count>\r\n...key-value pairs...`

_Symbol type:_ `macro`

#### `FIO_RESP3_STREAM_CHUNK`

```c
#define FIO_RESP3_STREAM_CHUNK ';'
```

Streamed string chunk: `;`

_Symbol type:_ `macro`

#### `FIO_RESP3_STREAM_END`

```c
#define FIO_RESP3_STREAM_END '.'
```

Streamed aggregate end: `.`

_Symbol type:_ `macro`

### Types

#### `fio_resp3_frame_s`

```c
typedef struct {
/** Context for this container (returned by on_array/on_map/etc) */
void *ctx;
/** For maps: the pending key waiting for its value */
void *key;
/** Expected remaining elements */
int64_t remaining;
/** Type of this frame */
uint8_t type;
/** Is this a streaming type? */
uint8_t streaming;
/** For maps: are we expecting a key (0) or value (1)? */
uint8_t expecting_value;
/** Set treated as map: need to duplicate values as key+value */
uint8_t set_as_map;
} fio_resp3_frame_s
```

Parser frame for tracking nested structures

_Symbol type:_ `type`

#### `fio_resp3_parser_s`

```c
typedef struct {
/** User data passed to all callbacks */
void *udata;
/** Current nesting depth */
uint32_t depth;
/** Protocol error flag */
uint8_t error;
/** Streaming string in progress flag */
uint8_t streaming_string;
/** Streaming string type (FIO_RESP3_BLOB_STR, FIO_RESP3_BLOB_ERR, etc.) */
uint8_t streaming_string_type;
/** Streamed fixed-length blob: trailing CRLF bytes pending (0...2) */
uint8_t streaming_blob_crlf;
/** Context for streaming string (from on_start_string) */
void *streaming_string_ctx;
/**
* Streamed fixed-length blob: data bytes remaining to stream.
* Zero when inactive or in `$?` (chunked) streaming mode.
*/
int64_t streaming_remaining;
/** Stack for nested structures */
fio_resp3_frame_s stack[FIO_RESP3_MAX_NESTING];
} fio_resp3_parser_s
```

RESP3 parser state

_Symbol type:_ `type`

#### `fio_resp3_callbacks_s`

```c
typedef struct {
/* ===== Primitive Callbacks - return the created object ===== */
/** Called when NULL (`_`) is received. Returns new object. */
void *(*on_null)(void *udata);
/** Called when Boolean (`#t` or `#f`) is received. Returns new object. */
void *(*on_bool)(void *udata, int is_true);
/** Called when a Number (`:`) is parsed. Returns new object. */
void *(*on_number)(void *udata, int64_t num);
/** Called when a Double (`,`) is parsed. Returns new object. */
void *(*on_double)(void *udata, double num);
/** Called when a Big Number (`(`) is parsed. Returns new object. */
void *(*on_bignum)(void *udata, const void *data, size_t len);
/**
* Called when a complete String is received.
* `type` is FIO_RESP3_SIMPLE_STR, FIO_RESP3_BLOB_STR, or FIO_RESP3_VERBATIM.
* Returns new object.
*/
void *(*on_string)(void *udata, const void *data, size_t len, uint8_t type);
/**
* Called when an error message is received (simple `-` or blob `!`).
* `type` is FIO_RESP3_SIMPLE_ERR or FIO_RESP3_BLOB_ERR.
* Returns new object.
*/
void *(*on_error)(void *udata, const void *data, size_t len, uint8_t type);
/* ===== Container Callbacks - receive parent ctx, return new ctx ===== */
/** Called when an Array starts. Returns new array context. */
void *(*on_array)(void *udata, void *parent_ctx, int64_t len);
/** Called when a Map starts. Returns new map context. */
void *(*on_map)(void *udata, void *parent_ctx, int64_t len);
/** Called when a Set starts. Returns new set context. */
void *(*on_set)(void *udata, void *parent_ctx, int64_t len);
/** Called when a Push message starts. Returns new push context. */
void *(*on_push)(void *udata, void *parent_ctx, int64_t len);
/** Called when an Attribute starts. Returns new attribute context. */
void *(*on_attr)(void *udata, void *parent_ctx, int64_t len);
/* ===== Push Callbacks - add child to container ===== */
/** Add value to array. Returns non-zero on error. */
int (*array_push)(void *udata, void *ctx, void *value);
/** Add key-value pair to map. Returns non-zero on error. */
int (*map_push)(void *udata, void *ctx, void *key, void *value);
/** Add value to set. Returns non-zero on error. */
int (*set_push)(void *udata, void *ctx, void *value);
/** Add value to push message. Returns non-zero on error. */
int (*push_push)(void *udata, void *ctx, void *value);
/** Add key-value pair to attribute. Returns non-zero on error. */
int (*attr_push)(void *udata, void *ctx, void *key, void *value);
/* ===== Done Callbacks (optional) - finalize container ===== */
/** Called when array is complete. Returns final object. */
void *(*array_done)(void *udata, void *ctx);
/** Called when map is complete. Returns final object. */
void *(*map_done)(void *udata, void *ctx);
/** Called when set is complete. Returns final object. */
void *(*set_done)(void *udata, void *ctx);
/** Called when push is complete. Returns final object. */
void *(*push_done)(void *udata, void *ctx);
/** Called when attribute is complete. Returns final object. */
void *(*attr_done)(void *udata, void *ctx);
/* ===== Error Handling ===== */
/** Free an unused object (e.g., orphaned key on error). */
void (*free_unused)(void *udata, void *obj);
/** Called on protocol error. */
void *(*on_error_protocol)(void *udata);
/* ===== Streaming String Callbacks (optional) ===== */
/**
* Called when a blob string starts (before data arrives).
* `len` is the declared length of the string ((size_t)-1 for streaming).
* `type` is FIO_RESP3_BLOB_STR, FIO_RESP3_BLOB_ERR, or FIO_RESP3_VERBATIM.
* Returns a context for the string being built (e.g., a string buffer).
* If NULL is returned, falls back to buffering and calling on_string when
* complete.
*/
void *(*on_start_string)(void *udata, size_t len, uint8_t type);
/**
* Called with partial string data (may be called multiple times).
* `ctx` is the context returned by on_start_string.
* Returns 0 on success, non-zero to abort parsing.
*/
int (*on_string_write)(void *udata, void *ctx, const void *data, size_t len);
/**
* Called when the string is complete.
* `ctx` is the context returned by on_start_string.
* Returns the final string object to be used as a value.
*/
void *(*on_string_done)(void *udata, void *ctx, uint8_t type);
} fio_resp3_callbacks_s
```

The RESP3 parser callbacks (designed to be static const).

All callbacks receive `udata` from the parser state as their first argument.

_Symbol type:_ `type`

#### `fio_resp3_result_s`

```c
typedef struct {
/** The parsed top-level object (or NULL on error/incomplete) */
void *obj;
/** Number of bytes consumed from the buffer */
size_t consumed;
/** Non-zero if an error occurred */
int err;
} fio_resp3_result_s
```

The RESP3 parse result type.

_Symbol type:_ `type`

### Functions

#### `fio_resp3_parse`

```c
fio_resp3_result_s fio_resp3_parse(fio_resp3_parser_s *parser, const fio_resp3_callbacks_s *callbacks, const void *buf, size_t len)
```

Parse RESP3 data from buffer.

`parser` is the parser state. Initialize with `{.udata = my_data}` for first
         call. For continuation after partial parse, pass the same parser.
`callbacks` contains the callback functions (should be static const).
`buf` is the data to parse.
`len` is the length of the data.

Returns a result struct containing:
- `obj`: The parsed top-level object (NULL if incomplete or error)
- `consumed`: Number of bytes consumed from the buffer
- `err`: Non-zero if a protocol error occurred

For partial data, the parser state is preserved. Call again with remaining
data appended to unconsumed data.

_Symbol type:_ `function`

-----------------------------------------------------
