Amf3 Compressed 29Bit Integer

Posted by mb0 on May 3rd, 2006

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;
}

Comments