TOP

C++ Representation of ASN.1 Notation

Applies to: ASN.1/C++ v7.3

PDUs

Each PDU defined in your ASN.1 input files can be represented in C++ when you compile your syntax. Representations of PDUs can be affected by the following:

  • ASN.1 type definition options (DEFAULT, SIZE())
  • Compiler options and directives (--<POINTER>--)
  • Platform defaults (typically optimized for size)

Values

Values are declared and initialized in the generated C++ code. When declaring values, you can use both ASN.1 syntax and XML syntax in the same specification. For example, the following lines of code are equivalent:

studentAge INTEGER ::= 23
  
studentAge ::= <INTEGER>23</INTEGER>

Names

Names defined in the input ASN.1 definitions are preserved in the generated header files. When element identifiers are missing, the ASN.1/C++ Compiler generates names derived from the type name.

The compiler also generates names, as needed, for anonymous types that are elements of constructed types. The names are derived from the type, for example, _seqofN for a SEQUENCE OF and _setofN for a SET OF, where N is a number. These automatically generated names are for internal use only and should not be referenced; the format could change in a later version of the ASN.1/C++ Compiler. Reference anonymous types using ContainerType::componentName notation for the component type of a SEQUENCE, SET, or CHOICE, and ContainerType::component notation for the component type of a SEQUENCE OF or SET OF.

In the generated C++ of the example below, notice that

  • The compiler switches the order of the Info and NameInfo classes; the NameInfo class can be referenced within the __seqof1 class and the __seqof1 class can be referenced within Info.
  • The ASN.1 SEQUENCE OF is named class __seqof1 in the C++ header file.
  • The other names in the ASN.1 input are passed by default to the header file without change.
ASN.1 C++
Age  ::= INTEGER

Info ::= SEQUENCE {
     Age,
     married    BOOLEAN,
     names      SEQUENCE OF NameInfo
}

NameInfo ::= SEQUENCE {
     firstName VisibleString (SIZE(20)),
     lastName  VisibleString (SIZE(20))
}
typedef OSS_INT32 Age;

class OSS_PUBLIC NameInfo   /* SEQUENCE */
{
public:
            . . .
    typedef OssString firstName;
    typedef OssString lastName;
            . . .
    firstName & get_firstName();
    const firstName & get_firstName() const;
    void set_firstName(const firstName &);

    lastName & get_lastName();
    const lastName & get_lastName() const;
    void set_lastName(const lastName &);
            . . .
};

class OSS_PUBLIC __seqof1 : public OssList  /* SEQUENCE OF */
{
public:
    typedef NameInfo component;
            . . .
    OssIndex prepend(const component & );
    OssIndex prepend(__seqof1 *);
    OssIndex insert_after(OssIndex, const component & );
    OssIndex insert_after(OssIndex, __seqof1 *);
            . . .
};

class OSS_PUBLIC Info   /* SEQUENCE */
{
public:
            . . .
    typedef OSS_INT32 age;
    typedef ossBoolean married;
    typedef __seqof1 names;
            . . .
    age & get_age();
    age get_age() const;
    void set_age(age);

    married & get_married();
    married get_married() const;
    void set_married(married);

    names & get_names();
    const names & get_names() const;
    void set_names(const names &);
            . . .
};

The compiler applies a disambiguation algorithm to confirm that all names are unique within the current scope of reference. It also verifies that no generated name conflicts with any C reserved name. If an ASN.1 Compiler-generated name is ambiguous and the named type is a member of a structure or enumeration, then the name is prefixed with the containing-structure's name. In the example below, notice how red and blue, used by both ASN.1 types, are prefixed with their parent-type's name and an underscore in the generated C++.

ASN.1 C++
PrimaryColors ::= INTEGER {blue(0), yellow(1), red(2)}
FlagColors ::= INTEGER {red(0), white(1), blue(2)}
const OSS_INT32 PrimaryColors_blue = 0;
const OSS_INT32 yellow = 1;
const OSS_INT32 PrimaryColors_red = 2;

const OSS_INT32 FlagColors_red = 0;
const OSS_INT32 white = 1;
const OSS_INT32 FlagColors_blue = 2;
typedef OSS_INT32 PrimaryColors;

typedef OSS_INT32 FlagColors;

Shortening Long Names

You can limit all variable names generated by the ASN.1/C++ Compiler to a maximum of 31 characters using the -shortenNames command-line option or the SHORTENNAMES compiler directive. When either is used, the compiler shortens user-supplied and compiler-generated names that are too long, and ensures that the names are unique.

Recursive Types

Recursively defined ASN.1 types are represented in C++ as self-referencing types. In the example below, the C++ representation is generated with the OSS.PDU directive specified for the TreeNode type.

ASN.1 C++
TreeNode ::= SEQUENCE {
        text        VisibleString (SIZE(1..255)),
        left    [1] TreeNode OPTIONAL,
        right   [2] TreeNode OPTIONAL
}
class OSS_PUBLIC TreeNode   /* SEQUENCE */
{
public:
            . . .
    typedef OssString text;
    typedef TreeNode left;
    typedef TreeNode right;

    TreeNode();
    TreeNode(const TreeNode &);
    TreeNode(const text &, const left &,
                                 const right &);
    TreeNode(const text &);
    ~TreeNode();

    TreeNode & operator = (const TreeNode &);
    int operator == (const TreeNode &) const;
    int operator != (const TreeNode &) const;

    text & get_text();
    const text & get_text() const;
    void set_text(const text &);

    left *get_left();
    const left *get_left() const;
    void set_left(const left &);
    int left_is_present() const;
    void omit_left();

    right *get_right();
    const right *get_right() const;
    void set_right(const right &);
    int right_is_present() const;
    void omit_right();
private:
    text text_field;
    left *left_field;
    right *right_field;
};

Constraints, Keywords, and Compiler Directives

