ordered-binary 1.6.0 → 1.6.2

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.
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "ordered-binary",
3
+ "author": "Kris Zyp",
4
+ "version": "1.6.1",
5
+ "description": "Conversion of JavaScript primitives to and from Buffer with binary order matching natural primitive order",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "http://github.com/kriszyp/ordered-binary"
10
+ },
11
+ "scripts": {
12
+ "build": "rollup -c",
13
+ "prepare": "rollup -c",
14
+ "test": "mocha tests -u tdd"
15
+ },
16
+ "type": "module",
17
+ "main": "dist/index.cjs",
18
+ "module": "index.js",
19
+ "exports": {
20
+ ".": {
21
+ "require": "./dist/index.cjs",
22
+ "import": "./index.js"
23
+ },
24
+ "./index.js": {
25
+ "require": "./dist/index.cjs",
26
+ "import": "./index.js"
27
+ }
28
+ },
29
+ "typings": "./index.d.ts",
30
+ "optionalDependencies": {},
31
+ "devDependencies": {
32
+ "@types/node": "latest",
33
+ "chai": "^4",
34
+ "mocha": "^9.2.0",
35
+ "rollup": "^2.61.1"
36
+ }
37
+ }
@@ -0,0 +1,11 @@
1
+ export default [
2
+ {
3
+ input: "index.js",
4
+ output: [
5
+ {
6
+ file: "dist/index.cjs",
7
+ format: "cjs"
8
+ }
9
+ ]
10
+ }
11
+ ];
@@ -0,0 +1,181 @@
1
+ import { assert } from 'chai'
2
+
3
+ import { toBufferKey, fromBufferKey, readKey, writeKey } from '../index.js'
4
+
5
+ function assertBufferComparison(lesser, greater) {
6
+ for (let i = 0; i < lesser.length; i++) {
7
+ if (lesser[i] < greater[i]) {
8
+ return
9
+ }
10
+ if (lesser[i] > (greater[i] || 0)) {
11
+ assert.fail('Byte ' + i + 'should not be ' + lesser[i] + '>' + greater[i])
12
+ }
13
+ }
14
+ }
15
+ //var inspector = require('inspector'); inspector.open(9330, null, true); debugger
16
+ let seed = 0;
17
+ export function random() {
18
+ seed++;
19
+ let a = seed * 15485863;
20
+ return ((a * a * a) % 2038074743) / 2038074743;
21
+ }
22
+
23
+ suite('key buffers', () => {
24
+
25
+ test('numbers equivalence', () => {
26
+ assert.strictEqual(fromBufferKey(toBufferKey(4)), 4)
27
+ assert.strictEqual(fromBufferKey(toBufferKey(-4)), -4)
28
+ assert.strictEqual(fromBufferKey(toBufferKey(3.4)), 3.4)
29
+ assert.strictEqual(fromBufferKey(toBufferKey(Math.PI)), Math.PI)
30
+ assert.strictEqual(fromBufferKey(toBufferKey(2002225)), 2002225)
31
+ // check to make sure it works with a limited ArrayBuffer
32
+ assert.strictEqual(fromBufferKey(new Uint8Array(toBufferKey(2002225))), 2002225)
33
+ assert.strictEqual(fromBufferKey(toBufferKey(9377288)), 9377288)
34
+ assert.strictEqual(fromBufferKey(toBufferKey(1503579323825)), 1503579323825)
35
+ assert.strictEqual(fromBufferKey(toBufferKey(1503579323825.3523532)), 1503579323825.3523532)
36
+ assert.strictEqual(fromBufferKey(toBufferKey(-1503579323825)), -1503579323825)
37
+ assert.strictEqual(fromBufferKey(toBufferKey(0.00005032)), 0.00005032)
38
+ assert.strictEqual(fromBufferKey(toBufferKey(-0.00005032)), -0.00005032)
39
+ assert.strictEqual(fromBufferKey(toBufferKey(0.00000000000000000000000005431)), 0.00000000000000000000000005431)
40
+ })
41
+ test('within buffer equivalence', () => {
42
+ let buffer = Buffer.alloc(1024, 0xff);
43
+ let length = writeKey(2002225, buffer, 0);
44
+ let position = length;
45
+ buffer[position++] = 0xff;
46
+ buffer[position++] = 0xff;
47
+ assert.strictEqual(readKey(buffer, 0, length), 2002225);
48
+ length = writeKey('hello, world', buffer, 0);
49
+ assert.strictEqual(readKey(buffer, 0, length), 'hello, world');
50
+ // ensure that reading the string didn't modify the buffer after the string (or is restored at least)
51
+ assert.strictEqual(buffer[length], 0xff);
52
+ });
53
+ test('number comparison', () => {
54
+ assertBufferComparison(toBufferKey(4), toBufferKey(5))
55
+ assertBufferComparison(toBufferKey(1503579323824), toBufferKey(1503579323825))
56
+ assertBufferComparison(toBufferKey(1.4), toBufferKey(2))
57
+ assertBufferComparison(toBufferKey(0.000000001), toBufferKey(0.00000001))
58
+ assertBufferComparison(toBufferKey(-4), toBufferKey(3))
59
+ assertBufferComparison(toBufferKey(0), toBufferKey(1))
60
+ assertBufferComparison(toBufferKey(-0.001), toBufferKey(0))
61
+ assertBufferComparison(toBufferKey(-0.001), toBufferKey(-0.000001))
62
+ assertBufferComparison(toBufferKey(-5236532532532), toBufferKey(-5236532532531))
63
+ })
64
+ test('bigint equivalence', () => {
65
+ assert.strictEqual(fromBufferKey(toBufferKey(-35913040084491349n)), -35913040084491349n)
66
+ assert.strictEqual(fromBufferKey(toBufferKey(6135421331404949076605986n)), 6135421331404949076605986n)
67
+ assert.strictEqual(fromBufferKey(toBufferKey(0xfffffffffffffffffffffn)), 0xfffffffffffffffffffffn)
68
+ assert.strictEqual(fromBufferKey(toBufferKey(12345678901234567890n)), 12345678901234567890n)
69
+ assert.deepEqual(fromBufferKey(toBufferKey([12345678901234567890n, 44])), [12345678901234567890n, 44])
70
+ assert.deepEqual(fromBufferKey(toBufferKey(['hi', 12345678901234567890n])), ['hi', 12345678901234567890n])
71
+ assert.deepEqual(fromBufferKey(toBufferKey([6135421331404949076605986n, 'after'])), [6135421331404949076605986n, 'after'])
72
+ assert.strictEqual(fromBufferKey(toBufferKey(132923456789012345678903533235253252353211125n)), 132923456789012345678903533235253252353211125n)
73
+ assert.strictEqual(fromBufferKey(toBufferKey(352n)), 352)
74
+ let num = 5325n
75
+ for (let i = 0; i < 1100; i++) {
76
+ num *= BigInt(Math.floor(random() * 3 + 1));
77
+ num -= BigInt(Math.floor(random() * 1000));
78
+ assert.strictEqual(BigInt(fromBufferKey(toBufferKey(num))), num)
79
+ assert.strictEqual(BigInt(fromBufferKey(toBufferKey(-num))), -num)
80
+ }
81
+ assert.strictEqual(fromBufferKey(toBufferKey(-352n)), -352)
82
+ })
83
+ test('bigint comparison', () => {
84
+ assertBufferComparison(toBufferKey(0xfffffffffffffffffffffn), toBufferKey(0x100fffffffffffffffffffn))
85
+ assertBufferComparison(toBufferKey(12345678901234567890), toBufferKey(12345678901234567890n))
86
+ assertBufferComparison(toBufferKey(6135421331404949076605986n), toBufferKey(6135421331404949076605987n))
87
+ assertBufferComparison(toBufferKey(-6135421331404949076605986n), toBufferKey(-6135421331404949076605985n))
88
+ assertBufferComparison(toBufferKey(-35913040084491349n), toBufferKey(-35913040084491348n))
89
+ })
90
+
91
+ test('string equivalence', () => {
92
+ assert.strictEqual(fromBufferKey(toBufferKey('4')), '4')
93
+ assert.strictEqual(fromBufferKey(toBufferKey('hello')), 'hello')
94
+ assert.strictEqual(fromBufferKey(toBufferKey('')), '')
95
+ assert.strictEqual(fromBufferKey(toBufferKey('\x00')), '\x00')
96
+ assert.strictEqual(fromBufferKey(toBufferKey('\x03test\x01\x00')), '\x03test\x01\x00')
97
+ assert.strictEqual(fromBufferKey(toBufferKey('prance 🧚🏻‍♀️🩷')), 'prance 🧚🏻‍♀️🩷')
98
+ })
99
+ test('string comparison', () => {
100
+ assertBufferComparison(toBufferKey('4'), toBufferKey('5'))
101
+ assertBufferComparison(toBufferKey('and'), toBufferKey('bad'))
102
+ assertBufferComparison(toBufferKey('hello'), toBufferKey('hello2'))
103
+ let buffer = Buffer.alloc(1024)
104
+ let end = writeKey(['this is a test', 5.25], buffer, 0)
105
+ })
106
+ test('boolean equivalence', () => {
107
+ assert.strictEqual(fromBufferKey(toBufferKey(true)), true)
108
+ assert.strictEqual(fromBufferKey(toBufferKey(false)), false)
109
+ })
110
+
111
+ test('multipart equivalence', () => {
112
+ assert.deepEqual(fromBufferKey(toBufferKey([4, 5])),
113
+ [4, 5])
114
+ assert.deepEqual(fromBufferKey(toBufferKey(['hello', 5.25])),
115
+ ['hello', 5.25])
116
+ assert.deepEqual(fromBufferKey(toBufferKey([5, 'hello', null, 5.25])),
117
+ [5, 'hello', null, 5.25])
118
+ assert.deepEqual(fromBufferKey(toBufferKey([true, 1503579323825])),
119
+ [true, 1503579323825])
120
+ assert.deepEqual(fromBufferKey(toBufferKey([-0.2525, 'sec\x00nd'])),
121
+ [-0.2525, 'sec\x00nd'])
122
+ assert.deepEqual(fromBufferKey(toBufferKey([-0.2525, '2nd', '3rd'])),
123
+ [-0.2525, '2nd', '3rd'])
124
+ })
125
+
126
+ test('multipart comparison', () => {
127
+ assertBufferComparison(
128
+ Buffer.concat([toBufferKey(4), Buffer.from([30]), toBufferKey(5)]),
129
+ Buffer.concat([toBufferKey(5), Buffer.from([30]), toBufferKey(5)]))
130
+ assertBufferComparison(
131
+ Buffer.concat([toBufferKey(4), Buffer.from([30]), toBufferKey(5)]),
132
+ Buffer.concat([toBufferKey(4), Buffer.from([30]), toBufferKey(6)]))
133
+ assertBufferComparison(
134
+ Buffer.concat([toBufferKey('and'), Buffer.from([30]), toBufferKey(5)]),
135
+ Buffer.concat([toBufferKey('and2'), Buffer.from([30]), toBufferKey(5)]))
136
+ assertBufferComparison(
137
+ Buffer.concat([toBufferKey(4), Buffer.from([30]), toBufferKey('and')]),
138
+ Buffer.concat([toBufferKey(4), Buffer.from([30]), toBufferKey('cat')]))
139
+ })
140
+ test('performance', () => {
141
+ let buffer = Buffer.alloc(1024)
142
+ let start = process.hrtime.bigint()
143
+ let end, value
144
+ for (let i = 0; i < 1000000; i++) {
145
+ end = writeKey('this is a test of a longer string to read and write', buffer, 0)
146
+ }
147
+ console.log('writeKey string time', nextTime(), end)
148
+ for (let i = 0; i < 1000000; i++) {
149
+ value = readKey(buffer, 0, end)
150
+ }
151
+ console.log('readKey string time', nextTime(), value)
152
+
153
+ for (let i = 0; i < 1000000; i++) {
154
+ end = writeKey(33456, buffer, 0)
155
+ }
156
+ console.log('writeKey number time', nextTime(), end)
157
+
158
+ for (let i = 0; i < 1000000; i++) {
159
+ value = readKey(buffer, 2, end)
160
+ }
161
+ console.log('readKey number time', nextTime(), value)
162
+
163
+ for (let i = 0; i < 1000000; i++) {
164
+ end = writeKey(['hello', 33456], buffer, 0)
165
+ }
166
+ console.log('writeKey array time', nextTime(), end, buffer.slice(0, end))
167
+
168
+ for (let i = 0; i < 1000000; i++) {
169
+ value = readKey(buffer, 0, end)
170
+ }
171
+ console.log('readKey array time', nextTime(), value)
172
+
173
+ function nextTime() {
174
+ let ns = process.hrtime.bigint()
175
+ let elapsed = ns - start
176
+ start = ns
177
+ return Number(elapsed) / 1000000 + 'ns'
178
+ }
179
+ })
180
+
181
+ })
package/dist/index.cjs CHANGED
@@ -212,7 +212,12 @@ function readKey(buffer, start, end, inSequence) {
212
212
  let size = end - position;
213
213
  let lowInt;
214
214
  if (size > 4) {
215
- lowInt = dataView.getInt32(position + 4);
215
+ lowInt = position + 8 <= buffer.length ? dataView.getInt32(position + 4) : (
216
+ buffer[position + 4] << 24 |
217
+ buffer[position + 5] << 16 |
218
+ buffer[position + 6] << 8 |
219
+ buffer[position + 7]
220
+ );
216
221
  highInt |= lowInt >>> 28;
217
222
  if (size <= 6) { // clear the last bits
218
223
  lowInt &= -0x10000;
@@ -372,7 +377,12 @@ const readString =
372
377
  position = getPosition();
373
378
  return value;
374
379
  };
375
- })((new Function('fromCharCode', 'let position; let readString = ' + makeStringBuilder() +
380
+ })((new Function('fromCharCode', 'let position; let pendingSurrogate; ' +
381
+ // finishUtf8 references `position`/`pendingSurrogate`, but new Function compiles
382
+ // in global scope and can't close over the module-level copies, so embed its
383
+ // source here to bind it to this function's local (synced) `position`.
384
+ 'let finishUtf8 = ' + finishUtf8.toString() + '; ' +
385
+ 'let readString = ' + makeStringBuilder() +
376
386
  ';return {' +
377
387
  'setPosition(p) { position = p },' +
378
388
  'getPosition() { return position },' +
package/index.js CHANGED
@@ -208,7 +208,12 @@ export function readKey(buffer, start, end, inSequence) {
208
208
  let size = end - position
209
209
  let lowInt
210
210
  if (size > 4) {
211
- lowInt = dataView.getInt32(position + 4)
211
+ lowInt = position + 8 <= buffer.length ? dataView.getInt32(position + 4) : (
212
+ buffer[position + 4] << 24 |
213
+ buffer[position + 5] << 16 |
214
+ buffer[position + 6] << 8 |
215
+ buffer[position + 7]
216
+ )
212
217
  highInt |= lowInt >>> 28
213
218
  if (size <= 6) { // clear the last bits
214
219
  lowInt &= -0x10000
@@ -368,7 +373,12 @@ const readString =
368
373
  position = getPosition();
369
374
  return value;
370
375
  };
371
- })((new Function('fromCharCode', 'let position; let readString = ' + makeStringBuilder() +
376
+ })((new Function('fromCharCode', 'let position; let pendingSurrogate; ' +
377
+ // finishUtf8 references `position`/`pendingSurrogate`, but new Function compiles
378
+ // in global scope and can't close over the module-level copies, so embed its
379
+ // source here to bind it to this function's local (synced) `position`.
380
+ 'let finishUtf8 = ' + finishUtf8.toString() + '; ' +
381
+ 'let readString = ' + makeStringBuilder() +
372
382
  ';return {' +
373
383
  'setPosition(p) { position = p },' +
374
384
  'getPosition() { return position },' +
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ordered-binary",
3
3
  "author": "Kris Zyp",
4
- "version": "1.6.0",
4
+ "version": "1.6.2",
5
5
  "description": "Conversion of JavaScript primitives to and from Buffer with binary order matching natural primitive order",
6
6
  "license": "MIT",
7
7
  "repository": {
package/tests/test.js CHANGED
@@ -28,6 +28,8 @@ suite('key buffers', () => {
28
28
  assert.strictEqual(fromBufferKey(toBufferKey(3.4)), 3.4)
29
29
  assert.strictEqual(fromBufferKey(toBufferKey(Math.PI)), Math.PI)
30
30
  assert.strictEqual(fromBufferKey(toBufferKey(2002225)), 2002225)
31
+ // check to make sure it works with a limited ArrayBuffer
32
+ assert.strictEqual(fromBufferKey(new Uint8Array(toBufferKey(2002225))), 2002225)
31
33
  assert.strictEqual(fromBufferKey(toBufferKey(9377288)), 9377288)
32
34
  assert.strictEqual(fromBufferKey(toBufferKey(1503579323825)), 1503579323825)
33
35
  assert.strictEqual(fromBufferKey(toBufferKey(1503579323825.3523532)), 1503579323825.3523532)