# 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;
}
```