Skip to content

Commit

Permalink
Merge pull request #2 from redboltz/add_bin_support
Browse files Browse the repository at this point in the history
Added bin format family support.
  • Loading branch information
uupaa committed Jul 2, 2015
2 parents da6d906 + caea0e4 commit 2cfda99
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 19 deletions.
36 changes: 32 additions & 4 deletions msgpack.codec.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ var _bin2num = {}, // BinaryStringToNumber { "\00": 0, ... "\ff": 255 }
_isArray = Array.isArray || (function(mix) {
return Object.prototype.toString.call(mix) === "[object Array]";
}),
_isUint8Array = function(mix) {
return Object.prototype.toString.call(mix) === "[object Uint8Array]";
},
_toString = String.fromCharCode, // CharCode/ByteArray to String
_MAX_DEPTH = 512;

Expand Down Expand Up @@ -176,6 +179,8 @@ function encode(rv, // @param ByteArray: result

if (size < 32) {
rv[pos] = 0xa0 + size; // rewrite
} else if (size < 0x100) { // 8
rv.splice(pos, 1, 0xd9, size);
} else if (size < 0x10000) { // 16
rv.splice(pos, 1, 0xda, size >> 8, size & 0xff);
} else if (size < 0x100000000) { // 32
Expand All @@ -184,7 +189,21 @@ function encode(rv, // @param ByteArray: result
(size >> 8) & 0xff, size & 0xff);
}
break;
default: // array or hash
default: // array, hash, or Uint8Array
if (_isUint8Array(mix)) {
size = mix.length;

if (size < 0x100) { // 8
rv.push(0xc4, size);
} else if (size < 0x10000) { // 16
rv.push(0xc5, size >> 8, size & 0xff);
} else if (size < 0x100000000) { // 32
rv.push(0xc6, size >>> 24, (size >> 16) & 0xff,
(size >> 8) & 0xff, size & 0xff);
}
Array.prototype.push.apply(rv, mix);
break;
}
if (++depth >= _MAX_DEPTH) {
_error = 1; // CYCLIC_REFERENCE_ERROR
return rv = []; // clear
Expand Down Expand Up @@ -324,9 +343,10 @@ function decode() { // @return Mix:
return num < 0x8000 ? num : num - 0x10000; // 0x8000 * 2
case 0xd0: num = buf[++_idx];
return num < 0x80 ? num : num - 0x100; // 0x80 * 2
// 0xdb: raw32, 0xda: raw16, 0xa0: raw ( string )
case 0xdb: num += buf[++_idx] * 0x1000000 + (buf[++_idx] << 16);
case 0xda: num += (buf[++_idx] << 8) + buf[++_idx];
// 0xdb: str32, 0xda: str16, 0xd9: str8, 0xa0: fixstr
case 0xdb: num += buf[++_idx] * 0x1000000 + (buf[++_idx] << 16);
case 0xda: num += buf[++_idx] << 8;
case 0xd9: num += buf[++_idx];
case 0xa0: // utf8.decode
for (ary = [], i = _idx, iz = i + num; i < iz; ) {
c = buf[++i]; // lead byte
Expand All @@ -338,6 +358,14 @@ function decode() { // @return Mix:
_idx = i;
return ary.length < 10240 ? _toString.apply(null, ary)
: byteArrayToByteString(ary);
// 0xc6: bin32, 0xc5: bin16, 0xc4: bin8
case 0xc6: num += buf[++_idx] * 0x1000000 + (buf[++_idx] << 16);
case 0xc5: num += buf[++_idx] << 8;
case 0xc4: num += buf[++_idx];
var end = ++_idx + num
var ret = buf.slice(_idx, end);
_idx += num;
return ret;
// 0xdf: map32, 0xde: map16, 0x80: map
case 0xdf: num += buf[++_idx] * 0x1000000 + (buf[++_idx] << 16);
case 0xde: num += (buf[++_idx] << 8) + buf[++_idx];
Expand Down
36 changes: 32 additions & 4 deletions msgpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ var _ie = /MSIE/.test(navigator.userAgent),
_isArray = Array.isArray || (function(mix) {
return Object.prototype.toString.call(mix) === "[object Array]";
}),
_isUint8Array = function(mix) {
return Object.prototype.toString.call(mix) === "[object Uint8Array]";
},
_toString = String.fromCharCode, // CharCode/ByteArray to String
_MAX_DEPTH = 512;

Expand Down Expand Up @@ -191,6 +194,8 @@ function encode(rv, // @param ByteArray: result

if (size < 32) {
rv[pos] = 0xa0 + size; // rewrite
} else if (size < 0x100) { // 8
rv.splice(pos, 1, 0xd9, size);
} else if (size < 0x10000) { // 16
rv.splice(pos, 1, 0xda, size >> 8, size & 0xff);
} else if (size < 0x100000000) { // 32
Expand All @@ -199,7 +204,21 @@ function encode(rv, // @param ByteArray: result
(size >> 8) & 0xff, size & 0xff);
}
break;
default: // array or hash
default: // array, hash, or Uint8Array
if (_isUint8Array(mix)) {
size = mix.length;

if (size < 0x100) { // 8
rv.push(0xc4, size);
} else if (size < 0x10000) { // 16
rv.push(0xc5, size >> 8, size & 0xff);
} else if (size < 0x100000000) { // 32
rv.push(0xc6, size >>> 24, (size >> 16) & 0xff,
(size >> 8) & 0xff, size & 0xff);
}
Array.prototype.push.apply(rv, mix);
break;
}
if (++depth >= _MAX_DEPTH) {
_error = 1; // CYCLIC_REFERENCE_ERROR
return rv = []; // clear
Expand Down Expand Up @@ -339,9 +358,10 @@ function decode() { // @return Mix:
return num < 0x8000 ? num : num - 0x10000; // 0x8000 * 2
case 0xd0: num = buf[++_idx];
return num < 0x80 ? num : num - 0x100; // 0x80 * 2
// 0xdb: raw32, 0xda: raw16, 0xa0: raw ( string )
case 0xdb: num += buf[++_idx] * 0x1000000 + (buf[++_idx] << 16);
case 0xda: num += (buf[++_idx] << 8) + buf[++_idx];
// 0xdb: str32, 0xda: str16, 0xd9: str8, 0xa0: fixstr
case 0xdb: num += buf[++_idx] * 0x1000000 + (buf[++_idx] << 16);
case 0xda: num += buf[++_idx] << 8;
case 0xd9: num += buf[++_idx];
case 0xa0: // utf8.decode
for (ary = [], i = _idx, iz = i + num; i < iz; ) {
c = buf[++i]; // lead byte
Expand All @@ -353,6 +373,14 @@ function decode() { // @return Mix:
_idx = i;
return ary.length < 10240 ? _toString.apply(null, ary)
: byteArrayToByteString(ary);
// 0xc6: bin32, 0xc5: bin16, 0xc4: bin8
case 0xc6: num += buf[++_idx] * 0x1000000 + (buf[++_idx] << 16);
case 0xc5: num += buf[++_idx] << 8;
case 0xc4: num += buf[++_idx];
var end = ++_idx + num
var ret = buf.slice(_idx, end);
_idx += num;
return ret;
// 0xdf: map32, 0xde: map16, 0x80: map
case 0xdf: num += buf[++_idx] * 0x1000000 + (buf[++_idx] << 16);
case 0xde: num += (buf[++_idx] << 8) + buf[++_idx];
Expand Down
79 changes: 68 additions & 11 deletions test/codec.htm
Original file line number Diff line number Diff line change
Expand Up @@ -486,31 +486,52 @@

return [rv, "==", -3.14159565358979, hex(pack)];
},
"Raw (as String)": "",
"String('') -> [0xa0] (FixRaw)": function() {
"Str (as String)": "",
"String('') -> [0xa0] (FixStr)": function() {
var pack = msgpack.pack("");
var rv = msgpack.unpack(pack);

return [rv, "==", "", hex(pack)];
},
"String('abc') -> [0xa3, 0x61, 0x62, 0x63] (FixRaw)": function() {
"String('abc') -> [0xa3, 0x61, 0x62, 0x63] (FixStr)": function() {
var pack = msgpack.pack("abc");
var rv = msgpack.unpack(pack);

return [rv, "==", "abc", hex(pack)];
},
"String('あいう') -> [0xa9, 0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86] (FixRaw)": function() {
"String('あいう') -> [0xa9, 0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86] (FixStr)": function() {
var pack = msgpack.pack("あいう");
var rv = msgpack.unpack(pack);

return [rv, "==", "あいう", hex(pack)];
},
"String('カルビx3, ハラミx2, ブタバラ, T-BORNx500g, ライス大盛りで') -> [] (Raw16)": function() {
"String('カルビx3, ハラミx2, ブタバラ, T-BORNx500g, ライス大盛りで') -> [] (Str8)": function() {
var pack = msgpack.pack("カルビx3, ハラミx2, ブタバラ, T-BORNx500g, ライス大盛りで");
var rv = msgpack.unpack(pack);

return [rv, "==", "カルビx3, ハラミx2, ブタバラ, T-BORNx500g, ライス大盛りで", hex(pack)];
},
"String('カルビx3, ハラミx2, ブタバラ, T-BORNx500g, ライス大盛りで、あとナポリタンと天丼、スープカレーに餃子とチャーハン、それからそれからビーフストロガノフとアクアパッツァ、すき焼きにざるそば') -> [] (Str16)": function() {
var pack = msgpack.pack("カルビx3, ハラミx2, ブタバラ, T-BORNx500g, ライス大盛りで、あとナポリタンと天丼、スープカレーに餃子とチャーハン、それからそれからビーフストロガノフとアクアパッツァ、すき焼きにざるそば");
var rv = msgpack.unpack(pack);

return [rv, "==", "カルビx3, ハラミx2, ブタバラ, T-BORNx500g, ライス大盛りで、あとナポリタンと天丼、スープカレーに餃子とチャーハン、それからそれからビーフストロガノフとアクアパッツァ、すき焼きにざるそば", hex(pack)];
},
"Bin (as Uint8Array)": "",
"Uint8Array(1,2,3) -> [1,2,3] (Bin8)": function() {
var pack = msgpack.pack(new Uint8Array([1,2,3]));
var rv = msgpack.unpack(pack);

return [rv, "==", [1,2,3], hex(pack)];
},
"Uint8Array(0..255) -> [0..255] (Bin16)": function() {
var expected = new Array(256);
for (var i = 0; i < 256; ++i) expected[i] = i;
var pack = msgpack.pack(new Uint8Array(expected));
var rv = msgpack.unpack(pack);

return [rv, "==", expected, hex(pack)];
},
"Map (as Hash)": "",
"Hash({}) -> [0x80] (FixMap)": function() {
var pack = msgpack.pack({});
Expand Down Expand Up @@ -769,50 +790,86 @@
return [rv, "==", -1.0, hex(result)];
},

'[a1 61] "a" FixRaw': function() {
'[a1 61] "a" FixStr': function() {
var data = unescape('%a1%61');
var result = [0xa1, 0x61];
var rv = msgpack.unpack(data);

return [rv, "==", "a", hex(result)];
},
'[da 00 01 61] "a" raw 16': function() {
'[d9 01 61] "a" str 8': function() {
var data = unescape('%d9%01%61');
var result = [0xda, 0x01, 0x61];
var rv = msgpack.unpack(data);

return [rv, "==", "a", hex(result)];
},
'[da 00 01 61] "a" str 16': function() {
var data = unescape('%da%00%01%61');
var result = [0xda, 0x00, 0x01, 0x61];
var rv = msgpack.unpack(data);

return [rv, "==", "a", hex(result)];
},
'[db 00 00 00 01 61] "a" raw 32': function() {
'[db 00 00 00 01 61] "a" str 32': function() {
var data = unescape('%db%00%00%00%01%61');
var result = [0xdb, 0x00, 0x00, 0x00, 0x01, 0x61];
var rv = msgpack.unpack(data);

return [rv, "==", "a", hex(result)];
},

'[a0] "" FixRaw': function() {
'[a0] "" FixStr': function() {
var data = unescape('%a0');
var result = [0xa0];
var rv = msgpack.unpack(data);

return [rv, "==", "", hex(result)];
},
'[da 00 00] "" raw 16': function() {
'[d9 00] "" str 8': function() {
var data = unescape('%d9%00');
var result = [0xd9, 0x00];
var rv = msgpack.unpack(data);

return [rv, "==", "", hex(result)];
},
'[da 00 00] "" str 16': function() {
var data = unescape('%da%00%00');
var result = [0xda, 0x00, 0x00];
var rv = msgpack.unpack(data);

return [rv, "==", "", hex(result)];
},
'[db 00 00 00 00] "" raw 32': function() {
'[db 00 00 00 00] "" str 32': function() {
var data = unescape('%db%00%00%00%00');
var result = [0xdb, 0x00, 0x00, 0x00, 0x00];
var rv = msgpack.unpack(data);

return [rv, "==", "", hex(result)];
},

'[c4 00] "" bin 8': function() {
var data = unescape('%c4%00');
var result = [0xc4, 0x00];
var rv = msgpack.unpack(data);

return [rv, "==", [], hex(result)];
},
'[c5 00 00] "" bin 16': function() {
var data = unescape('%c5%00%00');
var result = [0xc5, 0x00, 0x00];
var rv = msgpack.unpack(data);

return [rv, "==", [], hex(result)];
},
'[c6 00 00 00 00] "" bin 32': function() {
var data = unescape('%c6%00%00%00%00');
var result = [0xc6, 0x00, 0x00, 0x00, 0x00];
var rv = msgpack.unpack(data);

return [rv, "==", [], hex(result)];
},

'[91 00] [0] FixArray': function() {
var data = unescape('%91%00');
var result = [0x91, 0x00];
Expand Down

0 comments on commit 2cfda99

Please sign in to comment.