Skip to content

Commit

Permalink
Support big endian machines (trie file in LE) (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
liborm85 authored and devongovett committed Nov 17, 2019
1 parent 98df04c commit fc9ea64
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 9 deletions.
11 changes: 8 additions & 3 deletions builder.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const UnicodeTrie = require('./');
const pako = require('pako');
const { swap32LE } = require('./swap');

// Shift size for getting the index-1 table offset.
const SHIFT_1 = 6 + 5;
Expand Down Expand Up @@ -942,13 +943,17 @@ class UnicodeTrieBuilder {
const trie = this.freeze();

const data = new Uint8Array(trie.data.buffer);

// swap bytes to little-endian
swap32LE(data);

let compressed = pako.deflateRaw(data);
compressed = pako.deflateRaw(compressed);

const buf = Buffer.alloc(compressed.length + 12);
buf.writeUInt32BE(trie.highStart, 0);
buf.writeUInt32BE(trie.errorValue, 4);
buf.writeUInt32BE(data.length, 8);
buf.writeUInt32LE(trie.highStart, 0);
buf.writeUInt32LE(trie.errorValue, 4);
buf.writeUInt32LE(data.length, 8);
for (let i = 0; i < compressed.length; i++) {
const b = compressed[i];
buf[i + 12] = b;
Expand Down
17 changes: 11 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const inflate = require('tiny-inflate');
const { swap32LE } = require('./swap');

// Shift size for getting the index-1 table offset.
const SHIFT_1 = 6 + 5;
Expand Down Expand Up @@ -70,21 +71,25 @@ class UnicodeTrie {
// read binary format
let uncompressedLength;
if (isBuffer) {
this.highStart = data.readUInt32BE(0);
this.errorValue = data.readUInt32BE(4);
uncompressedLength = data.readUInt32BE(8);
this.highStart = data.readUInt32LE(0);
this.errorValue = data.readUInt32LE(4);
uncompressedLength = data.readUInt32LE(8);
data = data.slice(12);
} else {
const view = new DataView(data.buffer);
this.highStart = view.getUint32(0);
this.errorValue = view.getUint32(4);
uncompressedLength = view.getUint32(8);
this.highStart = view.getUint32(0, true);
this.errorValue = view.getUint32(4, true);
uncompressedLength = view.getUint32(8, true);
data = data.subarray(12);
}

// double inflate the actual trie data
data = inflate(data, new Uint8Array(uncompressedLength));
data = inflate(data, new Uint8Array(uncompressedLength));

// swap bytes from little-endian
swap32LE(data);

this.data = new Uint32Array(data.buffer);

} else {
Expand Down
25 changes: 25 additions & 0 deletions swap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const isBigEndian = (new Uint8Array(new Uint32Array([0x12345678]).buffer)[0] === 0x12);

const swap = (b, n, m) => {
let i = b[n];
b[n] = b[m];
b[m] = i;
};

const swap32 = array => {
const len = array.length;
for (let i = 0; i < len; i += 4) {
swap(array, i, i + 3);
swap(array, i + 1, i + 2);
}
};

const swap32LE = array => {
if (isBigEndian) {
swap32(array);
}
};

module.exports = {
swap32LE: swap32LE
};
9 changes: 9 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ describe('unicode trie', () => {
assert.equal(trie.get(0x110000), 666);
});

it('toBuffer written in little-endian', () => {
const trie = new UnicodeTrieBuilder();
trie.set(0x4567, 99);

const buf = trie.toBuffer();
const bufferExpected = new Buffer.from([0, 72, 0, 0, 0, 0, 0, 0, 128, 36, 0, 0, 123, 123, 206, 144, 235, 128, 2, 143, 67, 96, 225, 171, 23, 55, 54, 38, 231, 47, 44, 127, 233, 90, 109, 194, 92, 246, 126, 197, 131, 223, 31, 56, 102, 78, 154, 20, 108, 117, 88, 244, 93, 192, 190, 218, 229, 156, 12, 107, 86, 235, 125, 96, 102, 0, 129, 15, 239, 109, 219, 204, 58, 151, 92, 52, 126, 152, 198, 14, 0]);
assert.equal(buf.toString('hex'), bufferExpected.toString('hex'));
});

it('should work with compressed serialization format', () => {
const t = new UnicodeTrieBuilder(10, 666);
t.setRange(13, 6666, 7788, false);
Expand Down

0 comments on commit fc9ea64

Please sign in to comment.