
Decoding a Series of Messages Using the C++ Control Class Interface
The above example is fine as a sample for decoding a single message, but what happens in the more typical scenario of having a long-running loop that continuously decodes messages? The logic shown above would not be optimal from a performance standpoint because of the constant creation and destruction of the message processing objects. It would be much better to create all of the required objects outside of the loop and then reuse them to decode and process each message.
#include employee.h // include file generated by ASN1C main () { ASN1OCTET msgbuf[1024]; ASN1TAG msgtag; int msglen, status; // Create message buffer, ASN1T, and ASN1C objects ASN1BERDecodeBuffer decodeBuffer (msgbuf, len); ASN1T_PersonnelRecord employeeData; ASN1C_PersonnelRecord employee (decodeBuffer, employeeData); for (;;) {.. logic to read message into msgbuf .. status = decodeBuffer.ParseTagLen (msgtag, msglen); if (status != ASN_OK) { // handle error ... } // Now switch on initial tag value to determine what type of // message was received.. switch (msgtag) { case TV_PersonnelRecord: // compiler generated constant { if ((status = employee.Decode ()) == ASN_OK) { // decoding successful, data in employeeData process received data.. } else error processing... } break; default: // handle unknown message type here } // switch // Need to reinitialize objects for next iteration if (!isLastIteration) employee.memFreeAll (); } // end of loopThis is quite similar to the first example. Note that we have pulled the ASN1T_Employee and ASN1C_Employee object creation logic out of the switch statement and moved it above the loop. These objects can now be reused to process each received message.
The only other change was the call to employee.memFreeAll that was added at the bottom of the loop. Since we can't count on the objects being deleted to automatically release allocated memory, we need to do it manually. This call will free all memory held within the decoding context. This will allow the loop to start again with no outstanding memory allocations for the next pass.
If buffer already contains multiple BER messages encoded back-to-back then it is necessary to modify buffer's pointer in each iteration. decodeBuffer.getByteIndex () method should be used at the end of loop to get current offset in the buffer. This offset should be used for decodeBuffer.setBuffer method call at the beginning of the loop to determine correct buffer pointer and length:
ASN1UINT offset = 0; for (;offset < msglen;) {decodeBuffer.setBuffer (&msgbuf[offset], msglen - offset); int curlen = (int)(msglen - offset); status = decodeBuffer.ParseTagLen (msgtag, curlen); if (status != ASN_OK) { // handle error ... } // Now switch on initial tag value to determine what type of // message was received.. switch (msgtag) { case TV_PersonnelRecord: // compiler generated constant { if ((status = employee.Decode ()) == ASN_OK) { // decoding successful, data in employeeData process received data.. } else error processing... } break; default: // handle unknown message type here } // switch // get new offset offset += decodeBuffer.getByteIndex (); // Need to reinitialize objects for next iteration (if it is not // last iteration) if (offset < msglen) employee.memFreeAll (); } // end of loop
Objective Systems, Inc.102 Pickering Way, Suite #506Exton, Pennsylvania 19341 http://www.obj-sys.com Phone: (484) 875-9841 Toll-free: (877) 307-6855 (US only) Fax: (484) 875-9830 info@obj-sys.com |