├── .airtap.yml ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── index.js ├── package.json └── test.js /.airtap.yml: -------------------------------------------------------------------------------- 1 | sauce_connect: true 2 | browsers: 3 | - name: chrome 4 | version: 39..latest 5 | - name: firefox 6 | version: 34..latest 7 | - name: safari 8 | version: 8..latest 9 | - name: ie 10 | version: 10..latest 11 | - name: MicrosoftEdge 12 | version: 13..latest 13 | - name: iphone 14 | version: 9.3..latest 15 | - name: android 16 | version: 4.4..6.0 # TODO: change this back to latest once https://github.com/airtap/browsers/issues/3 is fixed -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | npm-debug.log 4 | .airtaprc 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "node" 4 | addons: 5 | sauce_connect: true 6 | hosts: 7 | - airtap.local -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2016 John Hiesey 4 | 5 | Permission is hereby granted, free of charge, 6 | to any person obtaining a copy of this software and 7 | associated documentation files (the "Software"), to 8 | deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, 10 | merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom 12 | the Software is furnished to do so, 13 | subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice 16 | shall be included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 22 | ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # to-arraybuffer [![Build Status](https://travis-ci.org/jhiesey/to-arraybuffer.svg?branch=master)](https://travis-ci.org/jhiesey/to-arraybuffer) 2 | 3 | [![Sauce Test Status](https://saucelabs.com/browser-matrix/to-arraybuffer.svg)](https://saucelabs.com/u/to-arraybuffer) 4 | 5 | Convert from a Buffer to an ArrayBuffer as fast as possible. 6 | 7 | Note that in some cases the returned ArrayBuffer is backed by the same memory as the original 8 | Buffer (but in other cases it is a copy), so **modifying the ArrayBuffer is not recommended**. 9 | 10 | This module is designed to work both in node.js and in all browsers with ArrayBuffer support 11 | when using [the Buffer implementation provided by Browserify](https://www.npmjs.com/package/buffer). 12 | 13 | ## Usage 14 | 15 | ``` js 16 | var toArrayBuffer = require('to-arraybuffer') 17 | 18 | var buffer = new Buffer(100) 19 | // Fill the buffer with some data 20 | 21 | var ab = toArrayBuffer(buffer) 22 | // `ab` now contains the same data as `buffer` 23 | ``` 24 | 25 | ## License 26 | 27 | MIT -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var Buffer = require('buffer').Buffer 2 | 3 | module.exports = function (buf) { 4 | // If the buffer is backed by a Uint8Array, a faster version will work 5 | if (buf instanceof Uint8Array) { 6 | // If the buffer isn't a subarray, return the underlying ArrayBuffer 7 | if (buf.byteOffset === 0 && buf.byteLength === buf.buffer.byteLength) { 8 | return buf.buffer 9 | } else if (typeof buf.buffer.slice === 'function') { 10 | // Otherwise we need to get a proper copy 11 | return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength) 12 | } 13 | } 14 | 15 | if (Buffer.isBuffer(buf)) { 16 | // This is the slow version that will work with any Buffer 17 | // implementation (even in old browsers) 18 | var arrayCopy = new Uint8Array(buf.length) 19 | var len = buf.length 20 | for (var i = 0; i < len; i++) { 21 | arrayCopy[i] = buf[i] 22 | } 23 | return arrayCopy.buffer 24 | } else { 25 | throw new Error('Argument must be a Buffer') 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "to-arraybuffer", 3 | "version": "1.0.1", 4 | "description": "Get an ArrayBuffer from a Buffer as fast as possible", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "npm run test-node && ([ -n \"${TRAVIS_PULL_REQUEST}\" -a \"${TRAVIS_PULL_REQUEST}\" != 'false' ] || npm run test-browser)", 8 | "test-node": "tape test.js", 9 | "test-browser": "airtap --loopback airtap.local -- test.js", 10 | "test-browser-local": "airtap --no-instrument --local 8080 -- test.js" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git://github.com/jhiesey/to-arraybuffer.git" 15 | }, 16 | "keywords": [ 17 | "buffer", 18 | "to", 19 | "arraybuffer", 20 | "fast", 21 | "read", 22 | "only" 23 | ], 24 | "author": "John Hiesey", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/jhiesey/to-arraybuffer/issues" 28 | }, 29 | "homepage": "https://github.com/jhiesey/to-arraybuffer#readme", 30 | "devDependencies": { 31 | "airtap": "^0.0.5", 32 | "tape": "^4.9.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var Buffer = require('buffer').Buffer 2 | var test = require('tape') 3 | 4 | var toArrayBuffer = require('.') 5 | 6 | function elementsEqual (ab, buffer) { 7 | var view = new Uint8Array(ab) 8 | for (var i = 0; i < view.length; i++) { 9 | if (view[i] !== buffer[i]) { 10 | return false 11 | } 12 | } 13 | return true 14 | } 15 | 16 | test('Basic behavior', function (t) { 17 | var buf = new Buffer(10) 18 | for (var i = 0; i < 10; i++) { 19 | buf[i] = i 20 | } 21 | 22 | var ab = toArrayBuffer(buf) 23 | 24 | t.equals(ab.byteLength, 10, 'correct length') 25 | t.ok(elementsEqual(ab, buf), 'elements equal') 26 | t.end() 27 | }) 28 | 29 | test('Behavior when input is a subarray 1', function (t) { 30 | var origBuf = new Buffer(10) 31 | for (var i = 0; i < 10; i++) { 32 | origBuf[i] = i 33 | } 34 | var buf = origBuf.slice(1) 35 | 36 | var ab = toArrayBuffer(buf) 37 | 38 | t.equals(ab.byteLength, 9, 'correct length') 39 | t.ok(elementsEqual(ab, buf), 'elements equal') 40 | t.notOk(ab === buf.buffer, 'the underlying ArrayBuffer is not returned when incorrect') 41 | t.end() 42 | }) 43 | 44 | test('Behavior when input is a subarray 2', function (t) { 45 | var origBuf = new Buffer(10) 46 | for (var i = 0; i < 10; i++) { 47 | origBuf[i] = i 48 | } 49 | var buf = origBuf.slice(0, 9) 50 | 51 | var ab = toArrayBuffer(buf) 52 | 53 | t.equals(ab.byteLength, 9, 'correct length') 54 | t.ok(elementsEqual(ab, buf), 'elements equal') 55 | t.notOk(ab === buf.buffer, 'the underlying ArrayBuffer is not returned when incorrect') 56 | t.end() 57 | }) 58 | --------------------------------------------------------------------------------