Procedure for Calling C# PER Decode Methods

The general procedure to decode an ASN.1 PER message involves the following three steps:

  1. Create a decode message buffer object to describe the message to be decoded

  2. Invoke the decode method

  3. Process the decoded data values

The first step is the creation of a decode message buffer object. The Asn1PerDecodeBuffer object contains constructors that can either accept a message as a byte array or as an I/O input stream. The input stream option makes it possible to decode messages directly from other mediums other than a memory buffer (for example, a message can be decoded directly from a file or a socket).

Unlike BER or DER, no mechanism exists in PER to peek at an outer level tag or identifier to identify the message type. This type must be known beforehand. Most protocols that employ PER have a specific outer level type know as a “Protocol Data Unit” (PDU) that encompasses all of the different message types that might be received. This is typically a CHOICE construct with each option representing a different type of message.

The generated decode method for the PDU is invoked to decode the message. 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 exceptions that may be thrown. Alternatively, the method from which the decode method is called can declare that it throws the exceptions leaving them to be dealt with at a higher level.

The final step is to process the data. All data is contained within public member variables so access is quite easy. All of the primitive data type classes contain a public member variable called mValue that contains decoded data. This can be accessed in nested structures by prefixing mValue with each of the element names from the top down. For example, the givenName element in the Name type shown earlier would be accessed as follows: name.givenName.mValue (this assumes an instance of the Name class was created using the variable name “name”).

A complete example showing how to invoke a decode method is as follows:

   try {

      // Step 1: create a decode message buffer object to describe the
      // message to be decoded. This example will use a file input
      // stream to decode a message directly from a binary file..

      // Create an input file stream object

      System.IO.FileStream ins = new System.IO.FileStream(
         filename, System.IO.FileMode.Open, System.IO.FileAccess.Read);

      // Create a decode buffer object

      Asn1PerDecodeBuffer decodeBuffer = new Asn1PerDecodeBuffer (ins);

      // Step 2: create an object of the generated type and invoke the
      // decode method..

      PersonnelRecord personnelRecord = new PersonnelRecord ();
      personnelRecord.Decode (decodeBuffer);

      // Step 3: process the data

      if (trace) {
         System.Console.Out.WriteLine ("Decode was successful");
         personnelRecord.Print ("personnelRecord");
      }
   }
   catch (Exception e) {
      System.Console.Out.WriteLine (e.Message);
      Asn1Util.WriteStackTrace(e, Console.Error);
      return;
   }