How do I decode multiple concatenated PDUs when using the default plain memory manager?

This section outlines the steps necessary to decode multiple concatenated PDUs contained in memory using the default plain memory manager. The steps involved when using the file and socket memory managers differ from what is outlined below. You can find a complete example in the answer to: If I have BER/DER DEFINITE-length concatenated unique encoded PDUs in a file, how can I use the OSS ASN.1 tools to test their validity?

The decoder is designed to handle one PDU at a time. If an input buffer contains multiple concatenated PDUs, it will have to be fed to the decoder multiple times. Generally speaking, the decoder expects that the input buffer pointer is set at the beginning of the PDU it is to decode. Thus, the input buffer pointer has to be advanced to the next PDU after each decode. In this respect, there are two methods for decoding concatenated PDUs from an input buffer:

  • Manually advance input buffer pointer after each PDU decode
  • Allow decoder to automatically advance input buffer pointer

If you are developing new code to decode multiple concatenated PDUs with version 5.0.0 or later of the OSS ASN.1 Tools, OSS recommends that you use the first option. If you developed application code with a version prior to 5.0.0 of the OSS ASN.1 Tools that relies on the decoder automatically updating the input buffer, you are probably better off using the second option.

To manually advance the input buffer pointer after the decoder returns successfully, you should call the ossGetBytesReadByDecoder() function to obtain the number of bytes read by the decoder from the input buffer. You should then modify the length and value fields of the OssBuf input variable accordingly. You should subtract the returned number of bytes from the length field and advance the value pointer by the number of bytes returned. Then, you can call the decoder again with the modified instance of OssBuf. This process can be repeated multiple times.

You can then process multiple concatenated PDUs by doing the following (this example assumes all messages have the same PDU number):

while (encodedData.length > 0) {
   DecodedDataPtr = NULL;
   if (ossDecode(world, &myPduNum,
            &encodedData, (void**)&DecodedDataPtr)) {
      ossPrint(world, "Decoder Error: %s\n", 
               ossGetErrMsg(world));
      break;
   }
   processDecodedData(DecodedDataPtr);
   ossFreePDU(world, myPduNum, DecodedDataPtr);
   bytesRead = ossGetBytesReadByDecoder(world);
   encodedData.length -= bytesRead;
   encodedData.value += bytesRead;
}

To allow the decoder to automatically advance the input buffer pointer when you are using version 5.0.0 or later of the OSS ASN.1 compiler, you must compile your ASN.1 syntax with the following option to enable the automatic advancing of the decoder input buffer pointer:

-compat encoderUpdatesInputAddress

If you are using a version of the compiler lower than 5.0.0, you need not worry about this -compat option since the decoder by default advanced the input buffer pointer in prior versions.

Once you are sure that your ASN.1 syntax was compiled with decoder input address updating enabled, you may assume the following about the input OssBuf variable:

  • After ossDecode() returns successfully, the value field of the instance of OssBuf will reference the byte that immediately follows the last decoded byte.
  • After ossDecode() returns successfully, the length field will hold the number of bytes left to be decoded in the input buffer.

You can then process multiple concatenated PDUs by doing the following (this example assumes all messages have the same PDU number):

while (encodedData.length > 0) {
   DecodedDataPtr=NULL;
   if (ossDecode(world, &myPduNum,
        &encodedData, (void**)&DecodedDataPtr)) {
  ossPrint(world, "Decoder Error: %s\n", 
     ossGetErrMsg(world));
   break;
   }
   processDecodedData(DecodedDataPtr);
   ossFreePDU(world, myPduNum, DecodedDataPtr);
}

Note: The decoder updates the input buffer address only if the decode was successful. If an error occurs, it is your responsibility to call ossDetermineMessageLength() function to find out how long the message is and to increment ossBuf.value and decrement OssBuf.length using the returned value (if non-zero) before calling the decoder again. (Be sure to ensure that the returned value does not put your pointer beyond the end of the input buffer!). If the returned value is zero, there is a serious problem (such as the encoding being in the indefinite-length format, which means that the message length cannot be determined without decoding).


The samples included with some of the Knowledge Center answers are meant for your general understanding of the OSS products. Different versions of the products might produce slightly different outputs. Consult the products documentation and samples for the most up-to-date products information and code examples.



Contact Support
contact Our office hours
24 hours/day, 7 days/week

  • Phone: 1-888-OSS-2761 (USA and Canada)
  • Phone: 1-732-302-9669 (International)
  • Fax: 1-732-302-0023
  • Email: support@oss.com
Free Trial
download

Test drive the OSS Nokalva ASN.1, LTE, and XML Tools now! Your trial includes complete software, documentation, sample programs, free 24x7 technical support and more.




Learn ASN.1
Learn ASN.1

Our expert personnel can help you learn ASN.1!

We offer 4-day ASN.1 courses at our headquarters or your premises.