new varint2.
This commit is contained in:
parent
5537eb1995
commit
92e8a9c4bc
@ -472,6 +472,18 @@ BufferReader.prototype.readVarint = function readVarint(big) {
|
|||||||
return result.value;
|
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).
|
* Read N bytes (will do a fast slice if zero copy).
|
||||||
* @param {Number} size
|
* @param {Number} size
|
||||||
|
|||||||
@ -1694,7 +1694,7 @@ utils.write64BE = function write64BE(dst, num, off) {
|
|||||||
* @param {Buffer} data
|
* @param {Buffer} data
|
||||||
* @param {Number} off
|
* @param {Number} off
|
||||||
* @param {Boolean?} big - Whether to read as a big number.
|
* @param {Boolean?} big - Whether to read as a big number.
|
||||||
* @returns {Number}
|
* @returns {Object}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
utils.readVarint = function readVarint(data, off, big) {
|
utils.readVarint = function readVarint(data, off, big) {
|
||||||
@ -1814,6 +1814,147 @@ utils.sizeVarint = function sizeVarint(num) {
|
|||||||
return 9;
|
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).
|
* Buffer comparator (memcmp + length comparison).
|
||||||
* @param {Buffer} a
|
* @param {Buffer} a
|
||||||
|
|||||||
@ -32,10 +32,11 @@ var FLBE = 16;
|
|||||||
var DBL = 17;
|
var DBL = 17;
|
||||||
var DBLBE = 18;
|
var DBLBE = 18;
|
||||||
var VARINT = 19;
|
var VARINT = 19;
|
||||||
var BYTES = 20;
|
var VARINT2 = 20;
|
||||||
var STR = 21;
|
var BYTES = 21;
|
||||||
var CHECKSUM = 22;
|
var STR = 22;
|
||||||
var FILL = 23;
|
var CHECKSUM = 23;
|
||||||
|
var FILL = 24;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An object that allows writing of buffers in a
|
* 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 DBL: off = data.writeDoubleLE(item[1], off, true); break;
|
||||||
case DBLBE: off = data.writeDoubleBE(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 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 BYTES: off += item[1].copy(data, off); break;
|
||||||
case STR: off += data.write(item[1], off, item[2]); break;
|
case STR: off += data.write(item[1], off, item[2]); break;
|
||||||
case CHECKSUM:
|
case CHECKSUM:
|
||||||
@ -343,6 +345,21 @@ BufferWriter.prototype.writeVarint = function writeVarint(value) {
|
|||||||
this.data.push([VARINT, 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.
|
* Write bytes.
|
||||||
* @param {Buffer} value
|
* @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 = [
|
var unsigned = [
|
||||||
new bn('ffeeffee'),
|
new bn('ffeeffee'),
|
||||||
new bn('001fffeeffeeffee'),
|
new bn('001fffeeffeeffee'),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user