Procedure for Calling Java BER Encode Methods

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:

  1. Create an encode message buffer object into which the value will be encoded.

  2. Invoke the encode method.

  3. Invoke encode message buffer methods to access the encoded message component.

The first step is the creation of an encode message buffer object. Unlike the C/C++ version of the product, there is no choice to be made between a static or dynamic encode buffer. In Java, everything is dynamic. There are two forms of the constructor: a default constructor and one that allows specification of a message buffer size increment. The size increment will determine how often the buffer will need to be resized to hold large messages. If you know that you will be encoding large messages, then this object should be constructed with a large value for the increment. If you know that you will be encoding small messages in a constrained environment, then this value can be set very low. The default constructor sets the value to a reasonable mid-range value (see SIZE_INCREMENT in Asn1EncodeBuffer.java, as of this writing the value was set to 1024).

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

Finally, encode buffer methods can be called to access the encoded message component. The encode method itself returns the length of the component, so this item is already known (however, there is a getMsgLength method available if you want to access this length from a different location). Unlike C or C++, a pointer to where the message starts in the encode buffer cannot be returned (recall that BER encoding is done from back to front, so a message rarely starts at the beginning of a buffer). However, the Java API provides an object called a ByteArrayInputStream that provides a way to look at the encoded component as a stream. The encode buffer object therefore provides a method called getByteArrayInputStream which is the preferred way to access the encoded component.

In addition to getByteArrayInputStream there is a getMsgCopy function 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. The 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). And of course, one could derive their own special encode buffer class from this class to add more functionality. See the description of the Asn1BerEncodeBuffer class in the run-time section for a full description of the available methods.

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

   // Note: personnelRecord object was previously populated with data

   // Step 1: Create a message buffer object. This object uses the
   // default size increment for buffer expansion..

   Asn1BerEncodeBuffer encodeBuffer = new Asn1BerEncodeBuffer();

   // Step 2: Invoke the encode method. Note that it must be done
   // from within a try/catch block..

   try {
       personnelRecord.encode (encodeBuffer, true);

       if (trace) {
           System.out.println ("Encoding was successful");
           System.out.println ("Hex dump of encoded record:");
           encodeBuffer.hexDump ();
           System.out.println ("Binary dump:");
           encodeBuffer.binDump ();
       }

       // Step 3: Access the encoded message component. In this
       // case, we use methods in the class to write the component
       // to a file and output a formatted dump to the message.dmp
       // file..

       // Write the encoded record to a file

       encodeBuffer.write (new FileOutputStream (filename));

       // Generate a dump file for comparisons

       encodeBuffer.hexDump
          (new PrintStream (new FileOutputStream ("message.dmp")));
   }
   catch (Exception e) {
      System.out.println (e.getMessage());
      e.printStackTrace();
      return;
   }