byte-data
JavaScript binary parser for any browser or environment.
Copyright (c) 2017-2019 Rafael da Silva Rocha.
https://github.com/rochars/byte-data
byte-data is JavaScript binary parser for any browser or environment.
- MIT licensed
- Compatible with IE6+ and any environment with ES3/ES5/ES6+ support
- Tested in little-endian and big-endian machines!
- Zero dependencies
Pack/unpack:
- Integers, unsigned and signed (two's complement)
- 16-bit half-precision floating-point numbers
- 32-bit single-precision floating-point numbers
- 64-bit double-precision floating-point numbers
- Little-endian and big-endian words
- UTF-8 strings (1 to 4 bytes per character, invalid characters are replaced)
Install
npm install byte-data
In the Browser
Use the byte-data.js file in the /dist folder:
Or load it from the jsDelivr CDN:
Or load it from unpkg:
Browser compatibility
This module is distributed as a minified UMD transpiled to ES3 and compatible with IE6+. It should work in all modern browsers and environments that support ES3/ES5/ES6+.
The polyfills used in the compilation are distributed with the package in the scripts/ folder. The polyfills are for the defineProperty and getOwnPropertyDescriptor properties of Object, and are not used in case those properties are already defined.
If you are not using a package manager to install this module, you can get the it via CDNs:
Cross-browser tests powered by
Node
const byteData = ; // Pack a signed 16-bit integer to a existing byte buffer// Start writing on index '4' of the bufferbyteData; // Pack a usigned 8-bit unsigned integer, returns a// array with the number represented as byteslet packed = byteData;
Or import just what you need:
; // Pack a 8-bit unsigned integerlet packed = ;
About
pack and packTo
pack(num, theType) will return a Array with the bytes of the passed value.
let packed = ;
packTo(num, theType, buffer, index) will write the bytes of the number to the provided buffer (Uint8Array or Array), start writing on index.
let buffer = 4;;
index can be ommited and will default to zero:
let buffer = 4;;
Packing null, false, true and undefined
Packing the following values
- undefined
- null
- true
- false
will values throw a TypeError.
Unpacking and input buffer length
When unpacking values, extra bytes in the end of the buffer are ignored and insufficient bytes will return a empty array by default.
You can unpack in safe mode with the optional safe param set to true. In safe mode insufficient bytes in the input array or extra bytes in the end of the input array will cause a 'Bad buffer length' error:
// throws a 'Bad buffer length' errorbyteData; // throws a 'Bad buffer length' errorbyteData; // throws a 'Bad buffer length' errorbyteData; // throws a 'Bad buffer length' errorbyteData; // do not throw errorbyteData;
Floating-point numbers
- Floating-point numbers are IEEE 754 standard.
- Overflows are rounded towards Infinity and -Infinity.
- NaN is packed as quiet NaN. Both quiet NaN and signaling NaN can be unpacked.
- Support packing and unpacking negative zeros.
- Support packing and unpacking Infinity and negative Infinity
Minifloats
Currently only 16-bit half-precision.
Integers
- Overflow on integers will throw a RangeError.
- Packing values other than integers will throw a TypeError.
To clamp integers on overflow and avoid RangeError, set the optional clamp param to true:
// Set clamp to true; values will be packed// as their max and min values on overflow;;;
Signed integers
Signed integers are two's complement.
Strings
UTF-8 strings with 1 to 4 bytes per character can be packed and unpacked. BOM is kept untouched if present. Invalid characters are replaced with Unicode Character 'REPLACEMENT CHARACTER' (U+FFFD). Packing values other than strings with packString() or packStringTo() will throw a TypeError.
Reading strings from buffers
Use unpackString(buffer, index, end). The paramters index and end determine a slice of the buffer to read. End is non-inclusive. So to read the first 4 bytes of a buffer:
let str = ;// read from buffer[0], buffer[1], buffer[2], buffer[3]
If index and end are ommited unpackString(buffer) will read the entire buffer:
let str = ;
Writing strings to buffers
packStringTo(str, buffer, index=0) will write the string to the provided buffer (Uint8Array or Array), starting on the index. Index defaults to zero if ommited (start from the beginning of the buffer).
// Will write the string to the buffer, array or Uint8Arraylet buffer = ;; // Will return the bytes of the string in a arraylet strBytes = ;
Types
Types are user-defined objects like this:
const binary32 = bits: 32 // required signed: true // optional, defaults to false fp: true // optional, defaults to false, true for floating-point numbers be: false // optional, defaults to false, true for big-endian
Tests on big-endian systems
Use QEMU with this PowerPC/Debian image:
https://people.debian.org/~aurel32/qemu/powerpc/
API
// Strings/** * Read a string of UTF-8 characters from a byte buffer. * @param * @param * @param * @return */ {} /** * Write a string of UTF-8 characters as a byte buffer. * @param * @return * @throws */ {} /** * Write a string of UTF-8 characters to a byte buffer. * @param * @param * @param * @return * @throws */ {} // Numbers/** * Pack a array of numbers to a byte buffer. * All other packing functions are interfaces to this function. * @param * @param {!{bits:number, * fp: (boolean|undefined), * signed: (boolean|undefined), * be: (boolean|undefined)}} theType The type definition. * @param * @param * @param * @return * @throws * @throws * @throws * @throws */ {} /** * Unpack a array of numbers from a byte buffer to a array or a typed array. * All other unpacking functions are interfaces to this function. * @param * @param {!{bits:number, * fp: (boolean|undefined), * signed: (boolean|undefined), * be: (boolean|undefined)}} theType The type definition. * @param * @param * @param * @param * the input array are ignored and input buffers with insufficient bytes will * write nothing to the output array. If safe is set to true the function * will throw a 'Bad buffer length' error on the aforementioned cases. * @throws * @throws */ {} /** * Pack a number to a byte buffer. * @param * @param {!{bits:number, * fp: (boolean|undefined), * signed: (boolean|undefined), * be: (boolean|undefined)}} theType The type definition. * @param * @param * @param * @return * @throws * @throws * @throws * @throws */ {} /** * Pack a number as a array of bytes. * @param * @param {!{bits:number, * fp: (boolean|undefined), * signed: (boolean|undefined), * be: (boolean|undefined)}} theType The type definition. * @param * @return * @throws * @throws * @throws * @throws */ {} /** * Unpack a number from a byte buffer. * @param * @param {!{bits:number, * fp: (boolean|undefined), * signed: (boolean|undefined), * be: (boolean|undefined)}} theType The type definition. * @param * @param * the input array are ignored and input buffers with insufficient bytes will * write nothing to the output array. If safe is set to true the function * will throw a 'Bad buffer length' error on the aforementioned cases. * @return * @throws * @throws */ {} /** * Pack a array of numbers as a array of bytes. * @param * @param {!{bits:number, * fp: (boolean|undefined), * signed: (boolean|undefined), * be: (boolean|undefined)}} theType The type definition. * @param * @return * @throws * @throws * @throws * @throws */ {} /** * Unpack a array of numbers from a byte buffer. * @param * @param {!{bits:number, * fp: (boolean|undefined), * signed: (boolean|undefined), * be: (boolean|undefined)}} theType The type definition. * @param * @param * @param * the input array are ignored and input buffers with insufficient bytes will * write nothing to the output array. If safe is set to true the function * will throw a 'Bad buffer length' error on the aforementioned cases. * @return * @throws * @throws */ {}
Contributing
byte-data welcomes all contributions from anyone willing to work in good faith with other contributors and the community. No contribution is too small and all contributions are valued.
See CONTRIBUTING.md for details.
Style guide
byte-data code should follow the Google JavaScript Style Guide:
https://google.github.io/styleguide/jsguide.html
Code of conduct
This project is bound by a code of conduct: The Contributor Covenant, version 1.4, also available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
Reporting issues
Use the GitHub issue tracker.
Reporting security issues
Report security issues to this e-mail: rocha.rafaelsilva@gmail.com.
Legal
LICENSE
Copyright (c) 2017-2019 Rafael da Silva Rocha.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.