msgpack5 4.0.0 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/decoder.js CHANGED
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  var bl = require('bl')
2
4
  var util = require('util')
3
5
 
@@ -242,7 +244,8 @@ module.exports = function buildDecode (decodingTypes) {
242
244
  length = buf.readUInt16BE(offset + 1)
243
245
  return decodeMap(buf, offset, length, 3)
244
246
  case 0xdf:
245
- throw new Error('map too big to decode in JS')
247
+ length = buf.readUInt32BE(offset + 1)
248
+ return decodeMap(buf, offset, length, 5)
246
249
  case 0xd4:
247
250
  return decodeFixExt(buf, offset, 1)
248
251
  case 0xd5:
@@ -375,19 +378,21 @@ module.exports = function buildDecode (decodingTypes) {
375
378
  var type = buf.readInt8(offset + 1) // Signed
376
379
  return decodeExt(buf, offset, type, size, 2)
377
380
  }
381
+
378
382
  function decodeTimestamp (buf, size, headerSize) {
379
- var seconds, nanoseconds
380
- nanoseconds = 0
383
+ var seconds
384
+ var nanoseconds = 0
381
385
 
382
386
  switch (size) {
383
387
  case 4:
384
- // timestamp 32 stores the number of seconds that have elapsed since 1970-01-01 00:00:00 UTC in an 32-bit unsigned integer
385
- seconds = buf.readUInt32BE()
388
+ // timestamp 32 stores the number of seconds that have elapsed since 1970-01-01 00:00:00 UTC in an 32-bit unsigned integer
389
+ seconds = buf.readUInt32BE(0)
386
390
  break
387
391
 
388
- case 8: // Timestamp 64 stores the number of seconds and nanoseconds that have elapsed
389
- // since 1970-01-01 00:00:00 UTC in 32-bit unsigned integers, split 30/34 bits
390
- var upper = buf.readUInt32BE()
392
+ case 8:
393
+ // Timestamp 64 stores the number of seconds and nanoseconds that have elapsed
394
+ // since 1970-01-01 00:00:00 UTC in 32-bit unsigned integers, split 30/34 bits
395
+ var upper = buf.readUInt32BE(0)
391
396
  var lower = buf.readUInt32BE(4)
392
397
  nanoseconds = upper / 4
393
398
  seconds = ((upper & 0x03) * Math.pow(2, 32)) + lower // If we use bitwise operators, we get truncated to 32bits
package/lib/encoder.js CHANGED
@@ -2,12 +2,11 @@
2
2
 
3
3
  var Buffer = require('safe-buffer').Buffer
4
4
  var bl = require('bl')
5
- var TOLERANCE = 0.1
6
5
 
7
6
  module.exports = function buildEncode (encodingTypes, forceFloat64, compatibilityMode, disableTimestampEncoding) {
8
7
  function encode (obj, avoidSlice) {
9
- var buf,
10
- len
8
+ var buf
9
+ var len
11
10
 
12
11
  if (obj === undefined) {
13
12
  throw new Error('undefined is not encodable in msgpack!')
@@ -158,8 +157,8 @@ module.exports = function buildEncode (encodingTypes, forceFloat64, compatibilit
158
157
  var nanos = (millis - (seconds * 1000)) * 1E6
159
158
 
160
159
  if (nanos || seconds > 0xFFFFFFFF) {
161
- // Timestamp64
162
- encoded = new Buffer(10)
160
+ // Timestamp64
161
+ encoded = Buffer.allocUnsafe(10)
163
162
  encoded[0] = 0xd7
164
163
  encoded[1] = -1
165
164
 
@@ -171,8 +170,8 @@ module.exports = function buildEncode (encodingTypes, forceFloat64, compatibilit
171
170
  encoded.writeInt32BE(upper, 2)
172
171
  encoded.writeInt32BE(lower, 6)
173
172
  } else {
174
- // Timestamp32
175
- encoded = new Buffer(6)
173
+ // Timestamp32
174
+ encoded = Buffer.allocUnsafe(6)
176
175
  encoded[0] = 0xd6
177
176
  encoded[1] = -1
178
177
  encoded.writeUInt32BE(Math.floor(millis / 1000), 2)
@@ -248,10 +247,14 @@ module.exports = function buildEncode (encodingTypes, forceFloat64, compatibilit
248
247
  if (length < 16) {
249
248
  header = Buffer.allocUnsafe(1)
250
249
  header[0] = 0x80 | length
251
- } else {
250
+ } else if (length < 0xFFFF) {
252
251
  header = Buffer.allocUnsafe(3)
253
252
  header[0] = 0xde
254
253
  header.writeUInt16BE(length, 1)
254
+ } else {
255
+ header = Buffer.allocUnsafe(5)
256
+ header[0] = 0xdf
257
+ header.writeUInt32BE(length, 1)
255
258
  }
256
259
 
257
260
  acc.unshift(header)
@@ -297,22 +300,35 @@ function write64BitInt (buf, offset, num) {
297
300
  }
298
301
 
299
302
  function isFloat (n) {
300
- return n !== Math.floor(n)
303
+ return n % 1 !== 0
301
304
  }
302
305
 
303
306
  function encodeFloat (obj, forceFloat64) {
304
- var buf
307
+ var useDoublePrecision = true
308
+
309
+ // If `fround` is supported, we can check if a float
310
+ // is double or single precision by rounding the object
311
+ // to single precision and comparing the difference.
312
+ // If it's not supported, it's safer to use a 64 bit
313
+ // float so we don't lose precision without meaning to.
314
+ if (Math.fround) {
315
+ useDoublePrecision = Math.fround(obj) !== obj
316
+ }
305
317
 
306
- buf = Buffer.allocUnsafe(5)
307
- buf[0] = 0xca
308
- buf.writeFloatBE(obj, 1)
318
+ if (forceFloat64) {
319
+ useDoublePrecision = true
320
+ }
321
+
322
+ var buf
309
323
 
310
- // FIXME is there a way to check if a
311
- // value fits in a float?
312
- if (forceFloat64 || Math.abs(obj - buf.readFloatBE(1)) > TOLERANCE) {
324
+ if (useDoublePrecision) {
313
325
  buf = Buffer.allocUnsafe(9)
314
326
  buf[0] = 0xcb
315
327
  buf.writeDoubleBE(obj, 1)
328
+ } else {
329
+ buf = Buffer.allocUnsafe(5)
330
+ buf[0] = 0xca
331
+ buf.writeFloatBE(obj, 1)
316
332
  }
317
333
 
318
334
  return buf
package/lib/streams.js CHANGED
@@ -25,6 +25,7 @@ function Encoder (opts) {
25
25
  }
26
26
 
27
27
  Base.call(this, opts)
28
+ this._wrap = ('wrap' in opts) && opts.wrap
28
29
  }
29
30
 
30
31
  inherits(Encoder, Base)
@@ -33,7 +34,7 @@ Encoder.prototype._transform = function (obj, enc, done) {
33
34
  var buf = null
34
35
 
35
36
  try {
36
- buf = this._msgpack.encode(obj).slice(0)
37
+ buf = this._msgpack.encode(this._wrap ? obj.value : obj).slice(0)
37
38
  } catch (err) {
38
39
  this.emit('error', err)
39
40
  return done()
@@ -53,6 +54,7 @@ function Decoder (opts) {
53
54
  Base.call(this, opts)
54
55
 
55
56
  this._chunks = bl()
57
+ this._wrap = ('wrap' in opts) && opts.wrap
56
58
  }
57
59
 
58
60
  inherits(Decoder, Base)
@@ -64,6 +66,9 @@ Decoder.prototype._transform = function (buf, enc, done) {
64
66
 
65
67
  try {
66
68
  var result = this._msgpack.decode(this._chunks)
69
+ if (this._wrap) {
70
+ result = {value: result}
71
+ }
67
72
  this.push(result)
68
73
  } catch (err) {
69
74
  if (err instanceof this._msgpack.IncompleteBufferError) {
package/package.json CHANGED
@@ -1,14 +1,13 @@
1
1
  {
2
2
  "name": "msgpack5",
3
- "version": "4.0.0",
3
+ "version": "4.2.0",
4
4
  "description": "A msgpack v5 implementation for node.js and the browser, with extension points",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "test": "standard && tape test/* | tap-mocha-reporter dot",
8
8
  "build": "npm run browserify && npm run dist",
9
- "browserify": "node_modules/.bin/browserify index.js -o dist/msgpack5.js -s msgpack5",
10
- "dist": "node_modules/.bin/uglifyjs dist/msgpack5.js -o dist/msgpack5.min.js",
11
- "test-browser": "browserify test/* | testling -u"
9
+ "browserify": "browserify index.js -o dist/msgpack5.js -s msgpack5",
10
+ "dist": "uglifyjs dist/msgpack5.js -o dist/msgpack5.min.js"
12
11
  },
13
12
  "pre-commit": [
14
13
  "test"
@@ -31,38 +30,23 @@
31
30
  },
32
31
  "homepage": "https://github.com/mcollina/msgpack5",
33
32
  "devDependencies": {
34
- "browserify": "^14.5.0",
35
- "jshint": "^2.9.5",
33
+ "browserify": "^16.2.0",
36
34
  "memdb": "^1.3.1",
37
35
  "pre-commit": "^1.2.2",
38
- "standard": "^10.0.3",
39
- "tap-mocha-reporter": "^3.0.6",
40
- "tape": "^4.8.0",
41
- "testling": "^1.7.1",
42
- "uglify-js": "^3.2.2"
36
+ "standard": "^11.0.1",
37
+ "tap-mocha-reporter": "^3.0.7",
38
+ "tape": "^4.9.0",
39
+ "uglify-js": "^3.3.25"
43
40
  },
44
41
  "standard": {
45
42
  "ignore": [
46
43
  "dist/"
47
44
  ]
48
45
  },
49
- "testling": {
50
- "files": "test/*.js",
51
- "browsers": [
52
- "ie/6..latest",
53
- "chrome/22..latest",
54
- "firefox/16..latest",
55
- "safari/latest",
56
- "opera/11.0..latest",
57
- "iphone/6",
58
- "ipad/6",
59
- "android-browser/latest"
60
- ]
61
- },
62
46
  "dependencies": {
63
- "bl": "^1.2.1",
47
+ "bl": "^2.0.0",
64
48
  "inherits": "^2.0.3",
65
- "readable-stream": "^2.3.3",
66
- "safe-buffer": "^5.1.1"
49
+ "readable-stream": "^2.3.6",
50
+ "safe-buffer": "^5.1.2"
67
51
  }
68
52
  }
@@ -34,7 +34,7 @@ test('encode/decode 2^8-1 Uint8Arrays', function (t) {
34
34
  })
35
35
 
36
36
  t.test('mirror test for an Uint8Array of length ' + array.byteLength + ' bytes', function (t) {
37
- t.deepEqual(encoder.decode(encoder.encode(array)), new Buffer(array), 'must stay the same')
37
+ t.deepEqual(encoder.decode(encoder.encode(array)), Buffer.from(array), 'must stay the same')
38
38
  t.end()
39
39
  })
40
40
  })
@@ -34,7 +34,7 @@ test('encode/decode 2^8-1 Uint8Arrays', function (t) {
34
34
  })
35
35
 
36
36
  t.test('mirror test for an Uint8Array of length ' + array.byteLength + ' bytes', function (t) {
37
- t.deepEqual(encoder.decode(encoder.encode(array)), new Buffer(array), 'must stay the same')
37
+ t.deepEqual(encoder.decode(encoder.encode(array)), Buffer.from(array), 'must stay the same')
38
38
  t.end()
39
39
  })
40
40
  })
@@ -33,7 +33,7 @@ test('encode/decode 2^8-1 Uint8Arrays', function (t) {
33
33
  })
34
34
 
35
35
  t.test('mirror test for an Uint8Array of length ' + array.byteLength + ' bytes', function (t) {
36
- t.deepEqual(encoder.decode(encoder.encode(array)), new Buffer(array), 'must stay the same')
36
+ t.deepEqual(encoder.decode(encoder.encode(array)), Buffer.from(array), 'must stay the same')
37
37
  t.end()
38
38
  })
39
39
  })
package/test/floats.js CHANGED
@@ -7,29 +7,67 @@ var bl = require('bl')
7
7
 
8
8
  test('encoding/decoding 32-bits float numbers', function (t) {
9
9
  var encoder = msgpack()
10
- var allNum = []
10
+ var float32 = [
11
+ 1.5,
12
+ 0.15625,
13
+ -2.5
14
+ ]
11
15
 
12
- allNum.push(-222.42)
13
- allNum.push(748364.2)
14
- allNum.push(2.2)
16
+ var float64 = [
17
+ 2 ** 150,
18
+ 1.337,
19
+ 2.2
20
+ ]
15
21
 
16
- allNum.forEach(function (num) {
22
+ float64.forEach(function (num) {
23
+ t.test('encoding ' + num, function (t) {
24
+ var buf = encoder.encode(num)
25
+ t.equal(buf.length, 9, 'must have 5 bytes')
26
+ t.equal(buf[0], 0xcb, 'must have the proper header')
27
+
28
+ var dec = buf.readDoubleBE(1)
29
+ t.equal(dec, num, 'must decode correctly')
30
+ t.end()
31
+ })
32
+
33
+ t.test('decoding ' + num, function (t) {
34
+ var buf = Buffer.allocUnsafe(9)
35
+ var dec
36
+ buf[0] = 0xcb
37
+ buf.writeDoubleBE(num, 1)
38
+
39
+ dec = encoder.decode(buf)
40
+ t.equal(dec, num, 'must decode correctly')
41
+ t.end()
42
+ })
43
+
44
+ t.test('mirror test ' + num, function (t) {
45
+ var dec = encoder.decode(encoder.encode(num))
46
+ t.equal(dec, num, 'must decode correctly')
47
+ t.end()
48
+ })
49
+ })
50
+
51
+ float32.forEach(function (num) {
17
52
  t.test('encoding ' + num, function (t) {
18
53
  var buf = encoder.encode(num)
19
- var dec = buf.readFloatBE(1)
20
54
  t.equal(buf.length, 5, 'must have 5 bytes')
21
55
  t.equal(buf[0], 0xca, 'must have the proper header')
22
- t.true(Math.abs(dec - num) < 0.1, 'must decode correctly')
56
+
57
+ var dec = buf.readFloatBE(1)
58
+ t.equal(dec, num, 'must decode correctly')
23
59
  t.end()
24
60
  })
25
61
 
26
62
  t.test('forceFloat64 encoding ' + num, function (t) {
27
63
  var enc = msgpack({ forceFloat64: true })
28
64
  var buf = enc.encode(num)
29
- var dec = buf.readDoubleBE(1)
65
+
30
66
  t.equal(buf.length, 9, 'must have 9 bytes')
31
67
  t.equal(buf[0], 0xcb, 'must have the proper header')
32
- t.true(Math.abs(dec - num) < 0.1, 'must decode correctly')
68
+
69
+ var dec = buf.readDoubleBE(1)
70
+ t.equal(dec, num, 'must decode correctly')
33
71
  t.end()
34
72
  })
35
73
 
@@ -38,14 +76,15 @@ test('encoding/decoding 32-bits float numbers', function (t) {
38
76
  var dec
39
77
  buf[0] = 0xca
40
78
  buf.writeFloatBE(num, 1)
79
+
41
80
  dec = encoder.decode(buf)
42
- t.true(Math.abs(dec - num) < 0.1, 'must decode correctly')
81
+ t.equal(dec, num, 'must decode correctly')
43
82
  t.end()
44
83
  })
45
84
 
46
85
  t.test('mirror test ' + num, function (t) {
47
86
  var dec = encoder.decode(encoder.encode(num))
48
- t.true(Math.abs(dec - num) < 0.1, 'must decode correctly')
87
+ t.equal(dec, num, 'must decode correctly')
49
88
  t.end()
50
89
  })
51
90
  })
@@ -65,3 +104,16 @@ test('decoding an incomplete 32-bits float numbers', function (t) {
65
104
  t.equals(buf.length, origLength, 'must not consume any byte')
66
105
  t.end()
67
106
  })
107
+
108
+ test('decoding an incomplete 64-bits float numbers', function (t) {
109
+ var encoder = msgpack()
110
+ var buf = Buffer.allocUnsafe(8)
111
+ buf[0] = 0xcb
112
+ buf = bl().append(buf)
113
+ var origLength = buf.length
114
+ t.throws(function () {
115
+ encoder.decode(buf)
116
+ }, encoder.IncompleteBufferError, 'must throw IncompleteBufferError')
117
+ t.equals(buf.length, origLength, 'must not consume any byte')
118
+ t.end()
119
+ })
@@ -0,0 +1,71 @@
1
+ 'use strict'
2
+
3
+ var test = require('tape').test
4
+ var msgpack = require('../')
5
+
6
+ test('encode/decode map with 10 keys', function (t) {
7
+ var map = {}
8
+
9
+ for (var i = 0; i < 10; i++) {
10
+ map[i] = i
11
+ }
12
+
13
+ var pack = msgpack()
14
+
15
+ var encoded = pack.encode(map)
16
+
17
+ // map16 byte
18
+ t.equal(encoded[0], 0x8A)
19
+
20
+ t.deepEqual(pack.decode(encoded), map)
21
+ t.end()
22
+ })
23
+
24
+ test('encode/decode map with 10000 keys', function (t) {
25
+ var map = {}
26
+
27
+ for (var i = 0; i < 10000; i++) {
28
+ map[i] = i
29
+ }
30
+
31
+ var pack = msgpack()
32
+
33
+ var encoded = pack.encode(map)
34
+
35
+ // map16 byte
36
+ t.equal(encoded[0], 0xde)
37
+
38
+ t.deepEqual(pack.decode(encoded), map)
39
+ t.end()
40
+ })
41
+
42
+ test('encode/decode map with 100000 keys', function (t) {
43
+ var map = {}
44
+
45
+ for (var i = 0; i < 100000; i++) {
46
+ map[i] = i
47
+ }
48
+
49
+ var pack = msgpack()
50
+
51
+ var encoded = pack.encode(map)
52
+
53
+ // map32 byte
54
+ t.equal(encoded[0], 0xdf)
55
+
56
+ t.deepEqual(pack.decode(encoded), map)
57
+ t.end()
58
+ })
59
+
60
+ test('encode/decode map with 1000000 keys', function (t) {
61
+ var map = {}
62
+
63
+ for (var i = 0; i < 1000000; i++) {
64
+ map[i] = i
65
+ }
66
+
67
+ var pack = msgpack()
68
+
69
+ t.deepEqual(pack.decode(pack.encode(map)), map)
70
+ t.end()
71
+ })
package/test/streams.js CHANGED
@@ -182,3 +182,80 @@ test('concatenated buffers work', function (t) {
182
182
 
183
183
  encoder.end()
184
184
  })
185
+
186
+ test('nil processing works', function (t) {
187
+ t.plan(3)
188
+
189
+ var pack = msgpack()
190
+ var decoder = pack.decoder({wrap: true})
191
+ var decodedItemIndex = 0
192
+
193
+ decoder.on('data', function (chunk) {
194
+ decodedItemIndex++
195
+ t.deepEqual(chunk.value, decodedItemIndex === 1 ? null : false)
196
+ })
197
+
198
+ decoder.on('end', function () {
199
+ t.equal(decodedItemIndex, 2)
200
+ })
201
+
202
+ decoder.write(new Buffer([0xc0, 0xc2]))
203
+ decoder.end()
204
+ })
205
+
206
+ test('encoder wrap mode works', function (t) {
207
+ t.plan(1)
208
+
209
+ var pack = msgpack()
210
+ var encoder = pack.encoder({wrap: true})
211
+ var decoder = pack.decoder()
212
+ var data = { hello: 'world' }
213
+ var wrappedData = {value: data}
214
+
215
+ encoder.pipe(decoder)
216
+
217
+ decoder.on('data', function (chunk) {
218
+ t.deepEqual(chunk, data)
219
+ })
220
+
221
+ encoder.end(wrappedData)
222
+ })
223
+
224
+ test('encoder/decoder wrap mode must send an object through', function (t) {
225
+ t.plan(1)
226
+
227
+ var pack = msgpack()
228
+ var encoder = pack.encoder({wrap: true})
229
+ var decoder = pack.decoder({wrap: true})
230
+ var data = {value: { hello: 'world' }}
231
+
232
+ encoder.pipe(decoder)
233
+
234
+ decoder.on('data', function (chunk) {
235
+ t.deepEqual(chunk, data)
236
+ })
237
+
238
+ encoder.end(data)
239
+ })
240
+
241
+ test('encoder pack null', function (t) {
242
+ t.plan(2)
243
+ var pack = msgpack()
244
+ var encoder = pack.encoder({wrap: true})
245
+ var decoder = pack.decoder({wrap: true})
246
+
247
+ encoder.pipe(decoder)
248
+
249
+ var decodedItemIndex = 0
250
+ decoder.on('data', function (chunk) {
251
+ decodedItemIndex++
252
+ t.deepEqual(chunk.value, null)
253
+ })
254
+
255
+ decoder.on('end', function () {
256
+ t.equal(decodedItemIndex, 1)
257
+ })
258
+
259
+ encoder.write({value: null})
260
+ encoder.end()
261
+ })
@@ -7,7 +7,7 @@ var msgpack = require('../')
7
7
  test('timestamp disabling', function (t) {
8
8
  var encoder = msgpack({disableTimestampEncoding: true})
9
9
  var timestamps = [
10
- [new Date('2018-01-02T03:04:05.000000000Z'), [0x80]]
10
+ [new Date('2018-01-02T03:04:05.000000000Z'), [0x80]]
11
11
  ]
12
12
 
13
13
  timestamps.forEach(function (testcase) {
@@ -27,11 +27,11 @@ test('timestamp disabling', function (t) {
27
27
  test('encoding/decoding timestamp 64', function (t) {
28
28
  var encoder = msgpack()
29
29
  var timestamps = [
30
- [new Date('2018-01-02T03:04:05.000000000Z'), [0xd6, 0xff, 0x5a, 0x4a, 0xf6, 0xa5]],
31
- [new Date('2038-01-19T03:14:08.000000000Z'), [0xd6, 0xff, 0x80, 0x00, 0x00, 0x00]],
32
- [new Date('2038-01-19T03:14:07.999000000Z'), [0xd7, 0xff, 0xee, 0x2E, 0x1F, 0x00, 0x7f, 0xff, 0xff, 0xff]],
33
- [new Date('2106-02-07T06:28:16.000000000Z'), [0xd7, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00]],
34
- [new Date('2018-01-02T03:04:05.678000000Z'), [0xd7, 0xff, 0xa1, 0xa5, 0xd6, 0x00, 0x5a, 0x4a, 0xf6, 0xa5]]
30
+ [new Date('2018-01-02T03:04:05.000000000Z'), [0xd6, 0xff, 0x5a, 0x4a, 0xf6, 0xa5]],
31
+ [new Date('2038-01-19T03:14:08.000000000Z'), [0xd6, 0xff, 0x80, 0x00, 0x00, 0x00]],
32
+ [new Date('2038-01-19T03:14:07.999000000Z'), [0xd7, 0xff, 0xee, 0x2E, 0x1F, 0x00, 0x7f, 0xff, 0xff, 0xff]],
33
+ [new Date('2106-02-07T06:28:16.000000000Z'), [0xd7, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00]],
34
+ [new Date('2018-01-02T03:04:05.678000000Z'), [0xd7, 0xff, 0xa1, 0xa5, 0xd6, 0x00, 0x5a, 0x4a, 0xf6, 0xa5]]
35
35
  ]
36
36
 
37
37
  timestamps.forEach(function (testcase) {