参照protobuf,将json数据转换成二进制在网络中传输。

json数据格式在网络中传输需要的数据比二进制庞大太多,我们可以省去key,外加将数字不需要编码成字符串,直接二进制编码就OK。

pack : 将json压包,unpack解包成json。

var Struct = module.exports = {};

Struct.TYPE = {
	int8:1,
	int16:2,
	int32:3,
	uint8:4,
	uint16:5,
	uint32:7,
	string:8,
	object:9,
	aint8:10,
	aint16:11,
	aint32:12,
	auint8:13,
	auint16:14,
	auint32:15,
	aobject:16
};

//
Struct.unpack = function(proto, buf) {
	var _unpack = function(proto, buf, pos) {
		var p = {};
		var ret;
		var length;

		for (var k in proto) {
			var type = proto[k][0];
			if (typeof type == 'object') {
				var json = type;
				type = 'object';
			}
			if (proto[k].length == 2 && proto[k][1] == 'array') {
				type = 'a' + type;
			}
			var value = [];
			switch(Struct.TYPE[type]) {
				case Struct.TYPE.int8:
					p[k] = buf.readInt8(pos);
					pos += 1;
					break;
				case Struct.TYPE.int16:
					p[k] = buf.readInt16BE(pos);
					pos += 2;
					break;
				case Struct.TYPE.int32:
					p[k] = buf.readInt32BE(pos);
					pos += 4;
					break;
				case Struct.TYPE.uint8:
					p[k] = buf.readUInt8(pos);
					pos += 1;
					break;
				case Struct.TYPE.uint16:
					p[k] = buf.readUInt16BE(pos);
					pos += 2;
					break;
				case Struct.TYPE.uint32:
					p[k] = buf.readUInt32BE(pos);
					pos += 4;
					break;
				case Struct.TYPE.string:
					ret = getLen(buf,pos);
					pos = ret[1];
					p[k] = buf.toString('utf-8',pos, pos + ret[0]);
					pos += ret[0];
					break;
				case Struct.TYPE.object:
					ret = _unpack(json, buf, pos);
					p[k] = ret[0];
					pos = ret[1];
					break;
				case Struct.TYPE.aint8:
					ret = getLen(buf,pos);
					length = ret[0];
					pos = ret[1];
					for (var i=0; i < length; i++) {
						value.push(buf.readInt8(pos));
						pos += 1;
					}
					p[k] = value;
					break;
				case Struct.TYPE.aint16:
					ret = getLen(buf,pos);
					length = ret[0];
					pos = ret[1];
					for (var i=0; i < length; i++) {
						value.push(buf.readInt16BE(pos));
						pos += 2;
					}
					p[k] = value;
					break;
				case Struct.TYPE.aint32:
					ret = getLen(buf,pos);
					length = ret[0];
					pos = ret[1];
					for (var i=0; i < length; i++) {
						value.push(buf.readInt32BE(pos));
						pos += 4;
					}
					p[k] = value;
					break;
				case Struct.TYPE.auint8:
					ret = getLen(buf,pos);
					length = ret[0];
					pos = ret[1];
					for (var i=0; i < length; i++) {
						value.push(buf.readUInt8(pos));
						pos += 1;
					}
					p[k] = value;
					break;
				case Struct.TYPE.auint16:
					ret = getLen(buf,pos);
					length = ret[0];
					pos = ret[1];
					for (var i=0; i < length; i++) {
						value.push(buf.readUInt16BE(pos));
						pos += 2;
					}
					p[k] = value;
					break;
				case Struct.TYPE.auint32:
					ret = getLen(buf,pos);
					length = ret[0];
					pos = ret[1];
					for (var i=0; i < length; i++) {
						value.push(buf.readUInt32BE(pos));
						pos += 4;
					}
					p[k] = value;
					break;
				case Struct.TYPE.astring:
					ret = getLen(buf,pos);
					length = ret[0];
					pos = ret[1];
					for (var i=0; i < length; i++) {
						ret = getLen(buf,pos);
						pos = ret[1];
						value.push(buf.toString('utf-8',pos, pos + ret[0]));
						pos += ret[0];
					}
					p[k] = value;
					break;
				case Struct.TYPE.aobject:
					ret = getLen(buf,pos);
					length = ret[0];
					pos = ret[1];
					for (var i=0; i < length; i++) {
						ret = _unpack(json, buf, pos);
						pos = ret[1];
						value.push(ret[0]);
					}
					p[k] = value;
					break;
			}
		}

		return [p,pos];
	}

	return _unpack(proto, buf, 0)[0];
}

