@iotize/device-client.js
Version:
IoTize Device client for Javascript
383 lines (382 loc) • 15 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var kaitai_stream_1 = require("./kaitai-stream");
var KaitaiStreamReader = /** @class */ (function (_super) {
__extends(KaitaiStreamReader, _super);
/**
KaitaiStream is an implementation of Kaitai Struct API for JavaScript.
Based on DataStream - https://github.com/kig/DataStream.js
@param {ArrayBuffer} arrayBuffer ArrayBuffer to read from.
@param {?Number} byteOffset Offset from arrayBuffer beginning for the KaitaiStream.
*/
function KaitaiStreamReader(arrayBuffer, byteOffset, isBigEndian) {
if (byteOffset === void 0) { byteOffset = 0; }
if (isBigEndian === void 0) { isBigEndian = true; }
return _super.call(this, arrayBuffer, byteOffset, isBigEndian) || this;
}
KaitaiStreamReader.fromArray = function (array) {
// let buffer = new ArrayBuffer(array.length);
var stream = new KaitaiStreamReader(array.buffer);
return stream;
};
KaitaiStreamReader.create = function (packet) {
return packet instanceof Uint8Array ? KaitaiStreamReader.fromArray(packet) : packet;
};
;
// ========================================================================
// Integer numbers
// ========================================================================
// ------------------------------------------------------------------------
// Signed
// ------------------------------------------------------------------------
KaitaiStreamReader.prototype.readS = function (size) {
return this.read('s', size * 8);
};
KaitaiStreamReader.prototype.read = function (type, bitSize, isLittleEndian) {
if (isLittleEndian === void 0) { isLittleEndian = this.isLittleEndian; }
if (type !== 'b') {
bitSize /= 8;
}
var methodType = "read" + type.toUpperCase() + (type != 'b' ? bitSize : '') + (bitSize > 1 && type != 'b' ? (isLittleEndian ? 'le' : 'be') : '');
if (!(methodType in this)) {
throw new Error("Invalid read type: type=" + type + ", size=" + bitSize + ", le=" + isLittleEndian + ". Method name: " + methodType);
}
// console.debug(`Will ${methodType} (le=${isLittleEndian}, pos=${this.pos}, size=${bitSize}, bitsLeft=${this.bitsLeft})`)
var val = this[methodType](bitSize);
// console.debug(`\t-Value red ${val}`)
return val;
};
/**
Reads an 8-bit signed int from the stream.
@return {number} The read number.
*/
KaitaiStreamReader.prototype.readS1 = function () {
var v = this._dataView.getInt8(this.pos);
this.pos += 1;
return v;
};
;
// ........................................................................
// Big-endian
// ........................................................................
/**
Reads a 16-bit big-endian signed int from the stream.
@return {number} The read number.
*/
KaitaiStreamReader.prototype.readS2be = function () {
var v = this._dataView.getInt16(this.pos);
this.pos += 2;
return v;
};
;
/**
Reads a 32-bit big-endian signed int from the stream.
@return {number} The read number.
*/
KaitaiStreamReader.prototype.readS4be = function () {
var v = this._dataView.getInt32(this.pos);
this.pos += 4;
return v;
};
;
/**
Reads a 64-bit big-endian unsigned int from the stream. Note that
JavaScript does not support 64-bit integers natively, so it will
automatically upgrade internal representation to use IEEE 754
double precision float.
@return {number} The read number.
*/
KaitaiStreamReader.prototype.readS8be = function () {
var v1 = this.readU4be();
var v2 = this.readU4be();
if ((v1 & 0x80000000) != 0) {
// negative number
return -(0x100000000 * (v1 ^ 0xffffffff) + (v2 ^ 0xffffffff)) - 1;
}
else {
return 0x100000000 * v1 + v2;
}
};
;
// ........................................................................
// Little-endian
// ........................................................................
/**
Reads a 16-bit little-endian signed int from the stream.
@return {number} The read number.
*/
KaitaiStreamReader.prototype.readS2le = function () {
var v = this._dataView.getInt16(this.pos, true);
this.pos += 2;
return v;
};
;
/**
Reads a 32-bit little-endian signed int from the stream.
@return {number} The read number.
*/
KaitaiStreamReader.prototype.readS4le = function () {
var v = this._dataView.getInt32(this.pos, true);
this.pos += 4;
return v;
};
;
/**
Reads a 64-bit little-endian unsigned int from the stream. Note that
JavaScript does not support 64-bit integers natively, so it will
automatically upgrade internal representation to use IEEE 754
double precision float.
@return {number} The read number.
*/
KaitaiStreamReader.prototype.readS8le = function () {
var v1 = this.readU4le();
var v2 = this.readU4le();
if ((v2 & 0x80000000) != 0) {
// negative number
return -(0x100000000 * (v2 ^ 0xffffffff) + (v1 ^ 0xffffffff)) - 1;
}
else {
return 0x100000000 * v2 + v1;
}
};
;
// ------------------------------------------------------------------------
// Unsigned
// ------------------------------------------------------------------------
/**
* Read unsigned
* @param size
*/
KaitaiStreamReader.prototype.readU = function (size) {
return this.read('u', size * 8);
};
/**
Reads an 8-bit unsigned int from the stream.
@return {number} The read number.
*/
KaitaiStreamReader.prototype.readU1 = function () {
var v = this._dataView.getUint8(this.pos);
this.pos += 1;
return v;
};
;
// ........................................................................
// Big-endian
// ........................................................................
/**
Reads a 16-bit big-endian unsigned int from the stream.
@return {number} The read number.
*/
KaitaiStreamReader.prototype.readU2be = function () {
var v = this._dataView.getUint16(this.pos);
this.pos += 2;
return v;
};
;
/**
Reads a 32-bit big-endian unsigned int from the stream.
@return {number} The read number.
*/
KaitaiStreamReader.prototype.readU4be = function () {
var v = this._dataView.getUint32(this.pos);
this.pos += 4;
return v;
};
;
/**
Reads a 64-bit big-endian unsigned int from the stream. Note that
JavaScript does not support 64-bit integers natively, so it will
automatically upgrade internal representation to use IEEE 754
double precision float.
@return {number} The read number.
*/
KaitaiStreamReader.prototype.readU8be = function () {
var v1 = this.readU4be();
var v2 = this.readU4be();
return 0x100000000 * v1 + v2;
};
;
// ........................................................................
// Little-endian
// ........................................................................
/**
Reads a 16-bit little-endian unsigned int from the stream.
@return {number} The read number.
*/
KaitaiStreamReader.prototype.readU2le = function () {
var v = this._dataView.getUint16(this.pos, true);
this.pos += 2;
return v;
};
;
/**
Reads a 32-bit little-endian unsigned int from the stream.
@return {number} The read number.
*/
KaitaiStreamReader.prototype.readU4le = function () {
var v = this._dataView.getUint32(this.pos, true);
this.pos += 4;
return v;
};
;
/**
Reads a 64-bit little-endian unsigned int from the stream. Note that
JavaScript does not support 64-bit integers natively, so it will
automatically upgrade internal representation to use IEEE 754
double precision float.
@return {number} The read number.
*/
KaitaiStreamReader.prototype.readU8le = function () {
var v1 = this.readU4le();
var v2 = this.readU4le();
return 0x100000000 * v2 + v1;
};
;
// ========================================================================
// Floating point numbers
// ========================================================================
// ------------------------------------------------------------------------
// Big endian
// ------------------------------------------------------------------------
KaitaiStreamReader.prototype.readF = function (size) {
return this.read('f', size * 8);
};
KaitaiStreamReader.prototype.readF4be = function () {
var v = this._dataView.getFloat32(this.pos);
this.pos += 4;
return v;
};
;
KaitaiStreamReader.prototype.readF8be = function () {
var v = this._dataView.getFloat64(this.pos);
this.pos += 8;
return v;
};
;
// ------------------------------------------------------------------------
// Little endian
// ------------------------------------------------------------------------
KaitaiStreamReader.prototype.readF4le = function () {
var v = this._dataView.getFloat32(this.pos, true);
this.pos += 4;
return v;
};
;
KaitaiStreamReader.prototype.readF8le = function () {
var v = this._dataView.getFloat64(this.pos, true);
this.pos += 8;
return v;
};
;
// ------------------------------------------------------------------------
// Unaligned bit values
// ------------------------------------------------------------------------
KaitaiStreamReader.prototype.readBitsBoolean = function (n) {
return this.readBitsInt(n) !== 0;
};
KaitaiStreamReader.prototype.readB = function (n) {
return this.readBitsInt(n);
};
KaitaiStreamReader.prototype.forwardBits = function (n) {
this.readBitsInt(n);
return this;
};
KaitaiStreamReader.prototype.readBitsInt = function (n) {
// console.debug('readBitsInt(' + n + '): bits: ', this.bits, ' | bitsLeft: ', this.bitsLeft, ' | pos:' + this.pos, ' | buffer: ' + FormatHelper.toHexString(this.toBytes))
// JS only supports bit operations on 32 bits
if (n > 32)
throw new Error("readBitsInt: the maximum supported bit length is 32 (tried to read " + n + " bits)");
var bitsNeeded = n - this.bitsLeft;
if (bitsNeeded > 0) {
// console.debug(`readBitsInt bitsNeeded ${bitsNeeded} but only ${this.bitsLeft} available`)
// 1 bit => 1 byte
// 8 bits => 1 byte
// 9 bits => 2 bytes
var bytesNeeded = Math.ceil(bitsNeeded / 8);
var buf = this.readBytes(bytesNeeded);
for (var i = 0; i < buf.length; i++) {
this.bits <<= 8;
this.bits |= buf[i];
this.bitsLeft += 8;
}
}
// raw mask with required number of 1s, starting from lowest bit
var mask = n == 32 ? 0xffffffff : (1 << n) - 1;
// shift mask to align with highest bits available in this.bits
var shiftBits = this.bitsLeft - n;
mask <<= shiftBits;
// derive reading result
var res = (this.bits & mask) >>> shiftBits;
// clear top bits that we've just read => AND with 1s
this.bitsLeft -= n;
mask = (1 << this.bitsLeft) - 1;
this.bits &= mask;
return res;
};
// ========================================================================
// Byte arrays
// ========================================================================
KaitaiStreamReader.prototype.readBytes = function (len) {
if (len < 0) {
len = this.byteLeft + len;
}
// console.debug('readBytes', len);
return this.mapUint8Array(len);
};
KaitaiStreamReader.prototype.readBytesFull = function () {
return this.mapUint8Array(this.size - this.pos);
};
KaitaiStreamReader.prototype.readBytesTerm = function (terminator, include, consume, eosError) {
var blen = this.size - this.pos;
var u8 = new Uint8Array(this._buffer, this._byteOffset + this.pos);
for (var i = 0; i < blen && u8[i] != terminator; i++)
; // find first zero byte
if (i == blen) {
// we've read all the buffer and haven't found the terminator
if (eosError) {
throw "End of stream reached, but no terminator " + terminator + " found";
}
else {
return this.mapUint8Array(i);
}
}
else {
var arr;
if (include) {
arr = this.mapUint8Array(i + 1);
}
else {
arr = this.mapUint8Array(i);
}
if (consume) {
this.pos += 1;
}
return arr;
}
};
KaitaiStreamReader.prototype.ensureFixedContents = function (expected) {
var actual = this.readBytes(expected.length);
if (actual.length !== expected.length) {
throw new kaitai_stream_1.UnexpectedDataError(expected, actual);
}
var actLen = actual.length;
for (var i = 0; i < actLen; i++) {
if (actual[i] != expected[i]) {
throw new kaitai_stream_1.UnexpectedDataError(expected, actual);
}
}
return actual;
};
return KaitaiStreamReader;
}(kaitai_stream_1.KaitaiStream));
exports.KaitaiStreamReader = KaitaiStreamReader;