
Procedure for Calling Stream-Oriented C Decode Functions
This section describes the step-by-step procedure for calling a stream-oriented C BER decode function. This procedure must be followed if C code generation was done. This procedure can also be used as an alternative to using the control class interface if C++ code generation was done.
Before any decode function can be called; the user must first initialize a context variable. This is a variable of type ASN1CTXT. This variable holds all of the working data used during the decoding of a message. The context variable is declared as a normal automatic variable within the top-level calling function. It must be initialized before use. This can be accomplished by using the rtInitContext function. Also, the context must be initialized for streaming operations by calling the rtStreamBufInit function:
ASN1CTXT ctxt; // context variable if (rtInitContext (&ctxt) != ASN_OK) { /* initialization failed, could be a license problem */ printf ("context initialization failed (check license)\n"); return -1; } rtStreamBufInit (&ctxt)); // Initialize streamThe next step is to create a stream object within the context. This object is an abstraction of the output device to which the data is to be encoded and is initialized by calling one of the following functions:
The flags parameter of these functions should be set to the OSRTSTRMF_INPUT constant value to indicate an input stream is being created (see the C/C++ Common Run-Time Library Reference Manual for a full description of these functions).
After initializing the context and populating a variable of the structure to be encoded, a decode function can be called to decode a message from the stream. If the return status indicates success, the C variable that was passed as an argument will contain the decoded message contents. Note that the decoder may have allocated dynamic memory and stored pointers to objects in the C structure. After processing on the C structure is complete, the run-time library function rtMemFree or the macro ASN1MEMFREE should be called to free the allocated memory.
After stream processing is complete, the stream is closed by invoking the rtStreamBufClose function.
#include employee.h /* include file generated by ASN1C */ main () { ASN1TAG msgtag; int msglen; ASN1CTXT ctxt; PersonnelRecord employee; const char* filename = "message.dat" /* Step 1: Initialize a context variable for decoding */ if (rtInitContext (&ctxt) != ASN_OK) { /* initialization failed, could be a license problem */ printf ("context initialization failed (check license)\n"); return -1; } rtStreamBufInit (&ctxt); /* Step 2: Open the input stream to read data */ stat = rtStreamFileOpen (&ctxt, filename, OSRTSTRMF_INPUT); if (stat != ASN_OK) { xu_perror (&ctxt); return stat; } /* Step 3: Test message tag for type of message received */ /* (note: this is optional, the decode function can be */ /* called directly if the type of message is known).. */ stat = rtStreamBufMark (&ctxt, 32); if (stat != ASN_OK) { xu_perror (&ctxt); return stat; } stat = berDecStrmTagAndLen (&ctxt, &msgtag, &msglen); if (stat != ASN_OK) { xu_perror (&ctxt); return stat; } if (msgtag == TV_PersonnelRecord) { stat = rtStreamBufReset (&ctxt); if (stat != ASN_OK) { xu_perror (&ctxt); return stat; } /* Step 4: Call decode function (note: last two args */ /* should always be ASN1EXPL and 0).. */ status = asn1BSD_PersonnelRecord (&ctxt, &employee, ASN1EXPL, 0); /* Step 5: Check return status */ if (status == ASN_OK) { process received data in `employee' variable.. } else error processing... } else check for other known message types.. /* Step 6: Close the stream */ rtStreamBufClose (&ctxt); /* Remember to release dynamic memory when done! */ rtFreeContext (&ctxt); }
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 |