diff --git a/.jshintrc b/.jshintrc
index 24dd06b..c93947d 100644
--- a/.jshintrc
+++ b/.jshintrc
@@ -1,4 +1,4 @@
{
- "undef": false,
- "evil": true
+ "undef": false,
+ "evil": true
}
diff --git a/jpacks.js b/jpacks.js
index 5f93edf..5dba847 100644
--- a/jpacks.js
+++ b/jpacks.js
@@ -5,9 +5,10 @@
* Binary data packing and unpacking.
* @author
* zswang (http://weibo.com/zswang)
- * @version 0.1.0
- * @date 2015-11-01
+ * @version 0.1.1
+ * @date 2015-11-02
*/
+ function createSchema() {
/**
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView
*/
@@ -208,6 +209,32 @@
return buffer;
}
Schema.pack = pack;
+ function stringify(obj) {
+ function scan(obj) {
+ if (typeof obj === 'object') {
+ if (obj instanceof Schema) {
+ return obj.schema;
+ }
+ var result = new obj.constructor();
+ Object.keys(obj).forEach(function (key) {
+ result[key] = scan(obj[key]);
+ });
+ return result;
+ } else if (typeof obj === 'function') {
+ return obj.schema;
+ }
+ return obj;
+ }
+ return JSON.stringify(scan(obj) || '').replace(/"/g, '');
+ }
+ Schema.stringify = stringify;
+ Schema.prototype.toString = function () {
+ return stringify(this);
+ };
+ return Schema;
+}
+ function create() {
+ var Schema = createSchema();
/**
* 基础类型
*
@@ -298,7 +325,7 @@
})('set' + item.type),
size: item.size,
name: name,
- namespace: 'base',
+ namespace: 'number',
array: item.array
});
Schema.register(name, schema);
@@ -307,198 +334,155 @@
});
});
/**
- * 声明数组类型
+ * 声明指定长度或者下标的数组
*
- * @param {string|Schema} itemSchema 数组元素类型
- * @param {number} count 元素个数
- * @return {Schema} 返回数据结构
+ * @param {string|Schema} itemSchema 元素类型
+ * @param {string|Schema|number=} count 下标类型或个数
+ * @return {Schema|Function} 返回数据结构
* @example 调用示例 1
```js
var _ = jpacks;
- var _schema = _.array(10, _.byte);
- var ab = _.pack(_.array(10, _.byte), [1, 2, 3, 4]);
- var u8a = new Uint8Array(ab);
- console.log(u8a);
- // -> [1, 2, 3, 4, 0, 0, 0, 0, 0, 0]
- console.log(_.unpack(_schema, u8a));
- // -> [1, 2, 3, 4, 0, 0, 0, 0, 0, 0]
+ var schema = jpacks.array('int16', 2);
+ console.log(String(schema));
+ // > array(int16,2)
+ var value = [12337, 12851];
+ var buffer = jpacks.pack(schema, value);
+ console.log(buffer);
+ // > [48, 49, 50, 51]
+ console.log(jpacks.unpack(schema, buffer));
+ // > [12337, 12851]
```
- */
- function array(count, itemSchema) {
- if (typeof count !== 'number') {
- var temp = count;
- count = itemSchema;
- itemSchema = temp;
- }
- var schema = Schema.from(itemSchema);
- if (!schema) {
- throw new Error('Schema "' + itemSchema + '" not define.');
- }
- var size = schema.size * count;
- return new Schema({
- unpack: function _unpack(buffer, options, offsets) {
- if (schema.array && options.littleEndian) {
- /* TypeArray littleEndian is true */
- var offset = offsets[0];
- offsets[0] += size;
- return [].slice.apply(new schema.array(buffer, offset, count));
- }
- var result = [];
- for (var i = 0; i < count; i++) {
- result.push(Schema.unpack(schema, buffer, options, offsets));
- }
- return result;
- },
- pack: function _pack(value, options, buffer) {
- if (schema.array && options.littleEndian) {
- /* TypeArray littleEndian is true */
- var arrayBuffer = new ArrayBuffer(size);
- var typeArray = new schema.array(arrayBuffer);
- typeArray.set(value);
- var uint8Array = new Uint8Array(arrayBuffer);
- [].push.apply(buffer, uint8Array);
- }
- for (var i = 0; i < count; i++) {
- Schema.pack(schema, value[i], options, buffer);
- }
- },
- name: schema.name + '[' + count + ']',
- size: size,
- namespace: 'array'
- });
- }
- Schema.register('array', array);
- Schema.register('staticArray', array);
- function bytes(size) {
- return array(size, 'uint8');
- }
- Schema.register('bytes', bytes);
- Schema.pushPattern(function (schema) {
- if (typeof schema === 'string') {
- var match = schema.match(/^(\w+)\[(\d+)\]$/);
- if (match) {
- var baseSchema = Schema.from(match[1]);
- if (baseSchema) {
- var arraySchema = array(parseInt(match[2]), baseSchema);
- Schema.register(schema, arraySchema); // 缓存
- return arraySchema;
- }
- }
- }
- });
- /**
- * 声明指定长度的数组类型
- *
- * @param {string|Schema} lengthSchema 长度类型
- * @param {string|Schema} itemSchema 元素类型
- * @return {Schema} 返回数据结构
- * @example 调用示例 1
+ * @example 调用示例 2
```js
var _ = jpacks;
- var _schema = _.dynamicArray(_.byte, _.byte);
- var ab = _.pack(_schema, [1, 2, 3, 4]);
- var u8a = new Uint8Array(ab);
- console.log(u8a);
- // -> [4, 1, 2, 3, 4]
- console.log(_.unpack(_schema, u8a));
- // -> [1, 2, 3, 4]
+ var schema = jpacks.array('int16', 'int8');
+ console.log(String(schema));
+ // > array(int16,int8)
+ var value = [12337, 12851];
+ var buffer = jpacks.pack(schema, value);
+ console.log(buffer);
+ // > [ 2, 48, 49, 50, 51 ]
+ console.log(jpacks.unpack(schema, buffer));
+ // > [ 12337, 12851 ]
```
- * @example 调用示例 2
+ * @example 调用示例 3
```js
var _ = jpacks;
- var _schema = _.dynamicArray(_.word, _.byte);
- var ab = _.pack(_schema, [1, 2, 3, 4]);
- var u8a = new Uint8Array(ab);
- console.log(u8a);
- // -> [0, 0, 0, 4, 1, 2, 3, 4]
- console.log(_.unpack(_schema, u8a));
- // -> [1, 2, 3, 4]
+ var schema = jpacks.array('int16')(6);
+ console.log(String(schema));
+ // > array(int16,6)
+ var value = [12337, 12851];
+ var buffer = jpacks.pack(schema, value);
+ console.log(buffer);
+ // > [ 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0 ]
+ console.log(jpacks.unpack(schema, buffer));
+ // > [ 12337, 12851, 0, 0, 0, 0 ]
```
- */
- function dynamicArray(lengthSchema, itemSchema) {
- lengthSchema = Schema.from(lengthSchema);
- if (lengthSchema.namespace !== 'base') {
- throw new Error('Parameter "lengthSchema" is not a numeric type.');
- }
- if (!itemSchema) {
+ */
+ function array(itemSchema, count) {
+ if (typeof itemSchema === 'undefined') {
throw new Error('Parameter "itemSchema" is undefined.');
}
- return new Schema({
- unpack: function _unpack(buffer, options, offsets) {
- var length = Schema.unpack(lengthSchema, buffer, options, offsets);
- return Schema.unpack(Schema.array(length, itemSchema), buffer, options, offsets);
- },
- pack: function _pack(value, options, buffer) {
- if (!value) {
- Schema.pack(lengthSchema, 0, options, buffer);
- } else {
- Schema.pack(lengthSchema, value.length, options, buffer);
- Schema.pack(Schema.array(value.length, itemSchema), value, options, buffer);
+ var creatorSchema = function (count) {
+ var size;
+ var countSchema;
+ if (typeof count === 'number') {
+ size = itemSchema.size * count;
+ } else {
+ countSchema = Schema.from(count);
+ if (countSchema.namespace !== 'number') {
+ throw new Error('Parameter "count" is not a numeric type.');
}
- },
- name: 'dynamic array[..' + lengthSchema.name + '..]',
- namespace: 'dynamicArray',
- size: lengthSchema.size
- });
- }
- Schema.register('dynamicArray', dynamicArray);
- function shortArray(schema) {
- return dynamicArray('uint8', schema);
+ }
+ return new Schema({
+ unpack: function _unpack(buffer, options, offsets) {
+ var length = count;
+ if (countSchema) {
+ length = Schema.unpack(countSchema, buffer, options, offsets);
+ }
+ if (itemSchema.array && options.littleEndian) {
+ size = countSchema.size * length;
+ /* TypeArray littleEndian is true */
+ var offset = offsets[0];
+ offsets[0] += size;
+ return [].slice.apply(new itemSchema.array(buffer, offset, length));
+ }
+ var result = [];
+ for (var i = 0; i < length; i++) {
+ result.push(Schema.unpack(itemSchema, buffer, options, offsets));
+ }
+ return result;
+ },
+ pack: function _pack(value, options, buffer) {
+ var length = count;
+ if (countSchema) {
+ length = value ? value.length : 0;
+ Schema.pack(countSchema, length, options, buffer);
+ }
+ if (itemSchema.array && options.littleEndian) {
+ size = itemSchema.size * length;
+ /* TypeArray littleEndian is true */
+ var arrayBuffer = new ArrayBuffer(size);
+ var typeArray = new itemSchema.array(arrayBuffer);
+ typeArray.set(value);
+ var uint8Array = new Uint8Array(arrayBuffer);
+ [].push.apply(buffer, uint8Array);
+ }
+ for (var i = 0; i < length; i++) {
+ Schema.pack(itemSchema, value[i], options, buffer);
+ }
+ },
+ schema: 'array(' + [Schema.stringify(itemSchema), Schema.stringify(count)] + ')',
+ namespace: 'array',
+ size: size
+ });
+ };
+ creatorSchema.name = 'array(' + itemSchema.name + ')';
+ if (arguments.length === 1) {
+ return creatorSchema;
+ } else {
+ return creatorSchema(count);
+ }
+ }
+ Schema.register('array', array);
+ function shortArray(itemSchema) {
+ return array(itemSchema, 'uint8');
}
Schema.register('shortArray', shortArray);
- function smallArray(schema) {
- return dynamicArray('uint16', schema);
+ function smallArray(itemSchema) {
+ return array(itemSchema, 'uint16');
}
Schema.register('smallArray', smallArray);
- function longArray(schema) {
- return dynamicArray('uint32', schema);
+ function longArray(itemSchema) {
+ return array(itemSchema, 'uint32');
}
Schema.register('longArray', longArray);
- // 'int8[.]' - shortArray
- // 'int8[..]' - smallArray
- // 'int8[....]' - longArray
- Schema.pushPattern(function (schema) {
- if (typeof schema === 'string') {
- var match = schema.match(/^(\w+)\[(\.|\..|\....)\]$/);
- if (match) {
- var baseSchema = Schema.from(match[1]);
- if (baseSchema) {
- var lengthSchema = 'uint16';
- switch (match[2]) {
- case '.':
- lengthSchema = 'uint8'
- break;
- case '....':
- lengthSchema = 'uint32'
- break;
- }
- var arraySchema = dynamicArray(lengthSchema, baseSchema);
- Schema.register(schema, arraySchema); // 缓存
- return arraySchema;
- }
- }
- }
- });
+ function bytes(count) {
+ return Schema.array('uint8', count);
+ }
+ Schema.register('bytes', bytes);
/**
* 定义一个对象结构
*
* @param {object} schema 数据结构
* @return {Schema} 返回构建的数据结构
*/
- function object(schema) {
- if (typeof schema !== 'object') {
+ function object(objectSchema) {
+ if (typeof objectSchema !== 'object') {
throw new Error('Parameter "schemas" must be a object type.');
}
- if (schema instanceof Schema) {
- return schema;
+ if (objectSchema instanceof Schema) {
+ return objectSchema;
}
+ var names = Schema.stringify(objectSchema);
+ var keys = Object.keys(objectSchema);
return new Schema({
unpack: function _unpack(buffer, options, offsets) {
- var result = {};
+ var result = new objectSchema.constructor();
var $scope = options.$scope;
options.$scope = result;
- Object.keys(schema).forEach(function (key) {
- result[key] = Schema.unpack(schema[key], buffer, options, offsets);
+ keys.forEach(function (key) {
+ result[key] = Schema.unpack(objectSchema[key], buffer, options, offsets);
});
options.$scope = $scope;
return result;
@@ -506,13 +490,14 @@
pack: function _pack(value, options, buffer) {
var $scope = options.$scope;
options.$scope = value;
- Object.keys(schema).forEach(function (key) {
- Schema.pack(schema[key], value[key], options, buffer);
+ keys.forEach(function (key) {
+ Schema.pack(objectSchema[key], value[key], options, buffer);
});
options.$scope = $scope;
},
- object: schema,
- name: 'object {}'
+ object: objectSchema,
+ schema: 'object(' + names + ')',
+ namespace: 'object'
});
};
Schema.register('object', object);
@@ -589,62 +574,43 @@
},
size: size,
object: schemas,
- name: 'union {}'
+ schema: 'union(' + Schema.stringify(size) + ')'
});
}
Schema.register('union', union);
/**
- * 创建条件类型
+ * 定义一个枚举结构
*
- * @param {Object} schemas 条件类型结构,第一个字段为条件字段,其他字段为数组。数组第一元素表示命中条件,第二位类型
- * @return {Schema} 返回联合类型
- * @example 调用示例 1
- ```js
- var _ = jpacks;
- var _schema = _.cases({
- type: _.shortString,
- name: ['name', _.shortString],
- age: ['age', _.byte]
- });
- var ab = _.pack(_schema, {
- type: 'name',
- name: 'tom'
- });
- var u8a = new Uint8Array(ab);
- console.log(u8a);
- // -> [4, 110, 97, 109, 101, 3, 116, 111, 109]
- console.log(_.unpack(_schema, u8a));
- // -> Object {type: "name", name: "tom"}
- var ab2 = _.pack(_schema, {
- type: 'age',
- age: 23
- });
- var u8a2 = new Uint8Array(ab2);
- console.log(u8a2);
- // -> [3, 97, 103, 101, 23]
- console.log(_.unpack(_schema, u8a2));
- // -> Object {type: "age", age: 23}
- ```
- */
- function cases(schemas) {
- if (typeof schemas !== 'object') {
- throw new Error('Parameter "schemas" must be a object type.');
+ * @param {Schema} baseSchema 枚举结构的基础类型
+ * @param {Array|Object} map 枚举类型字典
+ * @return {Schema} 返回构建的数据结构
+ */
+ function enums(baseSchema, map) {
+ baseSchema = Schema.from(baseSchema);
+ if (!baseSchema) {
+ throw new Error('Parameter "baseSchema" is undefined.');
}
- if (schemas instanceof Schema) {
- throw new Error('Parameter "schemas" cannot be a Schema object.');
+ if (baseSchema.namespace !== 'base') {
+ throw new Error('Parameter "baseSchema" is not a numeric type.');
}
- var keys = Object.keys(schemas);
- var patternName = keys[0];
- var patternSchema = schemas[patternName];
- keys = keys.slice(1);
+ if (typeof map !== 'object') {
+ throw new Error('Parameter "map" must be a object type.');
+ }
+ if (map instanceof Array) {
+ var temp = {};
+ map.forEach(function (item, index) {
+ temp[item] = index;
+ });
+ map = temp;
+ }
+ var keys = Object.keys(map);
return new Schema({
unpack: function _unpack(buffer, options, offsets) {
- var result = {};
- var patternValue = Schema.unpack(patternSchema, buffer, options, offsets);
- result[patternName] = patternValue;
+ var baseValue = Schema.unpack(baseSchema, buffer, options, offsets);
+ var result;
keys.every(function (key) {
- if (patternValue === schemas[key][0]) {
- result[key] = Schema.unpack(schemas[key][1], buffer, options, offsets);
+ if (map[key] === baseValue) {
+ result = key;
return false;
}
return true;
@@ -652,21 +618,22 @@
return result;
},
pack: function _pack(value, options, buffer) {
- var patternValue = value[patternName];
- Schema.pack(patternSchema, patternValue, options, buffer);
- keys.every(function (key) {
- if (patternValue === schemas[key][0]) {
- Schema.pack(schemas[key][1], value[key], options, buffer);
+ if (keys.every(function (key) {
+ if (key === value) {
+ Schema.pack(baseSchema, map[key], options, buffer);
return false;
}
return true;
- });
+ })) {
+ throw new Error('Not find enum "' + value + '".');
+ };
},
- name: 'cases{' + patternName + '}',
- namespace: 'cases'
+ map: map,
+ schema: 'enum(' + [Schema.stringify(baseSchema), Schema.stringify(map)] + ')',
+ namespace: 'base'
});
- }
- Schema.register('cases', cases);
+ };
+ Schema.register('enums', enums);
/**
* 对字符串进行 utf8 编码
*
@@ -723,11 +690,10 @@
});
}
}
- Schema.stringBytes = stringBytes;
/**
* 声明指定长度的字符串
*
- * @param {number} size 字节个数
+ * @param {number|string|Schema} size 字节个数下标类型
* @return {Schema} 返回数据结构
*/
function string(size) {
@@ -743,67 +709,12 @@
pack: function _pack(value, options, buffer) {
Schema.pack(schema, stringBytes(value), options, buffer);
},
- namespace: 'staticString',
- name: 'string{' + size + '}',
+ namespace: 'string',
+ name: 'string(' + Schema.stringify(size) + ')',
size: size
});
}
Schema.register('string', string);
- Schema.register('staticString', string);
- Schema.pushPattern(function (schema) {
- if (typeof schema === 'string') {
- var match = schema.match(/^string\{(\d+)\}$/);
- if (match) {
- var arraySchema = string(parseInt(match[1]));
- Schema.register(schema, arraySchema); // 缓存
- return arraySchema;
- }
- }
- });
- /**
- * 声明指定长度的字符串
- *
- * @param {string|Schema} lengthSchema 长度类型
- * @return {Schema} 返回数据结构
- * @example 调用示例
- ```js
- var _ = jpacks;
- var _schema = _.dynamicString('int32');
- var ab = _.pack(_schema, '你好 World!');
- var u8a = new Uint8Array(ab);
- console.log(u8a);
- // -> [0, 0, 0, 13, 228, 189, 160, 229, 165, 189, 32, 87, 111, 114, 108, 100, 33]
- console.log(_.unpack(_schema, u8a));
- // -> 你好 World!
- ```
- */
- function dynamicString(lengthSchema) {
- lengthSchema = Schema.from(lengthSchema);
- if (!lengthSchema) {
- throw new Error('Parameter "lengthSchema" is undefined.');
- }
- if (lengthSchema.namespace !== 'base') {
- throw new Error('Parameter "lengthSchema" is not a numeric type.');
- }
- return new Schema({
- unpack: function _unpack(buffer, options, offsets) {
- var length = Schema.unpack(lengthSchema, buffer, options, offsets);
- return Schema.unpack(Schema.string(length), buffer, options, offsets);
- },
- pack: function _pack(value, options, buffer) {
- if (!value) {
- Schema.pack(lengthSchema, 0, options, buffer);
- } else {
- var bytes = Schema.stringBytes(value);
- Schema.pack(lengthSchema, bytes.length, options, buffer);
- Schema.pack(Schema.bytes(bytes.length), bytes, options, buffer);
- }
- },
- namespace: 'dynamicString',
- name: 'string{..' + lengthSchema.name + '..}'
- });
- }
- Schema.register('dynamicString', dynamicString);
/**
* 短字符串类型
*
@@ -820,7 +731,7 @@
// -> 你好 World!
```
*/
- Schema.register('shortString', dynamicString('uint8'));
+ Schema.register('shortString', string('uint8'));
/**
* 长字符串类型
*
@@ -837,9 +748,9 @@
// -> 你好 World!
```
*/
- Schema.register('smallString', dynamicString('uint16'));
+ Schema.register('smallString', string('uint16'));
/**
- * 长字符串类型
+ * 超长字符串类型
*
* @return {Schema} 返回数据结构
* @example 调用示例
@@ -854,116 +765,7 @@
// -> 你好 World!
```
*/
- Schema.register('longString', dynamicString('uint32'));
- function dependArray(field, itemSchema) {
- if (typeof field !== 'string') {
- throw new Error('Parameter "field" must be a string.');
- }
- return new Schema({
- unpack: function _unpack(buffer, options, offsets) {
- if (!options.$scope) {
- throw new Error('Unpack must running in object.');
- }
- var length = options.$scope[field];
- if (typeof length !== 'number') {
- throw new Error('Field "' + field + '" must be a number.');
- }
- return Schema.unpack(Schema.staticArray(length, itemSchema), buffer, options, offsets);
- },
- pack: function _pack(value, options, buffer) {
- var length = options.$scope[field];
- if (typeof length !== 'number') {
- throw new Error('Field "' + field + '" must be a number.');
- }
- Schema.pack(Schema.array(length, itemSchema), value, options, buffer);
- },
- name: 'depend array{' + field + '}',
- namespace: 'dependArray'
- });
- }
- Schema.register('dependArray', dependArray);
- function dependString(field, itemSchema) {
- if (typeof field !== 'string') {
- throw new Error('Parameter "field" must be a string.');
- }
- return new Schema({
- unpack: function _unpack(buffer, options, offsets) {
- if (!options.$scope) {
- throw new Error('Unpack must running in object.');
- }
- var size = options.$scope[field];
- if (typeof size !== 'number') {
- throw new Error('Field "' + field + '" must be a number.');
- }
- return Schema.unpack(Schema.staticString(size, itemSchema), buffer, options, offsets);
- },
- pack: function _pack(value, options, buffer) {
- var size = options.$scope[field];
- if (typeof size !== 'number') {
- throw new Error('Field "' + field + '" must be a number.');
- }
- Schema.pack(Schema.string(size), value, options, buffer);
- },
- name: 'depend string{' + field + '}',
- namespace: 'dependString'
- });
- }
- Schema.register('dependString', dependString);
- /**
- * 定义一个枚举结构
- *
- * @param {Schema} baseSchema 枚举结构的基础类型
- * @param {Array|Object} map 枚举类型字典
- * @return {Schema} 返回构建的数据结构
- */
- function enums(baseSchema, map) {
- baseSchema = Schema.from(baseSchema);
- if (!baseSchema) {
- throw new Error('Parameter "baseSchema" is undefined.');
- }
- if (baseSchema.namespace !== 'base') {
- throw new Error('Parameter "baseSchema" is not a numeric type.');
- }
- if (typeof map !== 'object') {
- throw new Error('Parameter "map" must be a object type.');
- }
- if (map instanceof Array) {
- var temp = {};
- map.forEach(function (item, index) {
- temp[item] = index;
- });
- map = temp;
- }
- var keys = Object.keys(map);
- return new Schema({
- unpack: function _unpack(buffer, options, offsets) {
- var baseValue = Schema.unpack(baseSchema, buffer, options, offsets);
- var result;
- keys.every(function (key) {
- if (map[key] === baseValue) {
- result = key;
- return false;
- }
- return true;
- });
- return result;
- },
- pack: function _pack(value, options, buffer) {
- if (keys.every(function (key) {
- if (key === value) {
- Schema.pack(baseSchema, map[key], options, buffer);
- return false;
- }
- return true;
- })) {
- throw new Error('Not find enum "' + value + '".');
- };
- },
- map: map,
- name: 'enum {}'
- });
- };
- Schema.register('enums', enums);
+ Schema.register('longString', string('uint32'));
/**
* 以零号字符结尾的字符串
*
@@ -997,11 +799,116 @@
Schema.pack('byte', 0, options, buffer);
},
namespace: 'cstring',
- name: 'cstring'
+ schema: 'cstring'
});
Schema.register('cstring', cstring);
Schema.register('pchar', cstring);
- var exports = Schema;
+ /**
+ * 创建条件类型
+ *
+ * @param {Array of array} patterns 数组第一元素表示命中条件,第二位类型
+ * @return {Schema} 返回条件类型
+ * @example 调用示例 1
+ ```js
+ var _ = jpacks;
+ var _schema = {
+ name: ['name', _.shortString],
+ age: ['age', _.byte]
+ };
+ var ab = _.pack(_schema, {
+ type: 'name',
+ name: 'tom'
+ });
+ var u8a = new Uint8Array(ab);
+ console.log(u8a);
+ // -> [4, 110, 97, 109, 101, 3, 116, 111, 109]
+ console.log(_.unpack(_schema, u8a));
+ // -> Object {type: "name", name: "tom"}
+ var ab2 = _.pack(_schema, {
+ type: 'age',
+ age: 23
+ });
+ var u8a2 = new Uint8Array(ab2);
+ console.log(u8a2);
+ // -> [3, 97, 103, 101, 23]
+ console.log(_.unpack(_schema, u8a2));
+ // -> Object {type: "age", age: 23}
+ ```
+ */
+ function cases(patterns) {
+ /**/
+ if (typeof patterns !== 'object') {
+ throw new Error('Parameter "patterns" must be a object type.');
+ }
+ if (patterns instanceof Schema) {
+ throw new Error('Parameter "patterns" cannot be a Schema object.');
+ }
+ if (!(patterns instanceof Array)) {
+ throw new Error('Parameter "patterns" must be a array.');
+ }
+ /**/
+ var schemaCreator = function (value) {
+ for (var i = 0; i < patterns.length; i++) {
+ if (patterns[i][0] === value) {
+ return patterns[i][1];
+ }
+ }
+ };
+ schemaCreator.schema = 'cases(' + Schema.stringify(patterns) + ')';
+ schemaCreator.namespace = 'cases';
+ return schemaCreator;
+ }
+ Schema.register('cases', cases);
+ /**
+ * 声明字段依赖结构
+ *
+ * @param {string} field 字段名
+ * @param {Function} schemaCreator 创建数据结构的方法
+ * [[[
+ * @param {Any} value 传递值
+ * @return {Schema} 返回数据结构
+ * function schemaCreator(value) {}
+ * ]]]
+ */
+ function depend(field, schemaCreator) {
+ if (typeof field !== 'string') {
+ throw new Error('Parameter "field" must be a string.');
+ }
+ if (typeof schemaCreator !== 'function') {
+ throw new Error('Parameter "field" must be a function.');
+ }
+ return new Schema({
+ unpack: function _unpack(buffer, options, offsets) {
+ if (!options.$scope) {
+ throw new Error('Unpack must running in object.');
+ }
+ var fieldValue = options.$scope[field];
+ if (typeof fieldValue === 'undefined') {
+ throw new Error('Field "' + field + '" is undefined.');
+ }
+ return Schema.unpack(schemaCreator(fieldValue), buffer, options, offsets);
+ },
+ pack: function _pack(value, options, buffer) {
+ var fieldValue = options.$scope[field];
+ if (typeof fieldValue === 'undefined') {
+ throw new Error('Field "' + field + '" is undefined.');
+ }
+ Schema.pack(schemaCreator(fieldValue), value, options, buffer);
+ },
+ schema: 'depend(' + [field, Schema.stringify(schemaCreator)] + ')',
+ namespace: 'depend'
+ });
+ }
+ Schema.register('depend', depend);
+ function dependArray(field, itemSchema) {
+ return depend(field, Schema.array(itemSchema));
+ }
+ Schema.register('dependArray', dependArray);
+ return Schema;
+ }
+ var root = create();
+ root.create = create;
+ var exports = root;
if (typeof define === 'function') {
if (define.amd || define.cmd) {
define(function () {
diff --git a/jpacks.min.js b/jpacks.min.js
index d99001b..6b4a4f4 100644
--- a/jpacks.min.js
+++ b/jpacks.min.js
@@ -1 +1 @@
-!function(r){function e(r){var e=this;Object.keys(r).forEach(function(n){e[n]=r[n]})}function n(r){j=r}function t(r){if(r instanceof ArrayBuffer)return r;var e=new ArrayBuffer(r.length),n=new Uint8Array(e,0,r.length);return n.set(r),e}function a(r,n,a,i){var o=e.from(r);if(!o)throw new Error('Parameter schema "'+r+'" is unregister.');return n=t(n),a=a||{},i=i||[0],"undefined"==typeof a.littleEndian&&(a.littleEndian=j),o.unpack(n,a,i)}function i(r,n,t,a){var i=e.from(r);if(!i)throw new Error('Parameter schema "'+r+'" is unregister.');return a=a||[],t=t||{},"undefined"==typeof t.littleEndian&&(t.littleEndian=j),i.pack(n,t,a),a}function o(r,n){if("number"!=typeof r){var t=r;r=n,n=t}var a=e.from(n);if(!a)throw new Error('Schema "'+n+'" not define.');var i=a.size*r;return new e({unpack:function(n,t,o){if(a.array&&t.littleEndian){var c=o[0];return o[0]+=i,[].slice.apply(new a.array(n,c,r))}for(var u=[],f=0;r>f;f++)u.push(e.unpack(a,n,t,o));return u},pack:function(n,t,o){if(a.array&&t.littleEndian){var c=new ArrayBuffer(i),u=new a.array(c);u.set(n);var f=new Uint8Array(c);[].push.apply(o,f)}for(var s=0;r>s;s++)e.pack(a,n[s],t,o)},name:a.name+"["+r+"]",size:i,namespace:"array"})}function c(r){return o(r,"uint8")}function u(r,n){if(r=e.from(r),"base"!==r.namespace)throw new Error('Parameter "lengthSchema" is not a numeric type.');if(!n)throw new Error('Parameter "itemSchema" is undefined.');return new e({unpack:function(t,a,i){var o=e.unpack(r,t,a,i);return e.unpack(e.array(o,n),t,a,i)},pack:function(t,a,i){t?(e.pack(r,t.length,a,i),e.pack(e.array(t.length,n),t,a,i)):e.pack(r,0,a,i)},name:"dynamic array[.."+r.name+"..]",namespace:"dynamicArray",size:r.size})}function f(r){return u("uint8",r)}function s(r){return u("uint16",r)}function p(r){return u("uint32",r)}function m(r){if("object"!=typeof r)throw new Error('Parameter "schemas" must be a object type.');return r instanceof e?r:new e({unpack:function(n,t,a){var i={},o=t.$scope;return t.$scope=i,Object.keys(r).forEach(function(o){i[o]=e.unpack(r[o],n,t,a)}),t.$scope=o,i},pack:function(n,t,a){var i=t.$scope;t.$scope=n,Object.keys(r).forEach(function(i){e.pack(r[i],n[i],t,a)}),t.$scope=i},object:r,name:"object {}"})}function y(r,n){if("number"!=typeof r){var t=r;r=n,n=t}if("number"!=typeof r)throw new Error('Parameter "size" must be a numeric type.');if("object"!=typeof n)throw new Error('Parameter "schemas" must be a object type.');if(n instanceof e)throw new Error('Parameter "schemas" cannot be a Schema object.');var a=Object.keys(n);return new e({unpack:function(t,i,o){var c=o[0],u={};return a.forEach(function(r){o[0]=c,u[r]=e.unpack(n[r],t,i,o)}),o[0]+=r,u},pack:function(t,i,o){var c=new ArrayBuffer(r),u=new Uint8Array(c);a.forEach(function(r){var a=[];e.pack(n[r],t[r],i,a),u.set(a)}),[].push.apply(o,u)},size:r,object:n,name:"union {}"})}function g(r){if("object"!=typeof r)throw new Error('Parameter "schemas" must be a object type.');if(r instanceof e)throw new Error('Parameter "schemas" cannot be a Schema object.');var n=Object.keys(r),t=n[0],a=r[t];return n=n.slice(1),new e({unpack:function(i,o,c){var u={},f=e.unpack(a,i,o,c);return u[t]=f,n.every(function(n){return f===r[n][0]?(u[n]=e.unpack(r[n][1],i,o,c),!1):!0}),u},pack:function(i,o,c){var u=i[t];e.pack(a,u,o,c),n.every(function(n){return u===r[n][0]?(e.pack(r[n][1],i[n],o,c),!1):!0})},name:"cases{"+t+"}",namespace:"cases"})}function h(r){return String(r).replace(/[\u0080-\u07ff]/g,function(r){var e=r.charCodeAt(0);return String.fromCharCode(192|e>>6,128|63&e)}).replace(/[\u0800-\uffff]/g,function(r){var e=r.charCodeAt(0);return String.fromCharCode(224|e>>12,128|e>>6&63,128|63&e)})}function w(r){return String(r).replace(/[\u00c0-\u00df][\u0080-\u00bf]/g,function(r){var e=(31&r.charCodeAt(0))<<6|63&r.charCodeAt(1);return String.fromCharCode(e)}).replace(/[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g,function(r){var e=(15&r.charCodeAt(0))<<12|(63&r.charCodeAt(1))<<6|63&r.charCodeAt(2);return String.fromCharCode(e)})}function d(r,e){return"undefined"!=typeof Buffer?new Buffer(r,e):h(r).split("").map(function(r){return r.charCodeAt()})}function l(r){var n=e.array(r,"uint8");return new e({unpack:function(r,t,a){var i=e.unpack(n,r,t,a);return"undefined"!=typeof Buffer?new Buffer(i).toString():w(String.fromCharCode.apply(String,i))},pack:function(r,t,a){e.pack(n,d(r),t,a)},namespace:"staticString",name:"string{"+r+"}",size:r})}function k(r){if(r=e.from(r),!r)throw new Error('Parameter "lengthSchema" is undefined.');if("base"!==r.namespace)throw new Error('Parameter "lengthSchema" is not a numeric type.');return new e({unpack:function(n,t,a){var i=e.unpack(r,n,t,a);return e.unpack(e.string(i),n,t,a)},pack:function(n,t,a){if(n){var i=e.stringBytes(n);e.pack(r,i.length,t,a),e.pack(e.bytes(i.length),i,t,a)}else e.pack(r,0,t,a)},namespace:"dynamicString",name:"string{.."+r.name+"..}"})}function v(r,n){if("string"!=typeof r)throw new Error('Parameter "field" must be a string.');return new e({unpack:function(t,a,i){if(!a.$scope)throw new Error("Unpack must running in object.");var o=a.$scope[r];if("number"!=typeof o)throw new Error('Field "'+r+'" must be a number.');return e.unpack(e.staticArray(o,n),t,a,i)},pack:function(t,a,i){var o=a.$scope[r];if("number"!=typeof o)throw new Error('Field "'+r+'" must be a number.');e.pack(e.array(o,n),t,a,i)},name:"depend array{"+r+"}",namespace:"dependArray"})}function b(r,n){if("string"!=typeof r)throw new Error('Parameter "field" must be a string.');return new e({unpack:function(t,a,i){if(!a.$scope)throw new Error("Unpack must running in object.");var o=a.$scope[r];if("number"!=typeof o)throw new Error('Field "'+r+'" must be a number.');return e.unpack(e.staticString(o,n),t,a,i)},pack:function(n,t,a){var i=t.$scope[r];if("number"!=typeof i)throw new Error('Field "'+r+'" must be a number.');e.pack(e.string(i),n,t,a)},name:"depend string{"+r+"}",namespace:"dependString"})}function E(r,n){if(r=e.from(r),!r)throw new Error('Parameter "baseSchema" is undefined.');if("base"!==r.namespace)throw new Error('Parameter "baseSchema" is not a numeric type.');if("object"!=typeof n)throw new Error('Parameter "map" must be a object type.');if(n instanceof Array){var t={};n.forEach(function(r,e){t[r]=e}),n=t}var a=Object.keys(n);return new e({unpack:function(t,i,o){var c,u=e.unpack(r,t,i,o);return a.every(function(r){return n[r]===u?(c=r,!1):!0}),c},pack:function(t,i,o){if(a.every(function(a){return a===t?(e.pack(r,n[a],i,o),!1):!0}))throw new Error('Not find enum "'+t+'".')},map:n,name:"enum {}"})}var A={};e.register=function(r,n){if("undefined"==typeof r)throw new Error('Parameter "name" is undefined.');A[r]=n,e[r]||(e[r]=n)};var S=[function(r){for(var e={},n=r;"string"==typeof n;){if(e[n])return;n=A[n],e[n]=!0}return n}];e.pushPattern=function(r){"function"==typeof r&&S.push(r)},e.from=function(r){if("undefined"!=typeof r){if(r instanceof e)return r;for(var n=-1,t=0;ts;s++)c.push(g.unpack(r,a,i,o));return c},pack:function(a,i,o){var f=e;if(t&&(f=a?a.length:0,g.pack(t,f,i,o)),r.array&&i.littleEndian){n=r.size*f;var u=new ArrayBuffer(n),c=new r.array(u);c.set(a);var s=new Uint8Array(u);[].push.apply(o,s)}for(var p=0;f>p;p++)g.pack(r,a[p],i,o)},schema:"array("+[g.stringify(r),g.stringify(e)]+")",namespace:"array",size:n})};return n.name="array("+r.name+")",1===arguments.length?n:n(e)}function n(e){return r(e,"uint8")}function t(e){return r(e,"uint16")}function a(e){return r(e,"uint32")}function i(r){return g.array("uint8",r)}function o(r){if("object"!=typeof r)throw new Error('Parameter "schemas" must be a object type.');if(r instanceof g)return r;var e=g.stringify(r),n=Object.keys(r);return new g({unpack:function(e,t,a){var i=new r.constructor,o=t.$scope;return t.$scope=i,n.forEach(function(n){i[n]=g.unpack(r[n],e,t,a)}),t.$scope=o,i},pack:function(e,t,a){var i=t.$scope;t.$scope=e,n.forEach(function(n){g.pack(r[n],e[n],t,a)}),t.$scope=i},object:r,schema:"object("+e+")",namespace:"object"})}function f(r,e){if("number"!=typeof r){var n=r;r=e,e=n}if("number"!=typeof r)throw new Error('Parameter "size" must be a numeric type.');if("object"!=typeof e)throw new Error('Parameter "schemas" must be a object type.');if(e instanceof g)throw new Error('Parameter "schemas" cannot be a Schema object.');var t=Object.keys(e);return new g({unpack:function(n,a,i){var o=i[0],f={};return t.forEach(function(r){i[0]=o,f[r]=g.unpack(e[r],n,a,i)}),i[0]+=r,f},pack:function(n,a,i){var o=new ArrayBuffer(r),f=new Uint8Array(o);t.forEach(function(r){var t=[];g.pack(e[r],n[r],a,t),f.set(t)}),[].push.apply(i,f)},size:r,object:e,schema:"union("+g.stringify(r)+")"})}function u(r,e){if(r=g.from(r),!r)throw new Error('Parameter "baseSchema" is undefined.');if("base"!==r.namespace)throw new Error('Parameter "baseSchema" is not a numeric type.');if("object"!=typeof e)throw new Error('Parameter "map" must be a object type.');if(e instanceof Array){var n={};e.forEach(function(r,e){n[r]=e}),e=n}var t=Object.keys(e);return new g({unpack:function(n,a,i){var o,f=g.unpack(r,n,a,i);return t.every(function(r){return e[r]===f?(o=r,!1):!0}),o},pack:function(n,a,i){if(t.every(function(t){return t===n?(g.pack(r,e[t],a,i),!1):!0}))throw new Error('Not find enum "'+n+'".')},map:e,schema:"enum("+[g.stringify(r),g.stringify(e)]+")",namespace:"base"})}function c(r){return String(r).replace(/[\u0080-\u07ff]/g,function(r){var e=r.charCodeAt(0);return String.fromCharCode(192|e>>6,128|63&e)}).replace(/[\u0800-\uffff]/g,function(r){var e=r.charCodeAt(0);return String.fromCharCode(224|e>>12,128|e>>6&63,128|63&e)})}function s(r){return String(r).replace(/[\u00c0-\u00df][\u0080-\u00bf]/g,function(r){var e=(31&r.charCodeAt(0))<<6|63&r.charCodeAt(1);return String.fromCharCode(e)}).replace(/[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g,function(r){var e=(15&r.charCodeAt(0))<<12|(63&r.charCodeAt(1))<<6|63&r.charCodeAt(2);return String.fromCharCode(e)})}function p(r,e){return"undefined"!=typeof Buffer?new Buffer(r,e):c(r).split("").map(function(r){return r.charCodeAt()})}function y(r){var e=g.array(r,"uint8");return new g({unpack:function(r,n,t){var a=g.unpack(e,r,n,t);return"undefined"!=typeof Buffer?new Buffer(a).toString():s(String.fromCharCode.apply(String,a))},pack:function(r,n,t){g.pack(e,p(r),n,t)},namespace:"string",name:"string("+g.stringify(r)+")",size:r})}function m(r){if("object"!=typeof r)throw new Error('Parameter "patterns" must be a object type.');if(r instanceof g)throw new Error('Parameter "patterns" cannot be a Schema object.');if(!(r instanceof Array))throw new Error('Parameter "patterns" must be a array.');var e=function(e){for(var n=0;n*/
/**/
- var Schema = require('./schema');
+ var createSchema = require('./schema');
/**/
+
+ function create() {
+ var Schema = createSchema();
+ /**/
+ require('./schemas/number')(Schema);
- /**/
- /**/
- require('./schemas/base')(Schema);
- require('./schemas/staticArray')(Schema);
- require('./schemas/dynamicArray')(Schema);
+ require('./schemas/array')(Schema);
+ require('./schemas/bytes')(Schema);
- require('./schemas/object')(Schema);
- require('./schemas/union')(Schema);
- require('./schemas/cases')(Schema);
+ require('./schemas/object')(Schema);
+ require('./schemas/union')(Schema);
+ require('./schemas/enums')(Schema);
- require('./schemas/staticString')(Schema);
- require('./schemas/dynamicString')(Schema);
+ require('./schemas/string')(Schema);
- require('./schemas/dependArray')(Schema);
- require('./schemas/dependString')(Schema);
+ require('./schemas/cstring')(Schema);
- require('./schemas/enums')(Schema);
- require('./schemas/cstring')(Schema);
+ require('./schemas/cases')(Schema);
+ require('./schemas/depend')(Schema);
/**/
- /**/
-
- var exports = Schema;
+
+ return Schema;
+ }
+ var root = create();
+ root.create = create;
+ var exports = root;
if (typeof define === 'function') {
if (define.amd || define.cmd) {
diff --git a/src/schema.js b/src/schema.js
index 57969ed..87ac16a 100644
--- a/src/schema.js
+++ b/src/schema.js
@@ -1,5 +1,5 @@
+/**/
function createSchema() {
- /**/
/**
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView
*/
@@ -217,9 +217,31 @@ function createSchema() {
return buffer;
}
Schema.pack = pack;
- /**/
+ function stringify(obj) {
+ function scan(obj) {
+ if (typeof obj === 'object') {
+ if (obj instanceof Schema) {
+ return obj.schema;
+ }
+ var result = new obj.constructor();
+ Object.keys(obj).forEach(function (key) {
+ result[key] = scan(obj[key]);
+ });
+ return result;
+ } else if (typeof obj === 'function') {
+ return obj.schema;
+ }
+ return obj;
+ }
+ return JSON.stringify(scan(obj) || '').replace(/"/g, '');
+ }
+ Schema.stringify = stringify;
+
+ Schema.prototype.toString = function () {
+ return stringify(this);
+ };
return Schema;
}
-
-module.exports = createSchema();
\ No newline at end of file
+/**/
+module.exports = createSchema;
\ No newline at end of file
diff --git a/src/schemas/array.js b/src/schemas/array.js
new file mode 100644
index 0000000..e6506e9
--- /dev/null
+++ b/src/schemas/array.js
@@ -0,0 +1,137 @@
+module.exports = function (Schema) {
+ /**/
+ /**
+ * 声明指定长度或者下标的数组
+ *
+ * @param {string|Schema} itemSchema 元素类型
+ * @param {string|Schema|number=} count 下标类型或个数
+ * @return {Schema|Function} 返回数据结构
+ * @example 调用示例 1
+ ```js
+ var _ = jpacks;
+ var schema = jpacks.array('int16', 2);
+ console.log(String(schema));
+ // > array(int16,2)
+
+ var value = [12337, 12851];
+ var buffer = jpacks.pack(schema, value);
+ console.log(buffer);
+ // > [48, 49, 50, 51]
+
+ console.log(jpacks.unpack(schema, buffer));
+ // > [12337, 12851]
+ ```
+ * @example 调用示例 2
+ ```js
+ var _ = jpacks;
+ var schema = jpacks.array('int16', 'int8');
+ console.log(String(schema));
+ // > array(int16,int8)
+
+ var value = [12337, 12851];
+ var buffer = jpacks.pack(schema, value);
+ console.log(buffer);
+ // > [ 2, 48, 49, 50, 51 ]
+
+ console.log(jpacks.unpack(schema, buffer));
+ // > [ 12337, 12851 ]
+ ```
+ * @example 调用示例 3
+ ```js
+ var _ = jpacks;
+ var schema = jpacks.array('int16')(6);
+ console.log(String(schema));
+ // > array(int16,6)
+
+ var value = [12337, 12851];
+ var buffer = jpacks.pack(schema, value);
+ console.log(buffer);
+ // > [ 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0 ]
+
+ console.log(jpacks.unpack(schema, buffer));
+ // > [ 12337, 12851, 0, 0, 0, 0 ]
+ ```
+ */
+ function array(itemSchema, count) {
+ if (typeof itemSchema === 'undefined') {
+ throw new Error('Parameter "itemSchema" is undefined.');
+ }
+
+ var creatorSchema = function (count) {
+ var size;
+ var countSchema;
+ if (typeof count === 'number') {
+ 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) {
+ var length = count;
+ if (countSchema) {
+ length = Schema.unpack(countSchema, buffer, options, offsets);
+ }
+ if (itemSchema.array && options.littleEndian) {
+ size = countSchema.size * length;
+ /* TypeArray littleEndian is true */
+ var offset = offsets[0];
+ offsets[0] += size;
+ return [].slice.apply(new itemSchema.array(buffer, offset, length));
+ }
+ var result = [];
+ for (var i = 0; i < length; i++) {
+ result.push(Schema.unpack(itemSchema, buffer, options, offsets));
+ }
+ return result;
+ },
+ pack: function _pack(value, options, buffer) {
+ var length = count;
+ if (countSchema) {
+ length = value ? value.length : 0;
+ Schema.pack(countSchema, length, options, buffer);
+ }
+ if (itemSchema.array && options.littleEndian) {
+ size = itemSchema.size * length;
+ /* TypeArray littleEndian is true */
+ var arrayBuffer = new ArrayBuffer(size);
+ var typeArray = new itemSchema.array(arrayBuffer);
+ typeArray.set(value);
+ var uint8Array = new Uint8Array(arrayBuffer);
+ [].push.apply(buffer, uint8Array);
+ }
+
+ for (var i = 0; i < length; i++) {
+ Schema.pack(itemSchema, value[i], options, buffer);
+ }
+ },
+ schema: 'array(' + [Schema.stringify(itemSchema), Schema.stringify(count)] + ')',
+ namespace: 'array',
+ size: size
+ });
+ };
+ creatorSchema.name = 'array(' + itemSchema.name + ')';
+ if (arguments.length === 1) {
+ return creatorSchema;
+ } else {
+ return creatorSchema(count);
+ }
+ }
+ Schema.register('array', array);
+ function shortArray(itemSchema) {
+ return array(itemSchema, 'uint8');
+ }
+ Schema.register('shortArray', shortArray);
+ function smallArray(itemSchema) {
+ return array(itemSchema, 'uint16');
+ }
+ Schema.register('smallArray', smallArray);
+ function longArray(itemSchema) {
+ return array(itemSchema, 'uint32');
+ }
+ Schema.register('longArray', longArray);
+ /**/
+};
\ No newline at end of file
diff --git a/src/schemas/bytes.js b/src/schemas/bytes.js
new file mode 100644
index 0000000..5bf47c2
--- /dev/null
+++ b/src/schemas/bytes.js
@@ -0,0 +1,8 @@
+module.exports = function (Schema) {
+ /**/
+ function bytes(count) {
+ return Schema.array('uint8', count);
+ }
+ Schema.register('bytes', bytes);
+ /**/
+};
\ No newline at end of file
diff --git a/src/schemas/cases.js b/src/schemas/cases.js
index fee51b1..ac4a88d 100644
--- a/src/schemas/cases.js
+++ b/src/schemas/cases.js
@@ -1,18 +1,17 @@
-module.exports = function defineCases(Schema) {
+module.exports = function (Schema) {
/**/
/**
* 创建条件类型
*
- * @param {Object} schemas 条件类型结构,第一个字段为条件字段,其他字段为数组。数组第一元素表示命中条件,第二位类型
- * @return {Schema} 返回联合类型
+ * @param {Array of array} patterns 数组第一元素表示命中条件,第二位类型
+ * @return {Schema} 返回条件类型
* @example 调用示例 1
```js
var _ = jpacks;
- var _schema = _.cases({
- type: _.shortString,
+ var _schema = {
name: ['name', _.shortString],
age: ['age', _.byte]
- });
+ };
var ab = _.pack(_schema, {
type: 'name',
name: 'tom'
@@ -36,46 +35,29 @@ module.exports = function defineCases(Schema) {
// -> Object {type: "age", age: 23}
```
*/
- function cases(schemas) {
- if (typeof schemas !== 'object') {
- throw new Error('Parameter "schemas" must be a object type.');
+ function cases(patterns) {
+ /**/
+ if (typeof patterns !== 'object') {
+ throw new Error('Parameter "patterns" must be a object type.');
}
- if (schemas instanceof Schema) {
- throw new Error('Parameter "schemas" cannot be a Schema object.');
+ if (patterns instanceof Schema) {
+ throw new Error('Parameter "patterns" cannot be a Schema object.');
}
-
- var keys = Object.keys(schemas);
- var patternName = keys[0];
- var patternSchema = schemas[patternName];
- keys = keys.slice(1);
- return new Schema({
- unpack: function _unpack(buffer, options, offsets) {
- var result = {};
- var patternValue = Schema.unpack(patternSchema, buffer, options, offsets);
- result[patternName] = patternValue;
- keys.every(function (key) {
- if (patternValue === schemas[key][0]) {
- result[key] = Schema.unpack(schemas[key][1], buffer, options, offsets);
- return false;
- }
- return true;
- });
- return result;
- },
- pack: function _pack(value, options, buffer) {
- var patternValue = value[patternName];
- Schema.pack(patternSchema, patternValue, options, buffer);
- keys.every(function (key) {
- if (patternValue === schemas[key][0]) {
- Schema.pack(schemas[key][1], value[key], options, buffer);
- return false;
- }
- return true;
- });
- },
- name: 'cases{' + patternName + '}',
- namespace: 'cases'
- });
+ if (!(patterns instanceof Array)) {
+ throw new Error('Parameter "patterns" must be a array.');
+ }
+ /**/
+
+ var schemaCreator = function (value) {
+ for (var i = 0; i < patterns.length; i++) {
+ if (patterns[i][0] === value) {
+ return patterns[i][1];
+ }
+ }
+ };
+ schemaCreator.schema = 'cases(' + Schema.stringify(patterns) + ')';
+ schemaCreator.namespace = 'cases';
+ return schemaCreator;
}
Schema.register('cases', cases);
/**/
diff --git a/src/schemas/cstring.js b/src/schemas/cstring.js
index 9a97463..07c2f37 100644
--- a/src/schemas/cstring.js
+++ b/src/schemas/cstring.js
@@ -1,4 +1,4 @@
-module.exports = function defineCString(Schema) {
+module.exports = function (Schema) {
/**/
/**
* 以零号字符结尾的字符串
@@ -34,7 +34,7 @@ module.exports = function defineCString(Schema) {
Schema.pack('byte', 0, options, buffer);
},
namespace: 'cstring',
- name: 'cstring'
+ schema: 'cstring'
});
Schema.register('cstring', cstring);
Schema.register('pchar', cstring);
diff --git a/src/schemas/depend.js b/src/schemas/depend.js
new file mode 100644
index 0000000..2b1764e
--- /dev/null
+++ b/src/schemas/depend.js
@@ -0,0 +1,51 @@
+module.exports = function (Schema) {
+ /**/
+ /**
+ * 声明字段依赖结构
+ *
+ * @param {string} field 字段名
+ * @param {Function} schemaCreator 创建数据结构的方法
+ * [[[
+ * @param {Any} value 传递值
+ * @return {Schema} 返回数据结构
+ * function schemaCreator(value) {}
+ * ]]]
+ */
+ function depend(field, schemaCreator) {
+ if (typeof field !== 'string') {
+ throw new Error('Parameter "field" must be a string.');
+ }
+ if (typeof schemaCreator !== 'function') {
+ throw new Error('Parameter "field" must be a function.');
+ }
+
+ return new Schema({
+ unpack: function _unpack(buffer, options, offsets) {
+ if (!options.$scope) {
+ throw new Error('Unpack must running in object.');
+ }
+ var fieldValue = options.$scope[field];
+ if (typeof fieldValue === 'undefined') {
+ throw new Error('Field "' + field + '" is undefined.');
+ }
+ return Schema.unpack(schemaCreator(fieldValue), buffer, options, offsets);
+ },
+ pack: function _pack(value, options, buffer) {
+ var fieldValue = options.$scope[field];
+ if (typeof fieldValue === 'undefined') {
+ throw new Error('Field "' + field + '" is undefined.');
+ }
+ Schema.pack(schemaCreator(fieldValue), value, options, buffer);
+ },
+ schema: 'depend(' + [field, Schema.stringify(schemaCreator)] + ')',
+ namespace: 'depend'
+ });
+ }
+ Schema.register('depend', depend);
+
+ function dependArray(field, itemSchema) {
+ return depend(field, Schema.array(itemSchema));
+ }
+ Schema.register('dependArray', dependArray);
+ /**/
+};
\ No newline at end of file
diff --git a/src/schemas/dependArray.js b/src/schemas/dependArray.js
deleted file mode 100644
index 47dd426..0000000
--- a/src/schemas/dependArray.js
+++ /dev/null
@@ -1,32 +0,0 @@
-module.exports = function defineDependArray(Schema) {
- /**/
- function dependArray(field, itemSchema) {
- if (typeof field !== 'string') {
- throw new Error('Parameter "field" must be a string.');
- }
-
- return new Schema({
- unpack: function _unpack(buffer, options, offsets) {
- if (!options.$scope) {
- throw new Error('Unpack must running in object.');
- }
- var length = options.$scope[field];
- if (typeof length !== 'number') {
- throw new Error('Field "' + field + '" must be a number.');
- }
- return Schema.unpack(Schema.staticArray(length, itemSchema), buffer, options, offsets);
- },
- pack: function _pack(value, options, buffer) {
- var length = options.$scope[field];
- if (typeof length !== 'number') {
- throw new Error('Field "' + field + '" must be a number.');
- }
- Schema.pack(Schema.array(length, itemSchema), value, options, buffer);
- },
- name: 'depend array{' + field + '}',
- namespace: 'dependArray'
- });
- }
- Schema.register('dependArray', dependArray);
- /**/
-};
\ No newline at end of file
diff --git a/src/schemas/dependString.js b/src/schemas/dependString.js
deleted file mode 100644
index 64823db..0000000
--- a/src/schemas/dependString.js
+++ /dev/null
@@ -1,32 +0,0 @@
-module.exports = function defineDependString(Schema) {
- /**/
- function dependString(field, itemSchema) {
- if (typeof field !== 'string') {
- throw new Error('Parameter "field" must be a string.');
- }
-
- return new Schema({
- unpack: function _unpack(buffer, options, offsets) {
- if (!options.$scope) {
- throw new Error('Unpack must running in object.');
- }
- var size = options.$scope[field];
- if (typeof size !== 'number') {
- throw new Error('Field "' + field + '" must be a number.');
- }
- return Schema.unpack(Schema.staticString(size, itemSchema), buffer, options, offsets);
- },
- pack: function _pack(value, options, buffer) {
- var size = options.$scope[field];
- if (typeof size !== 'number') {
- throw new Error('Field "' + field + '" must be a number.');
- }
- Schema.pack(Schema.string(size), value, options, buffer);
- },
- name: 'depend string{' + field + '}',
- namespace: 'dependString'
- });
- }
- Schema.register('dependString', dependString);
- /**/
-};
\ No newline at end of file
diff --git a/src/schemas/dynamicArray.js b/src/schemas/dynamicArray.js
deleted file mode 100644
index 0dd7621..0000000
--- a/src/schemas/dynamicArray.js
+++ /dev/null
@@ -1,104 +0,0 @@
-module.exports = function defineDynamicArray(Schema) {
- /**/
- /**
- * 声明指定长度的数组类型
- *
- * @param {string|Schema} lengthSchema 长度类型
- * @param {string|Schema} itemSchema 元素类型
- * @return {Schema} 返回数据结构
- * @example 调用示例 1
- ```js
- var _ = jpacks;
- var _schema = _.dynamicArray(_.byte, _.byte);
- var ab = _.pack(_schema, [1, 2, 3, 4]);
- var u8a = new Uint8Array(ab);
- console.log(u8a);
- // -> [4, 1, 2, 3, 4]
-
- console.log(_.unpack(_schema, u8a));
- // -> [1, 2, 3, 4]
- ```
- * @example 调用示例 2
- ```js
- var _ = jpacks;
- var _schema = _.dynamicArray(_.word, _.byte);
- var ab = _.pack(_schema, [1, 2, 3, 4]);
- var u8a = new Uint8Array(ab);
- console.log(u8a);
- // -> [0, 0, 0, 4, 1, 2, 3, 4]
-
- console.log(_.unpack(_schema, u8a));
- // -> [1, 2, 3, 4]
- ```
- */
- function dynamicArray(lengthSchema, itemSchema) {
- lengthSchema = Schema.from(lengthSchema);
- if (lengthSchema.namespace !== 'base') {
- throw new Error('Parameter "lengthSchema" is not a numeric type.');
- }
- if (!itemSchema) {
- throw new Error('Parameter "itemSchema" is undefined.');
- }
- return new Schema({
- unpack: function _unpack(buffer, options, offsets) {
- var length = Schema.unpack(lengthSchema, buffer, options, offsets);
- return Schema.unpack(Schema.array(length, itemSchema), buffer, options, offsets);
- },
- pack: function _pack(value, options, buffer) {
- if (!value) {
- Schema.pack(lengthSchema, 0, options, buffer);
- } else {
- Schema.pack(lengthSchema, value.length, options, buffer);
- Schema.pack(Schema.array(value.length, itemSchema), value, options, buffer);
- }
- },
- name: 'dynamic array[..' + lengthSchema.name + '..]',
- namespace: 'dynamicArray',
- size: lengthSchema.size
- });
- }
-
- Schema.register('dynamicArray', dynamicArray);
-
- function shortArray(schema) {
- return dynamicArray('uint8', schema);
- }
- Schema.register('shortArray', shortArray);
-
- function smallArray(schema) {
- return dynamicArray('uint16', schema);
- }
- Schema.register('smallArray', smallArray);
-
- function longArray(schema) {
- return dynamicArray('uint32', schema);
- }
- Schema.register('longArray', longArray);
-
- // 'int8[.]' - shortArray
- // 'int8[..]' - smallArray
- // 'int8[....]' - longArray
- Schema.pushPattern(function (schema) {
- if (typeof schema === 'string') {
- var match = schema.match(/^(\w+)\[(\.|\..|\....)\]$/);
- if (match) {
- var baseSchema = Schema.from(match[1]);
- if (baseSchema) {
- var lengthSchema = 'uint16';
- switch (match[2]) {
- case '.':
- lengthSchema = 'uint8'
- break;
- case '....':
- lengthSchema = 'uint32'
- break;
- }
- var arraySchema = dynamicArray(lengthSchema, baseSchema);
- Schema.register(schema, arraySchema); // 缓存
- return arraySchema;
- }
- }
- }
- });
- /**/
-};
\ No newline at end of file
diff --git a/src/schemas/dynamicString.js b/src/schemas/dynamicString.js
deleted file mode 100644
index ccdf4dd..0000000
--- a/src/schemas/dynamicString.js
+++ /dev/null
@@ -1,107 +0,0 @@
-module.exports = function defineDynamicString(Schema) {
- /**/
- /**
- * 声明指定长度的字符串
- *
- * @param {string|Schema} lengthSchema 长度类型
- * @return {Schema} 返回数据结构
- * @example 调用示例
- ```js
- var _ = jpacks;
- var _schema = _.dynamicString('int32');
- var ab = _.pack(_schema, '你好 World!');
- var u8a = new Uint8Array(ab);
- console.log(u8a);
- // -> [0, 0, 0, 13, 228, 189, 160, 229, 165, 189, 32, 87, 111, 114, 108, 100, 33]
-
- console.log(_.unpack(_schema, u8a));
- // -> 你好 World!
- ```
- */
- function dynamicString(lengthSchema) {
- lengthSchema = Schema.from(lengthSchema);
- if (!lengthSchema) {
- throw new Error('Parameter "lengthSchema" is undefined.');
- }
- if (lengthSchema.namespace !== 'base') {
- throw new Error('Parameter "lengthSchema" is not a numeric type.');
- }
-
- return new Schema({
- unpack: function _unpack(buffer, options, offsets) {
- var length = Schema.unpack(lengthSchema, buffer, options, offsets);
- return Schema.unpack(Schema.string(length), buffer, options, offsets);
- },
- pack: function _pack(value, options, buffer) {
- if (!value) {
- Schema.pack(lengthSchema, 0, options, buffer);
- } else {
- var bytes = Schema.stringBytes(value);
- Schema.pack(lengthSchema, bytes.length, options, buffer);
- Schema.pack(Schema.bytes(bytes.length), bytes, options, buffer);
- }
- },
- namespace: 'dynamicString',
- name: 'string{..' + lengthSchema.name + '..}'
- });
- }
- Schema.register('dynamicString', dynamicString);
-
- /**
- * 短字符串类型
- *
- * @return {Schema} 返回数据结构
- * @example 调用示例
- ```js
- var _ = jpacks;
- var _schema = _.shortString;
- var ab = _.pack(_schema, '你好 World!');
- var u8a = new Uint8Array(ab);
- console.log(u8a);
- // -> [13, 228, 189, 160, 229, 165, 189, 32, 87, 111, 114, 108, 100, 33]
-
- console.log(_.unpack(_schema, u8a));
- // -> 你好 World!
- ```
- */
- Schema.register('shortString', dynamicString('uint8'));
-
- /**
- * 长字符串类型
- *
- * @return {Schema} 返回数据结构
- * @example 调用示例
- ```js
- var _ = jpacks;
- var _schema = _.smallString;
- var ab = _.pack(_schema, '你好 World!');
- var u8a = new Uint8Array(ab);
- console.log(u8a);
- // -> [0, 13, 228, 189, 160, 229, 165, 189, 32, 87, 111, 114, 108, 100, 33]
-
- console.log(_.unpack(_schema, u8a));
- // -> 你好 World!
- ```
- */
- Schema.register('smallString', dynamicString('uint16'));
-
- /**
- * 长字符串类型
- *
- * @return {Schema} 返回数据结构
- * @example 调用示例
- ```js
- var _ = jpacks;
- var _schema = _.longString;
- var ab = _.pack(_schema, '你好 World!');
- var u8a = new Uint8Array(ab);
- console.log(u8a);
- // -> [0, 0, 0, 13, 228, 189, 160, 229, 165, 189, 32, 87, 111, 114, 108, 100, 33]
-
- console.log(_.unpack(_schema, u8a));
- // -> 你好 World!
- ```
- */
- Schema.register('longString', dynamicString('uint32'));
- /**/
-};
\ No newline at end of file
diff --git a/src/schemas/enums.js b/src/schemas/enums.js
index b75954c..3140d4b 100644
--- a/src/schemas/enums.js
+++ b/src/schemas/enums.js
@@ -1,4 +1,4 @@
-module.exports = function defineEnum(Schema) {
+module.exports = function (Schema) {
/**/
/**
* 定义一个枚举结构
@@ -52,7 +52,8 @@ module.exports = function defineEnum(Schema) {
};
},
map: map,
- name: 'enum {}'
+ schema: 'enum(' + [Schema.stringify(baseSchema), Schema.stringify(map)] + ')',
+ namespace: 'base'
});
};
diff --git a/src/schemas/base.js b/src/schemas/number.js
similarity index 96%
rename from src/schemas/base.js
rename to src/schemas/number.js
index cd78c33..3b95b23 100644
--- a/src/schemas/base.js
+++ b/src/schemas/number.js
@@ -1,4 +1,4 @@
-module.exports = function defineArray(Schema) {
+module.exports = function defineNumber(Schema) {
/**/
/**
* 基础类型
@@ -91,7 +91,7 @@ module.exports = function defineArray(Schema) {
})('set' + item.type),
size: item.size,
name: name,
- namespace: 'base',
+ namespace: 'number',
array: item.array
});
diff --git a/src/schemas/object.js b/src/schemas/object.js
index 6c96aa5..7b51428 100644
--- a/src/schemas/object.js
+++ b/src/schemas/object.js
@@ -1,4 +1,4 @@
-module.exports = function defineObject(Schema) {
+module.exports = function (Schema) {
/**/
/**
* 定义一个对象结构
@@ -6,20 +6,22 @@ module.exports = function defineObject(Schema) {
* @param {object} schema 数据结构
* @return {Schema} 返回构建的数据结构
*/
- function object(schema) {
- if (typeof schema !== 'object') {
+ function object(objectSchema) {
+ if (typeof objectSchema !== 'object') {
throw new Error('Parameter "schemas" must be a object type.');
}
- if (schema instanceof Schema) {
- return schema;
+ if (objectSchema instanceof Schema) {
+ return objectSchema;
}
+ var names = Schema.stringify(objectSchema);
+ var keys = Object.keys(objectSchema);
return new Schema({
unpack: function _unpack(buffer, options, offsets) {
- var result = {};
+ var result = new objectSchema.constructor();
var $scope = options.$scope;
options.$scope = result;
- Object.keys(schema).forEach(function (key) {
- result[key] = Schema.unpack(schema[key], buffer, options, offsets);
+ keys.forEach(function (key) {
+ result[key] = Schema.unpack(objectSchema[key], buffer, options, offsets);
});
options.$scope = $scope;
return result;
@@ -27,13 +29,14 @@ module.exports = function defineObject(Schema) {
pack: function _pack(value, options, buffer) {
var $scope = options.$scope;
options.$scope = value;
- Object.keys(schema).forEach(function (key) {
- Schema.pack(schema[key], value[key], options, buffer);
+ keys.forEach(function (key) {
+ Schema.pack(objectSchema[key], value[key], options, buffer);
});
options.$scope = $scope;
},
- object: schema,
- name: 'object {}'
+ object: objectSchema,
+ schema: 'object(' + names + ')',
+ namespace: 'object'
});
};
diff --git a/src/schemas/staticArray.js b/src/schemas/staticArray.js
deleted file mode 100644
index d12d49d..0000000
--- a/src/schemas/staticArray.js
+++ /dev/null
@@ -1,92 +0,0 @@
-module.exports = function defineArray(Schema) {
- /**/
- /**
- * 声明数组类型
- *
- * @param {string|Schema} itemSchema 数组元素类型
- * @param {number} count 元素个数
- * @return {Schema} 返回数据结构
- * @example 调用示例 1
- ```js
- var _ = jpacks;
- var _schema = _.array(10, _.byte);
- var ab = _.pack(_.array(10, _.byte), [1, 2, 3, 4]);
- var u8a = new Uint8Array(ab);
- console.log(u8a);
- // -> [1, 2, 3, 4, 0, 0, 0, 0, 0, 0]
-
- console.log(_.unpack(_schema, u8a));
- // -> [1, 2, 3, 4, 0, 0, 0, 0, 0, 0]
- ```
- */
- function array(count, itemSchema) {
- if (typeof count !== 'number') {
- var temp = count;
- count = itemSchema;
- itemSchema = temp;
- }
- var schema = Schema.from(itemSchema);
- if (!schema) {
- throw new Error('Schema "' + itemSchema + '" not define.');
- }
-
- var size = schema.size * count;
-
- return new Schema({
- unpack: function _unpack(buffer, options, offsets) {
- if (schema.array && options.littleEndian) {
- /* TypeArray littleEndian is true */
- var offset = offsets[0];
- offsets[0] += size;
- return [].slice.apply(new schema.array(buffer, offset, count));
- }
-
- var result = [];
- for (var i = 0; i < count; i++) {
- result.push(Schema.unpack(schema, buffer, options, offsets));
- }
- return result;
- },
- pack: function _pack(value, options, buffer) {
- if (schema.array && options.littleEndian) {
- /* TypeArray littleEndian is true */
- var arrayBuffer = new ArrayBuffer(size);
- var typeArray = new schema.array(arrayBuffer);
- typeArray.set(value);
- var uint8Array = new Uint8Array(arrayBuffer);
- [].push.apply(buffer, uint8Array);
- }
-
- for (var i = 0; i < count; i++) {
- Schema.pack(schema, value[i], options, buffer);
- }
- },
- name: schema.name + '[' + count + ']',
- size: size,
- namespace: 'array'
- });
- }
-
- Schema.register('array', array);
- Schema.register('staticArray', array);
-
- function bytes(size) {
- return array(size, 'uint8');
- }
- Schema.register('bytes', bytes);
-
- Schema.pushPattern(function (schema) {
- if (typeof schema === 'string') {
- var match = schema.match(/^(\w+)\[(\d+)\]$/);
- if (match) {
- var baseSchema = Schema.from(match[1]);
- if (baseSchema) {
- var arraySchema = array(parseInt(match[2]), baseSchema);
- Schema.register(schema, arraySchema); // 缓存
- return arraySchema;
- }
- }
- }
- });
- /**/
-};
\ No newline at end of file
diff --git a/src/schemas/staticString.js b/src/schemas/string.js
similarity index 59%
rename from src/schemas/staticString.js
rename to src/schemas/string.js
index a3b35f9..4e13154 100644
--- a/src/schemas/staticString.js
+++ b/src/schemas/string.js
@@ -1,4 +1,4 @@
-module.exports = function defineStaticString(Schema) {
+module.exports = function (Schema) {
/**/
/**
* 对字符串进行 utf8 编码
@@ -20,7 +20,6 @@ module.exports = function defineStaticString(Schema) {
}
);
}
-
/**
* 对 utf8 字符串进行解码
*
@@ -41,7 +40,6 @@ module.exports = function defineStaticString(Schema) {
}
);
}
-
/**
* 将字符串转换为字节数组
*
@@ -58,12 +56,11 @@ module.exports = function defineStaticString(Schema) {
});
}
}
- Schema.stringBytes = stringBytes;
/**
* 声明指定长度的字符串
*
- * @param {number} size 字节个数
+ * @param {number|string|Schema} size 字节个数下标类型
* @return {Schema} 返回数据结构
*/
function string(size) {
@@ -79,23 +76,63 @@ module.exports = function defineStaticString(Schema) {
pack: function _pack(value, options, buffer) {
Schema.pack(schema, stringBytes(value), options, buffer);
},
- namespace: 'staticString',
- name: 'string{' + size + '}',
+ namespace: 'string',
+ name: 'string(' + Schema.stringify(size) + ')',
size: size
});
}
-
Schema.register('string', string);
- Schema.register('staticString', string);
- Schema.pushPattern(function (schema) {
- if (typeof schema === 'string') {
- var match = schema.match(/^string\{(\d+)\}$/);
- if (match) {
- var arraySchema = string(parseInt(match[1]));
- Schema.register(schema, arraySchema); // 缓存
- return arraySchema;
- }
- }
- });
+
+ /**
+ * 短字符串类型
+ *
+ * @return {Schema} 返回数据结构
+ * @example 调用示例
+ ```js
+ var _ = jpacks;
+ var _schema = _.shortString;
+ var ab = _.pack(_schema, '你好 World!');
+ var u8a = new Uint8Array(ab);
+ console.log(u8a);
+ // -> [13, 228, 189, 160, 229, 165, 189, 32, 87, 111, 114, 108, 100, 33]
+ console.log(_.unpack(_schema, u8a));
+ // -> 你好 World!
+ ```
+ */
+ Schema.register('shortString', string('uint8'));
+ /**
+ * 长字符串类型
+ *
+ * @return {Schema} 返回数据结构
+ * @example 调用示例
+ ```js
+ var _ = jpacks;
+ var _schema = _.smallString;
+ var ab = _.pack(_schema, '你好 World!');
+ var u8a = new Uint8Array(ab);
+ console.log(u8a);
+ // -> [0, 13, 228, 189, 160, 229, 165, 189, 32, 87, 111, 114, 108, 100, 33]
+ console.log(_.unpack(_schema, u8a));
+ // -> 你好 World!
+ ```
+ */
+ Schema.register('smallString', string('uint16'));
+ /**
+ * 超长字符串类型
+ *
+ * @return {Schema} 返回数据结构
+ * @example 调用示例
+ ```js
+ var _ = jpacks;
+ var _schema = _.longString;
+ var ab = _.pack(_schema, '你好 World!');
+ var u8a = new Uint8Array(ab);
+ console.log(u8a);
+ // -> [0, 0, 0, 13, 228, 189, 160, 229, 165, 189, 32, 87, 111, 114, 108, 100, 33]
+ console.log(_.unpack(_schema, u8a));
+ // -> 你好 World!
+ ```
+ */
+ Schema.register('longString', string('uint32'));
/**/
};
\ No newline at end of file
diff --git a/src/schemas/union.js b/src/schemas/union.js
index 9035f82..947d2b5 100644
--- a/src/schemas/union.js
+++ b/src/schemas/union.js
@@ -1,4 +1,4 @@
-module.exports = function defineUnion(Schema) {
+module.exports = function (Schema) {
/**/
/**
* 创建联合类型
@@ -64,7 +64,7 @@ module.exports = function defineUnion(Schema) {
},
size: size,
object: schemas,
- name: 'union {}'
+ schema: 'union(' + Schema.stringify(size) + ')'
});
}
Schema.register('union', union);
diff --git a/test/test.js b/test/test.js
index 35376ee..8157d4e 100644
--- a/test/test.js
+++ b/test/test.js
@@ -14,15 +14,17 @@ describe('fixtures', function () {
length: 'int32',
note: jpacks.shortString
});
- jpacks.register('CaseType', jpacks.cases({
+ jpacks.register('CaseType', {
type: 'uint8',
- point: [1, 'Point'],
- polar: [2, 'Polar']
- }));
+ data: jpacks.depend('type', jpacks.cases([
+ [1, 'Point'],
+ [2, 'Polar']
+ ]))
+ });
var value1 = {
type: 1,
- point: {
+ data: {
x: 1,
y: 2
}
@@ -33,7 +35,7 @@ describe('fixtures', function () {
var value3 = {
type: 2,
- polar: {
+ data: {
angle: Math.PI,
length: 2,
note: '极坐标 1'