I started today at 1 am to write an AMF3 deserializer. i didn't know what i were doing for 2 hours. i just wanted to get the protocol of the writeObject method of the new flash.net.Socket in ActionScript 3. Then i stumbled over some infos on osFlash. I remembered that i read a thread about it some time ago. i checked the integer parsing implementations of SabreAMF and Charles (found none in flourine[edit: ok there is one but 28bit unsigned as well] and Red5) ... but they were not working with my unitTests and were expecting 28bit integer. so i took some time (till 8 am) and looked into it.
It is a 29bit integer-data that can contain values from -268435456(int.MIN_VALUE>>3) to 268435455(int.MAX_VALUE>>3).
My java implementation works with signed bytes a bit faster (dont think so anymore).
I chained the steps for readability. enjoy !
int readInteger(java.io.DataInputStream in) throws IOException {
// byte type = in.readByte(); // for standalone use
int i = 0; // the returned value
byte b; // current byte
// byte array for nagativ int backtracking
byte[] ba = new byte[3];
ba[0] = b = in.readByte();
i |= b & 0x7f;
if (b < 0) { // nice , huh
// signed bytes starting with 1 are < 0
ba[1] = b = in.readByte();
i <<= 7;
i |= b & 0x7f;
if (b < 0) {
ba[2] = b = in.readByte();
i <<= 7;
i |= b & 0x7f;
if (b < 0) {
b = in.readByte();
i <<= 8;
// 29 bits
i |= b & 0xff;
if (ba[0] > -65) {
// 1st byte > -65 and 4 bytes long
// -> it is a negative integer
i = 0;
if (ba[0] != -1) {
// we need positiv numbers for shifting
// instead of (~ba[0])&0x7f;
// you can write -ba[0]-1;
// i dont know what is faster
i |= (~ba[0]) & 0x7f;
i <<= 7;
}
if (ba[1] != -1) {
i |= (~ba[1]) & 0x7f;
i <<= 7;
}
if (ba[2] != -1) {
i |= (~ba[2]) & 0x7f;
i <<= 8;
}// 29th bit
i |= (~b) & 0xff;
i *= -1;
i--;
}
}
}
}
return i;
}