Use of some ASN.1 constraints, keywords, and compiler directives can affect how C++ data types are generated.

Constraints

The encoding and decoding operations typically check the constraints applied to an ASN.1 type, but do not affect its C++ representation. However, when the -soed option is specified, the ASN.1/C++ Compiler uses the constraints applied to INTEGER types to determine their C++ representation, as shown in the following example.

ASN.1 C++
Name ::= INTEGER
typedef int Name;

Add a size constraint to the type and the C++ representation changes:

ASN.1 C++
Name ::= INTEGER (0..256)
typedef unsigned short int Name;

When a contents constraint is applied to an OCTET STRING or a BIT STRING type, the compiler will generate a different representation for that type. See Effect of Contents Constraints on the BIT STRING type and Effect of Contents Constraints on the OCTET STRING type for details.

ASN.1 permitted alphabet and pattern constraints have no effect on the C++ representation.

Keywords

Additional class methods and static constants are generated when the OPTIONAL and DEFAULT keywords are used.

Compiler Directives

Local directives take precedence over type constraints; global or module directives do not.

When the --<POINTER>-- directive is applied to a constructed type component, additional class methods will be generated for the constructed type.

When the --<DECIMAL>-- directive is applied, classes generated for the ASN.1 REAL type are derived from the OssDecimal class; by default, REAL is represented by the C++ double type.

Certain directives, such as --<SHORT>--, could conflict with the schema constraints, in which case the compiler issues a warning in response. At run-time, the encoder/decoder ensures that the value does not override the bounds of its C++ data type.

Tags

ASN.1 tags do not affect the C++ representation of ASN.1 types.

ASN.1 C++
IntegerType      ::= INTEGER
TaggedIntegerType  ::= [APPLICATION 1] IntegerType
MySeq ::= SEQUENCE {
     builtInInt        IntegerType,
     tagggedInt        TaggedIntegerType
}
typedef OSS_INT32 IntegerType;

typedef OSS_INT32 TaggedIntegerType;

class OSS_PUBLIC MySeq   /* SEQUENCE */
{
public:
            . . .
    typedef OSS_INT32 builtInInt;
    typedef OSS_INT32 tagggedInt;

    MySeq();
    MySeq(const MySeq &);
    MySeq(builtInInt, tagggedInt);

    MySeq & operator = (const MySeq &);
    int operator == (const MySeq &) const;
    int operator != (const MySeq &) const;

    builtInInt & get_builtInInt();
    builtInInt get_builtInInt() const;
    void set_builtInInt(builtInInt);

    tagggedInt & get_tagggedInt();
    tagggedInt get_tagggedInt() const;
    void set_tagggedInt(tagggedInt);
private:
    builtInInt builtInInt_field;
    tagggedInt tagggedInt_field;
};

Macros

ASN.1 macro notation is first expanded and then represented in C++.

Type Extensibility

Use of the ASN.1 extensibility marker ("...") or the OSS.EXTENSIBLE directive ensures compatibility between current and future versions of the schema.

The compiler generates code informing the encoder/decoder that extensible elements are possible. For each PDU, the decoder is instructed to

  • Ignore all CHOICE, SEQUENCE, and SET elements with undefined tags in the input ASN.1.
  • Ignore bits that are unnamed in the input ASN.1.
  • Ignore all unrecognized elements in ENUMERATED and INTEGER named number lists.
  • Allow values that are undefined in the original, constrained INTEGER type.
  • Allow array sizes that are unspecified in the original SEQUENCE OF or SET OF type definition.
  • Allow unrecognized sizes and values for constrained character string types (IA5String, NumericString, PrintableString, BMPString, UniversalString).

Any elements defined after the extensibility marker are treated as OPTIONAL components; corresponding methods are generated that indicate their presence or absence:

ASN.1 C++
NamesOfOfficers4 ::= SEQUENCE {
 president      VisibleString (SIZE(1..32)),
 vicePresident  VisibleString (SIZE(1..32)),
 secretary      VisibleString (SIZE(1..32)),
 ...
}

NamesOfOfficers5 ::= SEQUENCE {
 president      VisibleString (SIZE(1..32)),
 vicePresident  VisibleString (SIZE(1..32)),
 secretary      VisibleString (SIZE(1..32)),
 ...,
 treasurer      VisibleString (SIZE(1..32))
}
class OSS_PUBLIC NamesOfOfficers4   /* SEQUENCE */
{
       . . .
};

class OSS_PUBLIC NamesOfOfficers5   /* SEQUENCE */
{
public:
       . . .
 typedef OssString president;
 typedef OssString vicePresident;
 typedef OssString secretary;
 typedef OssString treasurer;

 NamesOfOfficers5();
 NamesOfOfficers5(const NamesOfOfficers5 &);
 NamesOfOfficers5(const president &,
   const vicePresident &, const secretary &, 
   const treasurer &);
 NamesOfOfficers5(const president &,
   const vicePresident &, const secretary &);

 NamesOfOfficers5 & operator = (const NamesOfOfficers5 &);
 int operator == (const NamesOfOfficers5 &) const;
 int operator != (const NamesOfOfficers5 &) const;

 president & get_president();
 const president & get_president() const;
 void set_president(const president &);

 vicePresident & get_vicePresident();
 const vicePresident & get_vicePresident() const;
 void set_vicePresident(const vicePresident &);

 secretary & get_secretary();
 const secretary & get_secretary() const;
 void set_secretary(const secretary &);

 treasurer *get_treasurer();
 const treasurer *get_treasurer() const;
 void set_treasurer(const treasurer &);
 int treasurer_is_present() const;
 void omit_treasurer();
};

General Translation Rules

For more details and examples of the rules the OSS ASN.1/C++ Compiler uses to represent ASN.1 in C++, see C++ Representation: Translation Rules.

Examples of C++ Representation: ASN.1 Types

For each ASN.1 type in this section, the default C++ representation is listed along with any factors that could affect it.

