"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.alloc = alloc;
exports.free = free;
exports.resize = resize;
exports.readInt = readInt;
exports.readUInt = readUInt;
exports.writeInt64 = writeInt64;
exports.writeUInt64 = writeUInt64;
var bufPool = [];
var TEMP_BUF_MAXIMUM_LENGTH = 20;
var MIN_EXACT_INT64 = -0x8000000000000000;
var MAX_EXACT_INT64 = 0x7ffffffffffffc00;
var MAX_EXACT_UINT64 = 0xfffffffffffff800;
var BIT_32 = 0x100000000;
var BIT_64 = 0x10000000000000000;
function lowestBit(num) {
return num & -num;
}
function isLossyToAdd(accum, num) {
if (num === 0) {
return false;
}
var lowBit = lowestBit(num);
var added = accum + lowBit;
if (added === accum) {
return true;
}
if (added - lowBit !== accum) {
return true;
}
return false;
}
function alloc(length) {
var result = bufPool[length];
if (result) {
bufPool[length] = undefined;
} else {
result = new Buffer(length);
}
result.fill(0);
return result;
}
function free(buffer) {
var length = buffer.length;
if (length < TEMP_BUF_MAXIMUM_LENGTH) {
bufPool[length] = buffer;
}
}
function resize(buffer, length) {
if (length === buffer.length) {
return buffer;
}
var newBuf = alloc(length);
buffer.copy(newBuf);
free(buffer);
return newBuf;
}
function readInt(buffer) {
var length = buffer.length;
var positive = buffer[length - 1] < 0x80;
var result = positive ? 0 : -1;
var lossy = false;
if (length < 7) {
for (var i = length - 1; i >= 0; i--) {
result = result * 0x100 + buffer[i];
}
} else {
for (var _i = length - 1; _i >= 0; _i--) {
var one = buffer[_i];
result *= 0x100;
if (isLossyToAdd(result, one)) {
lossy = true;
}
result += one;
}
}
return {
value: result,
lossy: lossy
};
}
function readUInt(buffer) {
var length = buffer.length;
var result = 0;
var lossy = false;
if (length < 7) {
for (var i = length - 1; i >= 0; i--) {
result = result * 0x100 + buffer[i];
}
} else {
for (var _i2 = length - 1; _i2 >= 0; _i2--) {
var one = buffer[_i2];
result *= 0x100;
if (isLossyToAdd(result, one)) {
lossy = true;
}
result += one;
}
}
return {
value: result,
lossy: lossy
};
}
function writeInt64(value, buffer) {
if (value < MIN_EXACT_INT64 || value > MAX_EXACT_INT64) {
throw new Error("Value out of range.");
}
if (value < 0) {
value += BIT_64;
}
writeUInt64(value, buffer);
}
function writeUInt64(value, buffer) {
if (value < 0 || value > MAX_EXACT_UINT64) {
throw new Error("Value out of range.");
}
var lowWord = value % BIT_32;
var highWord = Math.floor(value / BIT_32);
buffer.writeUInt32LE(lowWord, 0);
buffer.writeUInt32LE(highWord, 4);
}