Generated Streaming C++ Encode Method Format and Calling Parameters

C++ code generation of stream-based encoders is selected by using the –c++ and –stream compiler command line options. In this case, ASN1C generates an EncodeTo method that wraps the C function call. This method provides a more simplified calling interface because it hides things such as the context structure and tag type parameters.

The calling sequence for the generated C++ class method is as follows:

   stat = <object>.EncodeTo (<outputStream>);

In this definition, <object> is an instance of the control class (i.e., ASN1C_<prodName>) generated for the given production.

The <outputStream> placeholder represents an output stream object type. This is an object derived from an ASN1EncodeStream class.

The function result variable stat returns the completion status. Error status codes are negative. Return status values are defined in the rtxErrCodes.h include file.

Another way to encode a message using the C++ classes is to use the << streaming operator:

   <outputStream> << <object>;

Exceptions are not used in ASN1C C++, therefore, the user must fetch the status value following a call such as this in order to determine if it was successful. The getStatus method in the ASN1EncodeStream class is used for this purpose.

Also, the method Encode without parameters is supported for backward compatibility. In this case it is necessary to create control class (i.e., ASN1C_<prodName>) using an output stream reference as the first parameter and msgdata reference as the second parameter of the constructor.

Procedure for Using the Streaming C++ Control Class Encode Method

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

  1. Create an OSRTOutputStream object for the type of output stream. Choices are OSRTFileOutputStream for a file, OSRTMemoryOutputStream for a memory buffer, or OSRTSocketOutputStream for an IP socket connection.

  2. Create an ASN1BEREncodeStream object using the stream object created in 1) as an argument.

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

  4. Create a variable of the generated ASN1C_<name> class specifying the item created in 2 as an argument to the constructor.

  5. Invoke the EncodeTo method or << operator.

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

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

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

      // step 1: construct output stream object.

      ASN1BEREncodeStream out (new OSRTFileOutputStream (filename));
      if (out.getStatus () != 0) {
         out.printErrorInfo ();
         return -1;
      }

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

      ASN1T_PersonnelRecord msgData;
      ASN1C_PersonnelRecord employee (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 << operator or EncodeTo method

      out << employee;
      // or employee.EncodeTo (out); can be used here.

      // step 5: check status of the operation

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

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

Encoding a Series of Messages Using the Streaming C++ Control Class Interface

Encoding a series of messages using the streaming C++ control class is similar to the C method of encoding. All that is necessary is to create a loop in which EncodeTo or Encode methods will be called (or the overloaded << streaming operator). It is also possible to call different EncodeTo methods (or Encode or operator <<) one after another. An example showing how to do this is as follows:

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

   int main ()
   {
      const   OSOCTET* msgptr;
      OSOCTET msgbuf[1024];
      int     msglen;
      const   char* filename = “message.dat”

      // step 1: construct stream object.

      ASN1BEREncodeStream out (new OSRTFileOutputStream (filename));
      if (out.getStatus () != 0) {
         out.printErrorInfo ();
         return -1;
      }

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

      ASN1T_PersonnelRecord msgData;
      ASN1C_PersonnelRecord employee (msgData);

      for (;;) {
         // 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 << operator or EncodeTo method

         out << employee;
         // or employee.EncodeTo (out); can be used here.

         // step 5: fetch and check status

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

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