Procedure for Using the C++ Control Class Encode Method

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

  1. Instantiate an ASN.1 OER encode buffer object (ASN1OEREncodeBuffer) to describe the buffer into which the message will be encoded. Two overloaded constructors are available. The first form takes as arguments a static encode buffer and size. The second form has no arguments. This form is used to specify dynamic encoding.

  2. If the code is generated using the -coer switch, the encoding will be canonical without the user needing to take any additional steps. But if the code is generated using the -oer switch, in order to make the encoding canonical, the user must set the ASN1CANON flag in the context using the rtxCtxtSetFlag function.

  3. Instantiate an ASN1T_<ProdName> object and populate it with data to be encoded.

  4. Instantiate an ASN1C_<ProdName> object to associate the message buffer with the data to be encoded.

  5. Invoke the ASN1C_<ProdName> object Encode method.

  6. Check the return status. The return value is a status value indicating whether encoding was successful or not. Zero indicates success. If encoding failed, the status value will be a negative number. The encode buffer method printErrorInfo can be invoked to get a textual explanation and stack trace of where the error occurred.

  7. If encoding was successful, get the start-of-message pointer and message length. The start-of-message pointer is obtained by calling the getMsgPtr method of the encode buffer object. If static encoding was specified (i.e., a message buffer address and size were specified to the OER Encode Buffer class constructor), the start-of-message pointer is the buffer start address. The message length is obtained by calling the getMsgLen method of the encode buffer object.

A program fragment that could be used to encode an employee record is as follows:

   #include employee.h       // include file generated by ASN1C
               
   main ()
   {
      const OSOCTET* msgptr;
      OSOCTET msgbuf[1024];
      int msglen, stat;
               
      // step 1: instantiate an instance of the OER encode
      // buffer class. This example specifies a static
      // message buffer..
               
      ASN1OEREncodeBuffer encodeBuffer (msgbuf, sizeof(msgbuf));
      
      // Specify canonical encoding if desired.
      OSCTXT* pctxt = encodeBuffer.getCtxtPtr();
      rtxCtxtSetFlag(pctxt, ASN1CANON);
               
      // step 2: populate msgData with data to be encoded
               
      ASN1T_PersonnelRecord msgData;
      msgData.name.givenName = "SMITH";
      ...
               
      // step 3: instantiate an instance of the ASN1C_<ProdName>
      // class to associate the encode buffer and message data..
               
      ASN1C_PersonnelRecord employee (encodeBuffer, msgData);
               
      // steps 4 and 5: encode and check return status
               
      if ((stat = employee.Encode ()) == 0)
      {
         printf ("Encoding was successful\n");
         printf ("Hex dump of encoded record:\n");
         encodeBuffer.hexDump ();
               
         // step 6: get start-of-message pointer and message length.
         // start-of-message pointer is start of msgbuf
         // call getMsgLen to get message length..
               
         msgptr = encodeBuffer.getMsgPtr (); // will return &msgbuf
         len = encodeBuffer.getMsgLen ();
      }
      else
      {
         printf ("Encoding failed\n");
         encodeBuffer.printErrorInfo ();
         exit (0);
      }
               
      // msgptr and len now describe fully encoded message
               
      ...

In general, static buffers should be used for encoding messages where possible as they offer a substantial performance benefit over dynamic buffer allocation. The problem with static buffers, however, is that you are required to estimate in advance the approximate size of the messages you will be encoding. There is no built-in formula to do this, the size of an ASN.1 message can vary widely based on data types and other factors.

If performance is not a significant issue, then dynamic buffer allocation is a good alternative. Using the form of the ASN1OEREncodeBuffer constructor that does not include buffer address and size arguments specifies dynamic buffer allocation.