Reading a lot of integers from a byteArray

by leichtgewicht
Integers can be stored as 5byte values to save bytes. This however can make it slow to read all those integers afterwards. This is a test to show a horribly complex way to read them just a little faster.
♥0 | Line 1469 | Modified 2011-09-20 12:51:43 | MIT License
play

ActionScript3 source code

/**
 * Copyright leichtgewicht ( http://wonderfl.net/user/leichtgewicht )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/iuhO
 */

package {
    import flash.text.TextField;
    import flash.display.Sprite;
    import flash.utils.getTimer;

    public class FlashTest extends Sprite {
        
        private var out: TextField = new TextField();
        
        private function show(string:String=null ):void {
            out.appendText((string?string:"")+ "\n");
        }
        
        public function FlashTest() {
            addChild( out );
            out.width = stage.stageWidth;
            out.height = stage.stageHeight;
            functionalityTest();
            show();
            speedTest();
        }

        public function speedTest() : void {
            show("Speed Test: ");
            var dummy: CustomBA = createBA();
            for( var i: int = 0; i< 10000; ++i ) {
                createBA(dummy);
            }
            
            var nums: Vector.<int>;
            var t: Number;
            t = getTimer();
            nums = speedReadBytes(dummy);
            t = getTimer()-t;
            show( t+ "ms for reading "+ nums.length+ " integers with the new code");
            
            t = getTimer();
            nums = oldReadBytes(dummy);
            t = getTimer()-t;
            show( t+ "ms for reading "+ nums.length+ " integers with the old code");
        }

        public function functionalityTest() : void {
            var error : Error;
            try {
                var dummy : CustomBA = createBA();
                var nums : Vector.<int> = testReadBytes(dummy);
                if ( dummy.content.length != nums.length ) {
                    throw new Error("The variables length doesn't match!");
                }
                for ( var i : int = 0; i < nums.length; ++i ) {
                    var a : int = nums[i];
                    var b : int = dummy.content[i];
                    if ( a != b ) {
                        throw new Error("Number " + i + " wasn't read properly: " + b + " != " + a);
                    }
                }
            } catch( e : Error ) {
                show("Functionality: " + e.getStackTrace());
                error = e;
            }
            if ( !error ) {
                show("Functionality: OK!");
            }
        }
        
        public function oldReadBytes(ba : CustomBA) : Vector.<int> {
            ba.position = 0;
            var nums : Vector.<int> = new Vector.<int>();
            var numsRead : int = 0;
            var max: int = ba.content.length;
            while ( numsRead < max ) {
                var result : int = ba.readUnsignedByte();
                if ((result & 0x00000080)) {
                    result = result & 0x0000007f | ba.readUnsignedByte() << 7;
                    if ((result & 0x00004000)) {
                        result = result & 0x00003fff | ba.readUnsignedByte() << 14;
                        if ((result & 0x00200000)) {
                            result = result & 0x001fffff | ba.readUnsignedByte() << 21;
                            if ((result & 0x10000000)) {
                                result = result & 0x0fffffff | ba.readByte() << 28;
                            }
                        }
                    }
                }
                nums.push(result);
                ++numsRead;
            }
            return nums;
        }

        public function speedReadBytes(ba : CustomBA) : Vector.<int> {
            ba.position = 0;
            var max : int = ba.content.length - 4;
            var nums : Vector.<int> = new Vector.<int>();

            var current : int;
            var numsRead : int = 0;
            var bytesRead : int = 0;

            while ( numsRead < max ) {
                var i : int = ba.readInt();
                if ( bytesRead == 0 ) {
                    current = i & 0x7f;
                    if ( i & 0x80 ) {
                        current = current | (i & 0x7f00) >> 1;
                        if ( i & 0x8000 ) {
                            current = current | (i & 0x7f0000) >> 2;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 3;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 4;
                                } else {
                                    nums.push(current);
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            } else {
                                nums.push(current);
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                } else {
                                    nums.push(current);
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            }
                        } else {
                            nums.push(current);
                            ++numsRead;
                            current = (i & 0x7f0000) >> 16;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 17;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 2;
                                } else {
                                    nums.push(current);
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            } else {
                                nums.push(current);
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                } else {
                                    nums.push(current);
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            }
                        }
                    } else {
                        nums.push(current);
                        ++numsRead;

                        current = (i & 0x7f00) >> 8;
                        if ( i & 0x8000 ) {
                            current = current | (i & 0x7f0000) >> 9;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 10;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 3;
                                } else {
                                    nums.push(current);
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            } else {
                                nums.push(current);
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                } else {
                                    nums.push(current);
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            }
                        } else {
                            nums.push(current);
                            ++numsRead;

                            current = (i & 0x7f0000) >> 16;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 17;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 2;
                                } else {
                                    nums.push(current);
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            } else {
                                nums.push(current);
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                } else {
                                    nums.push(current);
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            }
                        }
                    }
                } else if ( bytesRead == 1 ) {
                    current = current | (i & 0x7f) << 7;
                    if ( i & 0x80 ) {
                        current = current | (i & 0x7f00) << 6;
                        if ( i & 0x8000 ) {
                            current = current | (i & 0x7f0000) << 5;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) << 4;
                                nums.push(current);
                                // 5 byte int
                                ++numsRead;
                                bytesRead = 0;
                                // after 5 bytes we are done
                            } else {
                                nums.push(current);
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                } else {
                                    nums.push(current);
                                    // 1 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            }
                        } else {
                            nums.push(current);
                            // 3 byte int
                            ++numsRead;

                            current = (i & 0x7f0000) >> 16;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 17;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 2;
                                } else {
                                    nums.push(current);
                                    // 2 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            } else {
                                nums.push(current);
                                // 1 byte int
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                } else {
                                    nums.push(current);
                                    // 1 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            }
                        }
                    } else {
                        nums.push(current);
                        // 2 byte int
                        ++numsRead;

                        current = (i & 0x7f00) >> 8;
                        if ( i & 0x8000 ) {
                            current = current | (i & 0x7f0000) >> 9;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 10;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 3;
                                } else {
                                    nums.push(current);
                                    // 3 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            } else {
                                nums.push(current);
                                // 2 byte int
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                } else {
                                    nums.push(current);
                                    // 1 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            }
                        } else {
                            nums.push(current);
                            // 1 byte int
                            ++numsRead;

                            current = (i & 0x7f0000) >> 16;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 17;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 2;
                                } else {
                                    nums.push(current);
                                    // 2 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            } else {
                                nums.push(current);
                                // 1 byte int
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                } else {
                                    nums.push(current);
                                    // 2 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            }
                        }
                    }
                } else if ( bytesRead == 2 ) {
                    current = current | (i & 0x7f) << 14;
                    if ( i & 0x80 ) {
                        current = current | (i & 0x7f00) << 13;
                        if ( i & 0x8000 ) {
                            current = current | (i & 0x7f0000) << 12;
                            nums.push(current);
                            // 5 byte int
                            ++numsRead;

                            // after 5 bytes we are done, next byte is always first one
                            current = (i & 0x7f000000) >> 24;
                            if ( i & 0x80000000 ) {
                                bytesRead = 1;
                            } else {
                                nums.push(current);
                                // 1 byte int
                                ++numsRead;
                                bytesRead = 0;
                            }
                        } else {
                            nums.push(current);
                            // 4 byte int
                            ++numsRead;

                            current = (i & 0x7f0000) >> 16;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 17;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 2;
                                } else {
                                    nums.push(current);
                                    // 2 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            } else {
                                nums.push(current);
                                // 1 byte int
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                } else {
                                    nums.push(current);
                                    // 1 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            }
                        }
                    } else {
                        nums.push(current);
                        // 3 byte int
                        ++numsRead;

                        current = (i & 0x7f00) >> 8;
                        if ( i & 0x8000 ) {
                            current = current | (i & 0x7f0000) >> 9;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 10;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 3;
                                } else {
                                    nums.push(current);
                                    // 3 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            } else {
                                nums.push(current);
                                // 2 byte int
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                } else {
                                    nums.push(current);
                                    // 1 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            }
                        } else {
                            nums.push(current);
                            // 1 byte int
                            ++numsRead;

                            current = (i & 0x7f0000) >> 16;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 17;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 2;
                                } else {
                                    nums.push(current);
                                    // 2 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            } else {
                                nums.push(current);
                                // 1 byte int
                                ++numsRead;

                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                } else {
                                    nums.push(current);
                                    // 1 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            }
                        }
                    }
                } else if ( bytesRead == 3 ) {
                    current = current | (i & 0x7f) << 21;
                    if ( i & 0x80 ) {
                        current = current | (i & 0x7f00) << 20;
                        nums.push(current);
                        // 5 byte int
                        ++numsRead;

                        // after 5 bytes we are done, next byte is always first one
                        current = (i & 0x7f0000) >> 16;
                        if ( i & 0x800000 ) {
                            current = current | (i & 0x7f000000) >> 17;
                            if ( i & 0x80000000 ) {
                                bytesRead = 2;
                            } else {
                                nums.push(current);
                                // 2 byte int
                                ++numsRead;
                                bytesRead = 0;
                            }
                        } else {
                            nums.push(current);
                            // 1 byte int
                            ++numsRead;

                            current = (i & 0x7f000000) >> 24;
                            if ( i & 0x80000000 ) {
                                bytesRead = 1;
                            } else {
                                nums.push(current);
                                // 1 byte int
                                ++numsRead;
                                bytesRead = 0;
                            }
                        }
                    } else {
                        nums.push(current);
                        // 4 byte int
                        ++numsRead;

                        current = (i & 0x7f00) >> 8;
                        if ( i & 0x8000 ) {
                            current = current | (i & 0x7f0000) >> 9;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 10;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 3;
                                } else {
                                    nums.push(current);
                                    // 3 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            } else {
                                nums.push(current);
                                // 2 byte int
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                } else {
                                    nums.push(current);
                                    // 1 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            }
                        } else {
                            nums.push(current);
                            // 1 byte int
                            ++numsRead;

                            current = (i & 0x7f0000) >> 16;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 17;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 2;
                                } else {
                                    nums.push(current);
                                    // 2 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            } else {
                                nums.push(current);
                                // 1 byte int
                                ++numsRead;

                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                } else {
                                    nums.push(current);
                                    // 1 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                }
                            }
                        }
                    }
                } else if ( bytesRead == 4 ) {
                    current = current | (i & 0x7f) << 28;
                    nums.push(current);
                    // 5 byte int
                    ++numsRead;

                    current = (i & 0x7f00) >> 8;
                    if ( i & 0x8000 ) {
                        current = current | (i & 0x7f0000) >> 9;
                        if ( i & 0x800000 ) {
                            current = current | (i & 0x7f000000) >> 10;
                            if ( i & 0x80000000 ) {
                                bytesRead = 3;
                            } else {
                                nums.push(current);
                                // 3 byte int
                                ++numsRead;
                                bytesRead = 0;
                            }
                        } else {
                            nums.push(current);
                            // 2 byte int
                            ++numsRead;
                            current = (i & 0x7f000000) >> 24;
                            if ( i & 0x80000000 ) {
                                bytesRead = 1;
                            } else {
                                nums.push(current);
                                // 1 byte int
                                ++numsRead;
                                bytesRead = 0;
                            }
                        }
                    } else {
                        nums.push(current);
                        // 1 byte int
                        ++numsRead;

                        current = (i & 0x7f0000) >> 16;
                        if ( i & 0x800000 ) {
                            current = current | (i & 0x7f000000) >> 17;
                            if ( i & 0x80000000 ) {
                                bytesRead = 2;
                            } else {
                                nums.push(current);
                                // 2 byte int
                                ++numsRead;
                                bytesRead = 0;
                            }
                        } else {
                            nums.push(current);
                            // 1 byte int
                            ++numsRead;

                            current = (i & 0x7f000000) >> 24;
                            if ( i & 0x80000000 ) {
                                bytesRead = 1;
                            } else {
                                nums.push(current);
                                // 1 byte int
                                ++numsRead;
                                bytesRead = 0;
                            }
                        }
                    }
                }
            }
            if ( bytesRead ) {
                ba.position -= bytesRead;
            }

            max = ba.content.length;
            while ( numsRead < max ) {
                var result : int = ba.readUnsignedByte();
                if ((result & 0x00000080)) {
                    result = result & 0x0000007f | ba.readUnsignedByte() << 7;
                    if ((result & 0x00004000)) {
                        result = result & 0x00003fff | ba.readUnsignedByte() << 14;
                        if ((result & 0x00200000)) {
                            result = result & 0x001fffff | ba.readUnsignedByte() << 21;
                            if ((result & 0x10000000)) {
                                result = result & 0x0fffffff | ba.readByte() << 28;
                            }
                        }
                    }
                }
                nums.push(result);
                ++numsRead;
            }
            return nums;
        }

        public function testReadBytes(ba : CustomBA) : Vector.<int> {
            ba.position = 0;
            var max : int = ba.content.length - 4;
            var nums : Vector.<int> = new Vector.<int>();

            var current : int;
            var numsRead : int = 0;
            var bytesRead : int = 0;
            var exit : int = 0;
            var exits : Object = {};

            while ( numsRead < max ) {
                var i : int = ba.readInt();
                if ( bytesRead == 0 ) {
                    current = i & 0x7f;
                    if ( i & 0x80 ) {
                        current = current | (i & 0x7f00) >> 1;
                        if ( i & 0x8000 ) {
                            current = current | (i & 0x7f0000) >> 2;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 3;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 4;
                                    exit = 1;
                                } else {
                                    nums.push(current);
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 2;
                                }
                            } else {
                                nums.push(current);
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                    exit = 3;
                                } else {
                                    nums.push(current);
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 4;
                                }
                            }
                        } else {
                            nums.push(current);
                            ++numsRead;
                            current = (i & 0x7f0000) >> 16;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 17;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 2;
                                    exit = 5;
                                } else {
                                    nums.push(current);
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 6;
                                }
                            } else {
                                nums.push(current);
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                    exit = 7;
                                } else {
                                    nums.push(current);
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 8;
                                }
                            }
                        }
                    } else {
                        nums.push(current);
                        ++numsRead;

                        current = (i & 0x7f00) >> 8;
                        if ( i & 0x8000 ) {
                            current = current | (i & 0x7f0000) >> 9;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 10;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 3;
                                    exit = 9;
                                } else {
                                    nums.push(current);
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 10;
                                }
                            } else {
                                nums.push(current);
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                    exit = 11;
                                } else {
                                    nums.push(current);
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 12;
                                }
                            }
                        } else {
                            nums.push(current);
                            ++numsRead;

                            current = (i & 0x7f0000) >> 16;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 17;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 2;
                                    exit = 13;
                                } else {
                                    nums.push(current);
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 14;
                                }
                            } else {
                                nums.push(current);
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                    exit = 15;
                                } else {
                                    nums.push(current);
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 16;
                                }
                            }
                        }
                    }
                } else if ( bytesRead == 1 ) {
                    current = current | (i & 0x7f) << 7;
                    if ( i & 0x80 ) {
                        current = current | (i & 0x7f00) << 6;
                        if ( i & 0x8000 ) {
                            current = current | (i & 0x7f0000) << 5;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) << 4;
                                nums.push(current);
                                // 5 byte int
                                ++numsRead;
                                bytesRead = 0;
                                exit = 17;
                                // after 5 bytes we are done
                            } else {
                                nums.push(current);
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                    exit = 18;
                                } else {
                                    nums.push(current);
                                    // 1 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 19;
                                }
                            }
                        } else {
                            nums.push(current);
                            // 3 byte int
                            ++numsRead;

                            current = (i & 0x7f0000) >> 16;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 17;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 2;
                                    exit = 20;
                                } else {
                                    nums.push(current);
                                    // 2 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 21;
                                }
                            } else {
                                nums.push(current);
                                // 1 byte int
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                    exit = 22;
                                } else {
                                    nums.push(current);
                                    // 1 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 23;
                                }
                            }
                        }
                    } else {
                        nums.push(current);
                        // 2 byte int
                        ++numsRead;

                        current = (i & 0x7f00) >> 8;
                        if ( i & 0x8000 ) {
                            current = current | (i & 0x7f0000) >> 9;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 10;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 3;
                                    exit = 24;
                                } else {
                                    nums.push(current);
                                    // 3 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 25;
                                }
                            } else {
                                nums.push(current);
                                // 2 byte int
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                    exit = 26;
                                } else {
                                    nums.push(current);
                                    // 1 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 27;
                                }
                            }
                        } else {
                            nums.push(current);
                            // 1 byte int
                            ++numsRead;

                            current = (i & 0x7f0000) >> 16;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 17;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 2;
                                    exit = 28;
                                } else {
                                    nums.push(current);
                                    // 2 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 29;
                                }
                            } else {
                                nums.push(current);
                                // 1 byte int
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                    exit = 30;
                                } else {
                                    nums.push(current);
                                    // 2 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 31;
                                }
                            }
                        }
                    }
                } else if ( bytesRead == 2 ) {
                    current = current | (i & 0x7f) << 14;
                    if ( i & 0x80 ) {
                        current = current | (i & 0x7f00) << 13;
                        if ( i & 0x8000 ) {
                            current = current | (i & 0x7f0000) << 12;
                            nums.push(current);
                            // 5 byte int
                            ++numsRead;

                            // after 5 bytes we are done, next byte is always first one
                            current = (i & 0x7f000000) >> 24;
                            if ( i & 0x80000000 ) {
                                bytesRead = 1;
                                exit = 32;
                            } else {
                                nums.push(current);
                                // 1 byte int
                                ++numsRead;
                                bytesRead = 0;
                                exit = 33;
                            }
                        } else {
                            nums.push(current);
                            // 4 byte int
                            ++numsRead;

                            current = (i & 0x7f0000) >> 16;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 17;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 2;
                                    exit = 34;
                                } else {
                                    nums.push(current);
                                    // 2 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 35;
                                }
                            } else {
                                nums.push(current);
                                // 1 byte int
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                    exit = 36;
                                } else {
                                    nums.push(current);
                                    // 1 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 37;
                                }
                            }
                        }
                    } else {
                        nums.push(current);
                        // 3 byte int
                        ++numsRead;

                        current = (i & 0x7f00) >> 8;
                        if ( i & 0x8000 ) {
                            current = current | (i & 0x7f0000) >> 9;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 10;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 3;
                                    exit = 38;
                                } else {
                                    nums.push(current);
                                    // 3 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 39;
                                }
                            } else {
                                nums.push(current);
                                // 2 byte int
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                    exit = 40;
                                } else {
                                    nums.push(current);
                                    // 1 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 41;
                                }
                            }
                        } else {
                            nums.push(current);
                            // 1 byte int
                            ++numsRead;

                            current = (i & 0x7f0000) >> 16;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 17;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 2;
                                    exit = 42;
                                } else {
                                    nums.push(current);
                                    // 2 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 43;
                                }
                            } else {
                                nums.push(current);
                                // 1 byte int
                                ++numsRead;

                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                    exit = 44;
                                } else {
                                    nums.push(current);
                                    // 1 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 45;
                                }
                            }
                        }
                    }
                } else if ( bytesRead == 3 ) {
                    current = current | (i & 0x7f) << 21;
                    if ( i & 0x80 ) {
                        current = current | (i & 0x7f00) << 20;
                        nums.push(current);
                        // 5 byte int
                        ++numsRead;

                        // after 5 bytes we are done, next byte is always first one
                        current = (i & 0x7f0000) >> 16;
                        if ( i & 0x800000 ) {
                            current = current | (i & 0x7f000000) >> 17;
                            if ( i & 0x80000000 ) {
                                bytesRead = 2;
                                exit = 46;
                            } else {
                                nums.push(current);
                                // 2 byte int
                                ++numsRead;
                                bytesRead = 0;
                                exit = 47;
                            }
                        } else {
                            nums.push(current);
                            // 1 byte int
                            ++numsRead;

                            current = (i & 0x7f000000) >> 24;
                            if ( i & 0x80000000 ) {
                                bytesRead = 1;
                                exit = 48;
                            } else {
                                nums.push(current);
                                // 1 byte int
                                ++numsRead;
                                bytesRead = 0;
                                exit = 49;
                            }
                        }
                    } else {
                        nums.push(current);
                        // 4 byte int
                        ++numsRead;

                        current = (i & 0x7f00) >> 8;
                        if ( i & 0x8000 ) {
                            current = current | (i & 0x7f0000) >> 9;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 10;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 3;
                                    exit = 50;
                                } else {
                                    nums.push(current);
                                    // 3 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 51;
                                }
                            } else {
                                nums.push(current);
                                // 2 byte int
                                ++numsRead;
                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                    exit = 52;
                                } else {
                                    nums.push(current);
                                    // 1 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 53;
                                }
                            }
                        } else {
                            nums.push(current);
                            // 1 byte int
                            ++numsRead;

                            current = (i & 0x7f0000) >> 16;
                            if ( i & 0x800000 ) {
                                current = current | (i & 0x7f000000) >> 17;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 2;
                                    exit = 54;
                                } else {
                                    nums.push(current);
                                    // 2 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 55;
                                }
                            } else {
                                nums.push(current);
                                // 1 byte int
                                ++numsRead;

                                current = (i & 0x7f000000) >> 24;
                                if ( i & 0x80000000 ) {
                                    bytesRead = 1;
                                    exit = 56;
                                } else {
                                    nums.push(current);
                                    // 1 byte int
                                    ++numsRead;
                                    bytesRead = 0;
                                    exit = 57;
                                }
                            }
                        }
                    }
                } else if ( bytesRead == 4 ) {
                    current = current | (i & 0x7f) << 28;
                    nums.push(current);
                    // 5 byte int
                    ++numsRead;

                    current = (i & 0x7f00) >> 8;
                    if ( i & 0x8000 ) {
                        current = current | (i & 0x7f0000) >> 9;
                        if ( i & 0x800000 ) {
                            current = current | (i & 0x7f000000) >> 10;
                            if ( i & 0x80000000 ) {
                                bytesRead = 3;
                                exit = 58;
                            } else {
                                nums.push(current);
                                // 3 byte int
                                ++numsRead;
                                bytesRead = 0;
                                exit = 59;
                            }
                        } else {
                            nums.push(current);
                            // 2 byte int
                            ++numsRead;
                            current = (i & 0x7f000000) >> 24;
                            if ( i & 0x80000000 ) {
                                bytesRead = 1;
                                exit = 60;
                            } else {
                                nums.push(current);
                                // 1 byte int
                                ++numsRead;
                                bytesRead = 0;
                                exit = 61;
                            }
                        }
                    } else {
                        nums.push(current);
                        // 1 byte int
                        ++numsRead;

                        current = (i & 0x7f0000) >> 16;
                        if ( i & 0x800000 ) {
                            current = current | (i & 0x7f000000) >> 17;
                            if ( i & 0x80000000 ) {
                                bytesRead = 2;
                                exit = 62;
                            } else {
                                nums.push(current);
                                // 2 byte int
                                ++numsRead;
                                bytesRead = 0;
                                exit = 63;
                            }
                        } else {
                            nums.push(current);
                            // 1 byte int
                            ++numsRead;

                            current = (i & 0x7f000000) >> 24;
                            if ( i & 0x80000000 ) {
                                bytesRead = 1;
                                exit = 64;
                            } else {
                                nums.push(current);
                                // 1 byte int
                                ++numsRead;
                                bytesRead = 0;
                                exit = 65;
                            }
                        }
                    }
                }
                exits[exit] = true;
            }
            if ( bytesRead ) {
                ba.position -= bytesRead;
            }

            max = ba.content.length;
            while ( numsRead < max ) {
                var result : int = ba.readUnsignedByte();
                if ((result & 0x00000080)) {
                    result = result & 0x0000007f | ba.readUnsignedByte() << 7;
                    if ((result & 0x00004000)) {
                        result = result & 0x00003fff | ba.readUnsignedByte() << 14;
                        if ((result & 0x00200000)) {
                            result = result & 0x001fffff | ba.readUnsignedByte() << 21;
                            if ((result & 0x10000000)) {
                                result = result & 0x0fffffff | ba.readByte() << 28;
                            }
                        }
                    }
                }
                nums.push(result);
                ++numsRead;
            }
            var missing : String = "";
            for ( var exitNo : int = 1; exitNo <= 65; ++exitNo ) {
                if ( !exits[exitNo] ) {
                    missing += exitNo + ",";
                }
            }
            if ( missing != "" ) {
                throw new Error("Exits missing: " + missing);
            }
            return nums;
        }

        public function createBA(ba: CustomBA=null) : CustomBA {
            if( !ba ) {
                ba = new CustomBA();
            }
            ba.write5Byte();
            ba.write3Byte();

            ba.write4Byte();

            ba.write3Byte();
            ba.write1Byte();

            ba.write3Byte();
            ba.write5Byte();

            ba.write3Byte();
            ba.write4Byte();
            ba.write1Byte();

            ba.write3Byte();
            ba.write3Byte();
            ba.write1Byte();
            ba.write5Byte();

            ba.write3Byte();
            ba.write4Byte();
            ba.write2Byte();
            ba.write3Byte();

            ba.write3Byte();
            ba.write2Byte();
            ba.write1Byte();
            ba.write2Byte();

            ba.write3Byte();
            ba.write2Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();

            ba.write3Byte();
            ba.write2Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write5Byte();

            ba.write3Byte();
            ba.write2Byte();
            ba.write1Byte();
            ba.write5Byte();
            ba.write1Byte();

            ba.write2Byte();
            ba.write2Byte();

            ba.write3Byte();
            ba.write2Byte();
            ba.write2Byte();
            ba.write1Byte();

            ba.write3Byte();
            ba.write2Byte();
            ba.write2Byte();
            ba.write5Byte();

            ba.write2Byte();
            ba.write5Byte();
            ba.write1Byte();

            ba.write2Byte();
            ba.write5Byte();
            ba.write5Byte();

            ba.write2Byte();
            ba.write4Byte();
            ba.write2Byte();

            ba.write2Byte();
            ba.write4Byte();
            ba.write3Byte();
            ba.write3Byte();

            ba.write2Byte();
            ba.write3Byte();
            ba.write3Byte();

            ba.write3Byte();
            ba.write4Byte();
            ba.write5Byte();

            ba.write1Byte();
            ba.write3Byte();

            ba.write1Byte();
            ba.write5Byte();
            ba.write2Byte();

            ba.write3Byte();
            ba.write3Byte();
            ba.write2Byte();

            ba.write3Byte();
            ba.write3Byte();
            ba.write3Byte();
            ba.write3Byte();

            ba.write3Byte();
            ba.write2Byte();
            ba.write3Byte();

            ba.write3Byte();
            ba.write2Byte();
            ba.write4Byte();
            ba.write3Byte();

            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();

            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write2Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();

            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write3Byte();
            ba.write1Byte();
            ba.write1Byte();

            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write4Byte();
            ba.write1Byte();

            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write5Byte();

            ba.write2Byte();
            ba.write1Byte();
            ba.write1Byte();

            ba.write2Byte();
            ba.write1Byte();
            ba.write2Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();

            ba.write2Byte();
            ba.write1Byte();
            ba.write3Byte();
            ba.write1Byte();
            ba.write1Byte();

            ba.write2Byte();
            ba.write1Byte();
            ba.write4Byte();
            ba.write1Byte();

            ba.write2Byte();
            ba.write1Byte();
            ba.write5Byte();

            ba.write1Byte();
            ba.write2Byte();
            ba.write1Byte();

            ba.write1Byte();
            ba.write2Byte();
            ba.write2Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();

            ba.write1Byte();
            ba.write2Byte();
            ba.write3Byte();
            ba.write1Byte();
            ba.write1Byte();

            ba.write1Byte();
            ba.write2Byte();
            ba.write4Byte();
            ba.write1Byte();

            ba.write1Byte();
            ba.write2Byte();
            ba.write5Byte();

            ba.write1Byte();
            ba.write1Byte();
            ba.write2Byte();

            ba.write1Byte();
            ba.write1Byte();
            ba.write3Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();

            ba.write1Byte();
            ba.write1Byte();
            ba.write3Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();

            ba.write2Byte();
            ba.write4Byte();
            ba.write1Byte();
            ba.write1Byte();

            ba.write2Byte();
            ba.write4Byte();
            ba.write1Byte();
            ba.write5Byte();

            ba.write2Byte();
            ba.write3Byte();
            ba.write4Byte();
            ba.write3Byte();

            ba.write2Byte();
            ba.write3Byte();
            ba.write3Byte();

            ba.write2Byte();
            ba.write3Byte();
            ba.write2Byte();
            ba.write1Byte();

            ba.write2Byte();
            ba.write3Byte();
            ba.write2Byte();
            ba.write5Byte();

            ba.write2Byte();
            ba.write4Byte();
            ba.write2Byte();

            ba.write2Byte();
            ba.write3Byte();
            ba.write2Byte();
            ba.write1Byte();

            ba.write2Byte();
            ba.write3Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();

            ba.write2Byte();
            ba.write3Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write5Byte();

            ba.write2Byte();
            ba.write3Byte();
            ba.write1Byte();
            ba.write2Byte();

            ba.write2Byte();
            ba.write3Byte();
            ba.write1Byte();
            ba.write4Byte();
            ba.write2Byte();

            ba.write1Byte();
            ba.write5Byte();
            ba.write2Byte();

            ba.write1Byte();
            ba.write5Byte();
            ba.write1Byte();
            ba.write1Byte();

            ba.write1Byte();
            ba.write5Byte();
            ba.write1Byte();
            ba.write5Byte();

            ba.write1Byte();
            ba.write5Byte();
            ba.write5Byte();
            ba.write1Byte();

            ba.write1Byte();
            ba.write4Byte();
            ba.write3Byte();

            ba.write1Byte();
            ba.write4Byte();
            ba.write4Byte();
            ba.write3Byte();

            ba.write1Byte();
            ba.write4Byte();
            ba.write2Byte();
            ba.write2Byte();
            ba.write3Byte();

            ba.write1Byte();
            ba.write4Byte();
            ba.write2Byte();
            ba.write1Byte();

            ba.write1Byte();
            ba.write4Byte();
            ba.write1Byte();
            ba.write2Byte();

            ba.write1Byte();
            ba.write4Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();

            ba.write1Byte();
            ba.write4Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write5Byte();

            ba.write1Byte();
            ba.write4Byte();
            ba.write1Byte();
            ba.write5Byte();
            ba.write1Byte();

            ba.write5Byte();
            ba.write5Byte();
            ba.write2Byte();

            ba.write5Byte();
            ba.write2Byte();
            ba.write1Byte();

            ba.write5Byte();
            ba.write2Byte();
            ba.write5Byte();

            ba.write5Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();

            ba.write5Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write5Byte();

            ba.write5Byte();
            ba.write1Byte();
            ba.write2Byte();

            ba.write5Byte();
            ba.write1Byte();
            ba.write5Byte();

            // Just some number at the emd
            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();
            ba.write1Byte();

            return ba;
        }
    }
}
import flash.utils.Endian;
import flash.utils.ByteArray;

