You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
4.8 KiB
207 lines
4.8 KiB
2 years ago
|
// Light implementation of binary buffer with helpers for easy access.
|
||
|
//
|
||
|
'use strict';
|
||
|
|
||
|
|
||
|
var TYPED_OK = (typeof Uint8Array !== 'undefined');
|
||
|
|
||
|
function createArray(size) {
|
||
|
return TYPED_OK ? new Uint8Array(size) : Array(size);
|
||
|
}
|
||
|
|
||
|
|
||
|
function MicroBuffer(buffer, start, length) {
|
||
|
|
||
|
var isInherited = buffer instanceof MicroBuffer;
|
||
|
|
||
|
this.buffer = isInherited ?
|
||
|
buffer.buffer
|
||
|
:
|
||
|
(typeof buffer === 'number' ? createArray(buffer) : buffer);
|
||
|
|
||
|
this.start = (start || 0) + (isInherited ? buffer.start : 0);
|
||
|
this.length = length || (this.buffer.length - this.start);
|
||
|
this.offset = 0;
|
||
|
|
||
|
this.isTyped = !Array.isArray(this.buffer);
|
||
|
}
|
||
|
|
||
|
|
||
|
MicroBuffer.prototype.getUint8 = function (pos) {
|
||
|
return this.buffer[pos + this.start];
|
||
|
};
|
||
|
|
||
|
|
||
|
MicroBuffer.prototype.getUint16 = function (pos, littleEndian) {
|
||
|
var val;
|
||
|
if (littleEndian) {
|
||
|
throw new Error('not implemented');
|
||
|
} else {
|
||
|
val = this.buffer[pos + 1 + this.start];
|
||
|
val += this.buffer[pos + this.start] << 8 >>> 0;
|
||
|
}
|
||
|
return val;
|
||
|
};
|
||
|
|
||
|
|
||
|
MicroBuffer.prototype.getUint32 = function (pos, littleEndian) {
|
||
|
var val;
|
||
|
if (littleEndian) {
|
||
|
throw new Error('not implemented');
|
||
|
} else {
|
||
|
val = this.buffer[pos + 1 + this.start] << 16;
|
||
|
val |= this.buffer[pos + 2 + this.start] << 8;
|
||
|
val |= this.buffer[pos + 3 + this.start];
|
||
|
val += this.buffer[pos + this.start] << 24 >>> 0;
|
||
|
}
|
||
|
return val;
|
||
|
};
|
||
|
|
||
|
|
||
|
MicroBuffer.prototype.setUint8 = function (pos, value) {
|
||
|
this.buffer[pos + this.start] = value & 0xFF;
|
||
|
};
|
||
|
|
||
|
|
||
|
MicroBuffer.prototype.setUint16 = function (pos, value, littleEndian) {
|
||
|
var offset = pos + this.start;
|
||
|
var buf = this.buffer;
|
||
|
if (littleEndian) {
|
||
|
buf[offset] = value & 0xFF;
|
||
|
buf[offset + 1] = (value >>> 8) & 0xFF;
|
||
|
} else {
|
||
|
buf[offset] = (value >>> 8) & 0xFF;
|
||
|
buf[offset + 1] = value & 0xFF;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
MicroBuffer.prototype.setUint32 = function (pos, value, littleEndian) {
|
||
|
var offset = pos + this.start;
|
||
|
var buf = this.buffer;
|
||
|
if (littleEndian) {
|
||
|
buf[offset] = value & 0xFF;
|
||
|
buf[offset + 1] = (value >>> 8) & 0xFF;
|
||
|
buf[offset + 2] = (value >>> 16) & 0xFF;
|
||
|
buf[offset + 3] = (value >>> 24) & 0xFF;
|
||
|
} else {
|
||
|
buf[offset] = (value >>> 24) & 0xFF;
|
||
|
buf[offset + 1] = (value >>> 16) & 0xFF;
|
||
|
buf[offset + 2] = (value >>> 8) & 0xFF;
|
||
|
buf[offset + 3] = value & 0xFF;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
MicroBuffer.prototype.writeUint8 = function (value) {
|
||
|
this.buffer[this.offset + this.start] = value & 0xFF;
|
||
|
this.offset++;
|
||
|
};
|
||
|
|
||
|
|
||
|
MicroBuffer.prototype.writeInt8 = function (value) {
|
||
|
this.setUint8(this.offset, (value < 0) ? 0xFF + value + 1 : value);
|
||
|
this.offset++;
|
||
|
};
|
||
|
|
||
|
|
||
|
MicroBuffer.prototype.writeUint16 = function (value, littleEndian) {
|
||
|
this.setUint16(this.offset, value, littleEndian);
|
||
|
this.offset += 2;
|
||
|
};
|
||
|
|
||
|
|
||
|
MicroBuffer.prototype.writeInt16 = function (value, littleEndian) {
|
||
|
this.setUint16(this.offset, (value < 0) ? 0xFFFF + value + 1 : value, littleEndian);
|
||
|
this.offset += 2;
|
||
|
};
|
||
|
|
||
|
|
||
|
MicroBuffer.prototype.writeUint32 = function (value, littleEndian) {
|
||
|
this.setUint32(this.offset, value, littleEndian);
|
||
|
this.offset += 4;
|
||
|
};
|
||
|
|
||
|
|
||
|
MicroBuffer.prototype.writeInt32 = function (value, littleEndian) {
|
||
|
this.setUint32(this.offset, (value < 0) ? 0xFFFFFFFF + value + 1 : value, littleEndian);
|
||
|
this.offset += 4;
|
||
|
};
|
||
|
|
||
|
|
||
|
// get current position
|
||
|
//
|
||
|
MicroBuffer.prototype.tell = function () {
|
||
|
return this.offset;
|
||
|
};
|
||
|
|
||
|
|
||
|
// set current position
|
||
|
//
|
||
|
MicroBuffer.prototype.seek = function (pos) {
|
||
|
this.offset = pos;
|
||
|
};
|
||
|
|
||
|
|
||
|
MicroBuffer.prototype.fill = function (value) {
|
||
|
var index = this.length - 1;
|
||
|
while (index >= 0) {
|
||
|
this.buffer[index + this.start] = value;
|
||
|
index--;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
MicroBuffer.prototype.writeUint64 = function (value) {
|
||
|
// we canot use bitwise operations for 64bit values because of JavaScript limitations,
|
||
|
// instead we should divide it to 2 Int32 numbers
|
||
|
// 2^32 = 4294967296
|
||
|
var hi = Math.floor(value / 4294967296);
|
||
|
var lo = value - hi * 4294967296;
|
||
|
this.writeUint32(hi);
|
||
|
this.writeUint32(lo);
|
||
|
};
|
||
|
|
||
|
|
||
|
MicroBuffer.prototype.writeBytes = function (data) {
|
||
|
var buffer = this.buffer;
|
||
|
var offset = this.offset + this.start;
|
||
|
if (this.isTyped) {
|
||
|
buffer.set(data, offset);
|
||
|
} else {
|
||
|
for (var i = 0; i < data.length; i++) {
|
||
|
buffer[i + offset] = data[i];
|
||
|
}
|
||
|
}
|
||
|
this.offset += data.length;
|
||
|
};
|
||
|
|
||
|
|
||
|
MicroBuffer.prototype.toString = function (offset, length) {
|
||
|
// default values if not set
|
||
|
offset = (offset || 0);
|
||
|
length = length || (this.length - offset);
|
||
|
|
||
|
// add buffer shift
|
||
|
var start = offset + this.start;
|
||
|
var end = start + length;
|
||
|
|
||
|
var string = '';
|
||
|
for (var i = start; i < end; i++) {
|
||
|
string += String.fromCharCode(this.buffer[i]);
|
||
|
}
|
||
|
return string;
|
||
|
};
|
||
|
|
||
|
|
||
|
MicroBuffer.prototype.toArray = function () {
|
||
|
if (this.isTyped) {
|
||
|
return this.buffer.subarray(this.start, this.start + this.length);
|
||
|
}
|
||
|
|
||
|
return this.buffer.slice(this.start, this.start + this.length);
|
||
|
};
|
||
|
|
||
|
|
||
|
module.exports = MicroBuffer;
|