Struct.pack = function(proto, msg) {
	function _pack(proto, msg, buf, pos) {
		for (var k in proto) {
			var type = proto[k][0];
			if (typeof type == 'object') {
				var json = type;
				type = 'object';
			}
			if (proto[k].length == 2 && proto[k][1] == 'array') {
				type = 'a' + type;
			}
			switch(Struct.TYPE[type]) {
				case Struct.TYPE.int8:
					buf.writeInt8(msg[k], pos);
					pos += 1;
					break;
				case Struct.TYPE.int16:
					buf.writeInt16BE(msg[k], pos);
					pos += 2;
					break;
				case Struct.TYPE.int32:
					buf.writeInt32BE(msg[k],pos);
					pos += 4;
					break;
				case Struct.TYPE.uint8:
					buf.writeUInt8(msg[k], pos);
					pos += 1;
					break;
				case Struct.TYPE.uint16:
					buf.writeUInt16BE(msg[k],pos);
					pos += 2;
					break;
				case Struct.TYPE.uint32:
					buf.writeUInt32BE(msg[k], pos);
					pos += 4;
					break;
				case Struct.TYPE.string:
					pos = setLen(buf, msg[k].length, pos);
					buf.write(msg[k],pos);
					pos += msg[k].length;
					break;
				case Struct.TYPE.object:
					pos = _pack(json, msg[k], buf, pos);
					break;

				case Struct.TYPE.aint8:
					var list = msg[k];
					pos = setLen(buf, list.length, pos);
					for (var i=0; i < list.length; i++) {
						buf.writeInt8(list[i], pos++);
					}
					break;
				case Struct.TYPE.aint16:
					var list = msg[k];
					pos = setLen(buf, list.length, pos);
					for (var i=0; i < list.length; i++) {
						buf.writeInt16BE(list[i], pos);
						pos += 2;
					}
					break;
				case Struct.TYPE.aint32:
					var list = msg[k];
					pos = setLen(buf, list.length, pos);
					for (var i=0; i < list.length; i++) {
						buf.writeInt32BE(list[i], pos);
						pos += 4;
					}
					break;
				case Struct.TYPE.auint8:
					var list = msg[k];
					pos = setLen(buf, list.length, pos);
					for (var i=0; i < list.length; i++) {
						buf.writeUInt8(list[i], pos++);
					}
					break;
				case Struct.TYPE.auint16:
					var list = msg[k];
					pos = setLen(buf, list.length, pos);
					for (var i=0; i < list.length; i++) {
						buf.writeUInt16BE(list[i], pos);
						pos += 2;
					}
					break;
				case Struct.TYPE.auint32:
					var list = msg[k];
					pos = setLen(buf, list.length, pos);
					for (var i=0; i < list.length; i++) {
						buf.writeUInt32BE(list[i], pos);
						pos +=4;
					}
					break;
				case Struct.TYPE.astring:
					var list = msg[k];
					pos = setLen(buf, list.length, pos);
					for (var i=0; i < list.length; i++) {
						pos = setLen(buf, list[i].length,pos);
						buf.write(list[i],pos);
						pos += list[i].length;
					}
					break;
				case Struct.TYPE.aobject:
					var list = msg[k];
					pos = setLen(buf, list.length, pos);
					for (var i=0; i < list.length; i++) {
						pos = _pack(json, list[i], buf, pos);
					}
					break;
			}
			//console.log('key: ' + k);
			//console.log('pos: ' + pos);
		}
		return pos;
	}

	var length = jsonSize(proto, msg);
	var buf = new Buffer(length);
	_pack(proto, msg, buf, 0);
	return buf;
};