ANY | ANY DEFINED BY

This type is represented by the ASN.1/C++ OssString class, as is the OCTET STRING type.

ASN.1 C++
AnyType ::= ANY
typedef OssString AnyType;

↩Examples Index

BIT STRING

This type is represented by the ASN.1/C++ OssBitString class.

ASN.1 C++
BitStr ::= BIT STRING
typedef OssBitString BitStr;

Effect of Named Bit Lists

When a named bit list is present, the compiler generates integer constants for each of the named bits.

ASN.1 C++
BitStrNbA ::= BIT STRING {a(0), b(1), c(4)}
const OSS_UINT32 a = 0;
const OSS_UINT32 b = 1;
const OSS_UINT32 c = 4;
typedef OssBitString BitStrNbA;

When the -compat externIntConst option is specified, named bit constants are generated as extern variables. In this example, the variables a, b, and c are set to 0, 1, and 4 respectively by the compiler-generated code.

ASN.1 C++
BitStrNbA ::= BIT STRING {a(0), b(1), c(4)}
extern OSS_PUBLIC const OSS_UINT32 a;
extern OSS_PUBLIC const OSS_UINT32 b;
extern OSS_PUBLIC const OSS_UINT32 c;
typedef OssBitString BitStrNbA;

Effect of Contents Constraints

When a contents constraint is applied to a BIT STRING type, the compiler generates a class derived from the ASN.1/C++ OssBitString class. This class has an additional member representing the value in decoded form, along with the accessors and mutators needed to access it. For more information, see BIT STRING with Contents Constraint.

ASN.1   where A is any type C++
BitStrCC ::= BIT STRING (CONTAINING A)
class OSS_PUBLIC BitStrCC : public OssBitString
/* BIT STRING with contents constraint */
{
public:
    typedef A contained;

    BitStrCC();
    BitStrCC(const BitStrCC &);
    BitStrCC & operator = (const BitStrCC &);
    ~BitStrCC();
    int operator == (const BitStrCC &) const;
    int operator != (const BitStrCC &) const;
    BitStrCC(OSS_UINT32 length, const unsigned char *);
    A *get_decoded();
    const A *get_decoded() const;
    A *release_decoded();
    void set_decoded(A);
    void grab_decoded(A *);
    int has_encoded() const;
    int has_decoded() const;
private:
    A *decoded;
};

↩Examples Index

BMPString

This type is represented by the ASN.1/C++ OssBMPString class.

ASN.1 C++
MyBMP ::= BMPString
typedef OssBMPString MyBMP;

↩Examples Index

BOOLEAN

This type is represented by the ossBoolean type, which is defined as C++ char.

ASN.1 C++
Married ::= BOOLEAN
typedef ossBoolean Married;

↩Examples Index

CHOICE

This type is represented by a compiler-generated class derived from the ASN.1/C++ OssChoice class. The class has the accessors and mutators needed to select and retrieve all possible CHOICE alternatives. See CHOICE Types for more details.

ASN.1 C++
ProductDesignator ::= CHOICE {
  departmentNo        INTEGER,
  description     [0] IMPLICIT VisibleString,
  inventoryNo     [1] IMPLICIT INTEGER
  }
class OSS_PUBLIC ProductDesignator  : public OssChoice
                                          /* CHOICE */
{
public:
    enum Id {
    unselected,
    departmentNo_chosen = 1,
    description_chosen = 2,
    inventoryNo_chosen = 3
    };
    typedef OSS_INT32 departmentNo;
    typedef OssString description;
    typedef OSS_INT32 inventoryNo;

    ProductDesignator();
    ProductDesignator(const ProductDesignator &);
    ~ProductDesignator();

    ProductDesignator & operator =
                          (const ProductDesignator &);
    int operator == (const ProductDesignator &) const;
    int operator != (const ProductDesignator &) const;

    departmentNo *get_departmentNo();
    const departmentNo *get_departmentNo() const;
    void set_departmentNo(departmentNo);

    description *get_description();
    const description *get_description() const;
    void set_description(const description &);

    inventoryNo *get_inventoryNo();
    const inventoryNo *get_inventoryNo() const;
    void set_inventoryNo(inventoryNo);
private:
    union {
    departmentNo departmentNo_field;
    OSSC::COssString description_field;
    inventoryNo inventoryNo_field;
    };
    void cleanup();
};

Effect of OSS.POINTER on a CHOICE Component

Another pair of ownership-transferring accessor/mutator methods is generated when the OSS.POINTER directive is applied to a CHOICE component. Use the mutator method to assign a new value to the component and the accessor method to obtain its current value. Neither method performs a deep copy of the source data, which can be very time-consuming for a large or complex component.

ASN.1 C++
ProductDesignator ::= CHOICE {
 departmentNo     INTEGER,
 description  [0] IMPLICIT VisibleString --<POINTER>--,
 inventoryNo  [1] IMPLICIT INTEGER
 }
class OSS_PUBLIC ProductDesignator  :
               public OssChoice  /* CHOICE */
{
public:
  enum Id {
  unselected,
  departmentNo_chosen = 1,
  description_chosen = 2,
  inventoryNo_chosen = 3
  };
  typedef OSS_INT32 departmentNo;
  typedef OssString description;
  typedef OSS_INT32 inventoryNo;

  ProductDesignator();
  ProductDesignator(const ProductDesignator &);
  ~ProductDesignator();

  ProductDesignator & operator = 
                  (const ProductDesignator &);
  int operator ==
            (const ProductDesignator &) const;
  int operator !=
            (const ProductDesignator &) const;

  departmentNo *get_departmentNo();
  const departmentNo *get_departmentNo() const;
  void set_departmentNo(departmentNo);

  description *get_description();
  const description *get_description() const;
  void set_description(const description &);
  void set_description(description *);
  description *release_description();

  inventoryNo *get_inventoryNo();
  const inventoryNo *get_inventoryNo() const;
  void set_inventoryNo(inventoryNo);
private:
  union {
  departmentNo departmentNo_field;
  description *description_field;
  inventoryNo inventoryNo_field;
  };
  void cleanup();
};

