synta 0.2.4

ASN.1 parser, decoder, and encoder library with DER/BER support and C FFI
Documentation
# Encoder


## Lifecycle

### synta_encoder_new

Create a new encoder.

```c
SyntaEncoder *synta_encoder_new(SyntaEncoding encoding);
```

**Returns:** Encoder pointer, or NULL on OOM.

**Example:**
```c
SyntaEncoder *encoder = synta_encoder_new(SyntaEncoding_Der);
if (!encoder) {
    fprintf(stderr, "Failed to create encoder\n");
    return 1;
}
```

### synta_encoder_finish

Finish encoding and get the encoded bytes.

```c
SyntaErrorCode synta_encoder_finish(SyntaEncoder *encoder,
                                     SyntaByteArray *out);
```

**Parameters:**
- `encoder` — Encoder to finish (**consumed** by this call; do not use after)
- `out` — Output byte array

**Memory:** Output byte array must be freed with `synta_byte_array_free()`.
The encoder is consumed and must not be used or freed after this call.

**Example:**
```c
SyntaByteArray output = {0};
if (synta_encoder_finish(encoder, &output) == SyntaErrorCode_Success) {
    /* use output.data and output.len */
    synta_byte_array_free(&output);
}
/* encoder is consumed; do not call synta_encoder_free(encoder) */
```

### synta_encoder_free

Free an encoder without finishing it.  Use this only when discarding an
encoder that was not finished.

```c
void synta_encoder_free(SyntaEncoder *encoder);
```

**Note:** Do not call this after `synta_encoder_finish()`.

## Primitive Type Encoding

### synta_encode_boolean

```c
SyntaErrorCode synta_encode_boolean(SyntaEncoder *encoder, bool value);
```

### synta_encode_integer_i64

Encode an INTEGER from a `int64_t`.

```c
SyntaErrorCode synta_encode_integer_i64(SyntaEncoder *encoder, int64_t value);
```

**Example:**
```c
synta_encode_integer_i64(encoder, 42);
```

### synta_encode_integer

Encode an INTEGER from a `SyntaInteger` object (arbitrary precision).

```c
SyntaErrorCode synta_encode_integer(SyntaEncoder *encoder,
                                     const SyntaInteger *integer);
```

### synta_encode_null

```c
SyntaErrorCode synta_encode_null(SyntaEncoder *encoder);
```

### synta_encode_real

Encode a REAL (IEEE 754 double) value.

```c
SyntaErrorCode synta_encode_real(SyntaEncoder *encoder, double value);
```

### synta_encode_octet_string

```c
SyntaErrorCode synta_encode_octet_string(SyntaEncoder *encoder,
                                          const uint8_t *data,
                                          uintptr_t len);
```

### synta_encode_bit_string

```c
SyntaErrorCode synta_encode_bit_string(SyntaEncoder *encoder,
                                        const uint8_t *data,
                                        uintptr_t len,
                                        uint8_t unused_bits);
```

### synta_encode_object_identifier

```c
SyntaErrorCode synta_encode_object_identifier(SyntaEncoder *encoder,
                                                const SyntaObjectIdentifier *oid);
```

## String Type Encoding

The string encode functions come in two flavours:

- **From null-terminated C string** (`synta_encode_utf8_string`, etc.) —
  accept a `const char *`; validate the character set; write the typed TLV.
- **From raw bytes / `_bytes`** (`synta_encode_utf8_string_bytes`, etc.) —
  accept a `const uint8_t *` + `len`; write the typed TLV **without**
  character-set validation.  Use these when round-tripping content decoded
  with the `_os` variants.

### synta_encode_utf8_string

Encode a UTF8String from a null-terminated C string (enforces valid UTF-8).

```c
SyntaErrorCode synta_encode_utf8_string(SyntaEncoder *encoder,
                                         const char *str);
```

### synta_encode_utf8_string_bytes

Encode a UTF8String (universal tag 12) from raw bytes without UTF-8 validation.

