• 【转】参照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
     
     在CODE上查看代码片派生到我的代码片
    1. var Struct = module.exports = {};  
    2.   
    3. Struct.TYPE = {  
    4.     int8:1,  
    5.     int16:2,  
    6.     int32:3,  
    7.     uint8:4,      
    8.     uint16:5,  
    9.     uint32:7,  
    10.     string:8,  
    11.     object:9,  
    12.     aint8:10,  
    13.     aint16:11,  
    14.     aint32:12,  
    15.     auint8:13,  
    16.     auint16:14,  
    17.     auint32:15,  
    18.     aobject:16  
    19. };  
    20.   
    21.   
    22. //  
    23. Struct.unpack = function(proto, buf) {  
    24.     var _unpack = function(proto, buf, pos) {  
    25.         var p = {};  
    26.         var ret;  
    27.         var length;  
    28.   
    29.         for (var k in proto) {  
    30.             var type = proto[k][0];  
    31.             if (typeof type == 'object') {  
    32.                 var json = type;  
    33.                 type = 'object';  
    34.             }  
    35.             if (proto[k].length == 2 && proto[k][1] == 'array') {  
    36.                 type = 'a' + type;  
    37.             }  
    38.             var value = [];  
    39.             switch(Struct.TYPE[type]) {  
    40.                 case Struct.TYPE.int8:  
    41.                     p[k] = buf.readInt8(pos);  
    42.                     pos += 1;  
    43.                     break;  
    44.                 case Struct.TYPE.int16:  
    45.                     p[k] = buf.readInt16BE(pos);  
    46.                     pos += 2;  
    47.                     break;  
    48.                 case Struct.TYPE.int32:  
    49.                     p[k] = buf.readInt32BE(pos);  
    50.                     pos += 4;  
    51.                     break;  
    52.                 case Struct.TYPE.uint8:  
    53.                     p[k] = buf.readUInt8(pos);  
    54.                     pos += 1;  
    55.                     break;  
    56.                 case Struct.TYPE.uint16:  
    57.                     p[k] = buf.readUInt16BE(pos);  
    58.                     pos += 2;  
    59.                     break;  
    60.                 case Struct.TYPE.uint32:  
    61.                     p[k] = buf.readUInt32BE(pos);  
    62.                     pos += 4;  
    63.                     break;  
    64.                 case Struct.TYPE.string:  
    65.                     ret = getLen(buf,pos);  
    66.                     pos = ret[1];  
    67.                     p[k] = buf.toString('utf-8',pos, pos + ret[0]);  
    68.                     pos += ret[0];  
    69.                     break;  
    70.                 case Struct.TYPE.object:  
    71.                     ret = _unpack(json, buf, pos);  
    72.                     p[k] = ret[0];  
    73.                     pos = ret[1];  
    74.                     break;  
    75.                 case Struct.TYPE.aint8:  
    76.                     ret = getLen(buf,pos);  
    77.                     length = ret[0];  
    78.                     pos = ret[1];  
    79.                     for (var i=0; i < length; i++) {  
    80.                         value.push(buf.readInt8(pos));  
    81.                         pos += 1;  
    82.                     }  
    83.                     p[k] = value;  
    84.                     break;  
    85.                 case Struct.TYPE.aint16:  
    86.                     ret = getLen(buf,pos);  
    87.                     length = ret[0];  
    88.                     pos = ret[1];  
    89.                     for (var i=0; i < length; i++) {  
    90.                         value.push(buf.readInt16BE(pos));  
    91.                         pos += 2;  
    92.                     }  
    93.                     p[k] = value;  
    94.                     break;  
    95.                 case Struct.TYPE.aint32:  
    96.                     ret = getLen(buf,pos);  
    97.                     length = ret[0];  
    98.                     pos = ret[1];  
    99.                     for (var i=0; i < length; i++) {  
    100.                         value.push(buf.readInt32BE(pos));  
    101.                         pos += 4;  
    102.                     }  
    103.                     p[k] = value;                 
    104.                     break;  
    105.                 case Struct.TYPE.auint8:  
    106.                     ret = getLen(buf,pos);  
    107.                     length = ret[0];  
    108.                     pos = ret[1];  
    109.                     for (var i=0; i < length; i++) {  
    110.                         value.push(buf.readUInt8(pos));  
    111.                         pos += 1;  
    112.                     }  
    113.                     p[k] = value;  
    114.                     break;  
    115.                 case Struct.TYPE.auint16:  
    116.                     ret = getLen(buf,pos);  
    117.                     length = ret[0];  
    118.                     pos = ret[1];  
    119.                     for (var i=0; i < length; i++) {  
    120.                         value.push(buf.readUInt16BE(pos));  
    121.                         pos += 2;  
    122.                     }  
    123.                     p[k] = value;  
    124.                     break;  
    125.                 case Struct.TYPE.auint32:  
    126.                     ret = getLen(buf,pos);  
    127.                     length = ret[0];  
    128.                     pos = ret[1];  
    129.                     for (var i=0; i < length; i++) {  
    130.                         value.push(buf.readUInt32BE(pos));  
    131.                         pos += 4;  
    132.                     }  
    133.                     p[k] = value;  
    134.                     break;  
    135.                 case Struct.TYPE.astring:  
    136.                     ret = getLen(buf,pos);  
    137.                     length = ret[0];  
    138.                     pos = ret[1];  
    139.                     for (var i=0; i < length; i++) {  
    140.                         ret = getLen(buf,pos);  
    141.                         pos = ret[1];  
    142.                         value.push(buf.toString('utf-8',pos, pos + ret[0]));  
    143.                         pos += ret[0];  
    144.                     }  
    145.                     p[k] = value;  
    146.                     break;  
    147.                 case Struct.TYPE.aobject:  
    148.                     ret = getLen(buf,pos);  
    149.                     length = ret[0];  
    150.                     pos = ret[1];  
    151.                     for (var i=0; i < length; i++) {  
    152.                         ret = _unpack(json, buf, pos);  
    153.                         pos = ret[1];  
    154.                         value.push(ret[0]);  
    155.                     }  
    156.                     p[k] = value;  
    157.                     break;  
    158.             }  
    159.         }  
    160.   
    161.         return [p,pos];  
    162.     }  
    163.   
    164.     return _unpack(proto, buf, 0)[0];  
    165. }  
    166.   
    167. Struct.pack = function(proto, msg) {  
    168.     function _pack(proto, msg, buf, pos) {  
    169.         for (var k in proto) {  
    170.             var type = proto[k][0];  
    171.             if (typeof type == 'object') {  
    172.                 var json = type;  
    173.                 type = 'object';  
    174.             }  
    175.             if (proto[k].length == 2 && proto[k][1] == 'array') {  
    176.                 type = 'a' + type;  
    177.             }  
    178.             switch(Struct.TYPE[type]) {  
    179.                 case Struct.TYPE.int8:  
    180.                     buf.writeInt8(msg[k], pos);  
    181.                     pos += 1;  
    182.                     break;  
    183.                 case Struct.TYPE.int16:  
    184.                     buf.writeInt16BE(msg[k], pos);  
    185.                     pos += 2;  
    186.                     break;  
    187.                 case Struct.TYPE.int32:  
    188.                     buf.writeInt32BE(msg[k],pos);  
    189.                     pos += 4;  
    190.                     break;  
    191.                 case Struct.TYPE.uint8:  
    192.                     buf.writeUInt8(msg[k], pos);  
    193.                     pos += 1;  
    194.                     break;  
    195.                 case Struct.TYPE.uint16:  
    196.                     buf.writeUInt16BE(msg[k],pos);  
    197.                     pos += 2;  
    198.                     break;  
    199.                 case Struct.TYPE.uint32:  
    200.                     buf.writeUInt32BE(msg[k], pos);  
    201.                     pos += 4;  
    202.                     break;  
    203.                 case Struct.TYPE.string:  
    204.                     pos = setLen(buf, msg[k].length, pos);  
    205.                     buf.write(msg[k],pos);  
    206.                     pos += msg[k].length;  
    207.                     break;  
    208.                 case Struct.TYPE.object:  
    209.                     pos = _pack(json, msg[k], buf, pos);  
    210.                     break;  
    211.   
    212.                 case Struct.TYPE.aint8:  
    213.                     var list = msg[k];  
    214.                     pos = setLen(buf, list.length, pos);  
    215.                     for (var i=0; i < list.length; i++) {  
    216.                         buf.writeInt8(list[i], pos++);  
    217.                     }  
    218.                     break;  
    219.                 case Struct.TYPE.aint16:  
    220.                     var list = msg[k];  
    221.                     pos = setLen(buf, list.length, pos);  
    222.                     for (var i=0; i < list.length; i++) {  
    223.                         buf.writeInt16BE(list[i], pos);  
    224.                         pos += 2;  
    225.                     }  
    226.                     break;  
    227.                 case Struct.TYPE.aint32:  
    228.                     var list = msg[k];  
    229.                     pos = setLen(buf, list.length, pos);  
    230.                     for (var i=0; i < list.length; i++) {  
    231.                         buf.writeInt32BE(list[i], pos);  
    232.                         pos += 4;  
    233.                     }                     
    234.                     break;  
    235.                 case Struct.TYPE.auint8:  
    236.                     var list = msg[k];  
    237.                     pos = setLen(buf, list.length, pos);  
    238.                     for (var i=0; i < list.length; i++) {  
    239.                         buf.writeUInt8(list[i], pos++);  
    240.                     }  
    241.                     break;  
    242.                 case Struct.TYPE.auint16:  
    243.                     var list = msg[k];  
    244.                     pos = setLen(buf, list.length, pos);  
    245.                     for (var i=0; i < list.length; i++) {  
    246.                         buf.writeUInt16BE(list[i], pos);  
    247.                         pos += 2;  
    248.                     }  
    249.                     break;  
    250.                 case Struct.TYPE.auint32:  
    251.                     var list = msg[k];  
    252.                     pos = setLen(buf, list.length, pos);  
    253.                     for (var i=0; i < list.length; i++) {  
    254.                         buf.writeUInt32BE(list[i], pos);  
    255.                         pos +=4;  
    256.                     }  
    257.                     break;    
    258.                 case Struct.TYPE.astring:  
    259.                     var list = msg[k];  
    260.                     pos = setLen(buf, list.length, pos);  
    261.                     for (var i=0; i < list.length; i++) {  
    262.                         pos = setLen(buf, list[i].length,pos);  
    263.                         buf.write(list[i],pos);  
    264.                         pos += list[i].length;  
    265.                     }                     
    266.                     break;  
    267.                 case Struct.TYPE.aobject:  
    268.                     var list = msg[k];  
    269.                     pos = setLen(buf, list.length, pos);  
    270.                     for (var i=0; i < list.length; i++) {  
    271.                         pos = _pack(json, list[i], buf, pos);  
    272.                     }  
    273.                     break;  
    274.             }  
    275.             //console.log('key: ' + k);  
    276.             //console.log('pos: ' + pos);  
    277.         }  
    278.         return pos;  
    279.     }  
    280.   
    281.     var length = jsonSize(proto, msg);  
    282.     var buf = new Buffer(length);  
    283.     _pack(proto, msg, buf, 0);  
    284.     return buf;  
    285. };  
    286.   
    287.   
    288. var jsonSize = function(proto, msg) {  
    289.     function _size(proto, msg) {  
    290.         var size = 0;  
    291.         var buf = new Buffer(4);  
    292.         for (var k in proto) {  
    293.             var type = proto[k][0];  
    294.             if (typeof type == 'object') {  
    295.                 var json = type;  
    296.                 type = 'object';  
    297.             }  
    298.             if (proto[k].length == 2 && proto[k][1] == 'array') {  
    299.                 type = 'a' + type;  
    300.             }  
    301.             switch(Struct.TYPE[type]) {  
    302.                 case Struct.TYPE.int8:  
    303.                     size += 1;  
    304.                     break;  
    305.                 case Struct.TYPE.int16:  
    306.                     size += 2;  
    307.                     break;  
    308.                 case Struct.TYPE.int32:  
    309.                     size += 4;  
    310.                     break;  
    311.                 case Struct.TYPE.uint8:  
    312.                     size += 1;  
    313.                     break;  
    314.                 case Struct.TYPE.uint16:  
    315.                     size += 2;  
    316.                     break;  
    317.                 case Struct.TYPE.uint32:  
    318.                     size += 4;  
    319.                     break;  
    320.                 case Struct.TYPE.string:  
    321.                     size += setLen(buf, msg[k].length, 0);  
    322.                     size += msg[k].length;  
    323.                     break;  
    324.                 case Struct.TYPE.object:  
    325.                     size += _size(json, msg[k]);  
    326.                     break;  
    327.                 case Struct.TYPE.aint8:  
    328.                     var list = msg[k];  
    329.                     size += setLen(buf, list.length, 0);  
    330.                     size += list.length;  
    331.                     break;  
    332.                 case Struct.TYPE.aint16:  
    333.                     var list = msg[k];  
    334.                     size += setLen(buf, list.length, 0);  
    335.                     size += list.length * 2;  
    336.                     break;  
    337.                 case Struct.TYPE.aint32:  
    338.                     var list = msg[k];  
    339.                     size += setLen(buf, list.length, 0);  
    340.                     size += list.length * 4;      
    341.                     break;  
    342.                 case Struct.TYPE.auint8:  
    343.                     var list = msg[k];  
    344.                     size += setLen(buf, list.length, 0);  
    345.                     size += list.length;      
    346.                     break;  
    347.                 case Struct.TYPE.auint16:  
    348.                     var list = msg[k];  
    349.                     size += setLen(buf, list.length, 0);  
    350.                     size += list.length * 2;      
    351.                     break;  
    352.                 case Struct.TYPE.auint32:  
    353.                     var list = msg[k];  
    354.                     size += setLen(buf, list.length, 0);  
    355.                     size += list.length * 4;      
    356.                     break;  
    357.                 case Struct.TYPE.astring:  
    358.                     var list = msg[k];  
    359.                     size += setLen(buf, list.length, 0);  
    360.                     for (var i=0; i < list.length; i++) {  
    361.                         size += setLen(buf, list[i].length,0);  
    362.                         size += list[i].length;  
    363.                     }                     
    364.                     break;  
    365.                 case Struct.TYPE.aobject:  
    366.                     var list = msg[k];  
    367.                     size += setLen(buf, list.length, 0);  
    368.                     for (var i=0; i < list.length; i++) {  
    369.                         size += _size(json, list[i]);  
    370.                     }  
    371.                     break;  
    372.             }  
    373.         }  
    374.         return size;  
    375.     }  
    376.     var size = 0;  
    377.     size += _size(proto, msg);  
    378.     return size;  
    379. }  
    380.   
    381. var MASK_7 = (1<<7) - 1;  
    382. var MASK_8 = (1<<8) - 1;  
    383. var MAX_LEN = (1<<28);  
    384.   
    385.   
    386. //不定长记录长度,1-4个字节,和MQTT表示长度的方法相同  
    387. var getLen = function(buf, pos) {  
    388.     var len = 0;  
    389.     for (var i = 0; i < 4; i++) {  
    390.         var value = buf.readUInt8(pos);  
    391.         //console.log('get: ' + value);  
    392.         len += (value & MASK_7) << (7 * i);  
    393.         pos += 1;  
    394.         if (value < 127) {   
    395.             break;  
    396.         }  
    397.     }  
    398.     return [len, pos];  
    399. }  
    400.   
    401. var setLen = function(buf, len, pos) {  
    402.   
    403.     while(len > 0) {  
    404.         var value = len & MASK_8;  
    405.         len = len >> 7;  
    406.         if (len > 0) {  
    407.             value = value | 128;  
    408.         }  
    409.         buf.writeUInt8(value, pos++);  
    410.     }  
    411.     return pos;  
    412. }  

    测试代码:

    [javascript] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. var Struct = require('./struct');  
    2.   
    3. var proto = {  
    4.     int8   : ['int8'],  
    5.     int16  : ['int16'],  
    6.     int32  : ['int32'],  
    7.     uint8  : ['uint8'],  
    8.     uint16 : ['uint16'],  
    9.     uint32 : ['uint32'],  
    10.     string : ['string'],  
    11.     aint8  : ['int8', 'array'],  
    12.     aint16 : ['int16', 'array'],  
    13.     aint32 : ['int32', 'array'],  
    14.     auint8 : ['uint8', 'array'],  
    15.     auint16: ['uint16', 'array'],  
    16.     auint32: ['uint32', 'array'],  
    17.     object : [  
    18.         {int8: ['int8'], int16: ['int16'], string: ['string'], astring: ['astring']}  
    19.     ],  
    20.     aobject : [  
    21.         {int8: ['int8'], int16: ['int16'], string: ['string'], astring: ['astring']},  
    22.         'array'  
    23.     ],  
    24.     astring: ['string', 'array']  
    25. }  
    26.   
    27. var msg = {  
    28.     int8   : 12,  
    29.     int16  : 1234,  
    30.     int32  : 12345,  
    31.     uint8  : 130,// > 128  
    32.     uint16 : 32800, // >> 128 * 256  
    33.     uint32 : 3221245472, // >> 3 * (1<<30)  
    34.     string : 'hello world',  
    35.     aint8  : [-1, -2, -3, -5, -6],  
    36.     aint16 : [-11, -12, -13, -15, -17],  
    37.     aint32 : [-337, -338, -339, -3310, -3311],  
    38.     auint8 : [1, 2, 3, 4],  
    39.     auint16: [8, 9, 10, 11, 12],  
    40.     auint32: [12, 13, 15, 16],  
    41.     object : {int8: 12, int16: 1234, string: 'somebady', astring: ['save me', 'Dont stop me now']},  
    42.     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']}],  
    43.     astring: ['melo', 'kaka', 'much', 'save']  
    44. }  
    45.   
    46.   
    47. var buf = Struct.pack(proto, msg);  
    48. console.log(buf);  
    49.   
    50. var remsg = Struct.unpack(proto, buf);  
    51. console.log(JSON.stringify(remsg));  
  • 相关阅读:
    「AHOI2018 初中组」根式化简(分解质因数+推性质)
    「TJOI2018」智力竞赛(二分+DAG最小可相交路径覆盖)
    「LibreOJ NOI Round #1」动态几何问题(mobius反演+分块)
    「LibreOJ NOI Round #1」北校门外的回忆(找性质+倍增+线段树)
    USACO 2020 Open Contest, Platinum(exercise)(min-max容斥+计数dp)
    「LibreOJ β Round」ZQC 的截图(随机+hash)
    BM算法模板
    「THUSCH 2017」如果奇迹有颜色(burnside引理+状压dp+打表+BM+常系数齐次线性递推)
    「THUSCH 2017」换桌(zkw费用流)—对几种费用流算法的总结
    iOS学习笔记42-Swift(二)函数和闭包
  • 原文地址:https://www.cnblogs.com/mimime/p/5466425.html
Copyright © 2020-2023  润新知