↩Examples Index

ENUMERATED

This type is represented by a C++ enum type that contains all values in the named number list of the ENUMERATED type.

ASN.1 C++
Colors ::= ENUMERATED {red(1), white(2), blue(3)}
enum Colors {
    red = 1,
    white = 2,
    blue = 3
};

Effect of Value References in the Named Number List

If a NamedNumber identifier has an associated value reference instead of a SignedNumber, the value reference is represented in C++ by the SignedNumber that it signifies. In the example, note how the value reference, purple, is replaced by 4 in the C++ representation.

ASN.1 C++
Colors ::= ENUMERATED {red(1), white(2), blue(purple)}
purple INTEGER ::= 4
enum Colors {
    red = 1,
    white = 2,
    blue = 4
};
. . .
/* External definitions for named values */

const OSS_INT32 purple = 4;

↩Examples Index

GeneralizedTime

This type is represented by the ASN.1/C++ OssGeneralizedTime class.

ASN.1 C++
GeneralTime ::= GeneralizedTime
typedef OssGeneralizedTime GeneralTime;

↩Examples Index

INSTANCE OF

This type is represented by an attribute-id and attribute-value pair.

ASN.1 C++
Module DEFINITIONS ::= BEGIN
   MHS-BODY        ::= TYPE-IDENTIFIER
   InstanceOfMHS   ::= INSTANCE OF MHS-BODY
END
class OSS_PUBLIC InstanceOfMHS   /* SEQUENCE */
{
public:
         . . .
    typedef OssEncOID type_id;
    typedef OssOpen value;

    InstanceOfMHS();
    InstanceOfMHS(const InstanceOfMHS &);
    InstanceOfMHS(const type_id &, const value &);

    InstanceOfMHS & operator = (const InstanceOfMHS &);
    int operator == (const InstanceOfMHS &) const;
    int operator != (const InstanceOfMHS &) const;

    type_id & get_type_id();
    const type_id & get_type_id() const;
    void set_type_id(const type_id &);

    value & get_value();
    const value & get_value() const;
    void set_value(const value &);
private:
    type_id type_id_field;
    value value_field;
};
Where TYPE-IDENTIFIER is internally defined as
TYPE-IDENTIFIER ::= CLASS
{
   &id OBJECT IDENTIFIER UNIQUE,
   &Type
}
WITH SYNTAX {&Type IDENTIFIED BY &id}
and InstanceOfMHS is this implied, associated SEQUENCE:
InstanceOfMHS ::= SEQUENCE
{
   type-id        MHS-BODY.&id,
   value      [0] MHS-BODY.&Type
}

↩Examples Index

INTEGER

By default, this type is represented by OSS_INT32, the 32-bit C++ signed integer type.

ASN.1 C++
RegInt   ::= INTEGER
typedef OSS_INT32 RegInt;

Effect of Named Number Lists

When a named number list is present, the compiler generates an additional integer constant for each named value.

ASN.1 C++
NumLstInt  ::= INTEGER {one(1), two(2), three(3)}
const OSS_INT32 one = 1;
const OSS_INT32 two = 2;
const OSS_INT32 three = 3;
typedef OSS_INT32 NumLstInt;

When the -compat externIntConst option is specified, named number constants are generated as extern variables. In this example, the variables one, two, and three are initialized to 1, 2, and 3 respectively.

ASN.1 C++
NumLstInt  ::= INTEGER {one(1), two(2), three(3)}
extern OSS_PUBLIC const OSS_INT32 one;
extern OSS_PUBLIC const OSS_INT32 two;
extern OSS_PUBLIC const OSS_INT32 three;
typedef OSS_INT32 NumLstInt;

Effect of the SingleValue Subtype

The compiler uses the SingleValue subtype to determine the number of bytes needed to hold the smallest or largest allowed integer value. Depending on the constraint, one of these types is generated:

   OSS_INT16	:  signed 16-bit integer (short on most platforms)
   OSS_UINT16	:  unsigned 16-bit integer (unsigned short on most platforms)
   OSS_INT32	:  signed 32-bit integer (long on most platforms)
   OSS_UINT32	:  unsigned 32-bit integer (unsigned long on most platforms)
   LONG_LONG	:  signed 64-bit integer (on platforms that support it)
   ULONG_LONG	:  unsigned 64-bit integer (on platforms that support it)

The LED does not support 16 bit integers, so the compiler will not generate OSS_INT16 or OSS_UINT16 when the -lean option is specified.

ASN.1 C++
SngValInt    ::= INTEGER (1|2)
typedef unsigned OSS_INT16 SngValInt;

Effect of the ValueRange Subtype

The compiler uses the ValueRange subtype to determine the number of bytes needed to hold the smallest or largest allowed integer value. Unless the -soed option is specified, the effect of subtypes on the INTEGER type is limited to generation of OSS_UINT32 and OSS_INT32; OSS_UINT64 and OSS_INT64 are possible on some platforms:

ASN.1 C++
SizeInt      ::= INTEGER (1..123456789)
typedef OSS_UINT32 SizeInt;

Effect of ASN1.HugeInteger and OSS.HUGE

When the ASN1.HugeInteger or OSS.HUGE directive is applied, an INTEGER type is represented by the ASN.1/C++ OssHugeInt class.

ASN.1 C++
HugeInt      ::= INTEGER --<HUGE>--
typedef OssHugeInt HugeInt;

Effect of OSS.SHORT, OSS.INT, OSS.LONG, and OSS.LONGLONG

The OSS.SHORT, OSS.INT, OSS.LONG, and OSS.LONGLONG directives can be used locally or globally to set the representation of an INTEGER type. Note that the OSS.SHORT, OSS.INT, and OSS.LONG directives can only be used with the -soed compiler option.

