Javascript字节流封装类


var ByteBuffer = function (length) {
    this.buffer = new ArrayBuffer(length);
    this.dataView = new DataView(this.buffer);
    //缓冲区偏移量
    this.offset=0;

    this.setBufferData=function(buffer){
    	this.buffer=buffer;
    	this.dataView = new DataView(this.buffer);
    	this.offset=0;
    	return this.dataView;
    }

    //copy buffer to another buffer,m.appendArrayBuffer(m.offset+2,n.buffer,0,5);
    this.appendArrayBuffer=function(toPos,fromBuffer,fromPos,length){
    	//console.log("appendArrayBuffer toPos=%d,fromPos=%d,length=%d \n",toPos,fromPos,length);

    	var uarr=new Uint8Array(fromBuffer);
    	for(var i=fromPos;i<length;i++){
    		this.dataView.setInt8(toPos++,uarr[i],true);
    	}
    }

    //将uarr复制到当前缓冲区
    this.appendUint8Array=function(toPos,uarr){
    	for(var i=0;i<uarr.length;i++){
    		this.dataView.setInt8(toPos++,uarr[i],true);
    	}
    }
   
    this.initHeader=function() {
		this.offset+=9;
	}

    this.setHeader=function(input) {
		this.dataView.setInt8(0,0x7c,true);
		this.dataView.setUint32(1,input,true);
		this.dataView.setUint32(5,input-5,true);
	}

    //writeChar("a")
    this.writeChar=function(input){
    	this.dataView.setInt8(this.offset++,input.charCodeAt(),true);
    	return this.offset;
    }

    //writeHex(0x04);
    this.writeHex=function(input){
    	this.dataView.setInt8(this.offset++,input);
    	return this.offset;
    }

    this.writeUint16=function(input) {
		this.dataView.setUint16(this.offset,input,true);
		this.offset+=2;
		return this.offset;
	}

	this.writeUint32=function(input) {
		this.dataView.setUint32(this.offset,input,true);
		this.offset+=4;
	}

	this.writeInt32=function(input) {
		this.dataView.setInt32(this.offset,input,true);
		this.offset+=4;
	}

	this.writeInt64=function(input){
	  var sign = input<0;
	  if (sign) input = -1-input;
	  for (var i=0;i<8;i++){
		var mod=input%0x100;
		input=(input-mod)/0x100;
		var v=sign?mod^0xFF:mod;
		this.dataView.setUint8(this.offset++,v);
	  }
	  return this.offset;
	}
	
	this.readInt64=function(){
	  var bytes=new Uint8Array(this.buffer,this.offset,8);
	  var sign=bytes[7]>>7;
	  this.offset+=8;
	  var sum=0;
	  var digits=1;
	  for (var i=0;i<8;i++){
		var value = bytes[i];
		sum += (sign?value^0xFF:value)*digits;
		digits *= 0x100;
	  }
	  return sign?-1-sum:sum;
	}

	this.writeString=function(input) {
		var utf8Length=this.UTF8Length(input);
		this.offset = this.writeUint16(utf8Length);
		this.stringToUTF8(input);
		
		return this.offset;
	}

	//======================

	this.readUint32=function() {
		var ret=this.dataView.getUint32(this.offset,true);
		this.offset+=4;
		return ret;
	}

	this.readInt32=function() {
		var ret=this.dataView.getInt32(this.offset,true);
		this.offset+=4;
		return ret;
	}

	this.readInt16=function() {
		var ret=this.dataView.getInt16(this.offset,true);
		this.offset+=2;
		return ret;
	}

	this.readString=function() {
		var length=this.readInt16();
		var uint8Array=new Uint8Array(this.buffer,this.offset, length);
		var ret=this.parseUTF8(uint8Array, 0, uint8Array.length);
		this.offset+=uint8Array.length;
		return ret;
	}

	this.readFloat32=function() {
		var ret=this.dataView.getFloat32(this.offset,true);
		this.offset+=4;
		return ret;
	}

	this.readFloat64=function() {
		var ret=this.dataView.getFloat64(this.offset,true);
		this.offset+=4;
		return ret;
	}

	this.readList=function(types){
		if(types.length<=0)return;
		var list=[];
		var length=this.readInt16();
		for(var row=0;row<length;row++){
			var values={};
			for(var i=0;i<types.length;i++){
				var type=types[i];

				if(types[i]=="int"){
					values[type]=this.readInt32();
				}else if(types[i]=="short"){
					values[type]=this.readInt16();
				}else if(types[i]=="float"){
					values[type]=this.readFloat32();
				}else if(types[i]=="double"){
					values[type]=this.readFloat64();
				}else if(types[i]=="string"){
					values[type]=this.readString();
				}
			}
			list[row]=values;
		}
		return list;
	}

	this.stringToUTF8=function(input) {
		for (var i = 0; i<input.length; i++) {
			var charCode = input.charCodeAt(i);
			
			// Check for a surrogate pair.
			if (0xD800 <= charCode && charCode <= 0xDBFF) {
				var lowCharCode = input.charCodeAt(++i);
				if (isNaN(lowCharCode)) {
					throw new Error(format(ERROR.MALFORMED_UNICODE, [charCode, lowCharCode]));
				}
				charCode = ((charCode - 0xD800)<<10) + (lowCharCode - 0xDC00) + 0x10000;
			}
			
			if (charCode <= 0x7F) {
				this.writeHex(charCode);
			} else if (charCode <= 0x7FF) {
				this.writeHex(charCode>>6  & 0x1F | 0xC0);
				this.writeHex(charCode     & 0x3F | 0x80);
			} else if (charCode <= 0xFFFF) {
				this.writeHex(charCode>>12 & 0x0F | 0xE0);    
				this.writeHex(charCode>>6  & 0x3F | 0x80);
				this.writeHex(charCode     & 0x3F | 0x80);
			} else {
				this.writeHex(charCode>>18 & 0x07 | 0xF0);    
				this.writeHex(charCode>>12 & 0x3F | 0x80);
				this.writeHex(charCode>>6  & 0x3F | 0x80);
				this.writeHex(charCode     & 0x3F | 0x80);
			};
		} 
		return this.byteStream;
	}

	this.UTF8Length=function(input) {
		var output = 0;
		for (var i = 0; i<input.length; i++) {
			var charCode = input.charCodeAt(i);
			if(charCode > 0x7FF){
				  // Surrogate pair means its a 4 byte character
				  if (0xD800 <= charCode && charCode <= 0xDBFF){
					  i++;
					  output++;
					}
			   		output +=3;
			}
			else if (charCode > 0x7F)
				output +=2;
			else
				output++;
		} 
		return output;
	}

	this.parseUTF8=function(input, offset, length) {
		var output = "";
		var utf16;
		var pos = offset;

		while (pos < offset+length)
		{
			var byte1 = input[pos++];
			if (byte1 < 128)
				utf16 = byte1;
			else 
			{
				var byte2 = input[pos++]-128;
				if (byte2 < 0) 
					throw new Error(format(ERROR.MALFORMED_UTF, [byte1.toString(16), byte2.toString(16),""]));
				if (byte1 < 0xE0)             // 2 byte character
					utf16 = 64*(byte1-0xC0) + byte2;
				else 
				{ 
					var byte3 = input[pos++]-128;
					if (byte3 < 0) 
						throw new Error(format(ERROR.MALFORMED_UTF, [byte1.toString(16), byte2.toString(16), byte3.toString(16)]));
					if (byte1 < 0xF0)        // 3 byte character
						utf16 = 4096*(byte1-0xE0) + 64*byte2 + byte3;
								else
								{
								   var byte4 = input[pos++]-128;
								   if (byte4 < 0) 
						throw new Error(format(ERROR.MALFORMED_UTF, [byte1.toString(16), byte2.toString(16), byte3.toString(16), byte4.toString(16)]));
								   if (byte1 < 0xF8)        // 4 byte character 
										   utf16 = 262144*(byte1-0xF0) + 4096*byte2 + 64*byte3 + byte4;
					   else                     // longer encodings are not supported  
						throw new Error(format(ERROR.MALFORMED_UTF, [byte1.toString(16), byte2.toString(16), byte3.toString(16), byte4.toString(16)]));
								}
				}
			}  

				if (utf16 > 0xFFFF)   // 4 byte character - express as a surrogate pair
				  {
					 utf16 -= 0x10000;
					 output += String.fromCharCode(0xD800 + (utf16 >> 10)); // lead character
					 utf16 = 0xDC00 + (utf16 & 0x3FF);  // trail character
				  }
			output += String.fromCharCode(utf16);
		}
		return output;
	}

	this.encode=function(bytes){
        for(var i = 0; i<bytes.length; i++){
            bytes[i] ^= 0xFF;
        }
        return bytes;
	}
}

 

转载于:https://my.oschina.net/appnet/blog/1647923

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值