TOC PREV NEXT INDEX


Procedure for Calling C# XER Encode Methods



The C# class variables corresponding to each of the ASN.1 types and method of population are the same as they were in the BER encoding case. See the section Populating Generated Variables for Encoding for instructions on how to populate the variables prior to encoding.

Once an object's member variables have been populated, the object's encode method can be invoked to encode the value. The general procedure to do this involves the following three steps:

The first step is the creation of an encode message buffer object. For XER encoding, this is an object of the Asn1XerEncodeBuffer class. The following constructors are available for creating an XER encode buffer object:

	public Asn1XerEncodeBuffer ();
 

 
	public Asn1XerEncodeBuffer (bool canonical, int sizeIncrement);
 

The default constructor sets all internal buffer control variables to default values. Canonical XER is set to false and size increment is set to 1024. The other forms of the constructor allow these variables to be changed. Canonical XER specifies that the canonical form of XER encoding (CXER as specified in X.693) should be used. Size increment specifies the amount by which the dynamic encode buffer should be expanded when it fills up. This should be set lower for small, memory-constrained environments and higher if large messages are being encoded.

If the output stream method is used then the first step is the creation of an output stream. For XER encoding, this is an object of the Asn1XerOutputStream class. The following constructors are available for creating an XER encode buffer object:

public Asn1XerOutputStream (OutputStream os);
 

 
public Asn1XerOutputStream (OutputStream os, bool canonical, int 										 bufSize);
 

The first constructor creates a buffered XER output stream with default size of an internal buffer. Canonical XER is set to false. The other form of the constructor allows these variables to be changed. Canonical XER specifies that the canonical form of XER encoding (CXER as specified in X.693) should be used. The buffer size argument specifies the size of the internal buffer of the stream. Larger buffer sizes typically provide better performance at the expense of increased memory consumption.

The second step is the invocation of the encode methods. The calling arguments were described earlier. As per the C# standard, this method must be invoked from within a try/catch block to catch the possible Asn1Exception or System.Exception that may be thrown. Alternatively, the method from which the encode method is called can declare that it throws Asn1Exception and System.Exception leaving it to be dealt with at a higher level.

Finally, if a message buffer is used, encode buffer methods can be called to access the encoded message component. The C# API provides an object called a ByteArrayInputStream that provides a way to look at the encoded component as a stream. The encode buffer object provides a method called GetInputStream that returns a byte array input stream representing the message component. This is the preferred way to access the encoded component.

In addition to GetInputStream, there is a MsgCopy property that will retrieve a copy of the generated message into a byte array object. This is somewhat slower because a copy needs to be done. Another option that is available when doing XER encoding is the Buffer property. This returns a reference to the actual message buffer into which the message was encoded. Since an XER message is encoded front-to-back (unlike the back-to-front used in BER/DER encoding), the buffer reference returned will point to the start of the encoded message. The MsgLength property can then be used to get the message length (in bytes). Note that the byte count may not correspond to the actual character count as UTF-8 encoding is used and some characters may be multiple bytes in length.

If an output stream is used, the stream should be closed when encoding is complete to ensure all buffered data is flushed to the output device.

The Asn1XerEncodeBuffer encode buffer class also contains other methods for operating directly on the encoded component (for example, the write method can be used to write it to a file or other medium). A user could also derive their own special encode buffer class from this class to add more functionality. See the description of the Asn1XerEncodeBuffer class in the run-time section for a full description of the available methods.