ASN.1 C++
LongInt      ::= INTEGER --<LONGLONG>--
     typedef LONG_LONG LongInt;

compiled with the -lean or -toed option

     typedef OSS_INT64 LongInt;

Effect of Combining Subtypes with Directives

When a ValueRange or SingleValue subtype conflicts with a local OSS.SHORT, OSS.INT, OSS.LONG, or OSS.LONGLONG directive, the directive takes precedence and the compiler issues a warning. In the example below, the subtype value is too large to fit in the type indicated by the directive. The compiler issues these warnings:

C0291W: The integer value (123456789) exceeds the directive or subtype constraints for type 'ShrtSzInt'.

C0255W: Number (123456789) is too large to fit in 2 bytes. It is being truncated to 65535.

ASN.1 C++
ShrtSzInt    ::= INTEGER (1..123456789) --<SHORT>--
     typedef OSS_UINT16 ShrtSzInt;

↩Examples Index

NULL

This type is represented by the Nulltype type, which is defined as a synonym of char.

ASN.1 C++
Name1 ::= NULL
typedef Nulltype Name1;

↩Examples Index

OBJECT IDENTIFIER

This type is represented by the ASN.1/C++ OssEncOID class.

ASN.1 C++
DefaultOID   ::= OBJECT IDENTIFIER
typedef OssEncOID DefaultOID;

↩Examples Index

OCTET STRING

This type is represented by the ASN.1/C++ OssString class.

ASN.1 C++
DefaultOctStr        ::= OCTET STRING
typedef OssString DefaultOctStr;

Effect of Contents Constraints

When a contents constraint is applied to a OCTET STRING type, the compiler generates a class derived from the ASN.1/C++ OssString class. This class has an additional member representing the value in decoded form, along with the accessors and mutators needed to access it. For more information, see OCTET STRING with Contents Constraint.

ASN.1   where A is any type C++
OctStrCC ::= OCTET STRING (CONTAINING A)
class OSS_PUBLIC OctStrCC : public OssString
/* OCTET STRING with content constraint */
{
public:
    typedef A contained;

    OctStrCC();
    OctStrCC(const OctStrCC &);
    OctStrCC & operator = (const OctStrCC &);
    ~OctStrCC();
    int operator == (const OctStrCC &) const;
    int operator != (const OctStrCC &) const;
    OctStrCC(const char *);
    OctStrCC(OSS_UINT32 length, const char *);
    A *get_decoded();
    const A *get_decoded() const;
    A *release_decoded();
    void set_decoded(const A &);
    void grab_decoded(A *);
    int has_encoded() const;
    int has_decoded() const;
private:
    A *decoded;
};

↩Examples Index

OID-IRI

This type is represented by the ASN.1/C++ OssString class.

ASN.1 C++
DefaultOidIri        ::= OID-IRI
typedef OssString DefaultOidIri;

↩Examples Index

Open Type

Unconstrained open types are represented by the ASN.1/C++ OssOpen class.

ASN.1 C++
Module DEFINITIONS ::= BEGIN
      A ::= TYPE-IDENTIFIER.&Type
END
typedef OssOpen A;
The TYPE-IDENTIFIER information object class is defined as follows:
TYPE-IDENTIFIER ::= CLASS
     {
          &id      OBJECT IDENTIFIER UNIQUE,
          &Type
     }
     WITH SYNTAX {&Type IDENTIFIED BY &id}

Effect of Table Constraints

When a table constraint limits the types available to an open type, it is represented by a compiler-generated class derived from the OssConstrainedOpenType class.

ASN.1 C++
CLS ::= CLASS {&key  INTEGER UNIQUE, &Type}
info1 CLS ::= {&key 22, &Type A}
info2 CLS ::= {&key 33, &Type B}

IOS CLS ::= { info1 | info2 }

Optype ::= CLS.&Type ({IOS})
class OSS_PUBLIC Optype : public OssConstrainedOpenType
{
public:
    Optype();
    Optype(const Optype &);
    ~Optype();
    Optype & operator = (const Optype &);
    int operator == (const Optype &) const;
    int operator != (const Optype &) const;
    int set_decoded(PDU &);
    int grab_decoded(PDU &);
    int set_encoded(const EncodedBuffer &);
    int grab_encoded(EncodedBuffer &);
    int encode(OssControl &);

    A *get_A();
    const A *get_A() const;
    void set_A(const A &);
    A *release_A();
    void set_A(A *);

    B *get_B();
    const B *get_B() const;
    void set_B(const B &);
    B *release_B();
    void set_B(B *);
private:
    void cleanup_decoded();
    int check_type(int);
};

Remarks

Open types in ASN.1: 2021 are equivalent to the ANY and ANY DEFINED BY types in ASN.1: 1990.

Unlike other types in this section, you cannot generate an open type with a reserved ASN.1 identifier. Instead, an open type results when information object notation is written so that the intended type for a field is unclear.

OssOpen objects are also generated for elements of CHOICE, SEQUENCE, and SET types that have the ASN1.DeferDecoding or OSS.ENCODABLE directive applied.

See Also

↩Examples Index

Parameterized Types

Parameterized types are represented in the same way as types obtained after parameter substitution.

ASN.1 C++
Module DEFINITIONS ::= BEGIN
   DesiredType ::= INTEGER
   Record {TypeForSubstitution} ::= SET{
      myTypeVar    TypeForSubstitution,
      filled       BOOLEAN
   }

   MyRec ::= Record {DesiredType}
END
typedef OSS_INT32 DesiredType;

class OSS_PUBLIC __shared1   /* SET */
{
public:
      . . .
    typedef OSS_INT32 myTypeVar;
    typedef ossBoolean filled;
      . . .
};

typedef __shared1 Record;

typedef __shared1 MyRec;

↩Examples Index

REAL

