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.
206 lines
4.8 KiB
206 lines
4.8 KiB
// 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;
|
|
|