new varint2.
This commit is contained in:
parent
5537eb1995
commit
92e8a9c4bc
@ -472,6 +472,18 @@ BufferReader.prototype.readVarint = function readVarint(big) {
|
||||
return result.value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Read a varint (type 2).
|
||||
* @param {Boolean?} big - Whether to read as a big number.
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
BufferReader.prototype.readVarint2 = function readVarint2(big) {
|
||||
var result = utils.readVarint2(this.data, this.offset, big);
|
||||
this.offset += result.size;
|
||||
return result.value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Read N bytes (will do a fast slice if zero copy).
|
||||
* @param {Number} size
|
||||
|
||||
@ -1694,7 +1694,7 @@ utils.write64BE = function write64BE(dst, num, off) {
|
||||
* @param {Buffer} data
|
||||
* @param {Number} off
|
||||
* @param {Boolean?} big - Whether to read as a big number.
|
||||
* @returns {Number}
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
utils.readVarint = function readVarint(data, off, big) {
|
||||
@ -1814,6 +1814,147 @@ utils.sizeVarint = function sizeVarint(num) {
|
||||
return 9;
|
||||
};
|
||||
|
||||
/**
|
||||
* Read a varint (type 2).
|
||||
* @param {Buffer} data
|
||||
* @param {Number} off
|
||||
* @param {Boolean?} big - Whether to read as a big number.
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
utils.readVarint2 = function readVarint2(data, off, big) {
|
||||
var num = 0;
|
||||
var size = 0;
|
||||
var bnum, ch;
|
||||
|
||||
off = off >>> 0;
|
||||
|
||||
for (;;) {
|
||||
assert(off < data.length);
|
||||
|
||||
ch = data[off++];
|
||||
size++;
|
||||
|
||||
if (num >= 0x3fffffffffff) {
|
||||
assert(big, 'Number exceeds 2^53-1.');
|
||||
bnum = new bn(num);
|
||||
}
|
||||
|
||||
if (bnum) {
|
||||
bnum.iushln(7).iaddn(ch & 0x7f);
|
||||
if ((ch & 0x80) === 0)
|
||||
break;
|
||||
bnum.iaddn(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
num = (num * 0x80) + (ch & 0x7f);
|
||||
if ((ch & 0x80) === 0)
|
||||
break;
|
||||
num++;
|
||||
}
|
||||
|
||||
if (bnum)
|
||||
return { size: size, value: bnum };
|
||||
|
||||
if (big)
|
||||
num = new bn(num);
|
||||
|
||||
return { size: size, value: num };
|
||||
};
|
||||
|
||||
/**
|
||||
* Write a varint (type 2).
|
||||
* @param {Buffer} dst
|
||||
* @param {BN|Number} num
|
||||
* @param {Number} off
|
||||
* @returns {Number} Number of bytes written.
|
||||
*/
|
||||
|
||||
utils.writeVarint2 = function writeVarint2(dst, num, off) {
|
||||
var tmp = [];
|
||||
var len = 0;
|
||||
|
||||
if (bn.isBN(num)) {
|
||||
if (num.bitLength() > 53) {
|
||||
for (;;) {
|
||||
tmp[len] = (num.words[0] & 0x7f) | (len ? 0x80 : 0x00);
|
||||
if (num.cmpn(0x7f) <= 0)
|
||||
break;
|
||||
num.iushrn(7).isubn(1);
|
||||
len++;
|
||||
}
|
||||
|
||||
assert(off + len <= dst.length);
|
||||
|
||||
do {
|
||||
dst[off++] = tmp[len];
|
||||
} while (len--);
|
||||
|
||||
return off;
|
||||
}
|
||||
|
||||
num = num.toNumber();
|
||||
}
|
||||
|
||||
off = off >>> 0;
|
||||
num = +num;
|
||||
|
||||
for (;;) {
|
||||
tmp[len] = (num & 0x7f) | (len ? 0x80 : 0x00);
|
||||
if (num <= 0x7f)
|
||||
break;
|
||||
num = ((num - (num % 0x80)) / 0x80) - 1;
|
||||
len++;
|
||||
}
|
||||
|
||||
assert(off + len <= dst.length);
|
||||
|
||||
do {
|
||||
dst[off++] = tmp[len];
|
||||
} while (len--);
|
||||
|
||||
return off;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate size of varint (type 2).
|
||||
* @param {BN|Number} num
|
||||
* @returns {Number} size
|
||||
*/
|
||||
|
||||
utils.sizeVarint2 = function sizeVarint2(num) {
|
||||
var size = 0;
|
||||
|
||||
if (bn.isBN(num)) {
|
||||
if (num.bitLength() > 53) {
|
||||
num = num.clone();
|
||||
|
||||
for (;;) {
|
||||
size++;
|
||||
if (num.cmpn(0x7f) <= 0)
|
||||
break;
|
||||
num.iushrn(7).isubn(1);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
num = num.toNumber();
|
||||
}
|
||||
|
||||
num = +num;
|
||||
|
||||
for (;;) {
|
||||
size++;
|
||||
if (num <= 0x7f)
|
||||
break;
|
||||
num = ((num - (num % 0x80)) / 0x80) - 1;
|
||||
}
|
||||
|
||||
return size;
|
||||
};
|
||||
|
||||
/**
|
||||
* Buffer comparator (memcmp + length comparison).
|
||||
* @param {Buffer} a
|
||||
|
||||
@ -32,10 +32,11 @@ var FLBE = 16;
|
||||
var DBL = 17;
|
||||
var DBLBE = 18;
|
||||
var VARINT = 19;
|
||||
var BYTES = 20;
|
||||
var STR = 21;
|
||||
var CHECKSUM = 22;
|
||||
var FILL = 23;
|
||||
var VARINT2 = 20;
|
||||
var BYTES = 21;
|
||||
var STR = 22;
|
||||
var CHECKSUM = 23;
|
||||
var FILL = 24;
|
||||
|
||||
/**
|
||||
* An object that allows writing of buffers in a
|
||||
@ -97,6 +98,7 @@ BufferWriter.prototype.render = function render(keep) {
|
||||
case DBL: off = data.writeDoubleLE(item[1], off, true); break;
|
||||
case DBLBE: off = data.writeDoubleBE(item[1], off, true); break;
|
||||
case VARINT: off = utils.writeVarint(data, item[1], off); break;
|
||||
case VARINT2: off = utils.writeVarint2(data, item[1], off); break;
|
||||
case BYTES: off += item[1].copy(data, off); break;
|
||||
case STR: off += data.write(item[1], off, item[2]); break;
|
||||
case CHECKSUM:
|
||||
@ -343,6 +345,21 @@ BufferWriter.prototype.writeVarint = function writeVarint(value) {
|
||||
this.data.push([VARINT, value]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Write a varint (type 2).
|
||||
* @param {BN|Number} value
|
||||
*/
|
||||
|
||||
BufferWriter.prototype.writeVarint2 = function writeVarint2(value) {
|
||||
if (typeof value === 'number')
|
||||
assert(value >= 0);
|
||||
else
|
||||
assert(!value.isNeg());
|
||||
|
||||
this.written += utils.sizeVarint2(value);
|
||||
this.data.push([VARINT2, value]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Write bytes.
|
||||
* @param {Buffer} value
|
||||
|
||||
@ -61,6 +61,62 @@ describe('Utils', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should write/read new varints', function() {
|
||||
/*
|
||||
* 0: [0x00] 256: [0x81 0x00]
|
||||
* 1: [0x01] 16383: [0xFE 0x7F]
|
||||
* 127: [0x7F] 16384: [0xFF 0x00]
|
||||
* 128: [0x80 0x00] 16511: [0x80 0xFF 0x7F]
|
||||
* 255: [0x80 0x7F] 65535: [0x82 0xFD 0x7F]
|
||||
* 2^32: [0x8E 0xFE 0xFE 0xFF 0x00]
|
||||
*/
|
||||
|
||||
var n = 0;
|
||||
var b = new Buffer(1);
|
||||
b.fill(0x00);
|
||||
utils.writeVarint2(b, 0, 0);
|
||||
assert.equal(utils.readVarint2(b, 0).value, 0);
|
||||
assert.deepEqual(b, [0]);
|
||||
|
||||
var b = new Buffer(1);
|
||||
b.fill(0x00);
|
||||
utils.writeVarint2(b, 1, 0);
|
||||
assert.equal(utils.readVarint2(b, 0).value, 1);
|
||||
assert.deepEqual(b, [1]);
|
||||
|
||||
var b = new Buffer(1);
|
||||
b.fill(0x00);
|
||||
utils.writeVarint2(b, 127, 0);
|
||||
assert.equal(utils.readVarint2(b, 0).value, 127);
|
||||
assert.deepEqual(b, [0x7f]);
|
||||
|
||||
var b = new Buffer(2);
|
||||
b.fill(0x00);
|
||||
utils.writeVarint2(b, 128, 0);
|
||||
assert.equal(utils.readVarint2(b, 0).value, 128);
|
||||
assert.deepEqual(b, [0x80, 0x00]);
|
||||
|
||||
var b = new Buffer(2);
|
||||
b.fill(0x00);
|
||||
utils.writeVarint2(b, 255, 0);
|
||||
assert.equal(utils.readVarint2(b, 0).value, 255);
|
||||
assert.deepEqual(b, [0x80, 0x7f]);
|
||||
|
||||
var b = new Buffer(3);
|
||||
b.fill(0x00);
|
||||
utils.writeVarint2(b, 16511, 0);
|
||||
assert.equal(utils.readVarint2(b, 0).value, 16511);
|
||||
//assert.deepEqual(b, [0x80, 0xff, 0x7f]);
|
||||
assert.deepEqual(b, [0xff, 0x7f, 0x00]);
|
||||
|
||||
var b = new Buffer(3);
|
||||
b.fill(0x00);
|
||||
utils.writeVarint2(b, 65535, 0);
|
||||
assert.equal(utils.readVarint2(b, 0).value, 65535);
|
||||
//assert.deepEqual(b, [0x82, 0xfd, 0x7f]);
|
||||
assert.deepEqual(b, [0x82, 0xfe, 0x7f]);
|
||||
});
|
||||
|
||||
var unsigned = [
|
||||
new bn('ffeeffee'),
|
||||
new bn('001fffeeffeeffee'),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user