This type is represented by the C++ double type.

ASN.1 C++
DefaultReal           ::= REAL
typedef double DefaultReal;

Effect of OSS.DECIMAL

When the OSS.DECIMAL directive is specified, a REAL type is represented by the ASN.1/C++ OssDecimal class.

ASN.1 C++
MyDecimalReal         ::= REAL --<DECIMAL>--
typedef OssDecimal MyDecimalReal;

Effect of Inner Subtyping

When the base component of a REAL type is constrained to 10, it is represented by the ASN.1/C++ OssDecimal class.

ASN.1 C++
MyDecimalReal  ::= REAL (WITH COMPONENTS { ..., base (10)})
typedef OssDecimal MyDecimalReal;

↩Examples Index

RELATIVE-OID

This type is represented by the ASN.1/C++ OssRelOID class.

ASN.1 C++
DefaultROID ::= RELATIVE-OID
typedef OssRelOID DefaultROID;

A relative object identifier identifies an object by its position relative to a known object identifier. So, the RELATIVE-OID type can be used to save bandwidth by transmitting just the trailing component(s) of an object identifier value, rather than the entire value. In the following simple example, relativeDept can be transmitted alone, provided the sender and receiver are both aware that engineering(4) is an offshoot (branch) of {iso member-body country(29) universities(56) universityOfNokalva(32)}.

ASN.1
DefaultROID ::= RELATIVE-OID

myUniversity OBJECT IDENTIFIER ::= {iso member-body country(29) universities(56) universityOfNokalva(32)}

relativeDept DefaultROID ::= {engineering(4) digitalSignalProcessing(3)}

dspDept OBJECT IDENTIFIER ::= { myUniversity relativeDept }

↩Examples Index

RELATIVE-OID-IRI

This type is represented by the ASN.1/C++ OssString class.

ASN.1 C++
DefaultRelOidIri      ::= RELATIVE-OID-IRI
typedef OssString DefaultRelOidIri;

↩Examples Index

GeneralString | GraphicString | ObjectDescriptor | IA5String | ISO646String | NumericString | PrintableString | TeletexString | T61String | VideotexString | VisibleString

These restricted character string types are represented by the ASN.1/C++ OssString class.

ASN.1 C++
Name1 ::= VisibleString
typedef OssString Name1;

Remarks

The BMPString, GeneralizedTime, UniversalString, UTCTime, and UTF8String ASN.1 types are represented differently from those listed above and are described elsewhere in this section:

↩Examples Index

Selection Type

A selection type is represented in C++ by the type that is selected. In the example below, the selection type of "name < Info1" has the same representation as VisibleString (OssString).

ASN.1 C++
Info1 ::= CHOICE
       {name   VisibleString,
        age    INTEGER}

Info2 ::= SEQUENCE
       {birthdate INTEGER,
        name < Info1}
class OSS_PUBLIC Info1  : public OssChoice  /* CHOICE */
{
public:
    enum Id {
    unselected,
    name_chosen = 1,
    age_chosen = 2
    };
    typedef OssString name;
    typedef OSS_INT32 age;
    . . .
};

class OSS_PUBLIC Info2   /* SEQUENCE */
{
public:
    . . .
    typedef OSS_INT32 birthdate;
    typedef OssString name;
    . . .
};

↩Examples Index

SEQUENCE | SET

A SEQUENCE or SET type is represented by a compiler-generated class that has the accessors and mutators needed to get and set its components. This class has one non-const accessor, one const accessor, and one mutator for each SEQUENCE or SET component. The compiler produces identical classes for SEQUENCE and SET.

ASN.1 C++
NamesOfOfficers ::= SEQUENCE {
president           VisibleString,
vicePresident       VisibleString,
secretary           VisibleString,
                    VisibleString}
class OSS_PUBLIC NamesOfOfficers   /* SEQUENCE */
{
public:
  void * operator new(size_t size);
  void operator delete(void *ptr);

  typedef OssString president;
  typedef OssString vicePresident;
  typedef OssString secretary;
  typedef OssString visibleString;

  NamesOfOfficers();
  NamesOfOfficers(const NamesOfOfficers &);
  NamesOfOfficers(const president &,
                  const vicePresident &,
                  const secretary &,
                  const visibleString &);

  NamesOfOfficers & operator = (const NamesOfOfficers &);
  int operator == (const NamesOfOfficers &) const;
  int operator != (const NamesOfOfficers &) const;

  president & get_president();
  const president & get_president() const;
  void set_president(const president &);

  vicePresident & get_vicePresident();
  const vicePresident & get_vicePresident() const;
  void set_vicePresident(const vicePresident &);

  secretary & get_secretary();
  const secretary & get_secretary() const;
  void set_secretary(const secretary &);

  visibleString & get_visibleString();
  const visibleString & get_visibleString() const;
  void set_visibleString(const visibleString &);
private:
  president president_field;
  vicePresident vicePresident_field;
  secretary secretary_field;
  visibleString visibleString_field;
};

Effect of OPTIONAL and DEFAULT in a SEQUENCE

Two additional methods are generated for each OPTIONAL component: one marks the component as absent and the other checks for its presence.

Two additional methods are generated for each DEFAULT component: one sets the component to the default and the other checks the component for the default value. Also, a static constant reference member and a static method are generated to access the component's default value.

ASN.1 C++
NamesOfOfficers2 ::= SEQUENCE {
president         VisibleString OPTIONAL,
vicePresident [1] VisibleString,
treasurer     [2] VisibleString OPTIONAL,
secretary         VisibleString DEFAULT
                          "No secretary"}
class OSS_PUBLIC NamesOfOfficers2   /* SEQUENCE */
{
public:
   void * operator new(size_t size);
   void operator delete(void *ptr);

   typedef OssString president;
   typedef OssString vicePresident;
   typedef OssString treasurer;
   typedef OssString secretary;

   static const secretary & default_secretary;

