Up ] CPEntry ]

Reflection
Home News Listen Read Resources Feedback Contents Search RSS, Contacts

 

 

 

Sponsor Links

Fast, reliable data access for ODBC, JDBC, ADO.NET and XML
Need an expert for Java, XML and Web Services projects?
WSSC 2008: The only event dedicated to Web Services Security technology and business
IBM MQSeries for Compaq NSK - ( v. 5.1 ) - media
88x31 CTIX Logo - Clear Background
Microsoft SQL Server 2005 Standard Edition X64 - complete package
Corel DESIGNER Technical Suite - ( v. 12 ) - complete package
Find XML examples at XML Pitstop

 

Madhu's Workshop

Reflecting on Binary Files

XML
BCEL
XML Spy

Compiler
ANTLR

Java
VM

Tools
Apache
Eclipse

Logo for grid computing portal: GridSummit.com
Logo for database portal logo: SQLSummit.com

<< Previous 1 2 3 4 5

Of course, we need to describe the structure, or specify the grammar for the Java class file in some language. Some might be tempted to use XML for this purpose. That's not an appealing idea. There's a lot of interest in domain-specific XML files, which is great if your audience is a non-developer or you plan to write a graphical tool to edit the XML. This is not the case here. More importantly, we would have to write code to read the XML grammar and turn it into an object model and do something with that. If we used XML to specify the grammar, we would be defining a language and building a parser to parse the grammar in order to build a parser to parse class files. It seems like too much work for me.

This sounds like a chicken and egg problem. We need a language and a parser for that language. The usual solution is to either bootstrap a parser by hand coding a simpler version, or use an existing parser and leverage someone else's hard work. Fortunately, there's a free, high quality parser that we are all familiar with: javac.

javac is the Java compiler which accepts the Java language as source code and emits binary class files as output. Now you're thinking we are back to where started. Not exactly. Instead of hand coding every low-level read, we could use a class model to drive the parse. In essence, the class model is the grammar. This approach has a couple of advantages:

  • We specify the grammar using a familiar language (Java)
  • There's a variety of developer tools for editing Java.

The Eclipse project offers an excellent graphical tool exists for editing Java language source code. Because Eclipse does a great job of validating the syntax and semantics of Java, development time is reduced. We could do something similar with XML schema and XML Spy, but that's more work.

How do we extract information from a class model? Simple: use the Java Reflection API. With reflection, we can get all of the information we need. Here's a simple example. Suppose we wanted to read the first few primitives from a class file. We could define an array of Class objects representing the data like this

Class[] header = {
    Integer.TYPE,    // magic
    Short.TYPE,      // minor_version
    Short.TYPE       // major_version
};

You will notice that the data in the class file is unsigned and the Java types are signed, but that's not a big deal, no bits are lost. We can deal with signs later. Here's a snippet of code that reads binary data from a stream given the array above as an argument:

Object parse(Class[] classes) {
    Object[] array = new Object[classes.length];
    for (int i=0; i<classes.length; i+=1) {
        Class clazz = classes[i];
        if (clazz == Byte.TYPE) {
            array[i] = new Byte((byte) readBytes(1));
        } else if (clazz == Short.TYPE) {
            array[i] = new Short((short) readBytes(2));
        } else if (clazz == Integer.TYPE) {
            array[i] = new Integer((int) readBytes(4));
        } else if (clazz == Long.TYPE) {
            array[i] = new Long(readBytes(8));
        } else if (clazz == Float.TYPE) {
            array[i] = new Float(Float.intBitsToFloat((int) readBytes(4)));
        } else if (clazz == Double.TYPE) {
            array[i] = new Double(Double.longBitsToDouble(readBytes(8)));
        }
        throw new IllegalArgumentException("Unsupported primitive " + clazz);
    }
    return array;
}

Next: Processing primitives and aggregates

1 2 3 4 5 Next>>

 

 


 

120x60 Red Creative Test Winner - General macmini_t1_120x90 No late fees - ever!

 

 

Home ] Up ] CPEntry ]

Copyright © 2008,  Ken North Computing, LLC
Last modified: March 31, 2008