A complete example showing how to invoke an XER encode method is as follows:



 
      // Note: personnelRecord object was previously populated with data
 

 
      // Step 1: Create a message buffer object.  This object uses 
 
      // standard XER (non-canonical) and the default size increment 
 
      // for buffer expansion..
 

 
      Asn1XerEncodeBuffer encodeBuffer = new Asn1XerEncodeBuffer();
 

 
      // Step 2: Invoke the encode methods.  These include 
 
      // encodeStartDocument to encode the XML document header, 
 
      // the generated C# encode method to encode the document body, 
 
      // and the encodeEndDocument method to complete the message. 
 
      // Note that these methods must be invoked from within a 
 
      // try/catch block..
 

 
      try {
 
         encodeBuffer.EncodeStartDocument ();
 

 
         personnelRecord.Encode (encodeBuffer, null);
 

 
         encodeBuffer.EncodeEndDocument ();
 

 
         if (trace) {
 
            System.Console.Out.WriteLine ("Encoding was successful");
 
            encodeBuffer.Write (System.Console.OpenStandardOutput());
 
         }
 

 
         // Step 3: Access the encoded message component.  In this 
 
         // case, we use methods in the class to write the encoded 
 
         // XML document to a file..
 

 
	   encodeBuffer.Write(new System.IO.FileStream(filename,
 
            System.IO.FileMode.Create));
 

 
          // We can also directly access the buffer as follows:
 

 
          byte[] buffer = encodeBuffer.Buffer;
 
          int msglen = encodeBuffer.MsgByteCnt;
 
      }
 
      catch (Exception e) {
 
         System.Console.Out.WriteLine (e.Message);
 
         Asn1Util.WriteStackTrace(e, Console.Error);          
 
         return;
 
      }
 

 

Figure 6 - XER Encoding Example

An example showing stream-based encoding is as follows:




 
      // Note: personnelRecord object was previously populated with data
 

 
      Asn1XerOutputSteram outs = null;
 

 
      try {
 

 
         // Step 1: Create an output stream object.  This object 
 
         // uses standard XER (non-canonical) and the default 
 
         // internal buffer's size.
 

 
         outs = new Asn1XerOutputStream(new System.IO.FileStream(
 
            filename, System.IO.FileMode.Create));
 

 
         // Step 2: Invoke the encode methods.  These include 
 
         // encodeStartDocument to encode the XML document header, 
 
         // the generated C# encode method to encode the document body, 
 
         // and the encodeEndDocument method to complete the message. 
 
         // Note that these methods must be invoked from within a 
 
         // try/catch block..
 

 
         outs.EncodeStartDocument ();
 

 
         personnelRecord.Encode (outs, null);
 

 
         outs.EncodeEndDocument ();
 

 
         if (trace) {
 
            System.Console.Out.WriteLine ("Encoding was successful");
 
            encodeBuffer.Write (System.Console.OpenStandardOutput());
 
         }
 

 
      }
 
      catch (Exception e) {
 
         System.Console.Out.WriteLine (e.Message);
 
         Asn1Util.WriteStackTrace(e, Console.Error);          
 
         return;
 
      }
 
      finally {
 
         // Step 3: Close the stream.
 

 
         try {
 
            if (outs != null) 
 
               outs.Close ();
 
          }
 
          catch (Exception e) {}
 
      }
 

 

Figure 7 - XER Stream-Oriented Encoding Example

If you compare these examples with the other encoding examples, you will see the procedures are similar. This makes it very easy to switch encoding methods should the need arise.

The resulting XML document from running the program above is as follows:


 
<?xml version="1.0" encoding="UTF-8"?>
 
<PersonnelRecord>
 
   <name>
 
      <givenName>John</givenName>
 
      <initial>P</initial>
 
      <familyName>Smith</familyName>
 
   </name>
 
   <number>51</number>
 
   <title>Director</title>
 
   <dateOfHire>19710917</dateOfHire>
 
   <nameOfSpouse>
 
      <givenName>Mary</givenName>
 
      <initial>T</initial>
 
      <familyName>Smith</familyName>
 
   </nameOfSpouse>
 
   <children>
 
      <ChildInformation>
 
         <name>
 
            <givenName>Ralph</givenName>
 
            <initial>T</initial>
 
            <familyName>Smith</familyName>
 
         </name>
 
         <dateOfBirth>19571111</dateOfBirth>
 
      </ChildInformation>
 
      <ChildInformation>
 
         <name>
 
            <givenName>Susan</givenName>
 
            <initial>B</initial>
 
            <familyName>Jones</familyName>
 
         </name>
 
         <dateOfBirth>19590717</dateOfBirth>
 
      </ChildInformation>
 
   </children>
 
</PersonnelRecord>
 


Figure 8 - Example of an Encoded XML Document


Objective Systems, Inc.

102 Pickering Way, Suite #506
Exton, 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
TOC PREV NEXT INDEX