Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a379349

Browse filesBrowse files
committed
working node-binarypack; untested
1 parent 23f0ce1 commit a379349
Copy full SHA for a379349

File tree

Expand file treeCollapse file tree

2 files changed

+413
-0
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+413
-0
lines changed
Open diff view settings
Collapse file

‎lib/binarypack.js‎

Copy file name to clipboard
+334Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
var BufferCursor = require('buffercursor');
2+
var BufferBuilder = require('./bufferbuilder');
3+
4+
BinaryPack = {
5+
unpack: function(data){
6+
var unpacker = new BinaryPack.Unpacker(data);
7+
return unpacker.unpack();
8+
},
9+
pack: function(data){
10+
var packer = new BinaryPack.Packer();
11+
var buffer = packer.pack(data);
12+
return buffer;
13+
}
14+
};
15+
16+
BinaryPack.Unpacker = function(buffer){
17+
this.cursor = new BufferCursor(buffer);
18+
this.length = buffer.length;
19+
}
20+
21+
BinaryPack.Unpacker.prototype.unpack = function(){
22+
var type = this.cursor.readUInt8();
23+
if (type < 0x80){
24+
var positive_fixnum = type;
25+
return positive_fixnum;
26+
} else if ((type ^ 0xe0) < 0x20){
27+
var negative_fixnum = (type ^ 0xe0) - 0x20;
28+
return negative_fixnum;
29+
}
30+
var size;
31+
if ((size = type ^ 0xa0) <= 0x0f){
32+
return this.readraw(size);
33+
} else if ((size = type ^ 0xb0) <= 0x0f){
34+
return this.readstring(size);
35+
} else if ((size = type ^ 0x90) <= 0x0f){
36+
return this.readarray(size);
37+
} else if ((size = type ^ 0x80) <= 0x0f){
38+
return this.readmap(size);
39+
}
40+
switch(type){
41+
case 0xc0:
42+
return null;
43+
case 0xc1:
44+
return undefined;
45+
case 0xc2:
46+
return false;
47+
case 0xc3:
48+
return true;
49+
case 0xca:
50+
return this.cursor.readFloatBE();
51+
case 0xcb:
52+
return this.cursor.readDoubleBE();
53+
case 0xcc:
54+
return this.cursor.readUInt8();
55+
case 0xcd:
56+
return this.cursor.readUInt16BE();
57+
case 0xce:
58+
return this.cursor.readUInt32BE();
59+
case 0xcf:
60+
return this.readUInt64();
61+
case 0xd0:
62+
return this.cursor.readInt8();
63+
case 0xd1:
64+
return this.cursor.readInt16BE();
65+
case 0xd2:
66+
return this.cursor.readInt32BE();
67+
case 0xd3:
68+
return this.readInt64();
69+
case 0xd4:
70+
return undefined;
71+
case 0xd5:
72+
return undefined;
73+
case 0xd6:
74+
return undefined;
75+
case 0xd7:
76+
return undefined;
77+
case 0xd8:
78+
size = this.cursor.readUInt16BE();
79+
return this.readstring(size);
80+
case 0xd9:
81+
size = this.cursor.readUInt32BE();
82+
return this.readstring(size);
83+
case 0xda:
84+
size = this.cursor.readUInt16BE();
85+
return this.readraw(size);
86+
case 0xdb:
87+
size = this.cursor.readUInt32BE();
88+
return this.readraw(size);
89+
case 0xdc:
90+
size = this.cursor.readUInt16BE();
91+
return this.readarray(size);
92+
case 0xdd:
93+
size = this.cursor.readUInt32BE();
94+
return this.readarray(size);
95+
case 0xde:
96+
size = this.cursor.readUInt16BE();
97+
return this.readmap(size);
98+
case 0xdf:
99+
size = this.cursor.readUInt32BE();
100+
return this.readmap(size);
101+
}
102+
}
103+
BinaryPack.Unpacker.prototype.readUInt64 = function(){
104+
var bytes = this.cursor.slice(8);
105+
return ((((((bytes[0] * 256 +
106+
bytes[1]) * 256 +
107+
bytes[2]) * 256 +
108+
bytes[3]) * 256 +
109+
bytes[4]) * 256 +
110+
bytes[5]) * 256 +
111+
bytes[6]) * 256 +
112+
bytes[7];
113+
}
114+
115+
BinaryPack.Unpacker.prototype.readInt64 = function(){
116+
var uint64 = this.readInt64();
117+
return (uint64 < Math.pow(2, 63) ) ? uint64 : uint64 - Math.pow(2, 64);
118+
}
119+
120+
BinaryPack.Unpacker.prototype.readraw = function(size){
121+
return this.cursor.slice(size);
122+
}
123+
124+
BinaryPack.Unpacker.prototype.readstring = function(size){
125+
return this.cursor.toString('utf8', size);
126+
}
127+
128+
BinaryPack.Unpacker.prototype.readarray = function(size){
129+
var objects = new Array(size);
130+
for(var i = 0; i < size ; i++){
131+
objects[i] = this.unpack();
132+
}
133+
return objects;
134+
}
135+
136+
BinaryPack.Unpacker.prototype.readmap = function(size){
137+
var map = {};
138+
for(var i = 0; i < size ; i++){
139+
var key = this.unpack();
140+
var value = this.unpack();
141+
map[key] = value;
142+
}
143+
return map;
144+
}
145+
146+
147+
148+
149+
BinaryPack.Packer = function(){
150+
this.bufferBuilder = new BufferBuilder();
151+
}
152+
153+
BinaryPack.Packer.prototype.pack = function(value){
154+
var type = typeof(value);
155+
if (type == 'string'){
156+
this.pack_string(value);
157+
} else if (type == 'number'){
158+
if (Math.floor(value) === value){
159+
this.pack_integer(value);
160+
} else{
161+
this.pack_double(value);
162+
}
163+
} else if (type == 'boolean'){
164+
if (value === true){
165+
this.bufferBuilder.append(0xc3, 2);
166+
} else if (value === false){
167+
this.bufferBuilder.append(0xc2, 2);
168+
}
169+
} else if (type == 'undefined'){
170+
this.bufferBuilder.append(0xc0, 2);
171+
} else if (type == 'object'){
172+
if (value === null){
173+
this.bufferBuilder.append(0xc0, 2);
174+
} else {
175+
var constructor = value.constructor;
176+
if (constructor == Array){
177+
this.pack_array(value);
178+
} else if (Buffer.isBuffer(value)) {
179+
this.pack_bin(value);
180+
} else if (constructor == Object){
181+
this.pack_object(value);
182+
} else if (constructor == Date){
183+
this.pack_string(value.toString());
184+
} else if (typeof value.toBinaryPack == 'function'){
185+
this.bufferBuilder.append(value.toBinaryPack(), 1);
186+
} else {
187+
throw new Error('Type "' + constructor.toString() + '" not yet supported');
188+
}
189+
}
190+
} else {
191+
throw new Error('Type "' + type + '" not yet supported');
192+
}
193+
return this.bufferBuilder.getBuffer();
194+
}
195+
196+
197+
BinaryPack.Packer.prototype.pack_bin = function(blob){
198+
var length = blob.length || blob.byteLength || blob.size;
199+
if (length <= 0x1f){
200+
this.bufferBuilder.append(0xa0 + length, 2);
201+
} else if (length <= 0xffff){
202+
this.bufferBuilder.append(0xda, 2) ;
203+
this.bufferBuilder.append(length, 3);
204+
} else if (length <= 0xffffffff){
205+
this.bufferBuilder.append(0xdb, 2);
206+
this.bufferBuilder.append(length, 4);
207+
} else{
208+
throw new Error('Invalid length');
209+
return;
210+
}
211+
this.bufferBuilder.append(blob, 1);
212+
}
213+
214+
BinaryPack.Packer.prototype.pack_string = function(str){
215+
var length = str.length;
216+
if (length <= 0x1f){
217+
this.bufferBuilder.append(0xb0 + length, 2);
218+
} else if (length <= 0xffff){
219+
this.bufferBuilder.append(0xd8, 2) ;
220+
this.bufferBuilder.append(length, 3);
221+
} else if (length <= 0xffffffff){
222+
this.bufferBuilder.append(0xd9, 2);
223+
this.bufferBuilder.append(length, 4);
224+
} else{
225+
throw new Error('Invalid length');
226+
return;
227+
}
228+
this.bufferBuilder.append(str, 0);
229+
}
230+
231+
BinaryPack.Packer.prototype.pack_array = function(ary){
232+
var length = ary.length;
233+
if (length <= 0x0f){
234+
this.bufferBuilder.append(0x90 + length, 2);
235+
} else if (length <= 0xffff){
236+
this.bufferBuilder.append(0xdc, 2)
237+
this.bufferBuilder.append(length, 3);
238+
} else if (length <= 0xffffffff){
239+
this.bufferBuilder.append(0xdd, 2);
240+
this.bufferBuilder.append(length, 4);
241+
} else{
242+
throw new Error('Invalid length');
243+
}
244+
for(var i = 0; i < length ; i++){
245+
this.pack(ary[i]);
246+
}
247+
}
248+
249+
BinaryPack.Packer.prototype.pack_integer = function(num){
250+
if ( -0x20 <= num && num <= 0x7f){
251+
this.bufferBuilder.append(num & 0xff, 2);
252+
} else if (0x00 <= num && num <= 0xff){
253+
this.bufferBuilder.append(0xcc, 2);
254+
this.bufferBuilder.append(num, 2);
255+
} else if (-0x80 <= num && num <= 0x7f){
256+
this.bufferBuilder.append(0xd0, 2);
257+
this.bufferBuilder.append(num, 5);
258+
} else if ( 0x0000 <= num && num <= 0xffff){
259+
this.bufferBuilder.append(0xcd, 2);
260+
this.bufferBuilder.append(num, 3);
261+
} else if (-0x8000 <= num && num <= 0x7fff){
262+
this.bufferBuilder.append(0xd1, 2);
263+
this.bufferBuilder.append(num, 6);
264+
} else if ( 0x00000000 <= num && num <= 0xffffffff){
265+
this.bufferBuilder.append(0xce, 2);
266+
this.bufferBuilder.append(num, 4);
267+
} else if (-0x80000000 <= num && num <= 0x7fffffff){
268+
this.bufferBuilder.append(0xd2, 2);
269+
this.bufferBuilder.append(num, 7);
270+
} else if (-0x8000000000000000 <= num && num <= 0x7FFFFFFFFFFFFFFF){
271+
this.bufferBuilder.append(0xd3, 2);
272+
this.pack_int64(num);
273+
} else if (0x0000000000000000 <= num && num <= 0xFFFFFFFFFFFFFFFF){
274+
this.bufferBuilder.append(0xcf);
275+
this.pack_uint64(num);
276+
} else{
277+
throw new Error('Invalid integer');
278+
}
279+
}
280+
281+
BinaryPack.Packer.prototype.pack_double = function(num){
282+
this.bufferBuilder.append(0xcb, 2);
283+
this.bufferBuilder.append(num, 9);
284+
}
285+
286+
BinaryPack.Packer.prototype.pack_object = function(obj){
287+
var keys = Object.keys(obj);
288+
var length = keys.length;
289+
if (length <= 0x0f){
290+
this.bufferBuilder.append(0x80 + length, 2);
291+
} else if (length <= 0xffff){
292+
this.bufferBuilder.append(0xde, 2);
293+
this.bufferBuilder.append(length, 3);
294+
} else if (length <= 0xffffffff){
295+
this.bufferBuilder.append(0xdf, 2);
296+
this.bufferBuilder.append(length, 4);
297+
} else{
298+
throw new Error('Invalid length');
299+
}
300+
for(var prop in obj){
301+
if (obj.hasOwnProperty(prop)){
302+
this.pack(prop);
303+
this.pack(obj[prop]);
304+
}
305+
}
306+
}
307+
308+
BinaryPack.Packer.prototype.pack_int64 = function(num){
309+
var high = Math.floor(num / Math.pow(2, 32));
310+
var low = num % Math.pow(2, 32);
311+
this.bufferBuilder.append((high & 0xff000000) >>> 24, 2);
312+
this.bufferBuilder.append((high & 0x00ff0000) >>> 16, 2);
313+
this.bufferBuilder.append((high & 0x0000ff00) >>> 8, 2);
314+
this.bufferBuilder.append((high & 0x000000ff), 2);
315+
this.bufferBuilder.append((low & 0xff000000) >>> 24, 2);
316+
this.bufferBuilder.append((low & 0x00ff0000) >>> 16, 2);
317+
this.bufferBuilder.append((low & 0x0000ff00) >>> 8, 2);
318+
this.bufferBuilder.append((low & 0x000000ff), 2);
319+
}
320+
321+
BinaryPack.Packer.prototype.pack_uint64 = function(num){
322+
var high = num / Math.pow(2, 32);
323+
var low = num % Math.pow(2, 32);
324+
this.bufferBuilder.append((high & 0xff000000) >>> 24, 2);
325+
this.bufferBuilder.append((high & 0x00ff0000) >>> 16, 2);
326+
this.bufferBuilder.append((high & 0x0000ff00) >>> 8, 2);
327+
this.bufferBuilder.append((high & 0x000000ff), 2);
328+
this.bufferBuilder.append((low & 0xff000000) >>> 24, 2);
329+
this.bufferBuilder.append((low & 0x00ff0000) >>> 16, 2);
330+
this.bufferBuilder.append((low & 0x0000ff00) >>> 8, 2);
331+
this.bufferBuilder.append((low & 0x000000ff), 2);
332+
}
333+
334+
module.exports = BinaryPack;

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.