var jsonSize = function(proto, msg) {
	function _size(proto, msg) {
		var size = 0;
		var buf = new Buffer(4);
		for (var k in proto) {
			var type = proto[k][0];
			if (typeof type == 'object') {
				var json = type;
				type = 'object';
			}
			if (proto[k].length == 2 && proto[k][1] == 'array') {
				type = 'a' + type;
			}
			switch(Struct.TYPE[type]) {
				case Struct.TYPE.int8:
					size += 1;
					break;
				case Struct.TYPE.int16:
					size += 2;
					break;
				case Struct.TYPE.int32:
					size += 4;
					break;
				case Struct.TYPE.uint8:
					size += 1;
					break;
				case Struct.TYPE.uint16:
					size += 2;
					break;
				case Struct.TYPE.uint32:
					size += 4;
					break;
				case Struct.TYPE.string:
					size += setLen(buf, msg[k].length, 0);
					size += msg[k].length;
					break;
				case Struct.TYPE.object:
					size += _size(json, msg[k]);
					break;
				case Struct.TYPE.aint8:
					var list = msg[k];
					size += setLen(buf, list.length, 0);
					size += list.length;
					break;
				case Struct.TYPE.aint16:
					var list = msg[k];
					size += setLen(buf, list.length, 0);
					size += list.length * 2;
					break;
				case Struct.TYPE.aint32:
					var list = msg[k];
					size += setLen(buf, list.length, 0);
					size += list.length * 4;
					break;
				case Struct.TYPE.auint8:
					var list = msg[k];
					size += setLen(buf, list.length, 0);
					size += list.length;
					break;
				case Struct.TYPE.auint16:
					var list = msg[k];
					size += setLen(buf, list.length, 0);
					size += list.length * 2;
					break;
				case Struct.TYPE.auint32:
					var list = msg[k];
					size += setLen(buf, list.length, 0);
					size += list.length * 4;
					break;
				case Struct.TYPE.astring:
					var list = msg[k];
					size += setLen(buf, list.length, 0);
					for (var i=0; i < list.length; i++) {
						size += setLen(buf, list[i].length,0);
						size += list[i].length;
					}
					break;
				case Struct.TYPE.aobject:
					var list = msg[k];
					size += setLen(buf, list.length, 0);
					for (var i=0; i < list.length; i++) {
						size += _size(json, list[i]);
					}
					break;
			}
		}
		return size;
	}
	var size = 0;
	size += _size(proto, msg);
	return size;
}

var MASK_7 = (1<<7) - 1;
var MASK_8 = (1<<8) - 1;
var MAX_LEN = (1<<28);

//不定长记录长度,1-4个字节,和MQTT表示长度的方法相同
var getLen = function(buf, pos) {
	var len = 0;
	for (var i = 0; i < 4; i++) {
		var value = buf.readUInt8(pos);
		//console.log('get: ' + value);
		len += (value & MASK_7) << (7 * i);
		pos += 1;
		if (value < 127) {
			break;
		}
	}
	return [len, pos];
}

var setLen = function(buf, len, pos) {

	while(len > 0) {
		var value = len & MASK_8;
		len = len >> 7;
		if (len > 0) {
			value = value | 128;
		}
		buf.writeUInt8(value, pos++);
	}
	return pos;
}

测试代码:

var Struct = require('./struct');

var proto = {
    int8   : ['int8'],
    int16  : ['int16'],
    int32  : ['int32'],
    uint8  : ['uint8'],
    uint16 : ['uint16'],
    uint32 : ['uint32'],
    string : ['string'],
    aint8  : ['int8', 'array'],
    aint16 : ['int16', 'array'],
    aint32 : ['int32', 'array'],
    auint8 : ['uint8', 'array'],
    auint16: ['uint16', 'array'],
    auint32: ['uint32', 'array'],
    object : [
        {int8: ['int8'], int16: ['int16'], string: ['string'], astring: ['astring']}
    ],
    aobject : [
        {int8: ['int8'], int16: ['int16'], string: ['string'], astring: ['astring']},
        'array'
    ],
    astring: ['string', 'array']
}

var msg = {
    int8   : 12,
    int16  : 1234,
    int32  : 12345,
    uint8  : 130,// > 128
    uint16 : 32800, // >> 128 * 256
    uint32 : 3221245472, // >> 3 * (1<<30)
    string : 'hello world',
    aint8  : [-1, -2, -3, -5, -6],
    aint16 : [-11, -12, -13, -15, -17],
    aint32 : [-337, -338, -339, -3310, -3311],
    auint8 : [1, 2, 3, 4],
    auint16: [8, 9, 10, 11, 12],
    auint32: [12, 13, 15, 16],
    object : {int8: 12, int16: 1234, string: 'somebady', astring: ['save me', 'Dont stop me now']},
    aobject : [{int8: 12, int16: 1234, string: 'somebady', astring: ['save me', 'Dont stop me now']}, {int8: 12, int16: 1234, string: 'somebady', astring: ['save me', 'Dont stop me now']}],
    astring: ['melo', 'kaka', 'much', 'save']
}

