Generated C++ Encode Method Format and Calling Parameters

When C++ code generation is specified, the ASN1C compiler generates a control class for PDU types. The control class wraps the C function, providing a simplified calling interface because it hides things such as the context structure.

Calling the generated C++ class encode method is done as follows:

   stat = <object>.Encode();

In this definition, <object> is an instance of the control class (i.e., ASN1C_<prodName>) generated for the given production. The function result variable stat returns 0 (success) or an error code. Error status codes are defined in rtsrc/asn1ErrCodes.h and rtxsrc/rtxErrCodes.h.

Procedure for Using the C++ Control Class Encode Method

The procedure to encode a message using the C++ class interface is as follows:

  1. Create a variable of the ASN1T_<name> type and populate it with the data to be encoded.

  2. Create an ASN1AVNEncodeBuffer object. ASN1AVNEncodeBuffer has constructors for encoding to a dynamic or static buffer and for encoding to a stream (any OSRTOutputStream subclass).

  3. Create a variable of the generated ASN1C_<name> class specifying the items created in 1 and 2 as arguments to the constructor.

  4. Invoke the Encode method.

After the data to be encoded is set, the Encode method is called. This method returns 0 (success) or an error code. Error status codes are defined in rtsrc/asn1ErrCodes.h and rtxsrc/rtxErrCodes.h and are listed in Appendix A of the C/C++ Common Functions Reference Manual.

After you successfully encode into a buffer, ASN1AVNEncodeBuffer methods GetMsgPtr() or GetMsgCopy can be used to access the encoded message. As the name implies, GetMsgCopy will return a copy of the message; memory is allocated using the standard new operator, so it is up to you to free this memory using delete. The buffer will not be null-terminated; use ASN1AVNEncodeBuffer.nullTerminate() to add a null terminator character if you want it.

When encoding to a buffer, after you have retrieved your encoded message, you may wish to reuse the same objects to encode a second message. This can be done by calling init() on the ASN1AVNEncodeBuffer

A program fragment that could be used to encode an employee record is as follows. This example uses a dynamic encode buffer:

   #include employee.h             // include file generated by ASN1C

   main ()
   {
      const char* filename = "message.txt";
     
      // step 1: construct ASN1C C++ generated class.
      // this specifies a dynamic encode message buffer

      ASN1AVNEncodeBuffer encodeBuffer (0, 0);
      ASN1T_PersonnelRecord msgData;
      ASN1C_PersonnelRecord employee (encodeBuffer, msgData);

      // step 2: populate msgData structure with data to be encoded

      msgData.name = “SMITH”;
      ...

      // step 3: invoke Encode method

      if (employee.Encode() == 0) {
         /* Encoding successful.  Null terminate the message so it can be
            treated as a C string. */
         encodeBuffer.nullTerminate();
         printf ("encoded AVN message:\n");
         printf ((const char*)encodeBuffer.getMsgPtr());         
         msgptr = encodeBuffer.getMsgPtr();
      }
      else
         error processing...
   }

To encode to a stream using the C++ control class, simply create the ASN1AVNEncodeBuffer object on a stream object. There are several OSRTOutputStream subclasses available. These include OSRTFileOutputStream, OSRTMemoryOutputStream, and OSRTSocketOutputStream.

Here is an illustration of encoding to a file stream:

   #include employee.h           // include file generated by ASN1C
   #include "rtxsrc/OSRTFileOutputStream.h"

   main ()
   {
      const char* filename = “message.dat”;
      int stat = 0;

      // step 1: construct output stream object.
      OSRTFileOutputStream ostream(filename);
      ASN1AVNEncodeBuffer encodeBuffer (ostream);
      
      if (encodeBuffer.getStatus () != 0) {
         encodeBuffer.printErrorInfo ();
         return -1;
      }

      // step 2: construct ASN1C C++ generated class.

      ASN1T_PersonnelRecord msgData;
      ASN1C_PersonnelRecord employee (encodeBuffer, msgData);

      // step 3: populate msgData structure with data to be
      // encoded. (note: this uses the generated assignment
      // operator to assign a string).

      msgData.name = “SMITH”;
      ...
      // step 4: invoke Encode method

      stat = employee.Encode(); 
      if ( stat != 0 )
      {
         printf ("Encoding failed. Status = %i\n", stat);
         encodeBuffer.printErrorInfo ();
         return -1;
      }

      if (trace) {
         printf ("Encoding was successful\n");
      }
   }