tags:

views:

622

answers:

5

I have to code a Java program that will receive messages from network and display their content to the user. The problem is that the messages that I receive are simply binary dumps of C structures. Add to this some of the messages are coming from little endian machines and some from big endian without the fields being converted to network byte order. One way I have is to use JNI and convert c structs to some XML string and then de serialize this XML string to a Java Object. This is a laborous job since there about 122 different structs and each one of them contains more than 20 fields. I wonder if there is a library/tool/methodology which could make my job a bit easy ?

+2  A: 

You can use DataInputStream to load data from any InputStream. As long as you know the exact layout of your structs, this should be sufficient.

Joachim Sauer
+2  A: 

There are several libraries that help in this area. One of the simplest to use (annotation driver) is certainly Preon

dfa
doh, beat me to it. I need to read more carefully before composing a long reply
Trevor Harrison
but your answer is **better**
dfa
+3  A: 

Swig will handle a lot of the tedious repetitive work for you in terms of mapping the C structs to Java objects. Check out the Swig/Java manual and the entry on wrapping C structures.

Brian Agnew
Thanks Brian, I guess Swig will certainly help
Rohin
A: 

java.nio has ByteBuffer, which supports flipping byte order when reading and writing, on-the-fly if necessary.

Ken
+4  A: 

There is a library called Preon that was designed to help you with this type of task: Preon site Basically, they try to keep all the logic for reading your pojo's from the binary stream in annotations tied to each field in your pojo.

An example from their docs where you control the size of the int you are reading:

class Rectangle
{
  @BoundNumber(size="16") private int x1;
  @BoundNumber(size="16") private int y1;
  @BoundNumber(size="16") private int x2;
  @BoundNumber(size="16") private int y2;
}

or to specify endianness:

class Rectangle
{
  @BoundNumber(byteOrder=LittleEndian) private int x1;
  @BoundNumber(byteOrder=LittleEndian) private int y1;
  @BoundNumber(byteOrder=LittleEndian) private int x2;  
  @BoundNumber(byteOrder=LittleEndian) private int y2;
}

You can even use mini-equations with references to values in previous fields to specify size / length, etc.

@BoundList(size="width * height") byte[] pixels;
@BoundNumber(size="nrBits * 2") int value;

Oh, and they also offer conditional logic, all in annotations.

Trevor Harrison