<!--
  Copyright (c) 2009-2026 ASN Lab
  All rights reserved.
-->

# ASN.1 C Compiler Guide

The ASN.1 C Compiler (`asncc`) generates C source code from ASN.1 modules.
Generated types are plain C structs and work with the C runtime library for
encoding and decoding.

## Compiler Options

| Field                               | Type    | Default      | Description |
|-------------------------------------|---------|--------------|-------------|
| `output-folder`                     | string  | `"c"`        | Output directory for generated C sources. |
| `mapping.integer`                   | ENUM    | `automatic`  | See [Integer Mapping](#integer-mapping). |
| `mapping.real`                      | ENUM    | `automatic`  | `automatic`, `float`, `double`. |
| `mapping.size-of-int`               | INTEGER | 4            | Size in bytes of `int` on the target platform. |
| `mapping.size-of-long`              | INTEGER | 8            | Size in bytes of `long` on the target platform. |
| `mapping.size-of-xlong`             | INTEGER | 8            | Size in bytes of `long long` on the target platform. |
| `using-module-name-as-type-prefix`  | BOOLEAN | FALSE        | Prefix generated type names with the module name. |
| `dont-generate-names`               | BOOLEAN | FALSE        | Suppress generation of named constant definitions. |
| `custom-type-prefix`                | string  | --           | Optional prefix for generated type names. |
| `generate.constraints`              | BOOLEAN | FALSE        | Generate constraint validation functions. |
| `generate.sample-test`              | BOOLEAN | FALSE        | Generate a sample test harness. |
| `generate.frees`                    | BOOLEAN | FALSE        | Generate `free()` functions for dynamic types. |
| `generate.equals`                   | BOOLEAN | FALSE        | Generate value equality comparison functions. |
| `generate.prints`                   | BOOLEAN | FALSE        | Generate `print()` functions. |

## Integer Mapping

Controls how ASN.1 INTEGER is mapped to C integer types. The `size-of-*`
options determine the bit-width of each C integer type on the target platform:

| Option             | C type |
|--------------------|--------|
| `automatic`        | Smallest of `int`/`long`/`long long` that fits the constraint range, or a big-int struct when unconstrained. |
| `automatic-int64`  | `int64_t` (via `stdint.h`). |
| `automatic-bigint` | Big-int struct for all INTEGER values. |
| `int32`            | `int32_t`. |
| `int64`            | `int64_t`. |
| `big-integer`      | Big-int struct. |

## Real Mapping

| Option      | C type |
|-------------|--------|
| `automatic` | `double`. |
| `float`     | `float`. |
| `double`    | `double`. |

## Platform Integer Sizes

The `mapping.size-of-int`, `mapping.size-of-long`, and `mapping.size-of-xlong`
options tell the compiler the byte sizes of C integer types on the target
platform. The compiler uses these to select the smallest type that fits the
ASN.1 constraint range.

Common platform defaults:

| Platform | `int` | `long` | `long long` |
|----------|-------|--------|-------------|
| 32-bit   | 4     | 4      | 8           |
| 64-bit (LP64) | 4 | 8    | 8           |
| 64-bit (LLP64) | 4 | 4   | 8           |

## Project Configuration Example

```asn1
compilers {
    {
        id "asncc",
        language "c",
        options {
            output-folder "c",
            mapping {
                integer automatic,
                real automatic,
                size-of-int 4,
                size-of-long 8,
                size-of-xlong 8
            },
            using-module-name-as-type-prefix FALSE,
            generate {
                constraints FALSE,
                sample-test FALSE,
                frees FALSE,
                equals FALSE,
                prints FALSE
            }
        }
    }
}
```

## Runtime Library Usage

After the compiler generates C source files for your ASN.1 modules, include
the generated headers and link against the C runtime library. Include
`asnrt.h` to access the runtime API.

### Encoding

Create a buffer, populate your PDU struct, and call `encode_object` with the
generated type descriptor:

```c
#include "asnrt.h"
#include "MyModule.h"

MyPdu_t pdu = {0};
pdu.field1 = 42;
// ... populate other fields ...

AsnBuffer* buf = alloc_buffer(1024, TRUE, ALIGNED_PACKED_ENCODING_RULES);
int rc = encode_object(buf, &pdu, &MYPDU_TYPE);
if (rc != 0) {
    // handle error
}
// encoded bytes are in buf->array, length is buf->position
free_buffer(buf);
```

### Decoding

Wrap received bytes in a buffer and call `decode_object`:

```c
AsnBuffer* buf = wrap_buffer(receivedBytes, receivedLength, ALIGNED_PACKED_ENCODING_RULES);
MyPdu_t pdu = {0};
int rc = decode_object(buf, &pdu, &MYPDU_TYPE);
if (rc != 0) {
    // handle error
}
// use pdu.field1, etc.
free_buffer(buf);
```

### Encoding Rules

Set the encoding rules when creating the buffer:

| Constant | Encoding |
|---|---|
| `BASIC_ENCODING_RULES` | BER |
| `CANONICAL_ENCODING_RULES` | CER |
| `DISTINGUISHED_ENCODING_RULES` | DER |
| `UNALIGNED_PACKED_ENCODING_RULES` | UPER |
| `ALIGNED_PACKED_ENCODING_RULES` | APER |
| `OCTET_ENCODING_RULES` | OER |
| `JSON_ENCODING_RULES` | JER |
| `ASN_VALUE_NOTATION` | AVN |

### Error Handling

`encode_object` and `decode_object` return 0 on success, or an error code:

```c
int rc = decode_object(buf, &pdu, &MYPDU_TYPE);
switch (rc) {
    case 0:                 break;  // success
    case INVALID_TAG:       /* ... */
    case BUFFER_UNDERFLOW:  /* ... */
    case MISSING_COMPONENT: /* ... */
    default:                /* ... */
}
```

Common error codes: `INVALID_TAG`, `INVALID_LENGTH`, `INVALID_INTEGER`,
`INVALID_ENUM`, `OUT_OF_MEMORY`, `BUFFER_OVERFLOW`, `BUFFER_UNDERFLOW`,
`MISSING_COMPONENT`, `NO_MATCH_INFO_OBJ`.

### Memory Management

Free dynamically allocated contents of a decoded struct:

```c
free_object(&pdu, &MYPDU_TYPE);
```

To integrate with custom allocators, override `asn_alloc` and `asn_free`:

```c
void* asn_alloc(size_t nitems, size_t size);
void  asn_free(void* block);
```

### Utility Functions

```c
void print_object(void* object, const AsnType* type, AsnPrinter* printer);
```

## Generated Output

With `output "build"` and `c.output-folder "c"`, output is written under
`build/c/`. Each ASN.1 module produces a header file (`ModuleName.h`) and an
implementation file (`ModuleName.c`).
