Kryo的变长序列化底层在AS3的实现

编程技术  /  houtizong 发布于 3年前   63
当前是个人把java的Output和Input的翻译成了AS3版本,虽然没什么技术含量,但是还是很有帮助,经过长时间使用,基本确保和java之间的通信没有任何问题。

package yxcq.kryo{import flash.utils.ByteArray;import yxcq.utils.math.Long;public class Input{protected var buffer:ByteArray;public function Input(bytes:ByteArray){if(bytes != null){this.buffer = bytes;this.buffer.position = 0;}}public function get bytesAvailable():int{return buffer.bytesAvailable;}public function setBytes(bytes:ByteArray):void{this.buffer = bytes;this.buffer.position = 0;}protected function require(required:int):int{if(buffer.bytesAvailable>=required)return buffer.bytesAvailable;elsethrow new Error();}public function read():int{if(buffer.bytesAvailable<1)return -1;return buffer.readUnsignedByte()&0xFF;}public function skip(count:int):void{this.buffer.position = this.buffer.position+count;}public function readByte():int{require(1);return buffer.readByte();}public function readByteUnsigned():int{require(1);return buffer.readUnsignedByte();}public function readBytes(length:int):ByteArray{var bytes:ByteArray = new ByteArray;_readBytes(bytes,0,length);return bytes;}protected function _readBytes(bytes:ByteArray,offset:int,length:int):void{buffer.readBytes(bytes,offset,length);}public function readInt():int{require(4);return (buffer.readUnsignedByte() & 0xFF) << 24 //| (buffer.readUnsignedByte() & 0xFF) << 16 //| (buffer.readUnsignedByte() & 0xFF) << 8 //| buffer.readUnsignedByte() & 0xFF;}/** Reads a 1-5 byte int. It is guaranteed that a varible length encoding will be used. */public function readVarInt (optimizePositive:Boolean):int {if (require(1) < 5) return readInt_slow(optimizePositive);var b:int = buffer.readUnsignedByte();var result:int = b & 0x7F;if ((b & 0x80) != 0) {b = buffer.readUnsignedByte();result |= (b & 0x7F) << 7;if ((b & 0x80) != 0) {b = buffer.readUnsignedByte();result |= (b & 0x7F) << 14;if ((b & 0x80) != 0) {b = buffer.readUnsignedByte();result |= (b & 0x7F) << 21;if ((b & 0x80) != 0) {b = buffer.readUnsignedByte();result |= (b & 0x7F) << 28;}}}}return optimizePositive ? result : ((result >>> 1) ^ -(result & 1));}private function readInt_slow (optimizePositive:Boolean):int {// The buffer is guaranteed to have at least 1 byte.var b:int = buffer.readUnsignedByte();var result:int = b & 0x7F;if ((b & 0x80) != 0) {require(1);b = buffer.readUnsignedByte();result |= (b & 0x7F) << 7;if ((b & 0x80) != 0) {require(1);b = buffer.readUnsignedByte();result |= (b & 0x7F) << 14;if ((b & 0x80) != 0) {require(1);b = buffer.readUnsignedByte();result |= (b & 0x7F) << 21;if ((b & 0x80) != 0) {require(1);b = buffer.readUnsignedByte();result |= (b & 0x7F) << 28;}}}}return optimizePositive ? result : ((result >>> 1) ^ -(result & 1));}protected var chars:ByteArray = new ByteArray;public function readString():String{var available:int = require(1);var b:int = buffer.readUnsignedByte();if((b&0x80) == 0)return readAscii();var charCount:int = available>=5?readUtf8Length(b) : readUtf8Length_slow(b);switch (charCount) {case 0:return null;case 1:return "";}charCount--;chars.clear();readUtf8(charCount);var len:int = chars.position;chars.position = 0;return chars.readUTFBytes(len);}private function readUtf8Length (b:int):int {var result:int = b & 0x3F; // Mask all but first 6 bits.if ((b & 0x40) != 0) { // Bit 7 means another byte, bit 8 means UTF8.b = buffer.readUnsignedByte();result |= (b & 0x7F) << 6;if ((b & 0x80) != 0) {b = buffer.readUnsignedByte();result |= (b & 0x7F) << 13;if ((b & 0x80) != 0) {b = buffer.readUnsignedByte();result |= (b & 0x7F) << 20;if ((b & 0x80) != 0) {b = buffer.readUnsignedByte();result |= (b & 0x7F) << 27;}}}}return result;}private function readUtf8Length_slow (b:int):int {var result:int = b & 0x3F; // Mask all but first 6 bits.if ((b & 0x40) != 0) { // Bit 7 means another byte, bit 8 means UTF8.require(1);b = buffer.readUnsignedByte();result |= (b & 0x7F) << 6;if ((b & 0x80) != 0) {require(1);b = buffer.readUnsignedByte();result |= (b & 0x7F) << 13;if ((b & 0x80) != 0) {require(1);b = buffer.readUnsignedByte();result |= (b & 0x7F) << 20;if ((b & 0x80) != 0) {require(1);b = buffer.readUnsignedByte();result |= (b & 0x7F) << 27;}}}}return result;}private function readUtf8 (charCount:int):void {// Try to read 7 bit ASCII chars.var charIndex:int = 0;var count:int = Math.min(require(1), charCount);var b:int;while (charIndex < count) {b = buffer.readByte();if (b < 0) {this.buffer.position--;break;}charIndex++;chars.writeByte(b);}// If buffer didn't hold all chars or any were not ASCII, use slow path for remainder.if (charIndex < charCount){ readUtf8_slow(charCount, charIndex);}}private function readUtf8_slow (charCount:int, charIndex:int):void {var utfstrlen:int = 0;var position:int = buffer.position;while (charIndex < charCount) {var b:int = buffer.readByte() & 0x000000FF;switch (b >> 4) {case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:chars.writeByte(b);break;case 12:case 13:chars.writeByte(b);chars.writeByte(buffer.readByte());break;case 14:chars.writeByte(b);chars.writeByte(buffer.readByte());chars.writeByte(buffer.readByte());break;}charIndex++;}}private function readAscii ():String {var position:int = buffer.position;var end:int = buffer.position;var start:int = end -1;var limit:int = buffer.length;var b:int;do {if(end == limit){buffer.position = position-1;return readAscii_slow();}b = buffer.readUnsignedByte();end++;} while ((b & 0x00000080) == 0);buffer[end - 1] &=0x0000007F; // Mask end of ascii bit.buffer.position = position-1;var value:String = (buffer as ByteArray).readMultiByte(end-start,'iso-8859-1');buffer[end - 1] |= 0x00000080;return value;}private function readAscii_slow ():String {throw new Error("数据流中有不支持的字符串解析");}public function readFloat():Number{return buffer.readFloat();}public function readFloat2(precision:Number,optimizePositive:Boolean):Number{return Number(readInt_slow(optimizePositive))/precision;}public function readShort():int{return buffer.readShort();}public function readShortUnsigned():int{return buffer.readUnsignedShort();}public function readLong():Long{var h:int = buffer.readUnsignedByte()<<22;h |= buffer.readUnsignedByte()<<16;h |= buffer.readUnsignedByte()<<8;h |= buffer.readUnsignedByte();var l:int = buffer.readUnsignedByte()<<22;l |= buffer.readUnsignedByte()<<16;l |= buffer.readUnsignedByte()<<8;l |= buffer.readUnsignedByte();return new Long(h,l);}public function readVarLong (optimizePositive:Boolean):Long{var b:int = buffer.readByte();var low:int = b & 0x7F;var high:int = 0;if ((b & 0x80) != 0) {b = buffer.readByte();low |= (b & 0x7F) << 7;if ((b & 0x80) != 0) {b = buffer.readByte();low |= (b & 0x7F) << 14;if ((b & 0x80) != 0) {b = buffer.readByte();low |= (b & 0x7F) << 21;if ((b & 0x80) != 0) {b = buffer.readByte();var temp:int = b&0x7F;high = ((0 << temp) | (temp >>> 4) )|high;low |= (temp << 28);if ((b & 0x80) != 0) {b = buffer.readByte();high |= (b & 0x7F)<<3;if ((b & 0x80) != 0) {b = buffer.readByte();high |= (b & 0x7F) << 10;if ((b & 0x80) != 0) {b = buffer.readByte();high |= (b & 0x7F) << 17;if ((b & 0x80) != 0) {b = buffer.readByte();high |= (b & 0x7F) << 24;}}}}}}}}var result:Long = new Long(high,low);if (!optimizePositive) result = result.rightShift(1,true).xor(result.and(1));return result;}public function readBoolean():Boolean{return buffer.readUnsignedByte()==1;}public function readChar():int{return buffer.readUnsignedShort();}public function readDouble():Number{return buffer.readDouble();}/** Bulk input of an int array. */public function readVarInts (length:int, optimizePositive:Boolean):Vector.<int>{var array:Vector.<int> = new Vector.<int>;for (var i:int = 0; i < length; i++)array[i] = readVarInt(optimizePositive);return array;}public function readVarLongs (length:int, optimizePositive:Boolean):Vector.<Long>{var array:Vector.<Long> = new Vector.<Long>;for (var i:int = 0; i < length; i++)array[i] = readVarLong(optimizePositive);return array;}/** Bulk input of an int array. */public function readInts (length:int) :Vector.<int> {var array:Vector.<int> = new Vector.<int>;for (var i:int = 0; i < length; i++)array[i] = readInt();return array;}/** Bulk input of a long array. */public function readLongs (length:int):Vector.<Long> {var array:Vector.<Long> = new Vector.<Long>;for (var i:int = 0; i < length; i++)array[i] = readLong();return array;}/** Bulk input of a float array. */public function readFloats (length:int) :Vector.<Number> {var array:Vector.<Number> = new Vector.<Number>;for (var i:int = 0; i < length; i++)array[i] = readFloat();return array;}/** Bulk input of a short array. */public function readShorts (length:int):Vector.<int>  {var array:Vector.<int> = new Vector.<int>;for (var i:int = 0; i < length; i++)array[i] = readShort();return array;}/** Bulk input of a char array. */public function readChars (length:int):Vector.<int>  {var array:Vector.<int> = new Vector.<int>;for (var i:int = 0; i < length; i++)array[i] = readChar();return array;}/** Bulk input of a double array. */public function readDoubles (length:int):Vector.<Number>  {var array:Vector.<Number> = new Vector.<Number>;for (var i:int = 0; i < length; i++)array[i] = readDouble();return array;}}}


package yxcq.kryo{import yxcq.utils.math.Long;import flash.utils.ByteArray;public class Output{protected var buffer:ByteArray = new ByteArray;public function Output(){}public function getBuffer():ByteArray{return buffer;}public function write(value:int):void{buffer.writeByte(value);}public function writeBytes(bytes:ByteArray,offset:int,length:int):void{buffer.writeBytes(bytes,offset,length);}public function writeByte(b:int):void{buffer.writeByte(b);}public function writeInt(value:int):void{buffer.writeInt(value);}public function writeVarInt(value:int,optimizePositive:Boolean):int{if(!optimizePositive) value = (value<<1)^(value>>31);if(value>>>7 == 0){buffer.writeByte(value&0xFF);return 1;}if(value>>>14 == 0){buffer.writeByte((value&0x7F | 0x80)&0xFF);buffer.writeByte((value>>>7)&0xFF);return 2;}if (value >>> 21 == 0) {buffer.writeByte((value&0x7F | 0x80)&0xFF);buffer.writeByte((value>>>7|0x80)&0xFF);buffer.writeByte((value>>>14)&0xFF);return 3;}if (value >>> 28 == 0) {buffer.writeByte((value&0x7F | 0x80)&0xFF);buffer.writeByte((value>>>7|0x80)&0xFF);buffer.writeByte((value>>>14|0x80)&0xFF);buffer.writeByte((value>>>21)&0xFF);return 4;}buffer.writeByte((value&0x7F | 0x80)&0xFF);buffer.writeByte((value>>>7|0x80)&0xFF);buffer.writeByte((value>>>14|0x80)&0xFF);buffer.writeByte((value>>>21|0x80)&0xFF);buffer.writeByte((value>>>28)&0xFF);return 5;}public function writeVarLong (value:Long, optimizePositive:Boolean):int{if (!optimizePositive) value = value.leftShift(1).xor(value.rightShift(63));if (value.rightShift(7,true).isZero()) {buffer.writeByte(value.getLow());return 1;}if (value.rightShift(14,true).isZero()) {buffer.writeByte(value.and(0x7F).or(0x80).getLow());buffer.writeByte(value.rightShift(7,true).getLow());return 2;}if (value.rightShift(21,true).isZero()) {buffer.writeByte(value.and(0x7F).or(0x80).getLow());buffer.writeByte(value.rightShift(7,true).or(0x80).getLow());buffer.writeByte(value.rightShift(14,true).getLow());return 3;}if (value.rightShift(28,true).isZero()) {buffer.writeByte(value.and(0x7F).or(0x80).getLow());buffer.writeByte(value.rightShift(7,true).or(0x80).getLow());buffer.writeByte(value.rightShift(14,true).or(0x80).getLow());buffer.writeByte(value.rightShift(21,true).getLow());return 4;}if (value.rightShift(35,true).isZero()) {buffer.writeByte(value.and(0x7F).or(0x80).getLow());buffer.writeByte(value.rightShift(7,true).or(0x80).getLow());buffer.writeByte(value.rightShift(14,true).or(0x80).getLow());buffer.writeByte(value.rightShift(21,true).or(0x80).getLow());buffer.writeByte(value.rightShift(28,true).getLow());return 5;}if (value.rightShift(42,true).isZero()) {buffer.writeByte(value.and(0x7F).or(0x80).getLow());buffer.writeByte(value.rightShift(7,true).or(0x80).getLow());buffer.writeByte(value.rightShift(14,true).or(0x80).getLow());buffer.writeByte(value.rightShift(21,true).or(0x80).getLow());buffer.writeByte(value.rightShift(28,true).or(0x80).getLow());buffer.writeByte(value.rightShift(35,true).getLow());return 6;}if (value.rightShift(49,true).isZero()) {buffer.writeByte(value.and(0x7F).or(0x80).getLow());buffer.writeByte(value.rightShift(7,true).or(0x80).getLow());buffer.writeByte(value.rightShift(14,true).or(0x80).getLow());buffer.writeByte(value.rightShift(21,true).or(0x80).getLow());buffer.writeByte(value.rightShift(28,true).or(0x80).getLow());buffer.writeByte(value.rightShift(35,true).or(0x80).getLow());buffer.writeByte(value.rightShift(42,true).getLow());return 7;}if (value.rightShift(56,true).isZero()) {buffer.writeByte(value.and(0x7F).or(0x80).getLow());buffer.writeByte(value.rightShift(7,true).or(0x80).getLow());buffer.writeByte(value.rightShift(14,true).or(0x80).getLow());buffer.writeByte(value.rightShift(21,true).or(0x80).getLow());buffer.writeByte(value.rightShift(28,true).or(0x80).getLow());buffer.writeByte(value.rightShift(35,true).or(0x80).getLow());buffer.writeByte(value.rightShift(42,true).or(0x80).getLow());buffer.writeByte(value.rightShift(49,true).getLow());return 8;}buffer.writeByte(value.and(0x7F).or(0x80).getLow());buffer.writeByte(value.rightShift(7,true).or(0x80).getLow());buffer.writeByte(value.rightShift(14,true).or(0x80).getLow());buffer.writeByte(value.rightShift(21,true).or(0x80).getLow());buffer.writeByte(value.rightShift(28,true).or(0x80).getLow());buffer.writeByte(value.rightShift(35,true).or(0x80).getLow());buffer.writeByte(value.rightShift(42,true).or(0x80).getLow());buffer.writeByte(value.rightShift(49,true).or(0x80).getLow());buffer.writeByte(value.rightShift(56,true).getLow());return 9;}public function writeString (value:String):void {if (value == null) {writeByte(0x80); // 0 means null, bit 8 means UTF8.return;}var charCount:int = value.length;if (charCount == 0) {writeByte(1 | 0x80); // 1 means empty string, bit 8 means UTF8.return;}// Detect ASCII. 检查是否ASCIIvar ascii:Boolean = false;if (charCount > 1 && charCount < 64) {ascii = true;for (var i:int = 0; i < charCount; i++) {var c:int = value.charCodeAt(i);if (c > 127) {ascii = false;break;}}}if (ascii) {buffer.writeUTFBytes(value);buffer[buffer.position - 1] |= 0x80;} else {writeUtf8Length(charCount + 1);var charIndex:int = 0;var position:int = buffer.position;// Try to write 8 bit chars.for (; charIndex < charCount; charIndex++) {var c:int = value.charCodeAt(charIndex);if (c > 127) break;buffer.writeByte(c&0xFF);position++;}buffer.position = position;if (charIndex < charCount) writeString_slow(value, charCount, charIndex);}}/** Writes a string that is known to contain only ASCII characters. Non-ASCII strings passed to this method will be corrupted. * Each byte is a 7 bit character with the remaining byte denoting if another character is available. This is slightly more * efficient than {@link #writeString(String)}. The string can be read using {@link Input#readString()} or * {@link Input#readStringBuilder()}. * @param value May be null. */public function writeAscii (value:String):void{if (value == null) {writeByte(0x80); // 0 means null, bit 8 means UTF8.return;}var charCount:int = value.length;switch (charCount) {case 0:writeByte(1 | 0x80); // 1 is string length + 1, bit 8 means UTF8.return;case 1:writeByte(2 | 0x80); // 2 is string length + 1, bit 8 means UTF8.writeByte(value.charCodeAt(0));return;}buffer.writeUTF(value);buffer[buffer.position - 1] |= 0x80; // Bit 8 means end of ASCII.}/** Writes the length of a string, which is a variable length encoded int except the first byte uses bit 8 to denote UTF8 and * bit 7 to denote if another byte is present. */private function writeUtf8Length (value:int):void {if (value >>> 6 == 0) {buffer.writeByte((value | 0x80)&0xFF); // Set bit 8.} else if (value >>> 13 == 0) {buffer.writeByte((value | 0x40 | 0x80)&0xFF); // Set bit 7 and 8.buffer.writeByte((value >>> 6)&0xFF);} else if (value >>> 20 == 0) {buffer.writeByte((value | 0x40 | 0x80)&0xFF); // Set bit 7 and 8.buffer.writeByte(((value >>> 6) | 0x80)&0xFF); // Set bit 8.buffer.writeByte((value >>> 13)&0xFF);} else if (value >>> 27 == 0) {buffer.writeByte((value | 0x40 | 0x80)&0xFF); // Set bit 7 and 8.buffer.writeByte(((value >>> 6) | 0x80)&0xFF); // Set bit 8.buffer.writeByte(((value >>> 13) | 0x80)&0xFF); // Set bit 8.buffer.writeByte((value >>> 20)&0xFF);} else {buffer.writeByte((value | 0x40 | 0x80)&0xFF); // Set bit 7 and 8.buffer.writeByte(((value >>> 6) | 0x80)&0xFF); // Set bit 8.buffer.writeByte(((value >>> 13) | 0x80)&0xFF); // Set bit 8.buffer.writeByte(((value >>> 20) | 0x80)&0xFF); // Set bit 8.buffer.writeByte((value >>> 27)&0xFF);}}private function writeString_slow (value:String, charCount:int, charIndex:int):void {for (; charIndex < charCount; charIndex++) {var c:int = value.charCodeAt(charIndex);if (c <= 0x007F) {buffer.writeByte(c&0xFF);} else if (c > 0x07FF) {buffer.writeByte((0xE0 | c >> 12 & 0x0F)&0xFF);buffer.writeByte((0x80 | c >> 6 & 0x3F)&0xFF);buffer.writeByte((0x80 | c & 0x3F)&0xFF);} else {buffer.writeByte((0xC0 | c >> 6 & 0x1F)&0xFF);buffer.writeByte((0x80 | c & 0x3F)&0xFF);}}}public function writeFloat(value:Number):void{this.buffer.writeFloat(value);}public function writeFloat2(value:Number,precision:Number,optimizePositive:Boolean):void{this.writeVarInt(value*precision,optimizePositive);}public function writeShort(value:int):void{this.buffer.writeShort(value);}public function writeLong(value:Long):void{this.buffer.writeByte(value.getHigh()>>>24);this.buffer.writeByte(value.getHigh()>>>16);this.buffer.writeByte(value.getHigh()>>>8);this.buffer.writeByte(value.getHigh());this.buffer.writeByte(value.getLow()>>>24);this.buffer.writeByte(value.getLow()>>>16);this.buffer.writeByte(value.getLow()>>>8);this.buffer.writeByte(value.getLow());}public function writeBoolean(value:Boolean):void{this.buffer.writeBoolean(value);}public function writeChar(value:int):void{this.buffer.writeShort(value);}public function writeDouble(value:Number):void{this.buffer.writeDouble(value);}/** Bulk output of an int array. */public function writeVarInts (object:Vector.<int>, optimizePositive:Boolean) :void {for (var i:int = 0, n:int = object.length; i < n; i++)writeVarInt(object[i], optimizePositive);}/** Bulk output of an int array. */public function writeInts (object:Vector.<int>) :void {for (var i:int = 0, n:int = object.length; i < n; i++)this.buffer.writeInt(object[i]);}public function writeVarLongs (object:Vector.<Long>, optimizePositive:Boolean):void{for (var i:int = 0, n:int = object.length; i < n; i++)writeVarLong(object[i], optimizePositive);}/** Bulk output of an long array. */public function writeLongs (object:Vector.<Long>) :void {for (var i:int = 0, n:int = object.length; i < n; i++)writeLong(object[i]);}/** Bulk output of a float array. */public function writeFloats (object:Vector.<Number>) :void {for (var i:int = 0, n:int = object.length; i < n; i++)writeFloat(object[i]);}/** Bulk output of a short array. */public function writeShorts (object:Vector.<int>) :void {for (var i:int = 0, n:int = object.length; i < n; i++)writeShort(object[i]);}/** Bulk output of a char array. */public function writeChars (object:Vector.<int>) :void {for (var i:int = 0, n:int = object.length; i < n; i++)writeChar(object[i]);}/** Bulk output of a double array. */public function writeDoubles (object:Vector.<int>) :void {for (var i:int = 0, n:int = object.length; i < n; i++)writeDouble(object[i]);}}}

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

留言需要登陆哦

技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成

网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];

      订阅博客周刊 去订阅

文章归档

文章标签

友情链接

Auther ·HouTiZong
侯体宗的博客
© 2020 zongscan.com
版权所有ICP证 : 粤ICP备20027696号
PHP交流群 也可以扫右边的二维码
侯体宗的博客