Generated C++ Encode Method Format and Calling Parameters

When C++ code generation is specified, the ASN1C compiler generates an Encode method in the generated control class that wraps the C function call. This method provides a more simplified calling interface because it hides things such as the context structure and the tag type parameters.

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

   len = <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 len returns the length of the data actually encoded or an error status code if encoding fails. Error status codes are negative to tell them apart from length values. Return status values are defined in the asn1type.h include file.

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 ASN1BEREncodeBuffer object.

  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.

The constructor of the ASN1C_<type> class takes a message buffer object argument. This makes it possible to specify a static encode message buffer when the class variable is declared. A static buffer can improve encoding performance greatly as it relieves the internal software from having to repeatedly resize the buffer to hold the encoded message. If you know the general size of the messages you will be sending, or have a fixed size maximum message length, then a static buffer should be used. The message buffer argument can also be used to specify the start address and length of a received message to be decoded.

After the data to be encoded is set, the Encode method is called. This method returns the length of the encoded message or a negative value indicating that an error occurred. The error codes can be found in the asn1type.h run-time header file or in Appendix A of the C/C++ Common Functions Reference Manual.

If encoding is successful, a pointer to the encoded message can be obtained by using the getMsgPtr or getMsgCopy methods available in the ASN1BEREncodeBuffer class. The getMsgPtr method is faster as it simply returns a pointer to the actual start-of-message that is maintained within the message buffer object. The getMsgCopy method will return a copy of the message. Memory for this copy will be allocated using the standard new operator, so it is up to the user to free this memory using delete when finished with the copy.

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

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

   main ()
   {
      const OSOCTET* msgptr;
      OSOCTET msgbuf[1024];
      int msglen;

      // step 1: construct ASN1C C++ generated class.
      // this specifies a static encode message buffer

      ASN1BEREncodeBuffer encodeBuffer (msgbuf, sizeof(msgbuf));
      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 ((msglen = employee.Encode ()) > 0) {
         // encoding successful, get pointer to start of message
         msgptr = encodeBuffer.getMsgPtr();
      }
      else
         error processing...
   }

The following code fragment illustrates encoding using a dynamic buffer. This also illustrates using the getMsgCopy method to fetch a copy of the encoded message:

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

   main ()
   {
      OSOCTET*  msgptr;
      int       msglen;

      // construct encodeBuffer class with no arguments

      ASN1BEREncodeBuffer encodeBuffer;
      ASN1T_PersonnelRecord msgData;
      ASN1C_PersonnelRecord employee (encodeBuffer, msgData);

      // populate msgData structure

      msgData.name = "SMITH";
      ...

      // call Encode method

      if ((msglen = employee.Encode ()) > 0) {
         // encoding successful, get copy of message
         msgptr = encodeBuffer.getMsgCopy();
         ...

         delete [] msgptr; // free the dynamic memory!
      }
      else
         error processing...
   }

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

A common application of BER encoding is the repetitive encoding of a series of the same type of message over and over again. For example, a TAP3 batch application might read billing data out of a database table and encode each of the records for a batch transmission.

If a user was to repeatedly instantiate and destroy the C++ objects involved in the encoding of a message, performance would suffer. This is not necessary however, because the C++ objects can be reused to allow multiple messages to be encoded. As example showing how to do this is as follows:

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

   main ()
   {
      const OSOCTET* msgptr;
      OSOCTET msgbuf[1024];
      int       msglen;

      ASN1BEREncodeBuffer encodeBuffer (msgbuf, sizeof(msgbuf));
      ASN1T_PersonnelRecord msgData;
      ASN1C_PersonnelRecord employee (encodeBuffer, msgData);

      // Encode loop starts here, this will repeatedly use the
      // objects declared above to encode the messages

      for (;;) {

      // logic here to read record from some source (database,
      // flat file, socket, etc.)..

      // populate structure with data to sbe encoded

      msgData.name = “SMITH”;
      ...

      // invoke Encode method

      if ((msglen = employee.Encode ()) > 0) {

         // encoding successful, get pointer to start of message

         smsgptr = encodeBuffer.getMsgPtr();

         // do something with the encoded message

         ...
      }
      else
         error processing...

      // Call the init method on the encodeBuffer object to
      // prepare the buffer for encoding another message..

      encodeBuffer.init();
   }
}