IAAPI Restrictions
Contents
General Restrictions
If the input ASN.1 syntax contains PDU types with the same type reference name, the ossGetComponentByAbsRef(), ossPutComponentByAbsRef(), and ossPduTypeHandleByName() functions might encounter name resolution problems (for example, if the input syntax contains several modules and the -root option is specified).
The ossIntervalPropertySettingsForPER(), ossDatePropertySettingsForPER(), and ossTimeOfDayIntervalPropertySettingsForPER() functions retrieve PER-visible property settings information only for time types that are constrained so that all their abstract values have PER encodings that are not encodings of the MIXED-ENCODING type, as defined in ITU-T Rec. X.691:2021 | ISO/IEC 8825-2:2021. In some cases, it is not possible to reproduce the original PropertySettingsConstraint based on this information.
Example 1
T ::= TIME ((SETTINGS "Basic=Rec-Interval Interval-type=SE SE-point=Date") ^
((SETTINGS "Date=C Year=Negative Recurrence=R10") |
(SETTINGS "Date=C Year=L5 Recurrence=Unlimited")))
The ossPrintASN1DescriptionOfType() function prints the PropertySettingsConstraint using a minimum permitted value for recurrence digits R10 and a minimum number of digits in large years L5, which is different from the actual constraint applied to the time type.
T ::= TIME ( (SETTINGS "Basic=Rec-Interval Recurrence=R10 Interval-type=SE SE-point=Date Date=C Year=Negative") | (SETTINGS "Basic=Rec-Interval Recurrence=R10 Interval-type=SE SE-point=Date Date=C Year=L5"))
Example 2
Time-date ::= TIME ("1234-12-12".."1450-10-01")
Time-interval ::= TIME ("R/-12345C/P12Y123M0D")
The ossPrintASN1DescriptionOfType() function prints the PropertySettingsConstraint corresponding to the property settings of the values specified in TimePointRange and SingleValue, not the actual range or single value constraint.
Time-date ::= TIME (SETTINGS "Basic=Date Date=YMD Year=Proleptic") Time-interval ::= TIME (SETTINGS "Basic=Interval Interval-type=SD SE-point=Date Date=C Year=L7")
The Lean Encoder/Decoder
Each ASN.1 type has a single C representation regardless of the applied constraints or directives. Only REAL, INTEGER, SET OF, and SEQUENCE OF can have two or more representations.
REAL
REAL types can have BINARY (double) as the default representation or DECIMAL (char *) if the OSS.DECIMAL directive is applied.
Example
DefaultReal ::= REAL typedef ossReal DefaultReal; DecimalReal ::= REAL --<DECIMAL>-- typedef char *DecimalReal;
SET OF and SEQUENCE OF
SET OF and SEQUENCE OF can have LINKED as the default representation or UNBOUNDED if the OSS.UNBOUNDED directive is applied.
Example
Sof ::= SEQUENCE OF INTEGER
typedef struct Sof {
struct Sof *next;
OSS_INT32 value;
} *Sof;
Sof ::= SEQUENCE --<UNBOUNDED>-- OF INTEGER
typedef struct Sof {
OSS_UINT32 count;
OSS_INT32 *value;
} *Sof;
INTEGER
By default, INTEGER types have the OSS_INT32 representation.
Example
I ::= INTEGER typedef OSS_INT32 I;
If the type is constrained to have only positive values, the OSS_UINT32 representation is used.
I ::= INTEGER (0..20) typedef OSS_UINT32 I;
I ::= INTEGER (-1..1234567890123) typedef OSS_INT64 I;
If the type is constrained to have only positive values with a 64-bit integer range, the OSS_UINT64 representation is used.
I ::= INTEGER (0..4294967295) typedef OSS_UINT64 I;
If the OSS.HUGE directive is applied to INTEGER types, the following C structure is generated:
I ::= INTEGER --<HUGE>-- typedef ossHugeInt I;
typedef struct ossHugeInt {
OSS_UINT32 length;
unsigned char *value;
} ossHugeInt;
BIT STRING, OCTET STRING, CharacterString
All string types have the UNBOUNDED representation with OSS_UINT32.
Example
typedef struct ossOctetString {
OSS_UINT32 length;
unsigned char *value;
} ossOctetString;
BMPString
typedef struct ossBMPString {
OSS_UINT32 length;
OSS_UINT16 *value;
} ossBMPString;
For more details, see leandef.h.
UniversalString
typedef struct ossUniversalString {
OSS_UINT32 length;
OSS_INT32 *value;
} ossUniversalString;
OBJECT IDENTIFIER, RELATIVE-OID
RELATIVE-OID and OBJECT IDENTIFIER have the UNBOUNDED ENCODED representation.
Example
typedef struct ossObjectID {
OSS_UINT32 length;
unsigned char *value;
} ossObjectID;
GeneralizedTime, UTCTime
GeneralizedTime and UTCTime have the char * representation.
Example
Generaltime ::= GeneralizedTime typedef char *Generaltime;
CHOICE
For CHOICE types, the structure consists of the choice selector and a union of alternatives. For each alternative, a #define is generated to identify which alternative is selected.
Example
Personal ::= CHOICE {
married BOOLEAN,
age INTEGER
}
typedef struct Personal {
OSS_UINT32 choice;
# define married_chosen 1
# define age_chosen 2
union {
ossBoolean married; /* to choose, set choice to married_chosen */
OSS_INT32 age; /* to choose, set choice to age_chosen */
} u;
} Personal;
SET, SEQUENCE
SET and SEQUENCE types with OPTIONAL or DEFAULT or with extension additions have the bit mask field (OSS_UINT32) generated to indicate their presence or absence. If the number (N) of OPTIONAL fields is greater than 32, the bit mask is defined as char [].
unsigned char bit_mask[N];
Example
Personal ::= SEQUENCE {
married BOOLEAN,
age INTEGER,
weight INTEGER OPTIONAL,
name IA5String OPTIONAL
}
typedef struct Personal {
OSS_UINT32 bit_mask;
# define weight_present 0x80000000
# define name_present 0x40000000
ossBoolean married;
OSS_INT32 age;
OSS_INT32 weight; /* optional; set in bit_mask weight_present if present */
ossCharString name; /* optional; set in bit_mask name_present if present */
} Personal;
ENUMERATED
ENUMERATED has the enum C representation. By default, it corresponds to OSS_INT32 or OSS_UINT32 integer C types.
In some cases, on a platform that requires a C compiler option like -short-enum, an enum type is represented by a minimum integer that is sufficient to keep any value of this type, which is char, short, or int.
Recursive ASN.1 Types
Recursive ASN.1 types are generated with an extra pointer.
Example
TreeNode ::= SEQUENCE {
text VisibleString (SIZE(1..255)),
left [1] TreeNode OPTIONAL,
right [2] TreeNode OPTIONAL
}
typedef struct TreeNode {
ossCharString text;
struct TreeNode *left; /* NULL for not present */
struct TreeNode *right; /* NULL for not present */
} TreeNode;
SOED versus LED
The following tables summarize the differences between SOED and LED.
ASN.1 definitions, directives and generated C-structures
| Feature | SOED | LED |
|---|---|---|
| OSS ASN.1 compiler directives | All OSS directives are allowed. | When -lean is specified, the ASN.1 compiler ignores the following compiler directives and issues a warning:
OSS.ARRAY OSS.DLINKED OSS.DLINKED-PLUS OSS.DOUBLE OSS.FLOAT OSS.INT OSS.LINKED OSS.LLONG OSS.LONG OSS.MIXED OSS.NULLTERM OSS.OBJECTID OSS.ONECHAR OSS.PADDED OSS.POINTER (will be supported) OSS.SHORT OSS.VARYING |
C Representations
| Feature | SOED | LED |
|---|---|---|
| ANY/ANY DEFINED BY | OSS.DLINKED OSS.LINKED OSS.POINTER OSS.UNBOUNDED |
ossAny(similar to OSS.UNBOUNDED) |
| BIT STRING | OSS.DLINKED OSS.LINKED OSS.PADDED OSS.POINTER OSS.UNBOUNDED OSS.VARYING |
ossBitString(similar to OSS.UNBOUNDED) |
| BMPString | OSS.POINTER
typedef
{
unsigned int length;
unsigned short *value;
}; |
ossBMPString(similar to OSS.UNBOUNDED) |
| BOOLEAN | typedef char ossBoolean; OSS.POINTER |
ossBoolean |
| CHOICE | default, OSS.POINTER | similar to default (choice index has OSS_UINT32 type) |
| EMBEDDED PDV | default, OSS.POINTER | similar to default |
| ENUMERATED | default, OSS.POINTER | similar to default |
| EXTERNAL | default, OSS.POINTER | similar to default |
| GeneralizedTime | typedef GeneralizedTime;
OSS.POINTER |
char * |
| INSTANCE OF | default | similar to default |
| INTEGER | int ASN1.HugeInteger | OSS.HUGE OSS.INT OSS.LONG OSS.LONGLONG OSS.POINTER OSS.SHORT |
OSS_INT32 OSS_UINT32 ossHugeInt OSS_INT64 OSS_UNIT64 (available in next release) (OSS.LONGLONG is supported if runtime compiled with OSS_LONGLONG_SUPPORTED) |
| NULL | typedef char Nulltype; OSS.POINTER |
typedef char Nulltype |
| OBJECT IDENTIFIER | OSS.ARRAY OSS.LINKED OSS.OBJECTID length OSS.OBJECTID ENCODED / ENCODED OSS.POINTER OSS.SHORT / OSS.INT / OSS.LONG (when applied locally) OSS.UNBOUNDED |
ossObjectID (similar to ENCODED) |
| ObjectDescriptor | <GraphicString> | ossCharString (similar to OSS.UNBOUNDED) |
| OCTET STRING | OSS.DLINKED OSS.LINKED OSS.POINTER OSS.UNBOUNDED OSS.VARYING |
ossOctetString (similar to OSS.UNBOUNDED) |
| OID-IRI | RELATIVE-OID-IRI OSS.NULLTERM OSS.POINTER OSS.UNBOUNDED OSS.VARYING |
ossCharString (similar to OSS.UNBOUNDED) |
| Open type | OSS.POINTERThe OSS.OBJHANDLE | OSS.NOCOPY directives are allowed on this type, but have no effect on the representation in the header file. |
The OSS.OBJHANDLE | OSS.NOCOPY directives are allowed on this type but have no effect on the representation in the header file. |
| REAL | OSS.FLOAT OSS.DECIMAL OSS.DOUBLE OSS.MIXED OSS.POINTER |
ossReal char * (for decimal representation) |
| RELATIVE-OID type | OSS.OBJECTID length OSS.OBJECTID ENCODED | ENCODED OSS.POINTER |
(similar to ENCODED) |
| Recursive types | extra pointer | extra pointer |
| (restricted) Character string types | OSS.DLINKED OSS.LINKED OSS.NULLTERM OSS.PADDED OSS.POINTER OSS.UNBOUNDED OSS.VARYING |
ossCharString (all similar to OSS.UNBOUNDED) |
| CHARACTER STRING | default | similar to default |
| Selection | default | similar to default |
| SEQUENCE | default, OSS.POINTER | similar to default Bit mask for OPTIONAL field has OSS_UINT32 or char * representation |
| SEQUENCE OF | OSS.ARRAY OSS.DLINKED OSS.LINKED OSS.POINTER OSS.UNBOUNDED |
OSS.LINKED - by default OSS.UNBOUNDED - with ASN.1 directive |
| SET | default, OSS.POINTER | similar to default Bit mask for OPTIONAL field has OSS_UINT32 or char * representation |
| SET OF | OSS.ARRAY OSS.DLINKED OSS.DLINKED-PLUS OSS.LINKED OSS.POINTER OSS.UNBOUNDED |
OSS.LINKED - by default OSS.UNBOUNDED - with ASN.1 directive |
| Tagged | default | similar to default |
| UniversalString | OSS.POINTER
typedef
{
unsigned int length;
unsigned int *value;
};
|
ossUniversalString (similar to OSS.UNBOUNDED) |
| UTCTime | typedef UTCTime;,
OSS.POINTER |
char * |
Compile / Link Aspects
| Feature | SOED | LED |
|---|---|---|
| Works on both aCC and cfront | Yes | aCC - Yes cfront - memory problems ? |
| Availability in 64-bit version | Yes | OSS_LONGLONG_SUPPORTED |
| Mixed SOED/LED encoding / decoding | No | No |
Runtime Aspects
| Feature | SOED | LED |
|---|---|---|
| Runtime constraints checking | Yes | The LED runtime library does not have any constraint-checking routines. But SOED constraint-checking can be used by linking with both the SOED and LED libraries. Additionally, the LED does not currently identify the exact field in which an error occurs. |
| Runtime copy and comparison of decoded PDUs | Yes | No SOED copy and comparison can be used. |
| Support functions for working with information object sets (e.g., ossAddInfoObject(), ossGetInfoObject(), ossGetInfoObjectSet(), and ossRemoveInfoObject()) | Yes | No SOED functions for working with information object sets can be used. |
| Function ossSetUser MallocFreeRealloc() | Yes | No (will be supported in the next release) |
| Support for automatic checking default values in encoding (for DER encoding) | Yes | Limited support for the following types: 1) NULL, ENUMERATED, BOOLEAN, INTEGER, REAL EMBEDDED PDV, CHARACTER STRING 2) OBJECT IDENTIFIER, RELATIVE-OID, OCTET STRING, IA5String, VisibleString, PrintableString, TeletexString if NOCOPY is not applied. 3) SET, SEQUENCE, CHOICE with the fields of the listed above ASN.1 types. The SOED can be used for full checking of default values. |
| Support for indefinite length encoding / decoding | Yes | The Lean encoder supports only definite length encoding. However, the Lean decoder supports any valid BER encoding. OSS can add this feature, if necessary. |
| Performance (encode / decode time) | 1 | ~ 0.5 * SOED |
Comma-Separated Value (CSV) Conversion
Starting with version 10.3, the IAAPI includes functions to convert decoded values to and from CSV format. To represent a structured decoded value in CSV format, the IAAPI flattens it into a fixed number of columns by recursively expanding complex SET, SEQUENCE, and CHOICE types, up to the innermost fields, with simple ASN.1 types. The resulting record includes a place for each simple type value, which can be empty for optional fields with absent values. Note that, like all IAAPI functions, the CSV conversion functions are not supported in the Time-Optimized Encoder/Decoder library (TOED), which is the runtime library used by default.
IAAPI supports two CSV formats, as follows:
- Row format, where each row is a record containing values separated by a comma or some other separator.
- Column format, where each value is placed on a separate line, possibly after an optional CSV header name and a column separator.
The CSV format can include an optional CSV header created by parsing the input PDU type definition. The header record consists of complete absolute references or single ASN.1 names that match the values in the rows or columns. The column values are generated by parsing encoded messages or value notation.
Example
| ASN.1 | CSV row format |
|---|---|
PersonnelRecord ::= SEQUENCE {
name PrintableString,
number INTEGER OPTIONAL,
children SEQUENCE OF ChildInformation
}
ChildInformation ::= SET {
name PrintableString,
date GeneralizedTime OPTIONAL
}
PersonnelRecord value:
{
name "Nancy",
number 20,
children {
{name "James", date "20020312000000"},
{name "Martha", date "20100820000000"}
}
} |
name,number,children_name,children_date "Nancy",20,"James",03/12/02 00:00:00 "Nancy",20,"Martha",08/20/10 00:00:00 |
CSV Conversion Restrictions
There are some restrictions imposed on CSV conversion because
- ASN.1 PDU types are usually structured and can be nested to an arbitrary depth.
- Some ASN.1 types can be defined recursively.
- Open types or types with contents constraints can include other type values, known or unknown.
These restrictions are as follows:
- The values for nested recursions are supported only in full CSV header format, which includes absolute references for all fields. Multiple CSV records of recursive types must have the same number of initialized nesting levels, so all records will have the same number of columns.
- Values of SET OF and SEQUENCE OF types with multiple components are mapped into several CSV records where only one component differs and the rest are repeated. SET OF and SEQUENCE OF types can be nested inside these types. By default, to avoid significant performance degradation, the IAAPI supports an additional CSV for up to 50 components inside each type. To set the maximum number of components, call ossSetCsvSetting() with the OSS_CSV_MAX_SET_OF_SEQ_OF_COMPONENTS identifier. The total number of additional CSVs for all SET OF and SEQUENCE OF types is limited to the maximum between the user-specified number set by the OSS_CSV_ALL_MAX setting and 50, multiplied by 50.
- Automatic decoding of open types is supported only in full CSV header format, which includes nested PDU names or numbers inside parentheses. When open types are included, at any nesting level and within SET OF or SEQUENCE OF types, their containing PDUs must be the same for all components, so that the CSV structure does not change.
Example
| ASN.1 | CSV |
|---|---|
ErrorEntry ::= SEQUENCE {
errorCode ERROR-CLASS.&code ({ErrorSet}),
errorInfo ERROR-CLASS.&Type ({ErrorSet}{@.errorCode})
}
e ErrorEntry ::= { errorCode 10, errorInfo Int : 20} |
errorCode,errorInfo(Int) 10,20 |
- The values of types with contents constraints and known containing types are always automatically decoded. If the CSV record includes values of such types in the form of xmlbstring (0101...) or xmlhstring (AB09...), an error is issued.
- By default, CSVs with string type values containing Unicode characters are written to the output file in binary format with UTF-8 character encoding. These CSVs are displayed using \x##, a special C-style character escape sequence. To create CSVs in this format, call the following function:
ossSetCsvSetting(world, OSS_CSV_FLAGS, ossGetCsvFlags(world, OSS_CSV_FLAGS) | OSS_CSV_TEXT_FORMAT);
Example
| ASN.1 | CSV |
|---|---|
myLabelUtf8 LabelUtf8 ::= "Umlaute: äÄöÖüÜ" |
LabelUtf8 "Umlaute: \xc3\xa4\xc3\x84\xc3\xb6\xc3\x96\xc3\xbc\xc3\x9c" |
- When the input ASN.1 syntax includes SET or CHOICE types with fields whose tags are not in PER-required ascending order, encoding and decoding in CSV format should be consistent with any field sorting for PER. When ASN.1 compiling the input ASN.1 syntax, if a CSV is created while sorting fields by tag because -per is specified (implicitly or explicitly), then -per should also be specified when decoding that CSV. This ensures that the order of the field names in the CSV header is the same as in the related SET or CHOICE internal structure, whether or not sorting occurs.
Type Mapping and Data Conversion
CSVs are in human-readable format similar to ASN.1 value notation. The following table shows the differences sorted by ASN.1 type. Additional CSV representations are available by passing special flags to the -csv option.
| ASN.1 Type | ASN.1 Value | CSV Value |
|---|---|---|
| BIT STRING | bstring
'0101011'B |
xmlbstring
010101 |
| BOOLEAN | TRUE or FALSE |
XML boolean extended items
TRUE or FALSE 1 or 0 |
| Restricted Character String types | Quoted cstring or list notation | Quoted strings UTF-8 encoding is used for Unicode characters; a special C-style character escape sequence \x## is used in the CSV text format. |
| CHOICE | The selected alternative name is included as chosen : <value> | All alternatives are present, the ones that are not chosen have empty values with extra separators for all their nested components. |
| ENUMERATED | identifier | identifier number |
| GeneralizedTime | "20120808131347+0500" |
Same non-quoted value
One of time stamp formats:
06/01/00 00:00:00 2007-11-07 11:36:49 |
| NULL | NULL | NULL |
| OBJECT IDENTIFIER, RELATIVE-OID | {arc1(num1) arc2 ... } or encoded format | Dot notation:
1.3.6.1.4.1.1900 |
| OCTET STRINGS | hstring
'6B646F726C793031'H |
xmlhstring
6B646F726C793031ASCII format: kdorly01 |
| OpenType | Either encoded or automatically decoded | Automatically decoded only if the full CSV header is present XML format Hexadecimal format |
| Types with ContentsConstraint | bstring | automatically decoded Automatically decoded if the containing PDU is known. |
| REAL | Different representations, including {mantissa, base, exponent} notation | Decimal format |
| SET, SEQUENCE | Values for fields with OPTIONAL/DEFAULT can be absent | Columns for all fields with all their nested components are present. Missing values for optional fields are marked with extra separators. |
| SET OF, SEQUENCE OF | Component values are included in
{val1, val2, ...} |
One column is present for only one component. The row for the complete PDU is repeated for each extra component. |
| TIME, DATE, and other time types | "2010-04-15T17:18:18-07:00" |
The same quoted value |
| UTCTime | "200808131347Z" |
The same non-quoted value |
| Circularly defined types | Values for nested types are printed. | CSVs for nested recursions are created only if the full CSV header is present |
| Fields marked with the ASN1.Remove directive | Ignored | Ignored without extra column separators |
Use the ossSetCsvSetting() function to instruct the CSV conversion functions to perform extra conversions when OCTET STRING values are converted to or from ASCII, BCD, TBCD, IP address, and time stamp format. Alternatively, use the OSS.PrintFunctionName directive with an OSS-specific function name for that conversion, for example "ossPrintOctetAsBCDString" for a BCD conversion. Applying the OSS.PrintFunctionName directive to OCTET STRING types converts their values to or from the specified format. For example, you can mark OCTET STRING types for conversion to TBCD, BCD, ASCII, IP address, or a special time stamp format using the following directives:
--<OSS.PrintFunctionName MOD.Seq.*.soctVarBcd "ossPrintOctetAsBCDString">-- --<OSS.PrintFunctionName MOD.Seq.*.soctVarTbcd "ossPrintOctetAsTBCDString">-- --<OSS.PrintFunctionName MOD.Seq.*.soctVarIp "ossPrintOctetAsIPAddress">-- --<OSS.PrintFunctionName MOD.Seq.*.soctVarAsc "ossPrintOctetAsASCII">-- --<OSS.PrintFunctionName MOD.Seq.*.soctVarTime "ossPrintOctetAsTimeStamp">--
When you include the following call in your application the type values to which the directives are applied will not be affected. However, other OCTET STRING type values will be converted to the ASCII format.
ossSetCsvSetting(world, OSS_CSV_OCTET_STRING, OSS_COS_ASCII); ossConvertPduValueToCsv(...);
When using ASCII to convert an OCTET STRING hstring value that begins with one or more space characters (0x20), the resulting CSV value is enclosed in quotation marks, indicating that the spaces are part of the value. The CSV decoder ignores quotation marks that follow space characters.
Example
| ASN.1 | CSV |
|---|---|
Oct ::= OCTET STRING oct Oct ::= '20206C65616469616720737061636573'H |
Oct " leading spaces" |
When conversion into one of the OSS.PrintFunctionName directive's formats fails, the original OCTET STRING value is printed in hexadecimal format and is prefixed with the ??? string. The CSV decoder ignores the prefix and uses the hstring value while omitting conversion.
Example
| ASN.1 | CSV |
|---|---|
--<OSS.PrintFunctionName Mod.Oct "ossPrintOctetAsBCDString">-- Oct ::= OCTET STRING oct Oct ::= '12191D'H |
Oct ???12191D |
This documentation applies to the OSS® ASN.1 Tools for C release 12.0 and later.
Copyright © 2025 OSS Nokalva, Inc. All rights reserved.
No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form or by any means electronic, mechanical, photocopying, recording or otherwise, without the prior permission of OSS Nokalva, Inc.
Every distributed copy of the OSS® ASN.1 Tools for C is associated with a specific license and related unique license number. That license determines, among other things, what functions of the OSS ASN.1 Tools for C are available to you.

