From c1b5bee86c302b0cd284d3dd6220636695d62ba3 Mon Sep 17 00:00:00 2001 From: zswang Date: Thu, 5 Nov 2015 18:07:11 +0800 Subject: [PATCH] add schema "virtual". --- bower.json | 2 +- example.jdists.js | 35 +++--- jpacks.dev.js | 186 +++++++++++++++++++++------- jpacks.js | 181 +++++++++++++++++++++------ jpacks.min.js | 2 +- package.json | 4 +- schemas-extend/bigint.js | 10 +- schemas-extend/protobuf.js | 8 +- schemas-extend/zlib.js | 10 +- src/jpacks.js | 2 + src/schema.js | 46 ++++--- src/schemas/array.js | 11 +- src/schemas/bytes.js | 2 +- src/schemas/cases.js | 2 +- src/schemas/cstring.js | 2 +- src/schemas/depend.js | 4 +- src/schemas/enums.js | 6 +- src/schemas/number.js | 2 +- src/schemas/object.js | 4 +- src/schemas/parse.js | 2 +- src/schemas/string.js | 2 - src/schemas/union.js | 2 +- src/schemas/virtual.js | 117 ++++++++++++++++++ test/example.js | 243 +++++++++++++++++++++++-------------- version.jdists | 1 + 25 files changed, 635 insertions(+), 251 deletions(-) create mode 100644 src/schemas/virtual.js diff --git a/bower.json b/bower.json index 0a8b147..9734ed6 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "jpacks", "description": "Binary data packing and unpacking.", - "version": "0.3.13", + "version": "0.3.15", "homepage": "https://github.com/zswang/jpacks", "authors": { "name": "zswang", diff --git a/example.jdists.js b/example.jdists.js index 798dbd3..58a760d 100644 --- a/example.jdists.js +++ b/example.jdists.js @@ -39,23 +39,18 @@ forEach(function (item) { }); /**/ - - - - - - - - - - - - - - - - - - - -/**/ +/**/ +function (content) { + content = content.replace(/^\s*\*\s*@example\s*(.*)$/mg, + ' it("$1", function () {'); + content = content.replace(/^\s*```js\s*$/mg, ''); + content = content.replace(/\/\/ -?>\s*(.*)/gm, function (all, output) { + return ' assert.equal(printValue, ' + JSON.stringify(output) + '); printValue = undefined;' + }); + content = content.replace(/console\.log/g, 'print'); + content = content.replace(/^\s*```\s*$/mg, + ' });'); + return content; +} +/**/ +/**/ diff --git a/jpacks.dev.js b/jpacks.dev.js index 7ce9264..5b87b31 100644 --- a/jpacks.dev.js +++ b/jpacks.dev.js @@ -5,7 +5,7 @@ * Binary data packing and unpacking. * @author * zswang (http://weibo.com/zswang) - * @version 0.3.13 + * @version 0.3.15 * @date 2015-11-05 */ function createSchema() { @@ -38,7 +38,7 @@ */ function Schema(options) { var self = this; - Object.keys(options).forEach(function (key) { + Object.keys(options).forEach(function(key) { self[key] = options[key]; }); } @@ -49,7 +49,7 @@ * @param {Schema|string|Function} schema 数据结构或者数据结构名 * @return {boolean} 返回是否定义成功 */ - Schema.register = function (name, schema) { + Schema.register = function(name, schema) { /**/ if (typeof name === 'undefined') { throw new Error('Parameter "name" is undefined.'); @@ -93,7 +93,7 @@ * function _pattern(schema) {} * ]]] */ - Schema.pushPattern = function (pattern) { + Schema.pushPattern = function(pattern) { /**/ if (typeof pattern !== 'function') { return; @@ -107,7 +107,7 @@ * @param {string|Object|Schema} schema 数据结构名 * @return {Schema} 返回名字对应的数据结构 */ - Schema.from = function (schema) { + Schema.from = function(schema) { /**/ if (typeof schema === 'undefined') { // 无效数据 return; @@ -147,7 +147,7 @@ */ function setDefaultOptions(options) { options = options || {}; - Object.keys(options).forEach(function (key) { + Object.keys(options).forEach(function(key) { defaultOptions[key] = options[key]; }); } @@ -187,7 +187,7 @@ buffer = arrayBufferFrom(buffer); // 确保是 ArrayBuffer 类型 options = options || {}; offsets = offsets || [0]; - Object.keys(defaultOptions).forEach(function (key) { + Object.keys(defaultOptions).forEach(function(key) { if (typeof options[key] === 'undefined') { options[key] = defaultOptions[key]; } @@ -213,7 +213,7 @@ } buffer = buffer || []; options = options || {}; - Object.keys(defaultOptions).forEach(function (key) { + Object.keys(defaultOptions).forEach(function(key) { if (typeof options[key] === 'undefined') { options[key] = defaultOptions[key]; } @@ -294,39 +294,45 @@ return result.join(); } function scan(obj) { + // if (obj === null) { + // return 'null'; + // } if (!obj) { return obj; } if (obj.namespace) { if (obj.namespace === 'number') { - return obj.name; + return "'" + obj.name + "'"; } if (obj.args) { return obj.namespace + '(' + stringify.apply(null, obj.args) + ')'; } - return obj.namespace; - } - if (obj.name) { - return obj.name; + return "'" + obj.namespace + "'"; } if (typeof obj === 'function') { - obj.name = '_pack_fn' + (guid++); - Schema.define(obj.name, obj); - return obj.name; - } - if (typeof obj === 'object') { + if (!obj.name) { + obj.name = '_pack_fn' + (guid++); + Schema.define(obj.name, obj); + } + } else if (typeof obj === 'object') { var result = new obj.constructor(); - Object.keys(obj).forEach(function (key) { + Object.keys(obj).forEach(function(key) { result[key] = scan(obj[key]); }); return result; } + if (obj.name) { + return "'" + obj.name + "'"; + } + if (typeof obj === 'string') { + return "'" + obj + "'"; + } return obj; } return JSON.stringify(scan(obj) || '').replace(/"/g, ''); } Schema.stringify = stringify; - Schema.prototype.toString = function () { + Schema.prototype.toString = function() { return stringify(this); }; return Schema; @@ -359,7 +365,7 @@ }); var _schema = _.union(_map, 8); console.log(_.stringify(_schema)); - // > union({bytes:array(uint8,8),int8:int8,int16:int16,int32:int32,uint8:uint8,uint16:uint16,uint32:uint32,float32:float32,float64:float64,shortint:shortint,smallint:smallint,longint:longint,byte:byte,word:word,longword:longword},8) + // > union({bytes:array('uint8',8),int8:'int8',int16:'int16',int32:'int32',uint8:'uint8',uint16:'uint16',uint32:'uint32',float32:'float32',float64:'float64',shortint:'shortint',smallint:'smallint',longint:'longint',byte:'byte',word:'word',longword:'longword'},8) var buffer = _.pack(_schema, { bytes: [0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89] }); @@ -471,7 +477,7 @@ var _ = jpacks; var _schema = jpacks.array('int16', 2); console.log(String(_schema)); - // > array(int16,2) + // > array('int16',2) var value = [12337, 12851]; var buffer = jpacks.pack(_schema, value); console.log(buffer.join(' ')); @@ -484,7 +490,7 @@ var _ = jpacks; var _schema = jpacks.array('int16', 'int8'); console.log(String(_schema)); - // > array(int16,int8) + // > array('int16','int8') var value = [12337, 12851]; var buffer = jpacks.pack(_schema, value); console.log(buffer.join(' ')); @@ -497,7 +503,7 @@ var _ = jpacks; var _schema = jpacks.array('int16')(6); console.log(String(_schema)); - // > array(int16,6) + // > array('int16',6) var value = [12337, 12851]; var buffer = jpacks.pack(_schema, value); console.log(buffer.join(' ')); @@ -522,11 +528,6 @@ size = itemSchema.size * count; } else { countSchema = Schema.from(count); - /**/ - if (countSchema.namespace !== 'number') { - throw new Error('Parameter "count" is not a numeric type.'); - } - /**/ } return new Schema({ unpack: function _unpack(buffer, options, offsets) { @@ -599,7 +600,7 @@ var _ = jpacks; var _schema = jpacks.bytes(6); console.log(String(_schema)); - // > array(uint8,6) + // > array('uint8',6) var value = [0, 1, 2, 3, 4, 5]; var buffer = jpacks.pack(_schema, value); console.log(buffer.join(' ')); @@ -624,7 +625,7 @@ var _ = jpacks; var _schema = _.object([_.shortString, _.word]); console.log(_.stringify(_schema)); - // > object([string(uint8),uint16]) + // > object([string('uint8'),'uint16']) var buffer = _.pack(_schema, ['zswang', 1978]); console.log(buffer.join(' ')); // > 6 122 115 119 97 110 103 186 7 @@ -639,7 +640,7 @@ year: _.word }); console.log(_.stringify(_schema)); - // > object({namespace:string,args:{0:uint8}}) + // > object({name:string('uint8'),year:'uint16'}) var buffer = _.pack(_schema, { name: 'zswang', year: 1978 @@ -715,7 +716,7 @@ content: _.shortString }, 20); console.log(_.stringify(_schema)); - // > union({length:uint8,content:string(uint8)},20) + // > union({length:'uint8',content:string('uint8')},20) var buffer = _.pack(_schema, { content: '0123456789' }); @@ -782,7 +783,7 @@ var _ = jpacks; var _schema = _.enums(['Sun', 'Mon', 'Tues', 'Wed', 'Thur', 'Fri', 'Sat'], 'uint8'); console.log(_.stringify(_schema)); - // > enums({Sun:0,Mon:1,Tues:2,Wed:3,Thur:4,Fri:5,Sat:6},uint8) + // > enums({Sun:0,Mon:1,Tues:2,Wed:3,Thur:4,Fri:5,Sat:6},'uint8') var buffer = _.pack(_schema, 'Tues'); console.log(buffer.join(' ')); // > 2 @@ -801,7 +802,7 @@ NotFound: 404 }, 'int8'); console.log(_.stringify(_schema)); - // > enums({Unknown:-1,Continue:100,Processing:100,OK:200,Created:201,NotFound:404},int8) + // > enums({Unknown:-1,Continue:100,Processing:100,OK:200,Created:201,NotFound:404},'int8') var buffer = _.pack(_schema, 'Unknown'); console.log(buffer.join(' ')); // > 255 @@ -819,7 +820,7 @@ NotFound: 404 }, 'int8'); console.log(_.stringify(_schema)); - // > enums({Unknown:-1,Continue:100,Processing:100,OK:200,Created:201,NotFound:404},int8) + // > enums({Unknown:-1,Continue:100,Processing:100,OK:200,Created:201,NotFound:404},'int8') var buffer = _.pack(_schema, 2); console.log(buffer.join(' ')); // > 2 @@ -966,8 +967,6 @@ // > 228 189 160 229 165 189 228 184 150 231 149 140 239 188 129 72 101 108 108 111 0 0 0 0 0 console.log(_.unpack(_schema, buffer)); // > 你好世界!Hello - '''''' - '''''' * @example stringCreator():dynamic var _ = jpacks; var _schema = _.string('int8'); @@ -1086,7 +1085,7 @@ var _ = jpacks; var _schema = _.array(_.pchar, 'uint8'); console.log(_.stringify(_schema)); - // > array(cstring(true),uint8) + // > array(cstring(true),'uint8') var buffer = _.pack(_schema, ['abc', 'defghijk', 'g']); console.log(buffer.join(' ')); // > 3 97 98 99 0 100 101 102 103 104 105 106 107 0 103 0 @@ -1150,7 +1149,7 @@ ])) }; console.log(_.stringify(_schema)); - // > {type:string(uint8),data:depend(type,cases([[name,string(uint8)],[age,uint8]]))} + // > {type:string('uint8'),data:depend('type',cases([['name',string('uint8')],['age','uint8']]))} var buffer = _.pack(_schema, { type: 'name', data: 'tom' @@ -1207,7 +1206,7 @@ * function schemaCreator(value) {} * ]]] '''''' - * @example dependCreator() + * @example dependCreator():base ```js var _ = jpacks; var _schema = _.object({ @@ -1217,7 +1216,7 @@ data2: _.depend('length2', _.array(_.shortString)) }); console.log(_.stringify(_schema)); - // > object({length1:int8,length2:int8,data1:depend(length1,bytes),data2:depend(length2,array(string(uint8)))}) + // > object({length1:'int8',length2:'int8',data1:depend('length1','bytes'),data2:depend('length2',array(string('uint8')))}) var buffer = _.pack(_schema, { length1: 2, length2: 3, @@ -1290,7 +1289,7 @@ }; var _schema = _.parse(_xor, _xor, 'float64', 8); console.log(_.stringify(_schema)); - // > parse(_xor,_xor,float64,8) + // > parse('_xor','_xor','float64',8) var buffer = _.pack(_schema, 2.94296650666094e+189); console.log(buffer.join(' ')); // > 111 75 41 7 126 92 58 24 @@ -1327,6 +1326,107 @@ fn.args = args; }); Schema.register('parse', parse); + /** + * 定义一个虚拟结构 + * + * @param {number|string} operator + * @param {object} value 数据结构 + '''''' + * @example virtualCreator:number + ```js + var _ = jpacks; + var _schema = _.object({ + f1: 'uint16', + v1: _.depend('f1', _.virtual(-4)) + }); + console.log(_.stringify(_schema)) + // > object({f1:'uint16',v1:depend('f1',virtual(-4))}) + var buffer = _.pack(_schema, { + f1: 4 + }); + console.log(buffer.join(' ')); + // > 4 0 + console.log(JSON.stringify(_.unpack(_schema, buffer, { littleEndian: false }))); + // > {"f1":1024,"v1":1020} + ``` + * @example virtualCreator:string + ```js + var _ = jpacks; + var _schema = _.object({ + name: _.shortString, + welcome: _.depend('name', _.virtual('Hello ')) + }); + console.log(_.stringify(_schema)) + // > object({name:string('uint8'),welcome:depend('name',virtual('Hello '))}) + var buffer = _.pack(_schema, { + name: 'World!' + }); + console.log(buffer.join(' ')); + // > 6 87 111 114 108 100 33 + console.log(JSON.stringify(_.unpack(_schema, buffer, { littleEndian: false }))); + // > {"name":"World!","welcome":"Hello World!"} + ``` + * @example virtualCreator:depend + ```js + var _ = jpacks; + var _schema = _.object({ + name: _.shortString, + welcome: _.depend('name', _.cases([ + ['zswang', _.depend('name', _.virtual('Hello '))], + ['wang', _.depend('name', _.virtual('Hi '))] + ])) + }); + console.log(_.stringify(_schema)) + // > object({name:string('uint8'),welcome:depend('name',cases([['zswang',depend('name',virtual('Hello '))],['wang',depend('name',virtual('Hi '))]]))}) + var buffer = _.pack(_schema, { + name: 'zswang' + }); + console.log(buffer.join(' ')); + // > 6 122 115 119 97 110 103 + console.log(JSON.stringify(_.unpack(_schema, buffer, { littleEndian: false }))); + // > {"name":"zswang","welcome":"Hello zswang"} + var buffer = _.pack(_schema, { + name: 'wang' + }); + console.log(buffer.join(' ')); + // > 4 119 97 110 103 + console.log(JSON.stringify(_.unpack(_schema, buffer, { littleEndian: false }))); + // > {"name":"wang","welcome":"Hi wang"} + ``` + '''''' + */ + function virtualCreator(operator, value) { + return new Schema({ + unpack: function _unpack() { + if (/string|number/.test(typeof operator)) { + return operator + value; + } + if (typeof operator === 'function') { + return operator(value); + } + return value; + }, + pack: function _pack() {}, + args: arguments, + namespace: 'virtual' + }); + } + var virtual = Schema.together(virtualCreator, function (fn, args) { + fn.namespace = 'virtual'; + fn.args = args; + }); + Schema.register('virtual', virtual); + Schema.pushPattern(function _virtualPattern(schema) { + if (typeof schema === 'virtual') { + if (schema instanceof Schema) { + return; + } + if (schema instanceof Array) { + return; + } + return virtual(schema); + } + }); return Schema; } var root = create(); diff --git a/jpacks.js b/jpacks.js index 20f6d30..e8d12bb 100644 --- a/jpacks.js +++ b/jpacks.js @@ -5,7 +5,7 @@ * Binary data packing and unpacking. * @author * zswang (http://weibo.com/zswang) - * @version 0.3.13 + * @version 0.3.15 * @date 2015-11-05 */ function createSchema() { @@ -38,7 +38,7 @@ */ function Schema(options) { var self = this; - Object.keys(options).forEach(function (key) { + Object.keys(options).forEach(function(key) { self[key] = options[key]; }); } @@ -49,7 +49,7 @@ * @param {Schema|string|Function} schema 数据结构或者数据结构名 * @return {boolean} 返回是否定义成功 */ - Schema.register = function (name, schema) { + Schema.register = function(name, schema) { schemas[name] = schema; if (!Schema[name]) { // 避免覆盖系统方法 Schema[name] = schema; @@ -88,7 +88,7 @@ * function _pattern(schema) {} * ]]] */ - Schema.pushPattern = function (pattern) { + Schema.pushPattern = function(pattern) { schemaPatterns.push(pattern); }; /** @@ -97,7 +97,7 @@ * @param {string|Object|Schema} schema 数据结构名 * @return {Schema} 返回名字对应的数据结构 */ - Schema.from = function (schema) { + Schema.from = function(schema) { if (schema instanceof Schema) { return schema; } @@ -132,7 +132,7 @@ */ function setDefaultOptions(options) { options = options || {}; - Object.keys(options).forEach(function (key) { + Object.keys(options).forEach(function(key) { defaultOptions[key] = options[key]; }); } @@ -169,7 +169,7 @@ buffer = arrayBufferFrom(buffer); // 确保是 ArrayBuffer 类型 options = options || {}; offsets = offsets || [0]; - Object.keys(defaultOptions).forEach(function (key) { + Object.keys(defaultOptions).forEach(function(key) { if (typeof options[key] === 'undefined') { options[key] = defaultOptions[key]; } @@ -192,7 +192,7 @@ } buffer = buffer || []; options = options || {}; - Object.keys(defaultOptions).forEach(function (key) { + Object.keys(defaultOptions).forEach(function(key) { if (typeof options[key] === 'undefined') { options[key] = defaultOptions[key]; } @@ -273,39 +273,45 @@ return result.join(); } function scan(obj) { + // if (obj === null) { + // return 'null'; + // } if (!obj) { return obj; } if (obj.namespace) { if (obj.namespace === 'number') { - return obj.name; + return "'" + obj.name + "'"; } if (obj.args) { return obj.namespace + '(' + stringify.apply(null, obj.args) + ')'; } - return obj.namespace; - } - if (obj.name) { - return obj.name; + return "'" + obj.namespace + "'"; } if (typeof obj === 'function') { - obj.name = '_pack_fn' + (guid++); - Schema.define(obj.name, obj); - return obj.name; - } - if (typeof obj === 'object') { + if (!obj.name) { + obj.name = '_pack_fn' + (guid++); + Schema.define(obj.name, obj); + } + } else if (typeof obj === 'object') { var result = new obj.constructor(); - Object.keys(obj).forEach(function (key) { + Object.keys(obj).forEach(function(key) { result[key] = scan(obj[key]); }); return result; } + if (obj.name) { + return "'" + obj.name + "'"; + } + if (typeof obj === 'string') { + return "'" + obj + "'"; + } return obj; } return JSON.stringify(scan(obj) || '').replace(/"/g, ''); } Schema.stringify = stringify; - Schema.prototype.toString = function () { + Schema.prototype.toString = function() { return stringify(this); }; return Schema; @@ -338,7 +344,7 @@ }); var _schema = _.union(_map, 8); console.log(_.stringify(_schema)); - // > union({bytes:array(uint8,8),int8:int8,int16:int16,int32:int32,uint8:uint8,uint16:uint16,uint32:uint32,float32:float32,float64:float64,shortint:shortint,smallint:smallint,longint:longint,byte:byte,word:word,longword:longword},8) + // > union({bytes:array('uint8',8),int8:'int8',int16:'int16',int32:'int32',uint8:'uint8',uint16:'uint16',uint32:'uint32',float32:'float32',float64:'float64',shortint:'shortint',smallint:'smallint',longint:'longint',byte:'byte',word:'word',longword:'longword'},8) var buffer = _.pack(_schema, { bytes: [0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89] }); @@ -450,7 +456,7 @@ var _ = jpacks; var _schema = jpacks.array('int16', 2); console.log(String(_schema)); - // > array(int16,2) + // > array('int16',2) var value = [12337, 12851]; var buffer = jpacks.pack(_schema, value); console.log(buffer.join(' ')); @@ -463,7 +469,7 @@ var _ = jpacks; var _schema = jpacks.array('int16', 'int8'); console.log(String(_schema)); - // > array(int16,int8) + // > array('int16','int8') var value = [12337, 12851]; var buffer = jpacks.pack(_schema, value); console.log(buffer.join(' ')); @@ -476,7 +482,7 @@ var _ = jpacks; var _schema = jpacks.array('int16')(6); console.log(String(_schema)); - // > array(int16,6) + // > array('int16',6) var value = [12337, 12851]; var buffer = jpacks.pack(_schema, value); console.log(buffer.join(' ')); @@ -565,7 +571,7 @@ var _ = jpacks; var _schema = jpacks.bytes(6); console.log(String(_schema)); - // > array(uint8,6) + // > array('uint8',6) var value = [0, 1, 2, 3, 4, 5]; var buffer = jpacks.pack(_schema, value); console.log(buffer.join(' ')); @@ -590,7 +596,7 @@ var _ = jpacks; var _schema = _.object([_.shortString, _.word]); console.log(_.stringify(_schema)); - // > object([string(uint8),uint16]) + // > object([string('uint8'),'uint16']) var buffer = _.pack(_schema, ['zswang', 1978]); console.log(buffer.join(' ')); // > 6 122 115 119 97 110 103 186 7 @@ -605,7 +611,7 @@ year: _.word }); console.log(_.stringify(_schema)); - // > object({namespace:string,args:{0:uint8}}) + // > object({name:string('uint8'),year:'uint16'}) var buffer = _.pack(_schema, { name: 'zswang', year: 1978 @@ -676,7 +682,7 @@ content: _.shortString }, 20); console.log(_.stringify(_schema)); - // > union({length:uint8,content:string(uint8)},20) + // > union({length:'uint8',content:string('uint8')},20) var buffer = _.pack(_schema, { content: '0123456789' }); @@ -735,7 +741,7 @@ var _ = jpacks; var _schema = _.enums(['Sun', 'Mon', 'Tues', 'Wed', 'Thur', 'Fri', 'Sat'], 'uint8'); console.log(_.stringify(_schema)); - // > enums({Sun:0,Mon:1,Tues:2,Wed:3,Thur:4,Fri:5,Sat:6},uint8) + // > enums({Sun:0,Mon:1,Tues:2,Wed:3,Thur:4,Fri:5,Sat:6},'uint8') var buffer = _.pack(_schema, 'Tues'); console.log(buffer.join(' ')); // > 2 @@ -754,7 +760,7 @@ NotFound: 404 }, 'int8'); console.log(_.stringify(_schema)); - // > enums({Unknown:-1,Continue:100,Processing:100,OK:200,Created:201,NotFound:404},int8) + // > enums({Unknown:-1,Continue:100,Processing:100,OK:200,Created:201,NotFound:404},'int8') var buffer = _.pack(_schema, 'Unknown'); console.log(buffer.join(' ')); // > 255 @@ -772,7 +778,7 @@ NotFound: 404 }, 'int8'); console.log(_.stringify(_schema)); - // > enums({Unknown:-1,Continue:100,Processing:100,OK:200,Created:201,NotFound:404},int8) + // > enums({Unknown:-1,Continue:100,Processing:100,OK:200,Created:201,NotFound:404},'int8') var buffer = _.pack(_schema, 2); console.log(buffer.join(' ')); // > 2 @@ -908,8 +914,6 @@ // > 228 189 160 229 165 189 228 184 150 231 149 140 239 188 129 72 101 108 108 111 0 0 0 0 0 console.log(_.unpack(_schema, buffer)); // > 你好世界!Hello - '''''' - '''''' * @example stringCreator():dynamic var _ = jpacks; var _schema = _.string('int8'); @@ -1028,7 +1032,7 @@ var _ = jpacks; var _schema = _.array(_.pchar, 'uint8'); console.log(_.stringify(_schema)); - // > array(cstring(true),uint8) + // > array(cstring(true),'uint8') var buffer = _.pack(_schema, ['abc', 'defghijk', 'g']); console.log(buffer.join(' ')); // > 3 97 98 99 0 100 101 102 103 104 105 106 107 0 103 0 @@ -1092,7 +1096,7 @@ ])) }; console.log(_.stringify(_schema)); - // > {type:string(uint8),data:depend(type,cases([[name,string(uint8)],[age,uint8]]))} + // > {type:string('uint8'),data:depend('type',cases([['name',string('uint8')],['age','uint8']]))} var buffer = _.pack(_schema, { type: 'name', data: 'tom' @@ -1135,7 +1139,7 @@ * function schemaCreator(value) {} * ]]] '''''' - * @example dependCreator() + * @example dependCreator():base ```js var _ = jpacks; var _schema = _.object({ @@ -1145,7 +1149,7 @@ data2: _.depend('length2', _.array(_.shortString)) }); console.log(_.stringify(_schema)); - // > object({length1:int8,length2:int8,data1:depend(length1,bytes),data2:depend(length2,array(string(uint8)))}) + // > object({length1:'int8',length2:'int8',data1:depend('length1','bytes'),data2:depend('length2',array(string('uint8')))}) var buffer = _.pack(_schema, { length1: 2, length2: 3, @@ -1210,7 +1214,7 @@ }; var _schema = _.parse(_xor, _xor, 'float64', 8); console.log(_.stringify(_schema)); - // > parse(_xor,_xor,float64,8) + // > parse('_xor','_xor','float64',8) var buffer = _.pack(_schema, 2.94296650666094e+189); console.log(buffer.join(' ')); // > 111 75 41 7 126 92 58 24 @@ -1239,6 +1243,107 @@ fn.args = args; }); Schema.register('parse', parse); + /** + * 定义一个虚拟结构 + * + * @param {number|string} operator + * @param {object} value 数据结构 + '''''' + * @example virtualCreator:number + ```js + var _ = jpacks; + var _schema = _.object({ + f1: 'uint16', + v1: _.depend('f1', _.virtual(-4)) + }); + console.log(_.stringify(_schema)) + // > object({f1:'uint16',v1:depend('f1',virtual(-4))}) + var buffer = _.pack(_schema, { + f1: 4 + }); + console.log(buffer.join(' ')); + // > 4 0 + console.log(JSON.stringify(_.unpack(_schema, buffer, { littleEndian: false }))); + // > {"f1":1024,"v1":1020} + ``` + * @example virtualCreator:string + ```js + var _ = jpacks; + var _schema = _.object({ + name: _.shortString, + welcome: _.depend('name', _.virtual('Hello ')) + }); + console.log(_.stringify(_schema)) + // > object({name:string('uint8'),welcome:depend('name',virtual('Hello '))}) + var buffer = _.pack(_schema, { + name: 'World!' + }); + console.log(buffer.join(' ')); + // > 6 87 111 114 108 100 33 + console.log(JSON.stringify(_.unpack(_schema, buffer, { littleEndian: false }))); + // > {"name":"World!","welcome":"Hello World!"} + ``` + * @example virtualCreator:depend + ```js + var _ = jpacks; + var _schema = _.object({ + name: _.shortString, + welcome: _.depend('name', _.cases([ + ['zswang', _.depend('name', _.virtual('Hello '))], + ['wang', _.depend('name', _.virtual('Hi '))] + ])) + }); + console.log(_.stringify(_schema)) + // > object({name:string('uint8'),welcome:depend('name',cases([['zswang',depend('name',virtual('Hello '))],['wang',depend('name',virtual('Hi '))]]))}) + var buffer = _.pack(_schema, { + name: 'zswang' + }); + console.log(buffer.join(' ')); + // > 6 122 115 119 97 110 103 + console.log(JSON.stringify(_.unpack(_schema, buffer, { littleEndian: false }))); + // > {"name":"zswang","welcome":"Hello zswang"} + var buffer = _.pack(_schema, { + name: 'wang' + }); + console.log(buffer.join(' ')); + // > 4 119 97 110 103 + console.log(JSON.stringify(_.unpack(_schema, buffer, { littleEndian: false }))); + // > {"name":"wang","welcome":"Hi wang"} + ``` + '''''' + */ + function virtualCreator(operator, value) { + return new Schema({ + unpack: function _unpack() { + if (/string|number/.test(typeof operator)) { + return operator + value; + } + if (typeof operator === 'function') { + return operator(value); + } + return value; + }, + pack: function _pack() {}, + args: arguments, + namespace: 'virtual' + }); + } + var virtual = Schema.together(virtualCreator, function (fn, args) { + fn.namespace = 'virtual'; + fn.args = args; + }); + Schema.register('virtual', virtual); + Schema.pushPattern(function _virtualPattern(schema) { + if (typeof schema === 'virtual') { + if (schema instanceof Schema) { + return; + } + if (schema instanceof Array) { + return; + } + return virtual(schema); + } + }); return Schema; } var root = create(); diff --git a/jpacks.min.js b/jpacks.min.js index 1e1ab54..d12da33 100644 --- a/jpacks.min.js +++ b/jpacks.min.js @@ -1 +1 @@ -!function(r){function n(){function r(r){var n=this;Object.keys(r).forEach(function(e){n[e]=r[e]})}function n(r){r=r||{},Object.keys(r).forEach(function(n){f[n]=r[n]})}function e(r){if(r instanceof ArrayBuffer)return r;var n=new ArrayBuffer(r.length),e=new Uint8Array(n,0,r.length);return e.set(r),n}function t(n,t,a,i){var u=r.from(n);if(!u)throw new Error('Parameter schema "'+n+'" is unregister.');return t=e(t),a=a||{},i=i||[0],Object.keys(f).forEach(function(r){"undefined"==typeof a[r]&&(a[r]=f[r])}),u.unpack(t,a,i)}function a(n,e,t,a){var i=r.from(n);if(!i)throw new Error('Parameter schema "'+n+'" is unregister.');return a=a||[],t=t||{},Object.keys(f).forEach(function(r){"undefined"==typeof t[r]&&(t[r]=f[r])}),i.pack(e,t,a),a}function i(r,n,e){if(r.length<=0)return r;var t=function(){var t=[];if([].push.apply(t,e),[].push.apply(t,arguments),t.length>=r.length)return r.apply(null,t);var a=i(r,n,t);return"function"==typeof n&&n(a,t),a};return t}function u(n){function e(n){if(!n)return n;if(n.namespace)return"number"===n.namespace?n.name:n.args?n.namespace+"("+u.apply(null,n.args)+")":n.namespace;if(n.name)return n.name;if("function"==typeof n)return n.name="_pack_fn"+s++,r.define(n.name,n),n.name;if("object"==typeof n){var t=new n.constructor;return Object.keys(n).forEach(function(r){t[r]=e(n[r])}),t}return n}if(arguments.length>1){for(var t=[],a=0;as;s++)f.push(d.unpack(r,a,i,u));return f},pack:function(a,i,u){var c=n;if(t&&(c=a?a.length:0,d.pack(t,c,i,u)),r.array&&i.littleEndian){e=r.size*c;var o=new ArrayBuffer(e),f=new r.array(o);f.set(a);var s=new Uint8Array(o);[].push.apply(u,s)}for(var p=0;c>p;p++)d.pack(r,(a||[])[p],i,u)},namespace:"array",args:arguments,size:e})}function e(r){return w(r,"uint8")}function t(r){return w(r,"uint16")}function a(r){return w(r,"uint32")}function i(r){return d.array("uint8",r)}function u(r){if(r instanceof d)return r;var n=Object.keys(r);return new d({unpack:function(e,t,a){var i=new r.constructor,u=t.$scope;return t.$scope=i,n.forEach(function(n){i[n]=d.unpack(r[n],e,t,a)}),t.$scope=u,i},pack:function(e,t,a){var i=t.$scope;t.$scope=e,n.forEach(function(n){d.pack(r[n],e[n],t,a)}),t.$scope=i},args:arguments,namespace:"object"})}function c(r,n){var e=Object.keys(r);return new d({unpack:function(t,a,i){var u=i[0],c={};return e.forEach(function(n){i[0]=u,c[n]=d.unpack(r[n],t,a,i)}),i[0]+=n,c},pack:function(t,a,i){var u=new ArrayBuffer(n),c=new Uint8Array(u);e.forEach(function(n){if("undefined"!=typeof t[n]){var e=[];d.pack(r[n],t[n],a,e),c.set(e)}}),[].push.apply(i,c)},size:n,args:arguments,namespace:"union"})}function o(r,n){if(n=d.from(n),r instanceof Array){var e={};r.forEach(function(r,n){e[r]=n}),r=e}var t=Object.keys(r);return new d({unpack:function(e,a,i){var u,c=d.unpack(n,e,a,i);return t.every(function(n){return r[n]===c?(u=n,!1):!0}),u||c},pack:function(e,a,i){if("number"==typeof e)return void d.pack(n,e,a,i);if(t.every(function(t){return t===e?(d.pack(n,r[t],a,i),!1):!0}))throw new Error('Not find enum "'+e+'".')},namespace:"enums",args:arguments})}function f(r){return String(r).replace(/[\u0080-\u07ff]/g,function(r){var n=r.charCodeAt(0);return String.fromCharCode(192|n>>6,128|63&n)}).replace(/[\u0800-\uffff]/g,function(r){var n=r.charCodeAt(0);return String.fromCharCode(224|n>>12,128|n>>6&63,128|63&n)})}function s(r){return String(r).replace(/[\u00c0-\u00df][\u0080-\u00bf]/g,function(r){var n=(31&r.charCodeAt(0))<<6|63&r.charCodeAt(1);return String.fromCharCode(n)}).replace(/[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g,function(r){var n=(15&r.charCodeAt(0))<<12|(63&r.charCodeAt(1))<<6|63&r.charCodeAt(2);return String.fromCharCode(n)})}function p(r,n){return n.browser||"undefined"==typeof Buffer?f(r).split("").map(function(r){return r.charCodeAt()}):new Buffer(r,n.encoding)}function g(r){var n=d.array("uint8",r);return new d({unpack:function(r,e,t){var a=d.unpack(n,r,e,t);return e.browser||"undefined"==typeof Buffer?s(String.fromCharCode.apply(String,a)):new Buffer(a).toString(e.encoding)},pack:function(r,e,t){d.pack(n,p(r,e),e,t)},namespace:"string",args:arguments})}function y(r){return new d({unpack:function(n,e,t){var a;a=r===!0?new Uint8Array(n,t[0]):d.unpack(d.bytes(r),n,e,t);for(var i=0;a[i];)i++;var u=d.unpack(d.string(i),a,e);return r===!0&&(t[0]+=i+1),u},pack:function(n,e,t){var a=[0];[].unshift.apply(a,d.stringBytes(n,e)),r===!0?d.pack(d.bytes(a.length),a,e,t):d.pack(d.bytes(r),a,e,t)},namespace:"cstring",args:arguments})}function l(r,n){for(var e=0;e=r.length)return r.apply(null,t);var a=i(r,n,t);return"function"==typeof n&&n(a,t),a};return t}function u(n){function e(n){if(!n)return n;if(n.namespace)return"number"===n.namespace?"'"+n.name+"'":n.args?n.namespace+"("+u.apply(null,n.args)+")":"'"+n.namespace+"'";if("function"==typeof n)n.name||(n.name="_pack_fn"+s++,r.define(n.name,n));else if("object"==typeof n){var t=new n.constructor;return Object.keys(n).forEach(function(r){t[r]=e(n[r])}),t}return n.name?"'"+n.name+"'":"string"==typeof n?"'"+n+"'":n}if(arguments.length>1){for(var t=[],a=0;as;s++)f.push(k.unpack(r,a,i,u));return f},pack:function(a,i,u){var o=n;if(t&&(o=a?a.length:0,k.pack(t,o,i,u)),r.array&&i.littleEndian){e=r.size*o;var c=new ArrayBuffer(e),f=new r.array(c);f.set(a);var s=new Uint8Array(c);[].push.apply(u,s)}for(var p=0;o>p;p++)k.pack(r,(a||[])[p],i,u)},namespace:"array",args:arguments,size:e})}function e(r){return A(r,"uint8")}function t(r){return A(r,"uint16")}function a(r){return A(r,"uint32")}function i(r){return k.array("uint8",r)}function u(r){if(r instanceof k)return r;var n=Object.keys(r);return new k({unpack:function(e,t,a){var i=new r.constructor,u=t.$scope;return t.$scope=i,n.forEach(function(n){i[n]=k.unpack(r[n],e,t,a)}),t.$scope=u,i},pack:function(e,t,a){var i=t.$scope;t.$scope=e,n.forEach(function(n){k.pack(r[n],e[n],t,a)}),t.$scope=i},args:arguments,namespace:"object"})}function o(r,n){var e=Object.keys(r);return new k({unpack:function(t,a,i){var u=i[0],o={};return e.forEach(function(n){i[0]=u,o[n]=k.unpack(r[n],t,a,i)}),i[0]+=n,o},pack:function(t,a,i){var u=new ArrayBuffer(n),o=new Uint8Array(u);e.forEach(function(n){if("undefined"!=typeof t[n]){var e=[];k.pack(r[n],t[n],a,e),o.set(e)}}),[].push.apply(i,o)},size:n,args:arguments,namespace:"union"})}function c(r,n){if(n=k.from(n),r instanceof Array){var e={};r.forEach(function(r,n){e[r]=n}),r=e}var t=Object.keys(r);return new k({unpack:function(e,a,i){var u,o=k.unpack(n,e,a,i);return t.every(function(n){return r[n]===o?(u=n,!1):!0}),u||o},pack:function(e,a,i){if("number"==typeof e)return void k.pack(n,e,a,i);if(t.every(function(t){return t===e?(k.pack(n,r[t],a,i),!1):!0}))throw new Error('Not find enum "'+e+'".')},namespace:"enums",args:arguments})}function f(r){return String(r).replace(/[\u0080-\u07ff]/g,function(r){var n=r.charCodeAt(0);return String.fromCharCode(192|n>>6,128|63&n)}).replace(/[\u0800-\uffff]/g,function(r){var n=r.charCodeAt(0);return String.fromCharCode(224|n>>12,128|n>>6&63,128|63&n)})}function s(r){return String(r).replace(/[\u00c0-\u00df][\u0080-\u00bf]/g,function(r){var n=(31&r.charCodeAt(0))<<6|63&r.charCodeAt(1);return String.fromCharCode(n)}).replace(/[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g,function(r){var n=(15&r.charCodeAt(0))<<12|(63&r.charCodeAt(1))<<6|63&r.charCodeAt(2);return String.fromCharCode(n)})}function p(r,n){return n.browser||"undefined"==typeof Buffer?f(r).split("").map(function(r){return r.charCodeAt()}):new Buffer(r,n.encoding)}function g(r){var n=k.array("uint8",r);return new k({unpack:function(r,e,t){var a=k.unpack(n,r,e,t);return e.browser||"undefined"==typeof Buffer?s(String.fromCharCode.apply(String,a)):new Buffer(a).toString(e.encoding)},pack:function(r,e,t){k.pack(n,p(r,e),e,t)},namespace:"string",args:arguments})}function y(r){return new k({unpack:function(n,e,t){var a;a=r===!0?new Uint8Array(n,t[0]):k.unpack(k.bytes(r),n,e,t);for(var i=0;a[i];)i++;var u=k.unpack(k.string(i),a,e);return r===!0&&(t[0]+=i+1),u},pack:function(n,e,t){var a=[0];[].unshift.apply(a,k.stringBytes(n,e)),r===!0?k.pack(k.bytes(a.length),a,e,t):k.pack(k.bytes(r),a,e,t)},namespace:"cstring",args:arguments})}function l(r,n){for(var e=0;e uint64 + // > 'uint64' var buffer = _.pack(_schema, '1609531171697315243'); @@ -41,7 +41,7 @@ module.exports = function(Schema) { var _ = jpacks; var _schema = _.uint64; console.log(_.stringify(_schema)) - // > uint64 + // > 'uint64' var buffer = _.pack(_schema, 171697315); @@ -56,7 +56,7 @@ module.exports = function(Schema) { var _ = jpacks; var _schema = _.uint64; console.log(_.stringify(_schema)) - // > uint64 + // > 'uint64' var buffer = _.pack(_schema, 171697315, { littleEndian: false }); @@ -71,7 +71,7 @@ module.exports = function(Schema) { var _ = jpacks; var _schema = _.int64; console.log(_.stringify(_schema)) - // > int64 + // > 'int64' var buffer = _.pack(_schema, '-1'); @@ -94,7 +94,7 @@ module.exports = function(Schema) { var _ = jpacks; var _schema = _.int64; console.log(_.stringify(_schema)) - // > int64 + // > 'int64' var buffer = _.pack(_schema, -2, { littleEndian: false }); diff --git a/schemas-extend/protobuf.js b/schemas-extend/protobuf.js index 55244ff..60bf895 100644 --- a/schemas-extend/protobuf.js +++ b/schemas-extend/protobuf.js @@ -61,7 +61,7 @@ module.exports = function(Schema) { * @param {Object} json JSON 数据 */ function jsonify(messager, json, options) { - if (!json) { + if (!json || !messager) { return; } var type = messager.$type; @@ -122,7 +122,7 @@ module.exports = function(Schema) { 'int8' ); console.log(_.stringify(_schema)) - // > array(protobuf(test/protoify/json.proto,js.Value,uint16),int8) + // > array(protobuf('test/protoify/json.proto','js.Value','uint16'),'int8') var buffer = _.pack(_schema, [{ integer: 123 @@ -155,7 +155,7 @@ module.exports = function(Schema) { 'int8' ); console.log(_.stringify(_schema)) - // > array(protobuf(test/protoify/bigint.proto,bigint.Value,uint16),int8) + // > array(protobuf('test/protoify/bigint.proto','bigint.Value','uint16'),'int8') var buffer = _.pack(_schema, [{ int64: "-192377746236123" @@ -177,7 +177,7 @@ module.exports = function(Schema) { 'int8' ); console.log(_.stringify(_schema)) - // > array(protobuf(test/protoify/string.proto,str.Value,uint16),int8) + // > array(protobuf('test/protoify/string.proto','str.Value','uint16'),'int8') _.setDefaultOptions({ protobuf_bytesAsString: true diff --git a/schemas-extend/zlib.js b/schemas-extend/zlib.js index e259989..9e225fa 100644 --- a/schemas-extend/zlib.js +++ b/schemas-extend/zlib.js @@ -16,15 +16,17 @@ module.exports = function(Schema) { data: _.gzip(_.shortString, 'uint16') }); console.log(_.stringify(_schema)) - // > object({type:uint8,data:parse(zlib.gzipSync,zlib.gunzipSync,string(uint8),uint16)}) + // > object({type:'uint8',data:parse('zlib.gzipSync','zlib.gunzipSync',string('uint8'),'uint16')}) var buffer = _.pack(_schema, { type: 2, data: '你好世界!Hello' }); - console.log(buffer.join(' ')); - // > 2 42 0 31 139 8 0 0 0 0 0 0 3 19 121 178 119 193 211 165 123 159 236 152 246 124 106 207 251 61 141 30 169 57 57 249 0 183 181 133 147 21 0 0 0 + console.log(buffer.slice(14).join(' ')); + // windows: 2 42 0 31 139 8 0 0 0 0 0 0 11 19 121 178 119 193 211 165 123 159 236 152 246 124 106 207 251 61 141 30 169 57 57 249 0 183 181 133 147 21 0 0 0 + // linux: 2 42 0 31 139 8 0 0 0 0 0 0 3 19 121 178 119 193 211 165 123 159 236 152 246 124 106 207 251 61 141 30 169 57 57 249 0 183 181 133 147 21 0 0 0 + // > 121 178 119 193 211 165 123 159 236 152 246 124 106 207 251 61 141 30 169 57 57 249 0 183 181 133 147 21 0 0 0 console.log(JSON.stringify(_.unpack(_schema, buffer))); // > {"type":2,"data":"你好世界!Hello"} @@ -63,7 +65,7 @@ module.exports = function(Schema) { data: _.inflate(_.shortString, 'uint16') }); console.log(_.stringify(_schema)) - // > object({type:uint8,data:parse(zlib.deflateSync,zlib.inflateSync,string(uint8),uint16)}) + // > object({type:'uint8',data:parse('zlib.deflateSync','zlib.inflateSync',string('uint8'),'uint16')}) var buffer = _.pack(_schema, { type: 2, diff --git a/src/jpacks.js b/src/jpacks.js index 45d697c..2246086 100644 --- a/src/jpacks.js +++ b/src/jpacks.js @@ -51,6 +51,8 @@ require('./schemas/cases')(Schema); require('./schemas/depend')(Schema); require('./schemas/parse')(Schema); + + require('./schemas/virtual')(Schema); /**/ return Schema; diff --git a/src/schema.js b/src/schema.js index 0d00ca5..1356b67 100644 --- a/src/schema.js +++ b/src/schema.js @@ -31,7 +31,7 @@ function createSchema() { */ function Schema(options) { var self = this; - Object.keys(options).forEach(function (key) { + Object.keys(options).forEach(function(key) { self[key] = options[key]; }); } @@ -43,7 +43,7 @@ function createSchema() { * @param {Schema|string|Function} schema 数据结构或者数据结构名 * @return {boolean} 返回是否定义成功 */ - Schema.register = function (name, schema) { + Schema.register = function(name, schema) { /**/ if (typeof name === 'undefined') { throw new Error('Parameter "name" is undefined.'); @@ -90,7 +90,7 @@ function createSchema() { * function _pattern(schema) {} * ]]] */ - Schema.pushPattern = function (pattern) { + Schema.pushPattern = function(pattern) { /**/ if (typeof pattern !== 'function') { return; @@ -105,7 +105,7 @@ function createSchema() { * @param {string|Object|Schema} schema 数据结构名 * @return {Schema} 返回名字对应的数据结构 */ - Schema.from = function (schema) { + Schema.from = function(schema) { /**/ if (typeof schema === 'undefined') { // 无效数据 return; @@ -147,7 +147,7 @@ function createSchema() { */ function setDefaultOptions(options) { options = options || {}; - Object.keys(options).forEach(function (key) { + Object.keys(options).forEach(function(key) { defaultOptions[key] = options[key]; }); } @@ -190,7 +190,7 @@ function createSchema() { buffer = arrayBufferFrom(buffer); // 确保是 ArrayBuffer 类型 options = options || {}; offsets = offsets || [0]; - Object.keys(defaultOptions).forEach(function (key) { + Object.keys(defaultOptions).forEach(function(key) { if (typeof options[key] === 'undefined') { options[key] = defaultOptions[key]; } @@ -220,7 +220,7 @@ function createSchema() { buffer = buffer || []; options = options || {}; - Object.keys(defaultOptions).forEach(function (key) { + Object.keys(defaultOptions).forEach(function(key) { if (typeof options[key] === 'undefined') { options[key] = defaultOptions[key]; } @@ -311,43 +311,49 @@ function createSchema() { } return result.join(); } + function scan(obj) { + // if (obj === null) { + // return 'null'; + // } if (!obj) { return obj; } if (obj.namespace) { if (obj.namespace === 'number') { - return obj.name; + return "'" + obj.name + "'"; } if (obj.args) { return obj.namespace + '(' + stringify.apply(null, obj.args) + ')'; } - return obj.namespace; - } - - if (obj.name) { - return obj.name; + return "'" + obj.namespace + "'"; } if (typeof obj === 'function') { - obj.name = '_pack_fn' + (guid++); - Schema.define(obj.name, obj); - return obj.name; - } - if (typeof obj === 'object') { + if (!obj.name) { + obj.name = '_pack_fn' + (guid++); + Schema.define(obj.name, obj); + } + } else if (typeof obj === 'object') { var result = new obj.constructor(); - Object.keys(obj).forEach(function (key) { + Object.keys(obj).forEach(function(key) { result[key] = scan(obj[key]); }); return result; } + if (obj.name) { + return "'" + obj.name + "'"; + } + if (typeof obj === 'string') { + return "'" + obj + "'"; + } return obj; } return JSON.stringify(scan(obj) || '').replace(/"/g, ''); } Schema.stringify = stringify; - Schema.prototype.toString = function () { + Schema.prototype.toString = function() { return stringify(this); }; return Schema; diff --git a/src/schemas/array.js b/src/schemas/array.js index 2db75c4..88ac7e1 100644 --- a/src/schemas/array.js +++ b/src/schemas/array.js @@ -12,7 +12,7 @@ module.exports = function (Schema) { var _ = jpacks; var _schema = jpacks.array('int16', 2); console.log(String(_schema)); - // > array(int16,2) + // > array('int16',2) var value = [12337, 12851]; var buffer = jpacks.pack(_schema, value); @@ -27,7 +27,7 @@ module.exports = function (Schema) { var _ = jpacks; var _schema = jpacks.array('int16', 'int8'); console.log(String(_schema)); - // > array(int16,int8) + // > array('int16','int8') var value = [12337, 12851]; var buffer = jpacks.pack(_schema, value); @@ -42,7 +42,7 @@ module.exports = function (Schema) { var _ = jpacks; var _schema = jpacks.array('int16')(6); console.log(String(_schema)); - // > array(int16,6) + // > array('int16',6) var value = [12337, 12851]; var buffer = jpacks.pack(_schema, value); @@ -70,11 +70,6 @@ module.exports = function (Schema) { size = itemSchema.size * count; } else { countSchema = Schema.from(count); - /**/ - if (countSchema.namespace !== 'number') { - throw new Error('Parameter "count" is not a numeric type.'); - } - /**/ } return new Schema({ diff --git a/src/schemas/bytes.js b/src/schemas/bytes.js index f44ea84..d594f05 100644 --- a/src/schemas/bytes.js +++ b/src/schemas/bytes.js @@ -11,7 +11,7 @@ module.exports = function (Schema) { var _ = jpacks; var _schema = jpacks.bytes(6); console.log(String(_schema)); - // > array(uint8,6) + // > array('uint8',6) var value = [0, 1, 2, 3, 4, 5]; var buffer = jpacks.pack(_schema, value); diff --git a/src/schemas/cases.js b/src/schemas/cases.js index d56b18f..eb415cf 100644 --- a/src/schemas/cases.js +++ b/src/schemas/cases.js @@ -17,7 +17,7 @@ module.exports = function (Schema) { ])) }; console.log(_.stringify(_schema)); - // > {type:string(uint8),data:depend(type,cases([[name,string(uint8)],[age,uint8]]))} + // > {type:string('uint8'),data:depend('type',cases([['name',string('uint8')],['age','uint8']]))} var buffer = _.pack(_schema, { type: 'name', diff --git a/src/schemas/cstring.js b/src/schemas/cstring.js index c07f3b1..d8686ca 100644 --- a/src/schemas/cstring.js +++ b/src/schemas/cstring.js @@ -25,7 +25,7 @@ module.exports = function(Schema) { var _ = jpacks; var _schema = _.array(_.pchar, 'uint8'); console.log(_.stringify(_schema)); - // > array(cstring(true),uint8) + // > array(cstring(true),'uint8') var buffer = _.pack(_schema, ['abc', 'defghijk', 'g']); console.log(buffer.join(' ')); diff --git a/src/schemas/depend.js b/src/schemas/depend.js index c7fea84..e22093e 100644 --- a/src/schemas/depend.js +++ b/src/schemas/depend.js @@ -11,7 +11,7 @@ module.exports = function (Schema) { * function schemaCreator(value) {} * ]]] '''''' - * @example dependCreator() + * @example dependCreator():base ```js var _ = jpacks; var _schema = _.object({ @@ -21,7 +21,7 @@ module.exports = function (Schema) { data2: _.depend('length2', _.array(_.shortString)) }); console.log(_.stringify(_schema)); - // > object({length1:int8,length2:int8,data1:depend(length1,bytes),data2:depend(length2,array(string(uint8)))}) + // > object({length1:'int8',length2:'int8',data1:depend('length1','bytes'),data2:depend('length2',array(string('uint8')))}) var buffer = _.pack(_schema, { length1: 2, diff --git a/src/schemas/enums.js b/src/schemas/enums.js index 2226b69..a9b53a2 100644 --- a/src/schemas/enums.js +++ b/src/schemas/enums.js @@ -12,7 +12,7 @@ module.exports = function (Schema) { var _ = jpacks; var _schema = _.enums(['Sun', 'Mon', 'Tues', 'Wed', 'Thur', 'Fri', 'Sat'], 'uint8'); console.log(_.stringify(_schema)); - // > enums({Sun:0,Mon:1,Tues:2,Wed:3,Thur:4,Fri:5,Sat:6},uint8) + // > enums({Sun:0,Mon:1,Tues:2,Wed:3,Thur:4,Fri:5,Sat:6},'uint8') var buffer = _.pack(_schema, 'Tues'); console.log(buffer.join(' ')); @@ -33,7 +33,7 @@ module.exports = function (Schema) { NotFound: 404 }, 'int8'); console.log(_.stringify(_schema)); - // > enums({Unknown:-1,Continue:100,Processing:100,OK:200,Created:201,NotFound:404},int8) + // > enums({Unknown:-1,Continue:100,Processing:100,OK:200,Created:201,NotFound:404},'int8') var buffer = _.pack(_schema, 'Unknown'); console.log(buffer.join(' ')); @@ -53,7 +53,7 @@ module.exports = function (Schema) { NotFound: 404 }, 'int8'); console.log(_.stringify(_schema)); - // > enums({Unknown:-1,Continue:100,Processing:100,OK:200,Created:201,NotFound:404},int8) + // > enums({Unknown:-1,Continue:100,Processing:100,OK:200,Created:201,NotFound:404},'int8') var buffer = _.pack(_schema, 2); console.log(buffer.join(' ')); diff --git a/src/schemas/number.js b/src/schemas/number.js index 7084254..06bfe93 100644 --- a/src/schemas/number.js +++ b/src/schemas/number.js @@ -21,7 +21,7 @@ module.exports = function defineNumber(Schema) { }); var _schema = _.union(_map, 8); console.log(_.stringify(_schema)); - // > union({bytes:array(uint8,8),int8:int8,int16:int16,int32:int32,uint8:uint8,uint16:uint16,uint32:uint32,float32:float32,float64:float64,shortint:shortint,smallint:smallint,longint:longint,byte:byte,word:word,longword:longword},8) + // > union({bytes:array('uint8',8),int8:'int8',int16:'int16',int32:'int32',uint8:'uint8',uint16:'uint16',uint32:'uint32',float32:'float32',float64:'float64',shortint:'shortint',smallint:'smallint',longint:'longint',byte:'byte',word:'word',longword:'longword'},8) var buffer = _.pack(_schema, { bytes: [0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89] diff --git a/src/schemas/object.js b/src/schemas/object.js index 3d2f4a8..4aacd5e 100644 --- a/src/schemas/object.js +++ b/src/schemas/object.js @@ -11,7 +11,7 @@ module.exports = function (Schema) { var _ = jpacks; var _schema = _.object([_.shortString, _.word]); console.log(_.stringify(_schema)); - // > object([string(uint8),uint16]) + // > object([string('uint8'),'uint16']) var buffer = _.pack(_schema, ['zswang', 1978]); console.log(buffer.join(' ')); @@ -28,7 +28,7 @@ module.exports = function (Schema) { year: _.word }); console.log(_.stringify(_schema)); - // > object({namespace:string,args:{0:uint8}}) + // > object({name:string('uint8'),year:'uint16'}) var buffer = _.pack(_schema, { name: 'zswang', diff --git a/src/schemas/parse.js b/src/schemas/parse.js index 9239a1f..f480498 100644 --- a/src/schemas/parse.js +++ b/src/schemas/parse.js @@ -19,7 +19,7 @@ module.exports = function(Schema) { }; var _schema = _.parse(_xor, _xor, 'float64', 8); console.log(_.stringify(_schema)); - // > parse(_xor,_xor,float64,8) + // > parse('_xor','_xor','float64',8) var buffer = _.pack(_schema, 2.94296650666094e+189); console.log(buffer.join(' ')); diff --git a/src/schemas/string.js b/src/schemas/string.js index 8404f9e..ba791a0 100644 --- a/src/schemas/string.js +++ b/src/schemas/string.js @@ -85,8 +85,6 @@ module.exports = function (Schema) { // > 228 189 160 229 165 189 228 184 150 231 149 140 239 188 129 72 101 108 108 111 0 0 0 0 0 console.log(_.unpack(_schema, buffer)); // > 你好世界!Hello - '''''' - '''''' * @example stringCreator():dynamic var _ = jpacks; var _schema = _.string('int8'); diff --git a/src/schemas/union.js b/src/schemas/union.js index 3210765..793d713 100644 --- a/src/schemas/union.js +++ b/src/schemas/union.js @@ -15,7 +15,7 @@ module.exports = function (Schema) { content: _.shortString }, 20); console.log(_.stringify(_schema)); - // > union({length:uint8,content:string(uint8)},20) + // > union({length:'uint8',content:string('uint8')},20) var buffer = _.pack(_schema, { content: '0123456789' diff --git a/src/schemas/virtual.js b/src/schemas/virtual.js new file mode 100644 index 0000000..c390867 --- /dev/null +++ b/src/schemas/virtual.js @@ -0,0 +1,117 @@ +module.exports = function (Schema) { + /**/ + /** + * 定义一个虚拟结构 + * + * @param {number|string} operator + * @param {object} value 数据结构 + '''''' + * @example virtualCreator:number + ```js + var _ = jpacks; + var _schema = _.object({ + f1: 'uint16', + v1: _.depend('f1', _.virtual(-4)) + }); + console.log(_.stringify(_schema)) + // > object({f1:'uint16',v1:depend('f1',virtual(-4))}) + + var buffer = _.pack(_schema, { + f1: 4 + }); + + console.log(buffer.join(' ')); + // > 4 0 + + console.log(JSON.stringify(_.unpack(_schema, buffer, { littleEndian: false }))); + // > {"f1":1024,"v1":1020} + ``` + * @example virtualCreator:string + ```js + var _ = jpacks; + var _schema = _.object({ + name: _.shortString, + welcome: _.depend('name', _.virtual('Hello ')) + }); + console.log(_.stringify(_schema)) + // > object({name:string('uint8'),welcome:depend('name',virtual('Hello '))}) + + var buffer = _.pack(_schema, { + name: 'World!' + }); + + console.log(buffer.join(' ')); + // > 6 87 111 114 108 100 33 + + console.log(JSON.stringify(_.unpack(_schema, buffer, { littleEndian: false }))); + // > {"name":"World!","welcome":"Hello World!"} + ``` + * @example virtualCreator:depend + ```js + var _ = jpacks; + var _schema = _.object({ + name: _.shortString, + welcome: _.depend('name', _.cases([ + ['zswang', _.depend('name', _.virtual('Hello '))], + ['wang', _.depend('name', _.virtual('Hi '))] + ])) + }); + console.log(_.stringify(_schema)) + // > object({name:string('uint8'),welcome:depend('name',cases([['zswang',depend('name',virtual('Hello '))],['wang',depend('name',virtual('Hi '))]]))}) + + var buffer = _.pack(_schema, { + name: 'zswang' + }); + + console.log(buffer.join(' ')); + // > 6 122 115 119 97 110 103 + + console.log(JSON.stringify(_.unpack(_schema, buffer, { littleEndian: false }))); + // > {"name":"zswang","welcome":"Hello zswang"} + + var buffer = _.pack(_schema, { + name: 'wang' + }); + + console.log(buffer.join(' ')); + // > 4 119 97 110 103 + + console.log(JSON.stringify(_.unpack(_schema, buffer, { littleEndian: false }))); + // > {"name":"wang","welcome":"Hi wang"} + ``` + '''''' + */ + function virtualCreator(operator, value) { + return new Schema({ + unpack: function _unpack() { + if (/string|number/.test(typeof operator)) { + return operator + value; + } + if (typeof operator === 'function') { + return operator(value); + } + return value; + }, + pack: function _pack() {}, + args: arguments, + namespace: 'virtual' + }); + } + var virtual = Schema.together(virtualCreator, function (fn, args) { + fn.namespace = 'virtual'; + fn.args = args; + }); + Schema.register('virtual', virtual); + Schema.pushPattern(function _virtualPattern(schema) { + if (typeof schema === 'virtual') { + if (schema instanceof Schema) { + return; + } + if (schema instanceof Array) { + return; + } + return virtual(schema); + } + }); + /**/ +}; diff --git a/test/example.js b/test/example.js index 5e3b960..1f54d07 100644 --- a/test/example.js +++ b/test/example.js @@ -26,15 +26,15 @@ describe("./src/schema.js", function () { } var t = _.together(f); t(1)()(2, 3); - assert.equal(printValue, '[1,2,3]'); printValue = undefined; + assert.equal(printValue, "[1,2,3]"); printValue = undefined; t(4)(5)()(6); - assert.equal(printValue, '[4,5,6]'); printValue = undefined; + assert.equal(printValue, "[4,5,6]"); printValue = undefined; t(7, 8, 9); - assert.equal(printValue, '[7,8,9]'); printValue = undefined; + assert.equal(printValue, "[7,8,9]"); printValue = undefined; t('a', 'b')('c'); - assert.equal(printValue, '["a","b","c"]'); printValue = undefined; + assert.equal(printValue, "[\"a\",\"b\",\"c\"]"); printValue = undefined; t()('x')()()('y')()()('z'); - assert.equal(printValue, '["x","y","z"]'); printValue = undefined; + assert.equal(printValue, "[\"x\",\"y\",\"z\"]"); printValue = undefined; }); it("together():hook", function () { var _ = jpacks; @@ -43,7 +43,7 @@ describe("./src/schema.js", function () { t.schema = 'f(' + args + ')'; }); print(t(1)(2).schema); - assert.equal(printValue, 'f(1,2)'); printValue = undefined; + assert.equal(printValue, "f(1,2)"); printValue = undefined; }); }); describe("./src/schemas/array.js", function () { @@ -52,37 +52,37 @@ describe("./src/schemas/array.js", function () { var _ = jpacks; var _schema = jpacks.array('int16', 2); print(String(_schema)); - assert.equal(printValue, 'array(int16,2)'); printValue = undefined; + assert.equal(printValue, "array('int16',2)"); printValue = undefined; var value = [12337, 12851]; var buffer = jpacks.pack(_schema, value); print(buffer.join(' ')); - assert.equal(printValue, '49 48 51 50'); printValue = undefined; + assert.equal(printValue, "49 48 51 50"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '[12337,12851]'); printValue = undefined; + assert.equal(printValue, "[12337,12851]"); printValue = undefined; }); it("arrayCreator():dynamic array", function () { var _ = jpacks; var _schema = jpacks.array('int16', 'int8'); print(String(_schema)); - assert.equal(printValue, 'array(int16,int8)'); printValue = undefined; + assert.equal(printValue, "array('int16','int8')"); printValue = undefined; var value = [12337, 12851]; var buffer = jpacks.pack(_schema, value); print(buffer.join(' ')); - assert.equal(printValue, '2 49 48 51 50'); printValue = undefined; + assert.equal(printValue, "2 49 48 51 50"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '[12337,12851]'); printValue = undefined; + assert.equal(printValue, "[12337,12851]"); printValue = undefined; }); it("arrayCreator():dynamic array 2", function () { var _ = jpacks; var _schema = jpacks.array('int16')(6); print(String(_schema)); - assert.equal(printValue, 'array(int16,6)'); printValue = undefined; + assert.equal(printValue, "array('int16',6)"); printValue = undefined; var value = [12337, 12851]; var buffer = jpacks.pack(_schema, value); print(buffer.join(' ')); - assert.equal(printValue, '49 48 51 50 0 0 0 0 0 0 0 0'); printValue = undefined; + assert.equal(printValue, "49 48 51 50 0 0 0 0 0 0 0 0"); printValue = undefined; print(JSON.stringify(jpacks.unpack(_schema, buffer))); - assert.equal(printValue, '[12337,12851,0,0,0,0]'); printValue = undefined; + assert.equal(printValue, "[12337,12851,0,0,0,0]"); printValue = undefined; }); }); describe("./src/schemas/bytes.js", function () { @@ -91,13 +91,13 @@ describe("./src/schemas/bytes.js", function () { var _ = jpacks; var _schema = jpacks.bytes(6); print(String(_schema)); - assert.equal(printValue, 'array(uint8,6)'); printValue = undefined; + assert.equal(printValue, "array('uint8',6)"); printValue = undefined; var value = [0, 1, 2, 3, 4, 5]; var buffer = jpacks.pack(_schema, value); print(buffer.join(' ')); - assert.equal(printValue, '0 1 2 3 4 5'); printValue = undefined; + assert.equal(printValue, "0 1 2 3 4 5"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '[0,1,2,3,4,5]'); printValue = undefined; + assert.equal(printValue, "[0,1,2,3,4,5]"); printValue = undefined; }); }); describe("./src/schemas/cases.js", function () { @@ -112,23 +112,23 @@ describe("./src/schemas/cases.js", function () { ])) }; print(_.stringify(_schema)); - assert.equal(printValue, '{type:string(uint8),data:depend(type,cases([[name,string(uint8)],[age,uint8]]))}'); printValue = undefined; + assert.equal(printValue, "{type:string('uint8'),data:depend('type',cases([['name',string('uint8')],['age','uint8']]))}"); printValue = undefined; var buffer = _.pack(_schema, { type: 'name', data: 'tom' }); print(buffer.join(' ')); - assert.equal(printValue, '4 110 97 109 101 3 116 111 109'); printValue = undefined; + assert.equal(printValue, "4 110 97 109 101 3 116 111 109"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '{"type":"name","data":"tom"}'); printValue = undefined; + assert.equal(printValue, "{\"type\":\"name\",\"data\":\"tom\"}"); printValue = undefined; var buffer = _.pack(_schema, { type: 'age', data: 23 }); print(buffer.join(' ')); - assert.equal(printValue, '3 97 103 101 23'); printValue = undefined; + assert.equal(printValue, "3 97 103 101 23"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '{"type":"age","data":23}'); printValue = undefined; + assert.equal(printValue, "{\"type\":\"age\",\"data\":23}"); printValue = undefined; }); }); describe("./src/schemas/cstring.js", function () { @@ -137,28 +137,28 @@ describe("./src/schemas/cstring.js", function () { var _ = jpacks; var _schema = _.cstring(32); print(_.stringify(_schema)); - assert.equal(printValue, 'cstring(32)'); printValue = undefined; + assert.equal(printValue, "cstring(32)"); printValue = undefined; var buffer = _.pack(_schema, 'Hello 你好!'); print(buffer.join(' ')); - assert.equal(printValue, '72 101 108 108 111 32 228 189 160 229 165 189 239 188 129 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0'); printValue = undefined; + assert.equal(printValue, "72 101 108 108 111 32 228 189 160 229 165 189 239 188 129 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '"Hello 你好!"'); printValue = undefined; + assert.equal(printValue, "\"Hello 你好!\""); printValue = undefined; }); it("cstringCreator():pchar", function () { var _ = jpacks; var _schema = _.array(_.pchar, 'uint8'); print(_.stringify(_schema)); - assert.equal(printValue, 'array(cstring(true),uint8)'); printValue = undefined; + assert.equal(printValue, "array(cstring(true),'uint8')"); printValue = undefined; var buffer = _.pack(_schema, ['abc', 'defghijk', 'g']); print(buffer.join(' ')); - assert.equal(printValue, '3 97 98 99 0 100 101 102 103 104 105 106 107 0 103 0'); printValue = undefined; + assert.equal(printValue, "3 97 98 99 0 100 101 102 103 104 105 106 107 0 103 0"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '["abc","defghijk","g"]'); printValue = undefined; + assert.equal(printValue, "[\"abc\",\"defghijk\",\"g\"]"); printValue = undefined; }); }); describe("./src/schemas/depend.js", function () { printValue = undefined; - it("dependCreator()", function () { + it("dependCreator():base", function () { var _ = jpacks; var _schema = _.object({ length1: 'int8', @@ -167,7 +167,7 @@ describe("./src/schemas/depend.js", function () { data2: _.depend('length2', _.array(_.shortString)) }); print(_.stringify(_schema)); - assert.equal(printValue, 'object({length1:int8,length2:int8,data1:depend(length1,bytes),data2:depend(length2,array(string(uint8)))})'); printValue = undefined; + assert.equal(printValue, "object({length1:'int8',length2:'int8',data1:depend('length1','bytes'),data2:depend('length2',array(string('uint8')))})"); printValue = undefined; var buffer = _.pack(_schema, { length1: 2, length2: 3, @@ -175,9 +175,9 @@ describe("./src/schemas/depend.js", function () { data2: ['甲', '乙', '丙'] }); print(buffer.join(' ')); - assert.equal(printValue, '2 3 1 2 3 231 148 178 3 228 185 153 3 228 184 153'); printValue = undefined; + assert.equal(printValue, "2 3 1 2 3 231 148 178 3 228 185 153 3 228 184 153"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '{"length1":2,"length2":3,"data1":[1,2],"data2":["甲","乙","丙"]}'); printValue = undefined; + assert.equal(printValue, "{\"length1\":2,\"length2\":3,\"data1\":[1,2],\"data2\":[\"甲\",\"乙\",\"丙\"]}"); printValue = undefined; }); }); describe("./src/schemas/enums.js", function () { @@ -186,12 +186,12 @@ describe("./src/schemas/enums.js", function () { var _ = jpacks; var _schema = _.enums(['Sun', 'Mon', 'Tues', 'Wed', 'Thur', 'Fri', 'Sat'], 'uint8'); print(_.stringify(_schema)); - assert.equal(printValue, 'enums({Sun:0,Mon:1,Tues:2,Wed:3,Thur:4,Fri:5,Sat:6},uint8)'); printValue = undefined; + assert.equal(printValue, "enums({Sun:0,Mon:1,Tues:2,Wed:3,Thur:4,Fri:5,Sat:6},'uint8')"); printValue = undefined; var buffer = _.pack(_schema, 'Tues'); print(buffer.join(' ')); - assert.equal(printValue, '2'); printValue = undefined; + assert.equal(printValue, "2"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '"Tues"'); printValue = undefined; + assert.equal(printValue, "\"Tues\""); printValue = undefined; }); it("enumsCreator():map is object", function () { var _ = jpacks; @@ -204,12 +204,12 @@ describe("./src/schemas/enums.js", function () { NotFound: 404 }, 'int8'); print(_.stringify(_schema)); - assert.equal(printValue, 'enums({Unknown:-1,Continue:100,Processing:100,OK:200,Created:201,NotFound:404},int8)'); printValue = undefined; + assert.equal(printValue, "enums({Unknown:-1,Continue:100,Processing:100,OK:200,Created:201,NotFound:404},'int8')"); printValue = undefined; var buffer = _.pack(_schema, 'Unknown'); print(buffer.join(' ')); - assert.equal(printValue, '255'); printValue = undefined; + assert.equal(printValue, "255"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '"Unknown"'); printValue = undefined; + assert.equal(printValue, "\"Unknown\""); printValue = undefined; }); it("enumsCreator():fault tolerant", function () { var _ = jpacks; @@ -222,12 +222,12 @@ describe("./src/schemas/enums.js", function () { NotFound: 404 }, 'int8'); print(_.stringify(_schema)); - assert.equal(printValue, 'enums({Unknown:-1,Continue:100,Processing:100,OK:200,Created:201,NotFound:404},int8)'); printValue = undefined; + assert.equal(printValue, "enums({Unknown:-1,Continue:100,Processing:100,OK:200,Created:201,NotFound:404},'int8')"); printValue = undefined; var buffer = _.pack(_schema, 2); print(buffer.join(' ')); - assert.equal(printValue, '2'); printValue = undefined; + assert.equal(printValue, "2"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '2'); printValue = undefined; + assert.equal(printValue, "2"); printValue = undefined; }); describe("./src/schemas/number.js", function () { printValue = undefined; @@ -240,14 +240,14 @@ describe("./src/schemas/number.js", function () { }); var _schema = _.union(_map, 8); print(_.stringify(_schema)); - assert.equal(printValue, 'union({bytes:array(uint8,8),int8:int8,int16:int16,int32:int32,uint8:uint8,uint16:uint16,uint32:uint32,float32:float32,float64:float64,shortint:shortint,smallint:smallint,longint:longint,byte:byte,word:word,longword:longword},8)'); printValue = undefined; + assert.equal(printValue, "union({bytes:array('uint8',8),int8:'int8',int16:'int16',int32:'int32',uint8:'uint8',uint16:'uint16',uint32:'uint32',float32:'float32',float64:'float64',shortint:'shortint',smallint:'smallint',longint:'longint',byte:'byte',word:'word',longword:'longword'},8)"); printValue = undefined; var buffer = _.pack(_schema, { bytes: [0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89] }); print(buffer.join(' ')); - assert.equal(printValue, '18 35 52 69 86 103 120 137'); printValue = undefined; + assert.equal(printValue, "18 35 52 69 86 103 120 137"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '{"bytes":[18,35,52,69,86,103,120,137],"int8":18,"int16":8978,"int32":1161044754,"uint8":18,"uint16":8978,"uint32":1161044754,"float32":2882.19189453125,"float64":-4.843717058781651e-263,"shortint":18,"smallint":8978,"longint":1161044754,"byte":18,"word":8978,"longword":1161044754}'); printValue = undefined; + assert.equal(printValue, "{\"bytes\":[18,35,52,69,86,103,120,137],\"int8\":18,\"int16\":8978,\"int32\":1161044754,\"uint8\":18,\"uint16\":8978,\"uint32\":1161044754,\"float32\":2882.19189453125,\"float64\":-4.843717058781651e-263,\"shortint\":18,\"smallint\":8978,\"longint\":1161044754,\"byte\":18,\"word\":8978,\"longword\":1161044754}"); printValue = undefined; }); }); describe("./src/schemas/object.js", function () { @@ -256,12 +256,12 @@ describe("./src/schemas/object.js", function () { var _ = jpacks; var _schema = _.object([_.shortString, _.word]); print(_.stringify(_schema)); - assert.equal(printValue, 'object([string(uint8),uint16])'); printValue = undefined; + assert.equal(printValue, "object([string('uint8'),'uint16'])"); printValue = undefined; var buffer = _.pack(_schema, ['zswang', 1978]); print(buffer.join(' ')); - assert.equal(printValue, '6 122 115 119 97 110 103 186 7'); printValue = undefined; + assert.equal(printValue, "6 122 115 119 97 110 103 186 7"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '["zswang",1978]'); printValue = undefined; + assert.equal(printValue, "[\"zswang\",1978]"); printValue = undefined; }); it("objectCreator:object", function () { var _ = jpacks; @@ -270,15 +270,15 @@ describe("./src/schemas/object.js", function () { year: _.word }); print(_.stringify(_schema)); - assert.equal(printValue, 'object({namespace:string,args:{0:uint8}})'); printValue = undefined; + assert.equal(printValue, "object({name:string('uint8'),year:'uint16'})"); printValue = undefined; var buffer = _.pack(_schema, { name: 'zswang', year: 1978 }); print(buffer.join(' ')); - assert.equal(printValue, '6 122 115 119 97 110 103 186 7'); printValue = undefined; + assert.equal(printValue, "6 122 115 119 97 110 103 186 7"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '{"name":"zswang","year":1978}'); printValue = undefined; + assert.equal(printValue, "{\"name\":\"zswang\",\"year\":1978}"); printValue = undefined; }); }); describe("./src/schemas/parse.js", function () { @@ -292,12 +292,12 @@ describe("./src/schemas/parse.js", function () { }; var _schema = _.parse(_xor, _xor, 'float64', 8); print(_.stringify(_schema)); - assert.equal(printValue, 'parse(_xor,_xor,float64,8)'); printValue = undefined; + assert.equal(printValue, "parse('_xor','_xor','float64',8)"); printValue = undefined; var buffer = _.pack(_schema, 2.94296650666094e+189); print(buffer.join(' ')); - assert.equal(printValue, '111 75 41 7 126 92 58 24'); printValue = undefined; + assert.equal(printValue, "111 75 41 7 126 92 58 24"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '2.94296650666094e+189'); printValue = undefined; + assert.equal(printValue, "2.94296650666094e+189"); printValue = undefined; }); }); describe("./src/schemas/string.js", function () { @@ -312,14 +312,75 @@ describe("./src/schemas/union.js", function () { content: _.shortString }, 20); print(_.stringify(_schema)); - assert.equal(printValue, 'union({length:uint8,content:string(uint8)},20)'); printValue = undefined; + assert.equal(printValue, "union({length:'uint8',content:string('uint8')},20)"); printValue = undefined; var buffer = _.pack(_schema, { content: '0123456789' }); print(buffer.join(' ')); - assert.equal(printValue, '10 48 49 50 51 52 53 54 55 56 57 0 0 0 0 0 0 0 0 0'); printValue = undefined; + assert.equal(printValue, "10 48 49 50 51 52 53 54 55 56 57 0 0 0 0 0 0 0 0 0"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '{"length":10,"content":"0123456789"}'); printValue = undefined; + assert.equal(printValue, "{\"length\":10,\"content\":\"0123456789\"}"); printValue = undefined; + }); +}); +describe("./src/schemas/virtual.js", function () { + printValue = undefined; + it("virtualCreator:number", function () { + var _ = jpacks; + var _schema = _.object({ + f1: 'uint16', + v1: _.depend('f1', _.virtual(-4)) + }); + print(_.stringify(_schema)) + assert.equal(printValue, "object({f1:'uint16',v1:depend('f1',virtual(-4))})"); printValue = undefined; + var buffer = _.pack(_schema, { + f1: 4 + }); + print(buffer.join(' ')); + assert.equal(printValue, "4 0"); printValue = undefined; + print(JSON.stringify(_.unpack(_schema, buffer, { littleEndian: false }))); + assert.equal(printValue, "{\"f1\":1024,\"v1\":1020}"); printValue = undefined; + }); + it("virtualCreator:string", function () { + var _ = jpacks; + var _schema = _.object({ + name: _.shortString, + welcome: _.depend('name', _.virtual('Hello ')) + }); + print(_.stringify(_schema)) + assert.equal(printValue, "object({name:string('uint8'),welcome:depend('name',virtual('Hello '))})"); printValue = undefined; + var buffer = _.pack(_schema, { + name: 'World!' + }); + print(buffer.join(' ')); + assert.equal(printValue, "6 87 111 114 108 100 33"); printValue = undefined; + print(JSON.stringify(_.unpack(_schema, buffer, { littleEndian: false }))); + assert.equal(printValue, "{\"name\":\"World!\",\"welcome\":\"Hello World!\"}"); printValue = undefined; + }); + it("virtualCreator:depend", function () { + var _ = jpacks; + var _schema = _.object({ + name: _.shortString, + welcome: _.depend('name', _.cases([ + ['zswang', _.depend('name', _.virtual('Hello '))], + ['wang', _.depend('name', _.virtual('Hi '))] + ])) + }); + print(_.stringify(_schema)) + assert.equal(printValue, "object({name:string('uint8'),welcome:depend('name',cases([['zswang',depend('name',virtual('Hello '))],['wang',depend('name',virtual('Hi '))]]))})"); printValue = undefined; + var buffer = _.pack(_schema, { + name: 'zswang' + }); + print(buffer.join(' ')); + assert.equal(printValue, "6 122 115 119 97 110 103"); printValue = undefined; + print(JSON.stringify(_.unpack(_schema, buffer, { littleEndian: false }))); + assert.equal(printValue, "{\"name\":\"zswang\",\"welcome\":\"Hello zswang\"}"); printValue = undefined; + var buffer = _.pack(_schema, { + name: 'wang' + }); + print(buffer.join(' ')); + assert.equal(printValue, "4 119 97 110 103"); printValue = undefined; + print(JSON.stringify(_.unpack(_schema, buffer, { littleEndian: false }))); + assert.equal(printValue, "{\"name\":\"wang\",\"welcome\":\"Hi wang\"}"); printValue = undefined; }); }); describe("./schemas-extend/bigint.js", function () { @@ -328,61 +389,61 @@ describe("./schemas-extend/bigint.js", function () { var _ = jpacks; var _schema = _.uint64; print(_.stringify(_schema)) - assert.equal(printValue, 'uint64'); printValue = undefined; + assert.equal(printValue, "'uint64'"); printValue = undefined; var buffer = _.pack(_schema, '1609531171697315243'); print(buffer.join(' ')); - assert.equal(printValue, '171 205 239 175 18 52 86 22'); printValue = undefined; + assert.equal(printValue, "171 205 239 175 18 52 86 22"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '"1609531171697315243"'); printValue = undefined; + assert.equal(printValue, "\"1609531171697315243\""); printValue = undefined; }); it("uint64():number", function () { var _ = jpacks; var _schema = _.uint64; print(_.stringify(_schema)) - assert.equal(printValue, 'uint64'); printValue = undefined; + assert.equal(printValue, "'uint64'"); printValue = undefined; var buffer = _.pack(_schema, 171697315); print(buffer.join(' ')); - assert.equal(printValue, '163 228 59 10 0 0 0 0'); printValue = undefined; + assert.equal(printValue, "163 228 59 10 0 0 0 0"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '"171697315"'); printValue = undefined; + assert.equal(printValue, "\"171697315\""); printValue = undefined; }); it("uint64():littleEndian = false;", function () { var _ = jpacks; var _schema = _.uint64; print(_.stringify(_schema)) - assert.equal(printValue, 'uint64'); printValue = undefined; + assert.equal(printValue, "'uint64'"); printValue = undefined; var buffer = _.pack(_schema, 171697315, { littleEndian: false }); print(buffer.join(' ')); - assert.equal(printValue, '0 0 0 0 10 59 228 163'); printValue = undefined; + assert.equal(printValue, "0 0 0 0 10 59 228 163"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer, { littleEndian: false }))); - assert.equal(printValue, '"171697315"'); printValue = undefined; + assert.equal(printValue, "\"171697315\""); printValue = undefined; }); it("int64():-1,-2", function () { var _ = jpacks; var _schema = _.int64; print(_.stringify(_schema)) - assert.equal(printValue, 'int64'); printValue = undefined; + assert.equal(printValue, "'int64'"); printValue = undefined; var buffer = _.pack(_schema, '-1'); print(buffer.join(' ')); - assert.equal(printValue, '255 255 255 255 255 255 255 255'); printValue = undefined; + assert.equal(printValue, "255 255 255 255 255 255 255 255"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '"-1"'); printValue = undefined; + assert.equal(printValue, "\"-1\""); printValue = undefined; var buffer = _.pack(_schema, '-2'); print(buffer.join(' ')); - assert.equal(printValue, '254 255 255 255 255 255 255 255'); printValue = undefined; + assert.equal(printValue, "254 255 255 255 255 255 255 255"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '"-2"'); printValue = undefined; + assert.equal(printValue, "\"-2\""); printValue = undefined; }); it("int64():-2, littleEndian = false", function () { var _ = jpacks; var _schema = _.int64; print(_.stringify(_schema)) - assert.equal(printValue, 'int64'); printValue = undefined; + assert.equal(printValue, "'int64'"); printValue = undefined; var buffer = _.pack(_schema, -2, { littleEndian: false }); print(buffer.join(' ')); - assert.equal(printValue, '255 255 255 255 255 255 255 254'); printValue = undefined; + assert.equal(printValue, "255 255 255 255 255 255 255 254"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer, { littleEndian: false }))); - assert.equal(printValue, '"-2"'); printValue = undefined; + assert.equal(printValue, "\"-2\""); printValue = undefined; }); }); describe("./schemas-extend/protobuf.js", function () { @@ -394,7 +455,7 @@ describe("./schemas-extend/protobuf.js", function () { 'int8' ); print(_.stringify(_schema)) - assert.equal(printValue, 'array(protobuf(test/protoify/json.proto,js.Value,uint16),int8)'); printValue = undefined; + assert.equal(printValue, "array(protobuf('test/protoify/json.proto','js.Value','uint16'),'int8')"); printValue = undefined; var buffer = _.pack(_schema, [{ integer: 123 }, { @@ -412,9 +473,9 @@ describe("./schemas-extend/protobuf.js", function () { } }]); print(buffer.join(' ')); - assert.equal(printValue, '2 3 0 8 246 1 33 0 58 31 10 6 26 4 110 97 109 101 10 6 26 4 121 101 97 114 18 8 26 6 122 115 119 97 110 103 18 3 8 190 31'); printValue = undefined; + assert.equal(printValue, "2 3 0 8 246 1 33 0 58 31 10 6 26 4 110 97 109 101 10 6 26 4 121 101 97 114 18 8 26 6 122 115 119 97 110 103 18 3 8 190 31"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '[{"integer":123},{"object":{"keys":[{"string":"name"},{"string":"year"}],"values":[{"string":"zswang"},{"integer":2015}]}}]'); printValue = undefined; + assert.equal(printValue, "[{\"integer\":123},{\"object\":{\"keys\":[{\"string\":\"name\"},{\"string\":\"year\"}],\"values\":[{\"string\":\"zswang\"},{\"integer\":2015}]}}]"); printValue = undefined; }); it("protobufCreator():bigint", function () { var _ = jpacks; @@ -423,16 +484,16 @@ describe("./schemas-extend/protobuf.js", function () { 'int8' ); print(_.stringify(_schema)) - assert.equal(printValue, 'array(protobuf(test/protoify/bigint.proto,bigint.Value,uint16),int8)'); printValue = undefined; + assert.equal(printValue, "array(protobuf('test/protoify/bigint.proto','bigint.Value','uint16'),'int8')"); printValue = undefined; var buffer = _.pack(_schema, [{ int64: "-192377746236123" }, { uint64: "192377746236123" }]); print(buffer.join(' ')); - assert.equal(printValue, '2 11 0 8 165 186 151 134 137 161 212 255 255 1 8 0 16 219 197 232 249 246 222 43'); printValue = undefined; + assert.equal(printValue, "2 11 0 8 165 186 151 134 137 161 212 255 255 1 8 0 16 219 197 232 249 246 222 43"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '[{"int64":"-192377746236123"},{"uint64":"192377746236123"}]'); printValue = undefined; + assert.equal(printValue, "[{\"int64\":\"-192377746236123\"},{\"uint64\":\"192377746236123\"}]"); printValue = undefined; }); it("protobufCreator():bytesAsString", function () { var _ = jpacks; @@ -441,7 +502,7 @@ describe("./schemas-extend/protobuf.js", function () { 'int8' ); print(_.stringify(_schema)) - assert.equal(printValue, 'array(protobuf(test/protoify/string.proto,str.Value,uint16),int8)'); printValue = undefined; + assert.equal(printValue, "array(protobuf('test/protoify/string.proto','str.Value','uint16'),'int8')"); printValue = undefined; _.setDefaultOptions({ protobuf_bytesAsString: true }); @@ -451,9 +512,9 @@ describe("./schemas-extend/protobuf.js", function () { bytes: "你好世界!Hello World!" }]); print(buffer.join(' ')); - assert.equal(printValue, '2 27 0 10 25 72 101 108 108 111 32 87 111 114 108 100 33 228 189 160 229 165 189 228 184 150 231 149 140 33 27 0 18 25 228 189 160 229 165 189 228 184 150 231 149 140 33 72 101 108 108 111 32 87 111 114 108 100 33'); printValue = undefined; + assert.equal(printValue, "2 27 0 10 25 72 101 108 108 111 32 87 111 114 108 100 33 228 189 160 229 165 189 228 184 150 231 149 140 33 27 0 18 25 228 189 160 229 165 189 228 184 150 231 149 140 33 72 101 108 108 111 32 87 111 114 108 100 33"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '[{"string":"Hello World!你好世界!"},{"bytes":"你好世界!Hello World!"}]'); printValue = undefined; + assert.equal(printValue, "[{\"string\":\"Hello World!你好世界!\"},{\"bytes\":\"你好世界!Hello World!\"}]"); printValue = undefined; }); }); describe("./schemas-extend/zlib.js", function () { @@ -465,15 +526,17 @@ describe("./schemas-extend/zlib.js", function () { data: _.gzip(_.shortString, 'uint16') }); print(_.stringify(_schema)) - assert.equal(printValue, 'object({type:uint8,data:parse(zlib.gzipSync,zlib.gunzipSync,string(uint8),uint16)})'); printValue = undefined; + assert.equal(printValue, "object({type:'uint8',data:parse('zlib.gzipSync','zlib.gunzipSync',string('uint8'),'uint16')})"); printValue = undefined; var buffer = _.pack(_schema, { type: 2, data: '你好世界!Hello' }); - print(buffer.join(' ')); - assert.equal(printValue, '2 42 0 31 139 8 0 0 0 0 0 0 3 19 121 178 119 193 211 165 123 159 236 152 246 124 106 207 251 61 141 30 169 57 57 249 0 183 181 133 147 21 0 0 0'); printValue = undefined; + print(buffer.slice(14).join(' ')); + // windows: 2 42 0 31 139 8 0 0 0 0 0 0 11 19 121 178 119 193 211 165 123 159 236 152 246 124 106 207 251 61 141 30 169 57 57 249 0 183 181 133 147 21 0 0 0 + // linux: 2 42 0 31 139 8 0 0 0 0 0 0 3 19 121 178 119 193 211 165 123 159 236 152 246 124 106 207 251 61 141 30 169 57 57 249 0 183 181 133 147 21 0 0 0 + assert.equal(printValue, "121 178 119 193 211 165 123 159 236 152 246 124 106 207 251 61 141 30 169 57 57 249 0 183 181 133 147 21 0 0 0"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '{"type":2,"data":"你好世界!Hello"}'); printValue = undefined; + assert.equal(printValue, "{\"type\":2,\"data\":\"你好世界!Hello\"}"); printValue = undefined; }); it("inflateCreator():base", function () { var _ = jpacks; @@ -482,14 +545,14 @@ describe("./schemas-extend/zlib.js", function () { data: _.inflate(_.shortString, 'uint16') }); print(_.stringify(_schema)) - assert.equal(printValue, 'object({type:uint8,data:parse(zlib.deflateSync,zlib.inflateSync,string(uint8),uint16)})'); printValue = undefined; + assert.equal(printValue, "object({type:'uint8',data:parse('zlib.deflateSync','zlib.inflateSync',string('uint8'),'uint16')})"); printValue = undefined; var buffer = _.pack(_schema, { type: 2, data: '你好世界!Hello' }); print(buffer.join(' ')); - assert.equal(printValue, '2 30 0 120 156 19 121 178 119 193 211 165 123 159 236 152 246 124 106 207 251 61 141 30 169 57 57 249 0 152 20 12 247'); printValue = undefined; + assert.equal(printValue, "2 30 0 120 156 19 121 178 119 193 211 165 123 159 236 152 246 124 106 207 251 61 141 30 169 57 57 249 0 152 20 12 247"); printValue = undefined; print(JSON.stringify(_.unpack(_schema, buffer))); - assert.equal(printValue, '{"type":2,"data":"你好世界!Hello"}'); printValue = undefined; + assert.equal(printValue, "{\"type\":2,\"data\":\"你好世界!Hello\"}"); printValue = undefined; }); }); diff --git a/version.jdists b/version.jdists index 6786da7..c4773c0 100644 --- a/version.jdists +++ b/version.jdists @@ -1,4 +1,5 @@ /**/ + main = 'jpacks.js'; version = version.replace(/\d+$/, function (value) { return parseInt(value) + 1; });