var buf = Struct.pack(proto, msg);
console.log(buf);

var remsg = Struct.unpack(proto, buf);
console.log(JSON.stringify(remsg));

参照protobuf,将json数据转换成二进制在网络中传输。

时间: 2024-10-13 12:30:02

参照protobuf,将json数据转换成二进制在网络中传输。的相关文章

【转】参照protobuf,将json数据转换成二进制在网络中传输。

http://blog.csdn.net/gamesofsailing/article/details/38335753?utm_source=tuicool&utm_medium=referral json数据格式在网络中传输需要的数据比二进制庞大太多,我们可以省去key,外加将数字不需要编码成字符串,直接二进制编码就OK. pack : 将json压包,unpack解包成json. [javascript] view plain copy var Struct = module.export

4.使用Jackson将Json数据转换成实体数据

Jar下载地址:http://jackson.codehaus.org/ 注意:类中的属性名称一定要和Json数据的属性名称一致(大小写敏感),类之间的嵌套关系也应该和Json数据的嵌套关系一致. 4.使用Jackson将Json数据转换成实体数据,布布扣,bubuko.com

利用JAVA反射机制将JSON数据转换成JAVA对象

net.sf.json.JSONObject为我们提供了toBean方法用来转换为JAVA对象, 功能更为强大,  这里借鉴采用JDK的反射机制, 作为简单的辅助工具使用,   有些数据类型需要进行转换, 根据需要进行扩展,  这里可以处理Long和Date类型. 只支持单个JSONObject对象的处理,   对于复杂的JSON对象, 如JSONArray数组, 可考虑先遍历, 获取JSONObject后再进行处理. package common; import java.lang.refle

将JSON数据转换成Java的实体类

思路:首先将JSON格式的数据转换成JSONObject,然后将JSONObject转换成Java的实体类(其中类属性包括List等类型) Java实体类: SearchFilter 类 1 public class SearchFilter { 2 private String groupOp; 3 4 private List<SearchRule> rules; 5 6 public String getGroupOp() { 7 return groupOp; 8 } 9 10 pub

我爱java系列之---【如何把数据库中查到的Skulist数据转换成elastic索引库中SkuInfo类数据?】

这里采用的是阿里的json转换,比传统的遍历然后再一个一个封装速度快多了.(例:sku类转换称skuinfo类) public void importDataToEs(String spuId) { List<Sku> skuList = skuFeign.findListBySpuId(spuId); if (null == skuList){ throw new RuntimeException("此商品对应的库存数据为空,无数据导入索引库:"+spuId); } //

把HDFS里的json数据转换成csv格式

1. 全景图 . 2. 用ListHDFS获取所有文件名 3. 用FetchHDFS 取出json 数据 4. 用ExecuteScript 转换 import org.apache.commons.io.IOUtilsimport java.nio.charset.*import java.text.SimpleDateFormatimport groovy.json.* def flowFile = session.get() flowFile = session.write(flowFil

把json数据转换成集合

Sting MessageList="";JSONArray json = JSONArray.fromObject(MessageList);JSONObject object = null;List<Object> messageList = new ArrayList<>();Message t=null;for (int i = 0; i < json.size(); i++) { object = JSONObject.fromObject(js

json数据转换成结构体

package main import ( "encoding/json" "fmt" ) type IT1 struct { Company string `json:"company"` Subjects []string `json:"subjects"` IsOk bool `json:"isok"` Price float64 `json:"price"` } type IT2

如何用Google APIs和Google的应用系统进行集成(7)----在把JSON转换成XML数据过程中,JSON数据中包含违背XML数据规范:XML节点名不能只是数字的解决方案

http://passport.baidu.com/?business&un=%E6%8C%89%E6%91%A9%E7%BE%8E%E5%A5%B3%E6%89%BE%E5%89%91%E6%B2%B3#0 http://passport.baidu.com/?business&un=%E5%8C%85%E5%A4%9C%E9%95%87%E8%BF%9C%E7%BE%8E%E5%A5%B3%E6%89%BE#0 http://passport.baidu.com/?business&a