├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── example.js ├── index.js ├── package.json └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '10' 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Mathias Buus 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # convert-endianness 2 | 3 | Easily convert Little/Big endian typed arrays to the host endianness or back. 4 | 5 | ``` 6 | npm install convert-endianness 7 | ``` 8 | 9 | The endianness of typed arrays is host specific. This might be an issue 10 | if you want to send them over the wire or persist them to disk. This 11 | module makes it easily to guarantee an endianness. 12 | 13 | ## Usage 14 | 15 | ``` js 16 | const endianness = require('convert-endianness') 17 | 18 | const arr = new Int32Array(2) 19 | 20 | arr[0] = 10 21 | arr[1] = 1000000 22 | 23 | console.log('as host:', arr) 24 | 25 | // ensures the endianness of arr is big endian 26 | endianness.hostToBE(arr) 27 | 28 | // if your machine is LE (prob is) then array has changed 29 | console.log('as BE:', arr) 30 | 31 | // convert it back to the host endianness 32 | endianness.BEToHost(arr) 33 | 34 | console.log('as host again:', arr) 35 | ``` 36 | 37 | ## API 38 | 39 | #### `endianness.hostToLE(typedArray)` 40 | 41 | Converts the endianness of the typed array to little endian. 42 | If your machine is little endian, this is a noop. 43 | 44 | #### `endianness.LEToHost(typedArray)` 45 | 46 | Converts the endianness of the typed array from little endian to your host endian. 47 | If your machine is little endian, this is a noop. 48 | 49 | #### `endianness.hostToBE(typedArray)` 50 | 51 | Converts the endianness of the typed array to big endian. 52 | If your machine is big endian, this is a noop. 53 | 54 | #### `endianness.BEToHost(typedArray)` 55 | 56 | Converts the endianness of the typed array from big endian to your host endian. 57 | If your machine is big endian, this is a noop. 58 | 59 | #### `endianness.LE` 60 | 61 | True if your machine is little endian. 62 | 63 | #### `endianness.BE` 64 | 65 | True if your machine is big endian. 66 | 67 | ## License 68 | 69 | MIT 70 | -------------------------------------------------------------------------------- /example.js: -------------------------------------------------------------------------------- 1 | const endianness = require('./') 2 | 3 | const arr = new Int32Array(2) 4 | 5 | arr[0] = 10 6 | arr[1] = 1000000 7 | 8 | console.log('as host:', arr) 9 | 10 | // ensures the endianness of arr is big endian 11 | endianness.hostToBE(arr) 12 | 13 | // if your machine is LE (prob is) then array has changed 14 | console.log('as BE:', arr) 15 | 16 | // convert it back to the host endianness 17 | endianness.BEToHost(arr) 18 | 19 | console.log('as host again:', arr) 20 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const LE = (new Uint8Array(new Uint16Array([255]).buffer))[0] === 0xff 2 | const BE = !LE 3 | 4 | exports.LE = LE 5 | exports.BE = BE 6 | 7 | exports.LEToHost = LE ? noop : otherToHost 8 | exports.hostToLE = LE ? noop : hostToOther 9 | 10 | exports.LEToHost16 = LE ? noop : otherToHost16 11 | exports.hostToLE16 = LE ? noop : hostToOther16 12 | 13 | exports.LEToHost32 = LE ? noop : otherToHost32 14 | exports.hostToLE32 = LE ? noop : hostToOther32 15 | 16 | exports.LEToHost64 = LE ? noop : otherToHost64 17 | exports.hostToLE64 = LE ? noop : hostToOther64 18 | 19 | exports.BEToHost = BE ? noop : otherToHost 20 | exports.hostToBE = BE ? noop : hostToOther 21 | 22 | exports.BEToHost16 = BE ? noop : otherToHost16 23 | exports.hostToBE16 = BE ? noop : hostToOther16 24 | 25 | exports.BEToHost32 = BE ? noop : otherToHost32 26 | exports.hostToBE32 = BE ? noop : hostToOther32 27 | 28 | exports.BEToHost64 = BE ? noop : otherToHost64 29 | exports.hostToBE64 = BE ? noop : hostToOther64 30 | 31 | function otherToHost (arr, n) { 32 | if (!n) n = 8 * arr.BYTES_PER_ELEMENT 33 | 34 | switch (n) { 35 | case 16: return otherToHost16(arr) 36 | case 32: return otherToHost32(arr) 37 | case 64: return otherToHost64(arr) 38 | } 39 | 40 | throw new Error('Number of bits must be 16, 32 or 64') 41 | } 42 | 43 | function hostToOther (arr, n) { 44 | if (!n) n = 8 * arr.BYTES_PER_ELEMENT 45 | 46 | switch (n) { 47 | case 16: return hostToOther16(arr) 48 | case 32: return hostToOther32(arr) 49 | case 64: return hostToOther64(arr) 50 | } 51 | 52 | throw new Error('Number of bits must be 16, 32 or 64') 53 | } 54 | 55 | function otherToHost16 (arr) { 56 | const view = new DataView(arr.buffer, arr.byteOffset) 57 | const host = new Uint16Array(arr.buffer, arr.byteOffset, arr.byteLength / 2) 58 | 59 | for (var i = 0; i < host.length; i++) { 60 | host[i] = view.getUint16(2 * i, BE) 61 | } 62 | } 63 | 64 | function hostToOther16 (arr) { 65 | const view = new DataView(arr.buffer, arr.byteOffset) 66 | const host = new Uint16Array(arr.buffer, arr.byteOffset, arr.byteLength / 2) 67 | 68 | for (var i = 0; i < host.length; i++) { 69 | view.setUint16(2 * i, host[i], BE) 70 | } 71 | } 72 | 73 | function otherToHost32 (arr) { 74 | const view = new DataView(arr.buffer, arr.byteOffset) 75 | const host = new Uint32Array(arr.buffer, arr.byteOffset, arr.byteLength / 4) 76 | 77 | for (var i = 0; i < host.length; i++) { 78 | host[i] = view.getUint32(4 * i, BE) 79 | } 80 | } 81 | 82 | function hostToOther32 (arr) { 83 | const view = new DataView(arr.buffer, arr.byteOffset) 84 | const host = new Uint32Array(arr.buffer, arr.byteOffset, arr.byteLength / 4) 85 | 86 | for (var i = 0; i < host.length; i++) { 87 | view.setUint32(4 * i, host[i], BE) 88 | } 89 | } 90 | 91 | function otherToHost64 (arr) { 92 | const view = new DataView(arr.buffer, arr.byteOffset) 93 | const host = new BigUint64Array(arr.buffer, arr.byteOffset, arr.byteLength / 8) 94 | 95 | for (var i = 0; i < host.length; i++) { 96 | host[i] = view.getBigUint64(8 * i, BE) 97 | } 98 | } 99 | 100 | function hostToOther64 (arr) { 101 | const view = new DataView(arr.buffer, arr.byteOffset) 102 | const host = new BigUint64Array(arr.buffer, arr.byteOffset, arr.byteLength / 8) 103 | 104 | for (var i = 0; i < host.length; i++) { 105 | view.setBigUint64(8 * i, host[i], BE) 106 | } 107 | } 108 | 109 | function noop (arr) {} 110 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "convert-endianness", 3 | "version": "1.0.0", 4 | "description": "Easily convert Little/Big endian typed arrays to the host endianness", 5 | "main": "index.js", 6 | "dependencies": {}, 7 | "devDependencies": { 8 | "tape": "^4.9.1" 9 | }, 10 | "scripts": { 11 | "test": "tape test.js" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/mafintosh/convert-endianness.git" 16 | }, 17 | "author": "Mathias Buus (@mafintosh)", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/mafintosh/convert-endianness/issues" 21 | }, 22 | "homepage": "https://github.com/mafintosh/convert-endianness" 23 | } 24 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | const endianness = require('./') 2 | const tape = require('tape') 3 | 4 | tape('le -> host', function (t) { 5 | const buf = new ArrayBuffer(16) 6 | const view = new DataView(buf) 7 | const u16 = new Uint16Array(buf) 8 | const i16 = new Int16Array(buf) 9 | const u32 = new Uint32Array(buf) 10 | const i32 = new Int32Array(buf) 11 | const u64 = new BigUint64Array(buf) 12 | const i64 = new BigInt64Array(buf) 13 | 14 | view.setUint16(0, 400, true) 15 | view.setUint16(2, 40, true) 16 | 17 | endianness.LEToHost(u16) 18 | t.same(u16[0], 400) 19 | t.same(u16[1], 40) 20 | 21 | view.setInt16(0, -400, true) 22 | view.setInt16(2, 40, true) 23 | 24 | endianness.LEToHost(i16) 25 | t.same(i16[0], -400) 26 | t.same(i16[1], 40) 27 | 28 | view.setUint32(0, 400000, true) 29 | view.setUint32(4, 400, true) 30 | 31 | endianness.LEToHost(u32) 32 | t.same(u32[0], 400000) 33 | t.same(u32[1], 400) 34 | 35 | view.setInt32(0, -400000, true) 36 | view.setInt32(4, 400, true) 37 | 38 | endianness.LEToHost(i32) 39 | t.same(i32[0], -400000) 40 | t.same(i32[1], 400) 41 | 42 | view.setBigUint64(0, 40000000000n, true) 43 | view.setBigUint64(8, 400n, true) 44 | 45 | endianness.LEToHost(u64) 46 | t.same(u64[0], 40000000000n) 47 | t.same(u64[1], 400n) 48 | 49 | view.setBigInt64(0, -40000000000n, true) 50 | view.setBigInt64(8, 400n, true) 51 | 52 | endianness.LEToHost(i64) 53 | t.same(i64[0], -40000000000n) 54 | t.same(i64[1], 400n) 55 | 56 | t.end() 57 | }) 58 | 59 | tape('be -> host', function (t) { 60 | const buf = new ArrayBuffer(16) 61 | const view = new DataView(buf) 62 | const u16 = new Uint16Array(buf) 63 | const i16 = new Int16Array(buf) 64 | const u32 = new Uint32Array(buf) 65 | const i32 = new Int32Array(buf) 66 | const u64 = new BigUint64Array(buf) 67 | const i64 = new BigInt64Array(buf) 68 | 69 | view.setUint16(0, 400, false) 70 | view.setUint16(2, 40, false) 71 | 72 | endianness.BEToHost(u16) 73 | t.same(u16[0], 400) 74 | t.same(u16[1], 40) 75 | 76 | view.setInt16(0, -400, false) 77 | view.setInt16(2, 40, false) 78 | 79 | endianness.BEToHost(i16) 80 | t.same(i16[0], -400) 81 | t.same(i16[1], 40) 82 | 83 | view.setUint32(0, 400000, false) 84 | view.setUint32(4, 400, false) 85 | 86 | endianness.BEToHost(u32) 87 | t.same(u32[0], 400000) 88 | t.same(u32[1], 400) 89 | 90 | view.setInt32(0, -400000, false) 91 | view.setInt32(4, 400, false) 92 | 93 | endianness.BEToHost(i32) 94 | t.same(i32[0], -400000) 95 | t.same(i32[1], 400) 96 | 97 | view.setBigUint64(0, 40000000000n, false) 98 | view.setBigUint64(8, 400n, false) 99 | 100 | endianness.BEToHost(u64) 101 | t.same(u64[0], 40000000000n) 102 | t.same(u64[1], 400n) 103 | 104 | view.setBigInt64(0, -40000000000n, false) 105 | view.setBigInt64(8, 400n, false) 106 | 107 | endianness.BEToHost(i64) 108 | t.same(i64[0], -40000000000n) 109 | t.same(i64[1], 400n) 110 | 111 | t.end() 112 | }) 113 | --------------------------------------------------------------------------------