├── .eslintrc.json ├── .gitignore ├── .travis.yml ├── browser.js ├── index.js ├── package.json ├── readme.md └── test.js /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "node": true, 5 | "commonjs": true, 6 | "es6": true 7 | }, 8 | "extends": "eslint:recommended", 9 | "rules": { 10 | "strict": 2, 11 | "indent": 0, 12 | "linebreak-style": 0, 13 | "quotes": 0, 14 | "semi": 0, 15 | "no-cond-assign": 1, 16 | "no-constant-condition": 1, 17 | "no-duplicate-case": 1, 18 | "no-empty": 1, 19 | "no-ex-assign": 1, 20 | "no-extra-boolean-cast": 1, 21 | "no-extra-semi": 1, 22 | "no-fallthrough": 1, 23 | "no-func-assign": 1, 24 | "no-global-assign": 1, 25 | "no-implicit-globals": 2, 26 | "no-inner-declarations": ["error", "functions"], 27 | "no-irregular-whitespace": 2, 28 | "no-loop-func": 1, 29 | "no-magic-numbers": ["warn", { "ignore": [1, 0, -1], "ignoreArrayIndexes": true}], 30 | "no-multi-str": 1, 31 | "no-mixed-spaces-and-tabs": 1, 32 | "no-proto": 1, 33 | "no-sequences": 1, 34 | "no-throw-literal": 1, 35 | "no-unmodified-loop-condition": 1, 36 | "no-useless-call": 1, 37 | "no-void": 1, 38 | "no-with": 2, 39 | "wrap-iife": 1, 40 | "no-redeclare": 1, 41 | "no-unused-vars": ["error", { "vars": "all", "args": "none" }], 42 | "no-sparse-arrays": 1 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | *.log 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '6' 4 | - '5' 5 | - '4' 6 | -------------------------------------------------------------------------------- /browser.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @module arraybuffer-to-string/browser 3 | */ 4 | 5 | 'use strict' 6 | 7 | module.exports = function ArrayBufferToString (buffer, encoding) { 8 | if (encoding == null) encoding = 'utf8' 9 | 10 | var uint8 = new Uint8Array(buffer) 11 | 12 | if (encoding === 'hex') { 13 | var out = '' 14 | for (var i = 0, l = uint8.byteLength; i < l; ++i) { 15 | out += toHex(uint8[i]) 16 | } 17 | return out 18 | } 19 | 20 | if (encoding === 'base64') { 21 | str = String.fromCharCode.apply(null, uint8) 22 | return btoa(str) 23 | } 24 | 25 | if (encoding === 'binary' || 26 | encoding === 'latin1' || 27 | !global.TextDecoder) { 28 | str = String.fromCharCode.apply(null, uint8) 29 | return str 30 | } 31 | 32 | 33 | //TextDecoder way 34 | if (encoding === 'utf16le') encoding = 'utf-16le' 35 | 36 | var decoder = new TextDecoder(encoding) 37 | var str = decoder.decode(uint8) 38 | return str 39 | } 40 | 41 | 42 | function toHex (n) { 43 | if (n < 16) return '0' + n.toString(16) 44 | return n.toString(16) 45 | } 46 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @module arraybuffer-to-string 3 | */ 4 | 5 | 'use strict' 6 | 7 | module.exports = function ArrayBufferToString (buffer, encoding) { 8 | if (encoding == null) encoding = 'utf8' 9 | 10 | return Buffer.from(buffer).toString(encoding) 11 | } 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "arraybuffer-to-string", 3 | "version": "1.0.2", 4 | "description": "Convert ArrayBuffer to string", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "node test.js" 8 | }, 9 | "browser": "./browser.js", 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/dy/arraybuffer-to-string.git" 13 | }, 14 | "keywords": [ 15 | "arraybuffer", 16 | "array-buffer", 17 | "array", 18 | "buffer", 19 | "string", 20 | "base64", 21 | "atob", 22 | "btoa", 23 | "datauri" 24 | ], 25 | "author": "Dima Yv ", 26 | "license": "MIT", 27 | "bugs": { 28 | "url": "https://github.com/dy/arraybuffer-to-string/issues" 29 | }, 30 | "homepage": "https://github.com/dy/arraybuffer-to-string#readme", 31 | "devDependencies": { 32 | "buffer-to-arraybuffer": "0.0.4", 33 | "is-browser": "^2.0.1", 34 | "string-to-arraybuffer": "^1.0.0", 35 | "tape": "^4.7.0" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # arraybuffer-to-string [![unstable](https://img.shields.io/badge/stability-unstable-orange.svg)](http://github.com/badges/stability-badges) [![Build Status](https://img.shields.io/travis/dy/arraybuffer-to-string.svg)](https://travis-ci.org/dy/arraybuffer-to-string) 2 | 3 | Convert _ArrayBuffer_ to string with optional encoding. 4 | 5 | [![npm install arraybuffer-to-string](https://nodei.co/npm/arraybuffer-to-string.png?mini=true)](https://npmjs.org/package/arraybuffer-to-string/) 6 | 7 | ```js 8 | var ab2str = require('arraybuffer-to-string') 9 | 10 | var uint8 = new Uint8Array([ 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33 ]) 11 | 12 | ab2str(uint8) // 'Hello World!' 13 | ab2str(uint8, 'base64') // 'SGVsbG8gV29ybGQh' 14 | ab2str(uint8, 'hex') // '48656c6c6f20576f726c6421' 15 | ab2str(uint8, 'iso-8859-2') // 'Hello World!' 16 | ``` 17 | 18 | ### var str = arrayBufferToString(buffer, encoding='utf8') 19 | 20 | Convert ArrayBuffer/ArrayBufferView/Array `buffer` to string with defined encoding. Available encoding: `utf8`, `binary`, `base64`, `hex`, `ascii`, `latin1`, `ucs2`, `utf16` and [many others](https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder/encoding). 21 | 22 | Note: in browser it relies on [TextDecoder API](https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder/decode), so if you are dealing with charsets other than `utf8`, `ascii`, `binary` or `base64` in old browsers, please include [encoding polyfill](https://github.com/inexorabletash/text-encoding). 23 | 24 | ### Related 25 | 26 | * [string-to-arraybuffer](https://github.com/dy/string-to-arraybuffer) − convert string to arraybuffer. 27 | * [create-data-uri](https://www.npmjs.com/package/create-data-uri) − convert binary data to datauri string. 28 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | 4 | var toString = require('./'); 5 | var t = require('tape') 6 | var b2ab = require('buffer-to-arraybuffer') 7 | var isBrowser = require('is-browser') 8 | var str2ab = require('string-to-arraybuffer') 9 | 10 | t('basics', t => { 11 | t.equal( 12 | toString(new Uint8Array([ 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33 ])), 13 | 'Hello World!' 14 | ) 15 | t.end() 16 | }) 17 | 18 | t('utf8 buffer to base64', function (t) { 19 | t.equal( 20 | toString(b2ab(Buffer.from('Ձאab', 'utf8')), 'base64'), 21 | '1YHXkGFi' 22 | ) 23 | t.end() 24 | }) 25 | 26 | t('utf8 buffer to hex', function (t) { 27 | t.equal( 28 | toString(b2ab(Buffer.from('Ձאab', 'utf8')), 'hex'), 29 | 'd581d7906162' 30 | ) 31 | t.end() 32 | }) 33 | 34 | t('utf8 to utf8', function (t) { 35 | t.equal( 36 | toString(b2ab(Buffer.from('öäüõÖÄÜÕ', 'utf8')), 'utf8'), 37 | 'öäüõÖÄÜÕ' 38 | ) 39 | t.end() 40 | }) 41 | 42 | t('utf16le to utf16', function (t) { 43 | t.equal( 44 | toString(b2ab(Buffer.from(toString(b2ab(Buffer.from('abcd', 'utf8')), 'utf16le'), 'utf16le')), 'utf8'), 45 | 'abcd' 46 | ) 47 | t.end() 48 | }) 49 | 50 | t('utf16le to hex', function (t) { 51 | t.equal( 52 | toString(b2ab(Buffer.from('abcd', 'utf16le')), 'hex'), 53 | '6100620063006400' 54 | ) 55 | t.end() 56 | }) 57 | 58 | t('ascii buffer to base64', function (t) { 59 | t.equal( 60 | toString(b2ab(Buffer.from('123456!@#$%^', 'ascii')), 'base64'), 61 | 'MTIzNDU2IUAjJCVe' 62 | ) 63 | t.end() 64 | }) 65 | 66 | t('ascii buffer to hex', function (t) { 67 | t.equal( 68 | toString(b2ab(Buffer.from('123456!@#$%^', 'ascii')), 'hex'), 69 | '31323334353621402324255e' 70 | ) 71 | t.end() 72 | }) 73 | 74 | t('base64 buffer to utf8', function (t) { 75 | t.equal( 76 | toString(b2ab(Buffer.from('1YHXkGFi', 'base64')), 'utf8'), 77 | 'Ձאab' 78 | ) 79 | t.end() 80 | }) 81 | 82 | t('hex buffer to utf8', function (t) { 83 | t.equal( 84 | toString(b2ab(Buffer.from('d581d7906162', 'hex')), 'utf8'), 85 | 'Ձאab' 86 | ) 87 | t.end() 88 | }) 89 | 90 | t('base64 buffer to ascii', function (t) { 91 | t.equal( 92 | toString(b2ab(Buffer.from('MTIzNDU2IUAjJCVe', 'base64')), 'ascii'), 93 | '123456!@#$%^' 94 | ) 95 | t.end() 96 | }) 97 | 98 | t('hex buffer to ascii', function (t) { 99 | t.equal( 100 | toString(b2ab(Buffer.from('31323334353621402324255e', 'hex')), 'ascii'), 101 | '123456!@#$%^' 102 | ) 103 | t.end() 104 | }) 105 | 106 | t('base64 buffer to binary', function (t) { 107 | t.equal( 108 | toString(b2ab(Buffer.from('MTIzNDU2IUAjJCVe', 'base64')), 'binary'), 109 | '123456!@#$%^' 110 | ) 111 | t.end() 112 | }) 113 | 114 | t('hex buffer to binary', function (t) { 115 | t.equal( 116 | toString(b2ab(Buffer.from('31323334353621402324255e', 'hex')), 'binary'), 117 | '123456!@#$%^' 118 | ) 119 | t.end() 120 | }) 121 | 122 | t('utf8 to binary', function (t) { 123 | /* jshint -W100 */ 124 | t.equal( 125 | toString(b2ab(Buffer.from('öäüõÖÄÜÕ', 'utf8')), 'binary'), 126 | 'öäüõÖÄÜÕ' 127 | ) 128 | /* jshint +W100 */ 129 | t.end() 130 | }) 131 | 132 | t('utf8 replacement chars (1 byte sequence)', function (t) { 133 | t.equal( 134 | toString(b2ab(Buffer.from([ 0x80 ])) ), 135 | '\uFFFD' 136 | ) 137 | t.equal( 138 | toString(b2ab(Buffer.from([ 0x7F ])) ), 139 | '\u007F' 140 | ) 141 | t.end() 142 | }) 143 | 144 | t('utf8 replacement chars (2 byte sequences)', function (t) { 145 | t.equal( 146 | toString(b2ab(Buffer.from([ 0xC7 ])) ), 147 | '\uFFFD' 148 | ) 149 | t.equal( 150 | toString(b2ab(Buffer.from([ 0xC7, 0xB1 ])) ), 151 | '\u01F1' 152 | ) 153 | t.equal( 154 | toString(b2ab(Buffer.from([ 0xC0, 0xB1 ])) ), 155 | '\uFFFD\uFFFD' 156 | ) 157 | t.equal( 158 | toString(b2ab(Buffer.from([ 0xC1, 0xB1 ])) ), 159 | '\uFFFD\uFFFD' 160 | ) 161 | t.end() 162 | }) 163 | 164 | //FIXME: browser-only case in some reason 165 | isBrowser && t('utf8 replacement chars (3 byte sequences)', function (t) { 166 | t.equal( 167 | toString(b2ab(Buffer.from([ 0xE0 ])) ), 168 | '\uFFFD' 169 | ) 170 | t.equal( 171 | toString(Buffer.from([ 0xE0, 0xAC ]) ), 172 | // new Buffer([ 0xE0, 0xAC ]).toString(), 173 | '\uFFFD\uFFFD' 174 | ) 175 | t.equal( 176 | toString(b2ab(Buffer.from([ 0xE0, 0xAC, 0xB9 ])) ), 177 | '\u0B39' 178 | ) 179 | t.end() 180 | }) 181 | 182 | isBrowser && t('utf8 replacement chars (4 byte sequences)', function (t) { 183 | t.equal( 184 | toString(b2ab(Buffer.from([ 0xF4 ])) ), 185 | '\uFFFD' 186 | ) 187 | t.equal( 188 | toString(b2ab(Buffer.from([ 0xF4, 0x8F ])) ), 189 | '\uFFFD\uFFFD' 190 | ) 191 | t.equal( 192 | toString(b2ab(Buffer.from([ 0xF4, 0x8F, 0x80 ])) ), 193 | '\uFFFD\uFFFD\uFFFD' 194 | ) 195 | t.equal( 196 | toString(b2ab(Buffer.from([ 0xF4, 0x8F, 0x80, 0x84 ])) ), 197 | '\uDBFC\uDC04' 198 | ) 199 | t.equal( 200 | toString(b2ab(Buffer.from([ 0xFF ])) ), 201 | '\uFFFD' 202 | ) 203 | t.equal( 204 | toString(b2ab(Buffer.from([ 0xFF, 0x8F, 0x80, 0x84 ])) ), 205 | '\uFFFD\uFFFD\uFFFD\uFFFD' 206 | ) 207 | t.end() 208 | }) 209 | 210 | t.skip('bad utf part', t => { 211 | t.equal( 212 | toString(new Uint8Array([236, 134, 219])), 213 | '���' 214 | ) 215 | 216 | t.end() 217 | }) 218 | 219 | t.skip('utf8 replacement chars on 256 random bytes', function (t) { 220 | t.equal( 221 | toString(b2ab(Buffer.from([ 152, 130, 206, 23, 243, 238, 197, 44, 27, 86, 208, 36, 163, 184, 164, 21, 94, 242, 178, 46, 25, 26, 253, 178, 72, 147, 207, 112, 236, 68, 179, 190, 29, 83, 239, 147, 125, 55, 143, 19, 157, 68, 157, 58, 212, 224, 150, 39, 128, 24, 94, 225, 120, 121, 75, 192, 112, 19, 184, 142, 203, 36, 43, 85, 26, 147, 227, 139, 242, 186, 57, 78, 11, 102, 136, 117, 180, 210, 241, 92, 3, 215, 54, 167, 249, 1, 44, 225, 146, 86, 2, 42, 68, 21, 47, 238, 204, 153, 216, 252, 183, 66, 222, 255, 15, 202, 16, 51, 134, 1, 17, 19, 209, 76, 238, 38, 76, 19, 7, 103, 249, 5, 107, 137, 64, 62, 170, 57, 16, 85, 179, 193, 97, 86, 166, 196, 36, 148, 138, 193, 210, 69, 187, 38, 242, 97, 195, 219, 252, 244, 38, 1, 197, 18, 31, 246, 53, 47, 134, 52, 105, 72, 43, 239, 128, 203, 73, 93, 199, 75, 222, 220, 166, 34, 63, 236, 11, 212, 76, 243, 171, 110, 78, 39, 205, 204, 6, 177, 233, 212, 243, 0, 33, 41, 122, 118, 92, 252, 0, 157, 108, 120, 70, 137, 100, 223, 243, 171, 232, 66, 126, 111, 142, 33, 3, 39, 117, 27, 107, 54, 1, 217, 227, 132, 13, 166, 3, 73, 53, 127, 225, 236, 134, 219, 98, 214, 125, 148, 24, 64, 142, 111, 231, 194, 42, 150, 185, 10, 182, 163, 244, 19, 4, 59, 135, 16 ])) ), 222 | '\uFFFD\uFFFD\uFFFD\u0017\uFFFD\uFFFD\uFFFD\u002C\u001B\u0056\uFFFD\u0024\uFFFD\uFFFD\uFFFD\u0015\u005E\uFFFD\uFFFD\u002E\u0019\u001A\uFFFD\uFFFD\u0048\uFFFD\uFFFD\u0070\uFFFD\u0044\uFFFD\uFFFD\u001D\u0053\uFFFD\uFFFD\u007D\u0037\uFFFD\u0013\uFFFD\u0044\uFFFD\u003A\uFFFD\uFFFD\uFFFD\u0027\uFFFD\u0018\u005E\uFFFD\u0078\u0079\u004B\uFFFD\u0070\u0013\uFFFD\uFFFD\uFFFD\u0024\u002B\u0055\u001A\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0039\u004E\u000B\u0066\uFFFD\u0075\uFFFD\uFFFD\uFFFD\u005C\u0003\uFFFD\u0036\uFFFD\uFFFD\u0001\u002C\uFFFD\uFFFD\u0056\u0002\u002A\u0044\u0015\u002F\uFFFD\u0319\uFFFD\uFFFD\uFFFD\u0042\uFFFD\uFFFD\u000F\uFFFD\u0010\u0033\uFFFD\u0001\u0011\u0013\uFFFD\u004C\uFFFD\u0026\u004C\u0013\u0007\u0067\uFFFD\u0005\u006B\uFFFD\u0040\u003E\uFFFD\u0039\u0010\u0055\uFFFD\uFFFD\u0061\u0056\uFFFD\uFFFD\u0024\uFFFD\uFFFD\uFFFD\uFFFD\u0045\uFFFD\u0026\uFFFD\u0061\uFFFD\uFFFD\uFFFD\uFFFD\u0026\u0001\uFFFD\u0012\u001F\uFFFD\u0035\u002F\uFFFD\u0034\u0069\u0048\u002B\uFFFD\uFFFD\uFFFD\u0049\u005D\uFFFD\u004B\uFFFD\u0726\u0022\u003F\uFFFD\u000B\uFFFD\u004C\uFFFD\uFFFD\u006E\u004E\u0027\uFFFD\uFFFD\u0006\uFFFD\uFFFD\uFFFD\uFFFD\u0000\u0021\u0029\u007A\u0076\u005C\uFFFD\u0000\uFFFD\u006C\u0078\u0046\uFFFD\u0064\uFFFD\uFFFD\uFFFD\uFFFD\u0042\u007E\u006F\uFFFD\u0021\u0003\u0027\u0075\u001B\u006B\u0036\u0001\uFFFD\uFFFD\uFFFD\u000D\uFFFD\u0003\u0049\u0035\u007F\uFFFD\uFFFD\uFFFD\uFFFD\u0062\uFFFD\u007D\uFFFD\u0018\u0040\uFFFD\u006F\uFFFD\uFFFD\u002A\uFFFD\uFFFD\u000A\uFFFD\uFFFD\uFFFD\u0013\u0004\u003B\uFFFD\u0010' 223 | ) 224 | t.end() 225 | }) 226 | 227 | isBrowser && t('utf8 replacement chars for anything in the surrogate pair range', function (t) { 228 | t.equal( 229 | toString(b2ab(Buffer.from([ 0xED, 0x9F, 0xBF ])) ), 230 | '\uD7FF' 231 | ) 232 | t.equal( 233 | toString(b2ab(Buffer.from([ 0xED, 0xA0, 0x80 ])) ), 234 | '\uFFFD\uFFFD\uFFFD' 235 | ) 236 | t.equal( 237 | toString(b2ab(Buffer.from([ 0xED, 0xBE, 0x8B ])) ), 238 | '\uFFFD\uFFFD\uFFFD' 239 | ) 240 | t.equal( 241 | toString(b2ab(Buffer.from([ 0xED, 0xBF, 0xBF ])) ), 242 | '\uFFFD\uFFFD\uFFFD' 243 | ) 244 | t.equal( 245 | toString(b2ab(Buffer.from([ 0xEE, 0x80, 0x80 ])) ), 246 | '\uE000' 247 | ) 248 | t.end() 249 | }) 250 | 251 | t('utf8 don\'t replace the replacement char', function (t) { 252 | t.equal( 253 | toString(b2ab(Buffer.from('\uFFFD')) ), 254 | '\uFFFD' 255 | ) 256 | t.end() 257 | }) 258 | --------------------------------------------------------------------------------