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

# ASN.1 C++ Compiler Guide

The ASN.1 C++ Compiler (`asncpp`) generates C++ source code from ASN.1
modules. Generated types are C++ classes/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.choice`                    | ENUM    | `union`          | `union` (C++ union), `variant` (std::variant, requires C++17). |
| `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-namespace`    | BOOLEAN | TRUE             | Wrap generated types in a namespace named after the module. |
| `namespace`                         | string  | `""`             | Additional namespace prefix. |
| `cpp-standard`                      | ENUM    | `cpp03`          | `cpp03` or `cpp17`. Affects `variant` choice mapping and C++17 features. |
| `nullable-member`                   | ENUM    | `shared-pointer` | See [Nullable Member Mapping](#nullable-member-mapping). |
| `precompiled-header`                | string  | `""`             | Path to a precompiled header to include. |
| `generate.copy-constructor`         | BOOLEAN | FALSE           | Generate copy constructors. |
| `generate.clone`                    | BOOLEAN | FALSE           | Generate `clone()` methods. |
| `generate.frees`                    | BOOLEAN | TRUE            | Generate destructors / free functions. |
| `generate.equals`                   | BOOLEAN | FALSE           | Generate `operator==`. |
| `generate.prints`                   | BOOLEAN | FALSE           | Generate `operator<<` stream output. |

## Integer Mapping

Controls how ASN.1 INTEGER is mapped to C++ integer types:

| Option        | C++ type |
|---------------|----------|
| `automatic`   | Smallest of `int`/`long`/`long long` that fits the constraint range, or a big-int class when unconstrained. |
| `int32`       | `int32_t`. |
| `int64`       | `int64_t`. |
| `big-integer` | Big-int class. |

## Real Mapping

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

## Choice Mapping

| Option    | Description |
|-----------|-------------|
| `union`   | A C++ `union` of the alternative types. Available in all C++ standards. |
| `variant` | `std::variant<T...>`. Requires C++17 (`cpp-standard cpp17`). |

## Nullable Member Mapping

Controls how OPTIONAL fields are represented in generated C++ types:

| Option            | C++ type for OPTIONAL fields |
|-------------------|------------------------------|
| `raw-pointer`     | Raw pointer (`T*`). Caller manages lifetime. |
| `unique-pointer`  | `std::unique_ptr<T>`. |
| `shared-pointer`  | `std::shared_ptr<T>`. |

## Project Configuration Example

```asn1
compilers {
    {
        id "asncpp",
        language "c++",
        options {
            output-folder "c++",
            mapping {
                integer automatic,
                real automatic,
                choice union
            },
            using-module-name-as-namespace TRUE,
            cpp-standard cpp17,
            nullable-member shared-pointer,
            generate {
                copy-constructor FALSE,
                clone FALSE,
                frees TRUE,
                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
`AsnRuntime.h` for the runtime API. All types are in the `asnrt` namespace.

### Encoding

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

```cpp
#include "AsnRuntime.h"
#include "MyModule.h"

using namespace asnrt;

MyPdu pdu;
pdu.field1 = 42;
// ... populate other fields ...

AsnBuffer* buf = alloc_buffer(1024, true, ALIGNED_PACKED_ENCODING_RULES);
try {
    encode_object(buf, &pdu, MyPdu::TYPE, MyPdu::CONVERTER);
} catch (const AsnException& e) {
    // handle error: e.getErrorCode(), e.getMessage()
}
free_buffer(buf);
```

### Decoding

Wrap received bytes and call `decode_object`:

```cpp
AsnBuffer* buf = wrap_buffer(receivedBytes, receivedLength, ALIGNED_PACKED_ENCODING_RULES);
MyPdu pdu;
try {
    decode_object(buf, &pdu, MyPdu::TYPE, MyPdu::CONVERTER);
} catch (const AsnException& e) {
    // handle error
}
free_buffer(buf);
// use pdu.field1, etc.
```

Generated types declare static `TYPE` and `CONVERTER` members. Pass these to
every encode/decode call.

### 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

Errors throw `AsnException`:

```cpp
try {
    decode_object(buf, &pdu, MyPdu::TYPE, MyPdu::CONVERTER);
} catch (const AsnException& e) {
    int code = e.getErrorCode();
    const std::string& msg = e.getMessage();
}
```

Common error codes: `INVALID_TAG`, `BUFFER_UNDERFLOW`, `MISSING_COMPONENT`,
`NO_MATCH_INFO_OBJ`, `OUT_OF_MEMORY`, `INVALID_VALUE`.

### Utility Functions

```cpp
void print_object(const void* object, AsnType* type, AsnConverter* converter, std::ostream* out);
bool equals_to(const void* o1, const void* o2, AsnType* type, AsnConverter* converter);
void clone_object(const void* o1, const void* o2, AsnType* type, AsnConverter* converter);
void free_object(void* object, AsnType* type, AsnConverter* converter);
```

## Generated Output

With `output "build"` and `cpp.output-folder "c++"`, output is written under
`build/c++/`. Each ASN.1 module produces a header file and an implementation
file inside a namespace derived from the module name.