```c
SyntaErrorCode synta_encode_utf8_string_bytes(SyntaEncoder *encoder,
                                               const uint8_t *data,
                                               uintptr_t len);
```

### synta_encode_printable_string

Encode a PrintableString from a null-terminated C string (enforces PrintableString alphabet).

```c
SyntaErrorCode synta_encode_printable_string(SyntaEncoder *encoder,
                                               const char *str);
```

### synta_encode_printable_string_bytes

Encode a PrintableString (universal tag 19) from raw bytes without character-set validation.

```c
SyntaErrorCode synta_encode_printable_string_bytes(SyntaEncoder *encoder,
                                                    const uint8_t *data,
                                                    uintptr_t len);
```

### synta_encode_ia5_string

Encode an IA5String from a null-terminated C string (enforces ASCII range).

```c
SyntaErrorCode synta_encode_ia5_string(SyntaEncoder *encoder,
                                        const char *str);
```

### synta_encode_ia5_string_bytes

Encode an IA5String (universal tag 22) from raw bytes without character-set validation.

```c
SyntaErrorCode synta_encode_ia5_string_bytes(SyntaEncoder *encoder,
                                              const uint8_t *data,
                                              uintptr_t len);
```

### synta_encode_utctime_bytes

Encode a UTCTime (universal tag 23) from raw bytes without time-syntax validation.

```c
SyntaErrorCode synta_encode_utctime_bytes(SyntaEncoder *encoder,
                                           const uint8_t *data,
                                           uintptr_t len);
```

### synta_encode_generalized_time_bytes

Encode a GeneralizedTime (universal tag 24) from raw bytes without time-syntax validation.

```c
SyntaErrorCode synta_encode_generalized_time_bytes(SyntaEncoder *encoder,
                                                    const uint8_t *data,
                                                    uintptr_t len);
```

## Constructed Type Encoding

### synta_encoder_start_sequence

Start encoding a SEQUENCE.

```c
SyntaErrorCode synta_encoder_start_sequence(SyntaEncoder *encoder,
                                              SyntaEncoder **out);
```

**Note:** The returned encoder pointer aliases the input encoder.  Use it to
encode the SEQUENCE contents, then call `synta_encoder_end_constructed` to
finalize.

**Example:**
```c
SyntaEncoder *seq_encoder = NULL;
synta_encoder_start_sequence(encoder, &seq_encoder);
synta_encode_integer_i64(seq_encoder, 42);
synta_encode_boolean(seq_encoder, true);
synta_encoder_end_constructed(seq_encoder);
```

### synta_encoder_start_set

Start encoding a SET.

```c
SyntaErrorCode synta_encoder_start_set(SyntaEncoder *encoder,
                                        SyntaEncoder **out);
```

### synta_encoder_start_constructed

Start encoding a constructed type with an explicit or implicit tag.

```c
SyntaErrorCode synta_encoder_start_constructed(SyntaEncoder *encoder,
                                                 SyntaTag tag,
                                                 SyntaEncoder **out);
```

### synta_encoder_end_constructed

End the current constructed type.

```c
SyntaErrorCode synta_encoder_end_constructed(SyntaEncoder *encoder);
```

**Important:** Must be called for each `start_*` call to properly finalize
length encoding.

## Full Example

```c
#include <synta.h>

int main(void) {
    SyntaEncoder *enc = synta_encoder_new(SyntaEncoding_Der);

    /* Build SEQUENCE { INTEGER 42, BOOLEAN TRUE } */
    SyntaEncoder *seq = NULL;
    synta_encoder_start_sequence(enc, &seq);
    synta_encode_integer_i64(seq, 42);
    synta_encode_boolean(seq, true);
    synta_encoder_end_constructed(seq);

    SyntaByteArray output = {0};
    synta_encoder_finish(enc, &output);
    /* enc consumed; do not free it */

    /* use output.data / output.len */

    synta_byte_array_free(&output);
    return 0;
}
```