class CustomBA extends ByteArray {
    public var content : Vector.<int> = new Vector.<int>;

    public function CustomBA() {
        endian = Endian.LITTLE_ENDIAN;
    }

    public function write1Byte() : void {
        var num : int = Math.random() * 127;
        content.push(num);
        writeByte(num);
    }

    public function write2Byte() : void {
        var numA : int = Math.random() * 127;
        var numB : int = Math.random() * 127;
        content.push(numA | numB << 7);
        writeByte(numA | 128);
        writeByte(numB);
    }

    public function write3Byte() : void {
        var numA : int = Math.random() * 127;
        var numB : int = Math.random() * 127;
        var numC : int = Math.random() * 127;
        content.push(numA | (numB << 7) | (numC << 14));
        writeByte(numA | 128);
        writeByte(numB | 128);
        writeByte(numC);
    }

    public function write4Byte() : void {
        var numA : int = Math.random() * 127;
        var numB : int = Math.random() * 127;
        var numC : int = Math.random() * 127;
        var numD : int = Math.random() * 127;
        content.push(numA | (numB << 7) | (numC << 14) | (numD << 21));
        writeByte(numA | 128);
        writeByte(numB | 128);
        writeByte(numC | 128);
        writeByte(numD);
    }

    public function write5Byte() : void {
        var numA : int = Math.random() * 127;
        var numB : int = Math.random() * 127;
        var numC : int = Math.random() * 127;
        var numD : int = Math.random() * 127;
        var numE : int = Math.random() * 15;
        content.push(numA | (numB << 7) | (numC << 14) | (numD << 21) | (numE << 28));
        writeByte(numA | 128);
        writeByte(numB | 128);
        writeByte(numC | 128);
        writeByte(numD | 128);
        writeByte(numE);
    }
}