   static const secretary& get_default_secretary();

   NamesOfOfficers2();
   NamesOfOfficers2(const NamesOfOfficers2 &);
   NamesOfOfficers2(const president &,
        const vicePresident &,
        const treasurer &, 
        const secretary &);
    NamesOfOfficers2(const vicePresident &);
    ~NamesOfOfficers2();

    NamesOfOfficers2 & operator = (const NamesOfOfficers2 &);
    int operator == (const NamesOfOfficers2 &) const;
    int operator != (const NamesOfOfficers2 &) const;

    president *get_president();
    const president *get_president() const;
    void set_president(const president &);
    int president_is_present() const;
    void omit_president();

    vicePresident & get_vicePresident();
    const vicePresident & get_vicePresident() const;
    void set_vicePresident(const vicePresident &);

    treasurer *get_treasurer();
    const treasurer *get_treasurer() const;
    void set_treasurer(const treasurer &);
    int treasurer_is_present() const;
    void omit_treasurer();

    secretary *get_secretary();
    const secretary *get_secretary() const;
    void set_secretary(const secretary &);
    int secretary_is_default() const;
    void set_default_secretary();
private:
    OSS_UINT32 bit_mask;
    president president_field;
    vicePresident vicePresident_field;
    treasurer treasurer_field;
    secretary secretary_field;
};

Effect of COMPONENTS OF in a SEQUENCE

The generated code is the same as if the elements of the referenced SEQUENCE were copied inline. For example, the following C++ representation is identical to that of the first example in this section.

ASN.1 C++
NamesOfOfficers ::= SEQUENCE {
    president      VisibleString,
    vicePresident   VisibleString,
    COMPONENTS OF MoreOfficers}

MoreOfficers ::= [1] SEQUENCE {
    secretary     VisibleString,
    VisibleString}
class OSS_PUBLIC NamesOfOfficers   /* SEQUENCE */
{
public:
  void * operator new(size_t size);
  void operator delete(void *ptr);

  typedef OssString president;
  typedef OssString vicePresident;
  typedef OssString secretary;
  typedef OssString visibleString;

  NamesOfOfficers();
  NamesOfOfficers(const NamesOfOfficers &);
  NamesOfOfficers(const president &,
                  const vicePresident &,
                  const secretary &,
                  const visibleString &);

  NamesOfOfficers & operator = (const NamesOfOfficers &);
  int operator == (const NamesOfOfficers &) const;
  int operator != (const NamesOfOfficers &) const;

  president & get_president();
  const president & get_president() const;
  void set_president(const president &);

  vicePresident & get_vicePresident();
  const vicePresident & get_vicePresident() const;
  void set_vicePresident(const vicePresident &);

  secretary & get_secretary();
  const secretary & get_secretary() const;
  void set_secretary(const secretary &);

  visibleString & get_visibleString();
  const visibleString & get_visibleString() const;
  void set_visibleString(const visibleString &);
private:
  president president_field;
  vicePresident vicePresident_field;
  secretary secretary_field;
  visibleString visibleString_field;
};

Effect of OSS.POINTER on a SEQUENCE or SET Component

Another pair of ownership-transferring accessor/mutator methods is generated when the OSS.POINTER directive is applied to a SEQUENCE or SET component. These methods can be used to avoid unnecessary data copying in the application.

ASN.1 C++
NamesOfOfficers4 ::= SEQUENCE {
    president      VisibleString --<POINTER>--,
    vicePresident  VisibleString --<POINTER>--,
    secretary      VisibleString, VisibleString}
class OSS_PUBLIC NamesOfOfficers4   /* SEQUENCE */ 
{
public:
  void * operator new(size_t size);
  void operator delete(void *ptr);

  typedef OssString president;
  typedef OssString vicePresident;
  typedef OssString secretary;
  typedef OssString visibleString;

  NamesOfOfficers4();
  NamesOfOfficers4(const NamesOfOfficers4 &);
  NamesOfOfficers4(const president &,
    const vicePresident &, const secretary &,
    const visibleString &);
  NamesOfOfficers4(president *, vicePresident *,
    const secretary &, const visibleString &);
  ~NamesOfOfficers4();

  NamesOfOfficers4 & operator =
                        (const NamesOfOfficers4 &);
  int operator == (const NamesOfOfficers4 &) const;
  int operator != (const NamesOfOfficers4 &) const;

  president & get_president();
  const president & get_president() const;
  void set_president(const president &);
  void set_president(president *);
  president *release_president();

  vicePresident & get_vicePresident();
  const vicePresident & get_vicePresident() const;
  void set_vicePresident(const vicePresident &);
  void set_vicePresident(vicePresident *);
  vicePresident *release_vicePresident();

  secretary & get_secretary();
  const secretary & get_secretary() const;
  void set_secretary(const secretary &);

  visibleString & get_visibleString();
  const visibleString & get_visibleString() const;
  void set_visibleString(const visibleString &);
private:
  president *president_field;
  vicePresident *vicePresident_field;
  secretary secretary_field;
  visibleString visibleString_field;
};

See Also

↩Examples Index

SEQUENCE OF | SET OF

A SEQUENCE OF or SET OF type is represented by a compiler-generated class derived from the ASN.1/C++ OssList class. This class has the accessors and mutators needed to get and set its components. The compiler produces identical classes for SEQUENCE OF and SET OF.

ASN.1 C++
SeqOfInt   ::= SEQUENCE OF INTEGER
class OSS_PUBLIC SeqOfInt : public OssList  /* SEQUENCE OF */
{
public:
    typedef OSS_INT32 component;

    SeqOfInt();
    SeqOfInt(const SeqOfInt &);
    ~SeqOfInt();

    SeqOfInt & operator = (const SeqOfInt &);
    int operator == (const SeqOfInt &) const;
    int operator != (const SeqOfInt &) const;

    component *at(OssIndex);
    const component *at(OssIndex) const;

