views:

1297

answers:

2

Given the following Java code for generating a binary file:

DataOutputStream out = new DataOutputStream(new FileOutputStream("foo.dat"));
out.writeInt(1234);
out.writeShort(30000);
out.writeFloat(256.384f);

I'm using the following Objective-C code and manage to parse the int and the short values:

NSString *path = [[NSBundle mainBundle] pathForResource:@"foo" ofType:@"dat"];
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path];

unsigned long intValue;
memcpy(&intValue, [[file readDataOfLength:4] bytes], 4);
intValue = NSSwapBigLongToHost(intValue);

unsigned short shortValue;
memcpy(&shortValue, [[file readDataOfLength:2] bytes], 2);
shortValue = NSSwapBigShortToHost(shortValue);

My problem for now is with the float value: any clues on how to parse it?

+2  A: 

Sorry I can't provide the whole answer, but I can say the Java float is saved into the file as a four-byte IEEE 754 representation of the float as per this document:

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Float.html#floatToIntBits(float)

That describes the exact structure of the value saved, so you could read it in as an int and manually parse the bits for the significand and exponent into a float. It does seem there should be a library call to parse floating point values packed into an int of this format. Hopefully someone else will know of a library call to handle this.

Kendall Helmstetter Gelner
+5  A: 

Just us the functions and types provided by <Foundation/Foundation.h>.

NSSwappedFloat bigEndianFloat;
memcpy(&bigEndianFloat, [[file readDataOfLength:4] bytes], 4);
float floatValue = NSSwapBigFloatToHost(bigEndianFloat);

Note that they use a special type to hold the float before the bytes are swapped. This is because if you swap the bytes of a floating point value, it can be changed into a Signaling NaN, and on some processors, this will cause a hardware exception by just assigning it to a variable.

Derek Ledbetter