    OssIndex prepend(component );
    OssIndex prepend(SeqOfInt *);
    OssIndex insert_after(OssIndex, component );
    OssIndex insert_after(OssIndex, SeqOfInt *);

    int remove_front();
    int remove_after(OssIndex);

    SeqOfInt *extract_after(OssIndex, OssIndex);
};

Effect of OSS.POINTER on a SEQUENCE OF or SET OF Component

When the OSS.POINTER directive is applied to a SEQUENCE OF or SET OF component, additional methods are generated to access or change the component without excessive copying.

ASN.1 C++
SeqOfStr  ::= SEQUENCE  OF IA5String  --<POINTER>--
class OSS_PUBLIC SeqOfStr : public OssList
                                 /* SEQUENCE OF */
{
public:
    typedef OssString component;

    SeqOfStr();
    SeqOfStr(const SeqOfStr &);
    ~SeqOfStr();

    SeqOfStr & operator = (const SeqOfStr &);
    int operator == (const SeqOfStr &) const;
    int operator != (const SeqOfStr &) const;

    component *at(OssIndex);
    const component *at(OssIndex) const;
    int replace(OssIndex, component *);

    OssIndex prepend(const component & );
    OssIndex prepend(component *);
    OssIndex prepend(SeqOfStr *);
    OssIndex insert_after
                  (OssIndex, const component & );
    OssIndex insert_after(OssIndex, component *);
    OssIndex insert_after(OssIndex, SeqOfStr *);

    int remove_front();
    int remove_after(OssIndex);

    component *extract_front();
    component *extract_after(OssIndex);
    SeqOfStr *extract_after(OssIndex, OssIndex);
};

Nested SEQUENCE OF Types

In the example below, _seqof1 is an automatically generated name for the Street-addresses component. Do not reference _seqof1 as explained in Names. Instead, reference this class as Street_addresses::component.

ASN.1 C++
Street-addresses ::= SEQUENCE OF SEQUENCE OF
         VisibleString (SIZE (1..64))
class OSS_PUBLIC __seqof1;

class OSS_PUBLIC Street_addresses : public OssList
                                    /* SEQUENCE OF */
{
public:
    typedef __seqof1 component;

    Street_addresses();
    Street_addresses(const Street_addresses &);
    ~Street_addresses();

    Street_addresses & operator = 
                    (const Street_addresses &);
    int operator == (const Street_addresses &) const;
    int operator != (const Street_addresses &) const;

    component *at(OssIndex);
    const component *at(OssIndex) const;

    OssIndex prepend(const component & );
    OssIndex prepend(Street_addresses *);
    OssIndex insert_after(OssIndex, const component & );
    OssIndex insert_after(OssIndex, Street_addresses *);

    int remove_front();
    int remove_after(OssIndex);

    Street_addresses *extract_after(OssIndex, OssIndex);
};

class OSS_PUBLIC __seqof1 : public OssList
                                      /* SEQUENCE OF */
{
public:
    typedef OssString component;

    __seqof1();
    __seqof1(const __seqof1 &);
    ~__seqof1();

    __seqof1 & operator = (const __seqof1 &);
    int operator == (const __seqof1 &) const;
    int operator != (const __seqof1 &) const;

    component *at(OssIndex);
    const component *at(OssIndex) const;

    OssIndex prepend(const component & );
    OssIndex prepend(__seqof1 *);
    OssIndex insert_after(OssIndex, const component & );
    OssIndex insert_after(OssIndex, __seqof1 *);

    int remove_front();
    int remove_after(OssIndex);

    __seqof1 *extract_after(OssIndex, OssIndex);
};

See Also

↩Examples Index

TIME | DATE | DATE-TIME | DURATION | TIME-OF-DAY

The ASN.1 TIME type is represented by the OssTime class.
DATE, DATE-TIME, DURATION, and TIME-OF-DAY are retagged, constrained ASN.1 TIME types, also represented by the OssTime class.

ASN.1 C++
MyTime      ::= TIME

MyDate      ::= DATE

MyDateTime  ::= DATE-TIME

MyDuration  ::= DURATION

MyTimeOfDay ::= TIME-OF-DAY
typedef OssTime MyTime;

typedef OssTime MyDate;

typedef OssTime MyDateTime;

typedef OssTime MyDuration;

typedef OssTime MyTimeOfDay;

↩Examples Index

UniversalString

This type is represented by the OssUniversalString class.

ASN.1 C++
MyString ::= UniversalString
typedef OssUniversalString MyString;

↩Examples Index

UTCTime

This type is represented by the ASN.1/C++ OssUTCTime class.

ASN.1 C++
Name1     ::= UTCTime
typedef OssUTCTime Name1;

↩Examples Index

UTF8String

This type is represented by the C++ OssString class by default. String values in this class are in UTF-8 form.

ASN.1 C++
MyString ::= UTF8String
typedef OssString MyString;

Effect of OSS.BMPSTRING

When the OSS.BMPSTRING directive is specified, a UTF8String value is represented by the OssBMPString class in UTF-16 form (16-bit characters).

ASN.1 C++
MyString ::= UTF8String --<BMPSTRING>--
typedef OssBMPString MyString;

Effect of OSS.UNIVERSALSTRING

When the OSS.UNIVERSALSTRING directive is specified, a UTF8String value is represented by the OssUniversalString class in UCS-4 (UTF-32) form (32-bit characters).

ASN.1 C++
MyString ::= UTF8String --<UNIVERSALSTRING>--
typedef OssUniversalString MyString;

Effect of the -compat Flag

When the -compat UTF8StringasBMPString compiler option or any equivalent compatibility option is specified in the compiler command line, the UTF8String type is represented by the ASN.1/C++ OssBMPString class by default.

↩Examples Index


This documentation applies to release 7.3 and later of the OSS® ASN.1 Tools for C++.

Copyright © 2024 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.