script parser code added and tested
This commit is contained in:
parent
40ee699453
commit
05c5538162
286
Script.js
286
Script.js
|
@ -31,7 +31,7 @@ function spec(b) {
|
|||
];
|
||||
|
||||
function Script(buffer) {
|
||||
if(buffer) {
|
||||
if (buffer) {
|
||||
this.buffer = buffer;
|
||||
} else {
|
||||
this.buffer = util.EMPTY_BUFFER;
|
||||
|
@ -41,13 +41,13 @@ function spec(b) {
|
|||
};
|
||||
this.class = Script;
|
||||
|
||||
Script.TX_UNKNOWN=TX_UNKNOWN;
|
||||
Script.TX_PUBKEY=TX_PUBKEY;
|
||||
Script.TX_PUBKEYHASH=TX_PUBKEYHASH;
|
||||
Script.TX_MULTISIG=TX_MULTISIG;
|
||||
Script.TX_SCRIPTHASH=TX_SCRIPTHASH;
|
||||
Script.TX_UNKNOWN = TX_UNKNOWN;
|
||||
Script.TX_PUBKEY = TX_PUBKEY;
|
||||
Script.TX_PUBKEYHASH = TX_PUBKEYHASH;
|
||||
Script.TX_MULTISIG = TX_MULTISIG;
|
||||
Script.TX_SCRIPTHASH = TX_SCRIPTHASH;
|
||||
|
||||
Script.prototype.parse = function () {
|
||||
Script.prototype.parse = function() {
|
||||
this.chunks = [];
|
||||
|
||||
var parser = new Parser(this.buffer);
|
||||
|
@ -73,8 +73,7 @@ function spec(b) {
|
|||
}
|
||||
};
|
||||
|
||||
Script.prototype.isPushOnly = function ()
|
||||
{
|
||||
Script.prototype.isPushOnly = function() {
|
||||
for (var i = 0; i < this.chunks.length; i++)
|
||||
if (!Buffer.isBuffer(this.chunks[i]))
|
||||
return false;
|
||||
|
@ -82,8 +81,7 @@ function spec(b) {
|
|||
return true;
|
||||
};
|
||||
|
||||
Script.prototype.isP2SH = function ()
|
||||
{
|
||||
Script.prototype.isP2SH = function() {
|
||||
return (this.chunks.length == 3 &&
|
||||
this.chunks[0] == OP_HASH160 &&
|
||||
Buffer.isBuffer(this.chunks[1]) &&
|
||||
|
@ -91,46 +89,41 @@ function spec(b) {
|
|||
this.chunks[2] == OP_EQUAL);
|
||||
};
|
||||
|
||||
Script.prototype.isPubkey = function ()
|
||||
{
|
||||
Script.prototype.isPubkey = function() {
|
||||
return (this.chunks.length == 2 &&
|
||||
Buffer.isBuffer(this.chunks[0]) &&
|
||||
this.chunks[1] == OP_CHECKSIG);
|
||||
Buffer.isBuffer(this.chunks[0]) &&
|
||||
this.chunks[1] == OP_CHECKSIG);
|
||||
};
|
||||
|
||||
Script.prototype.isPubkeyHash = function ()
|
||||
{
|
||||
Script.prototype.isPubkeyHash = function() {
|
||||
return (this.chunks.length == 5 &&
|
||||
this.chunks[0] == OP_DUP &&
|
||||
this.chunks[1] == OP_HASH160 &&
|
||||
this.chunks[0] == OP_DUP &&
|
||||
this.chunks[1] == OP_HASH160 &&
|
||||
Buffer.isBuffer(this.chunks[2]) &&
|
||||
this.chunks[2].length == 20 &&
|
||||
this.chunks[3] == OP_EQUALVERIFY &&
|
||||
this.chunks[4] == OP_CHECKSIG);
|
||||
this.chunks[3] == OP_EQUALVERIFY &&
|
||||
this.chunks[4] == OP_CHECKSIG);
|
||||
};
|
||||
|
||||
function isSmallIntOp(opcode)
|
||||
{
|
||||
function isSmallIntOp(opcode) {
|
||||
return ((opcode == OP_0) ||
|
||||
((opcode >= OP_1) && (opcode <= OP_16)));
|
||||
((opcode >= OP_1) && (opcode <= OP_16)));
|
||||
};
|
||||
|
||||
Script.prototype.isMultiSig = function ()
|
||||
{
|
||||
Script.prototype.isMultiSig = function() {
|
||||
return (this.chunks.length > 3 &&
|
||||
isSmallIntOp(this.chunks[0]) &&
|
||||
isSmallIntOp(this.chunks[this.chunks.length-2]) &&
|
||||
this.chunks[this.chunks.length-1] == OP_CHECKMULTISIG);
|
||||
isSmallIntOp(this.chunks[0]) &&
|
||||
isSmallIntOp(this.chunks[this.chunks.length - 2]) &&
|
||||
this.chunks[this.chunks.length - 1] == OP_CHECKMULTISIG);
|
||||
};
|
||||
|
||||
Script.prototype.finishedMultiSig = function()
|
||||
{
|
||||
Script.prototype.finishedMultiSig = function() {
|
||||
var nsigs = 0;
|
||||
for (var i = 0; i < this.chunks.length-1; i++)
|
||||
for (var i = 0; i < this.chunks.length - 1; i++)
|
||||
if (this.chunks[i] !== 0)
|
||||
nsigs++;
|
||||
|
||||
var serializedScript = this.chunks[this.chunks.length-1];
|
||||
var serializedScript = this.chunks[this.chunks.length - 1];
|
||||
var script = new Script(serializedScript);
|
||||
var nreq = script.chunks[0] - 80; //see OP_2-OP_16
|
||||
|
||||
|
@ -140,11 +133,9 @@ function spec(b) {
|
|||
return false;
|
||||
}
|
||||
|
||||
Script.prototype.removePlaceHolders = function()
|
||||
{
|
||||
Script.prototype.removePlaceHolders = function() {
|
||||
var chunks = [];
|
||||
for (var i in this.chunks)
|
||||
{
|
||||
for (var i in this.chunks) {
|
||||
if (this.chunks.hasOwnProperty(i)) {
|
||||
var chunk = this.chunks[i];
|
||||
if (chunk != 0)
|
||||
|
@ -156,8 +147,7 @@ function spec(b) {
|
|||
return this;
|
||||
}
|
||||
|
||||
Script.prototype.prependOp0 = function()
|
||||
{
|
||||
Script.prototype.prependOp0 = function() {
|
||||
var chunks = [0];
|
||||
for (i in this.chunks) {
|
||||
if (this.chunks.hasOwnProperty(i)) {
|
||||
|
@ -170,62 +160,61 @@ function spec(b) {
|
|||
}
|
||||
|
||||
// is this a script form we know?
|
||||
Script.prototype.classify = function ()
|
||||
{
|
||||
Script.prototype.classify = function() {
|
||||
if (this.isPubkeyHash())
|
||||
return TX_PUBKEYHASH;
|
||||
if (this.isP2SH())
|
||||
return TX_SCRIPTHASH;
|
||||
if (this.isMultiSig())
|
||||
return TX_MULTISIG;
|
||||
if (this.isPubkey())
|
||||
return TX_PUBKEY;
|
||||
return TX_UNKNOWN;
|
||||
return TX_PUBKEYHASH;
|
||||
if (this.isP2SH())
|
||||
return TX_SCRIPTHASH;
|
||||
if (this.isMultiSig())
|
||||
return TX_MULTISIG;
|
||||
if (this.isPubkey())
|
||||
return TX_PUBKEY;
|
||||
return TX_UNKNOWN;
|
||||
};
|
||||
|
||||
// extract useful data items from known scripts
|
||||
Script.prototype.capture = function ()
|
||||
{
|
||||
Script.prototype.capture = function() {
|
||||
var txType = this.classify();
|
||||
var res = [];
|
||||
switch (txType) {
|
||||
case TX_PUBKEY:
|
||||
res.push(this.chunks[0]);
|
||||
break;
|
||||
case TX_PUBKEYHASH:
|
||||
res.push(this.chunks[2]);
|
||||
break;
|
||||
case TX_MULTISIG:
|
||||
for (var i = 1; i < (this.chunks.length - 2); i++)
|
||||
res.push(this.chunks[i]);
|
||||
break;
|
||||
case TX_SCRIPTHASH:
|
||||
res.push(this.chunks[1]);
|
||||
break;
|
||||
var res = [];
|
||||
switch (txType) {
|
||||
case TX_PUBKEY:
|
||||
res.push(this.chunks[0]);
|
||||
break;
|
||||
case TX_PUBKEYHASH:
|
||||
res.push(this.chunks[2]);
|
||||
break;
|
||||
case TX_MULTISIG:
|
||||
for (var i = 1; i < (this.chunks.length - 2); i++)
|
||||
res.push(this.chunks[i]);
|
||||
break;
|
||||
case TX_SCRIPTHASH:
|
||||
res.push(this.chunks[1]);
|
||||
break;
|
||||
|
||||
case TX_UNKNOWN:
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
case TX_UNKNOWN:
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
return res;
|
||||
};
|
||||
|
||||
// return first extracted data item from script
|
||||
Script.prototype.captureOne = function ()
|
||||
{
|
||||
Script.prototype.captureOne = function() {
|
||||
var arr = this.capture();
|
||||
return arr[0];
|
||||
return arr[0];
|
||||
};
|
||||
|
||||
Script.prototype.getOutType = function ()
|
||||
{
|
||||
Script.prototype.getOutType = function() {
|
||||
var txType = this.classify();
|
||||
switch (txType) {
|
||||
case TX_PUBKEY: return 'Pubkey';
|
||||
case TX_PUBKEYHASH: return 'Address';
|
||||
default: return 'Strange';
|
||||
case TX_PUBKEY:
|
||||
return 'Pubkey';
|
||||
case TX_PUBKEYHASH:
|
||||
return 'Address';
|
||||
default:
|
||||
return 'Strange';
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -233,84 +222,79 @@ function spec(b) {
|
|||
return TX_TYPES[this.classify()];
|
||||
};
|
||||
|
||||
Script.prototype.simpleOutHash = function ()
|
||||
{
|
||||
Script.prototype.simpleOutHash = function() {
|
||||
switch (this.getOutType()) {
|
||||
case 'Address':
|
||||
return this.chunks[2];
|
||||
case 'Pubkey':
|
||||
return util.sha256ripe160(this.chunks[0]);
|
||||
default:
|
||||
log.debug("Encountered non-standard scriptPubKey");
|
||||
log.debug("Strange script was: " + this.toString());
|
||||
return null;
|
||||
case 'Address':
|
||||
return this.chunks[2];
|
||||
case 'Pubkey':
|
||||
return util.sha256ripe160(this.chunks[0]);
|
||||
default:
|
||||
log.debug("Encountered non-standard scriptPubKey");
|
||||
log.debug("Strange script was: " + this.toString());
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
Script.prototype.getInType = function ()
|
||||
{
|
||||
Script.prototype.getInType = function() {
|
||||
if (this.chunks.length == 1) {
|
||||
// Direct IP to IP transactions only have the public key in their scriptSig.
|
||||
return 'Pubkey';
|
||||
} else if (this.chunks.length == 2 &&
|
||||
Buffer.isBuffer(this.chunks[0]) &&
|
||||
Buffer.isBuffer(this.chunks[1])) {
|
||||
Buffer.isBuffer(this.chunks[0]) &&
|
||||
Buffer.isBuffer(this.chunks[1])) {
|
||||
return 'Address';
|
||||
} else {
|
||||
return 'Strange';
|
||||
}
|
||||
};
|
||||
|
||||
Script.prototype.simpleInPubKey = function ()
|
||||
{
|
||||
Script.prototype.simpleInPubKey = function() {
|
||||
switch (this.getInType()) {
|
||||
case 'Address':
|
||||
return this.chunks[1];
|
||||
case 'Pubkey':
|
||||
return null;
|
||||
default:
|
||||
log.debug("Encountered non-standard scriptSig");
|
||||
log.debug("Strange script was: " + this.toString());
|
||||
return null;
|
||||
case 'Address':
|
||||
return this.chunks[1];
|
||||
case 'Pubkey':
|
||||
return null;
|
||||
default:
|
||||
log.debug("Encountered non-standard scriptSig");
|
||||
log.debug("Strange script was: " + this.toString());
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
Script.prototype.getBuffer = function ()
|
||||
{
|
||||
Script.prototype.getBuffer = function() {
|
||||
return this.buffer;
|
||||
};
|
||||
|
||||
Script.fromStringContent = function(s) {
|
||||
var chunks = [];
|
||||
var split = s.split(' ');
|
||||
console.log(split);
|
||||
for (var i=0; i<split.length; i++) {
|
||||
var word = split[i];
|
||||
if (word.length > 2 && word.substring(0,2) === '0x') {
|
||||
chunks.push(new Buffer(word.substring(2,word.length), 'hex'));
|
||||
} else {
|
||||
var integer = parseInt(word);
|
||||
if (isNaN(integer)) {
|
||||
chunks.push(Opcode.map['OP_'+word]);
|
||||
} else {
|
||||
var hexi = integer.toString(16);
|
||||
if (hexi.length %2 === 1) hexi = '0'+hexi;
|
||||
console.log(hexi);
|
||||
chunks.push(new Buffer(hexi,'hex'));
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < split.length; i++) {
|
||||
var word = split[i];
|
||||
if (word.length > 2 && word.substring(0, 2) === '0x') {
|
||||
chunks.push(new Buffer(word.substring(2, word.length), 'hex'));
|
||||
} else {
|
||||
var opcode = Opcode.map['OP_' + word];
|
||||
if (opcode) {
|
||||
chunks.push(opcode);
|
||||
} else {
|
||||
var integer = parseInt(word);
|
||||
if (!isNaN(integer)) {
|
||||
//console.log(integer+' bits=\t'+integer.toString(2).replace('-','').length);
|
||||
var data = util.intToBuffer(integer);
|
||||
chunks.push(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Script.fromChunks(chunks);
|
||||
};
|
||||
|
||||
Script.prototype.getStringContent = function (truncate, maxEl)
|
||||
{
|
||||
Script.prototype.getStringContent = function(truncate, maxEl) {
|
||||
if (truncate === null) {
|
||||
truncate = true;
|
||||
}
|
||||
|
||||
if ("undefined" === typeof maxEl) {
|
||||
if ('undefined' === typeof maxEl) {
|
||||
maxEl = 15;
|
||||
}
|
||||
|
||||
|
@ -323,7 +307,7 @@ function spec(b) {
|
|||
}
|
||||
|
||||
if (Buffer.isBuffer(chunk)) {
|
||||
s += '0x'+util.formatBuffer(chunk, truncate ? null : 0);
|
||||
s += '0x' + util.formatBuffer(chunk, truncate ? null : 0);
|
||||
} else {
|
||||
s += Opcode.reverseMap[chunk];
|
||||
}
|
||||
|
@ -336,8 +320,7 @@ function spec(b) {
|
|||
return s;
|
||||
};
|
||||
|
||||
Script.prototype.toString = function (truncate, maxEl)
|
||||
{
|
||||
Script.prototype.toString = function(truncate, maxEl) {
|
||||
var script = "<Script ";
|
||||
script += this.getStringContent(truncate, maxEl);
|
||||
script += ">";
|
||||
|
@ -345,8 +328,7 @@ function spec(b) {
|
|||
};
|
||||
|
||||
|
||||
Script.prototype.writeOp = function (opcode)
|
||||
{
|
||||
Script.prototype.writeOp = function(opcode) {
|
||||
var buf = Buffer(this.buffer.length + 1);
|
||||
this.buffer.copy(buf);
|
||||
buf.writeUInt8(opcode, this.buffer.length);
|
||||
|
@ -356,8 +338,7 @@ function spec(b) {
|
|||
this.chunks.push(opcode);
|
||||
};
|
||||
|
||||
Script.prototype.writeN = function (n)
|
||||
{
|
||||
Script.prototype.writeN = function(n) {
|
||||
if (n < 0 || n > 16)
|
||||
throw new Error("writeN: out of range value " + n);
|
||||
|
||||
|
@ -367,8 +348,7 @@ function spec(b) {
|
|||
this.writeOp(OP_1 + n - 1);
|
||||
};
|
||||
|
||||
function prefixSize(data_length)
|
||||
{
|
||||
function prefixSize(data_length) {
|
||||
if (data_length < OP_PUSHDATA1) {
|
||||
return 1;
|
||||
} else if (data_length <= 0xff) {
|
||||
|
@ -385,21 +365,15 @@ function spec(b) {
|
|||
if (data_length < OP_PUSHDATA1) {
|
||||
buf = new Buffer(1);
|
||||
buf.writeUInt8(data_length, 0);
|
||||
}
|
||||
|
||||
else if (data_length <= 0xff) {
|
||||
} else if (data_length <= 0xff) {
|
||||
buf = new Buffer(1 + 1);
|
||||
buf.writeUInt8(OP_PUSHDATA1, 0);
|
||||
buf.writeUInt8(data_length, 1);
|
||||
}
|
||||
|
||||
else if (data_length <= 0xffff) {
|
||||
} else if (data_length <= 0xffff) {
|
||||
buf = new Buffer(1 + 2);
|
||||
buf.writeUInt8(OP_PUSHDATA2, 0);
|
||||
buf.writeUInt16LE(data_length, 1);
|
||||
}
|
||||
|
||||
else {
|
||||
} else {
|
||||
buf = new Buffer(1 + 4);
|
||||
buf.writeUInt8(OP_PUSHDATA4, 0);
|
||||
buf.writeUInt32LE(data_length, 1);
|
||||
|
@ -408,25 +382,22 @@ function spec(b) {
|
|||
return buf;
|
||||
};
|
||||
|
||||
Script.prototype.writeBytes = function (data)
|
||||
{
|
||||
Script.prototype.writeBytes = function(data) {
|
||||
var newSize = this.buffer.length + prefixSize(data.length) + data.length;
|
||||
this.buffer = Buffer.concat([this.buffer, encodeLen(data.length), data]);
|
||||
this.chunks.push(data);
|
||||
};
|
||||
|
||||
Script.prototype.updateBuffer = function ()
|
||||
{
|
||||
Script.prototype.updateBuffer = function() {
|
||||
this.buffer = Script.chunksToBuffer(this.chunks);
|
||||
};
|
||||
|
||||
Script.prototype.findAndDelete = function (chunk)
|
||||
{
|
||||
Script.prototype.findAndDelete = function(chunk) {
|
||||
var dirty = false;
|
||||
if (Buffer.isBuffer(chunk)) {
|
||||
for (var i = 0, l = this.chunks.length; i < l; i++) {
|
||||
if (Buffer.isBuffer(this.chunks[i]) &&
|
||||
buffertools.compare(this.chunks[i], chunk) === 0) {
|
||||
buffertools.compare(this.chunks[i], chunk) === 0) {
|
||||
this.chunks.splice(i, 1);
|
||||
dirty = true;
|
||||
}
|
||||
|
@ -452,7 +423,7 @@ function spec(b) {
|
|||
* These are used for coinbase transactions and at some point were used for
|
||||
* IP-based transactions as well.
|
||||
*/
|
||||
Script.createPubKeyOut = function (pubkey) {
|
||||
Script.createPubKeyOut = function(pubkey) {
|
||||
var script = new Script();
|
||||
script.writeBytes(pubkey);
|
||||
script.writeOp(OP_CHECKSIG);
|
||||
|
@ -462,7 +433,7 @@ function spec(b) {
|
|||
/**
|
||||
* Creates a standard txout script.
|
||||
*/
|
||||
Script.createPubKeyHashOut = function (pubKeyHash) {
|
||||
Script.createPubKeyHashOut = function(pubKeyHash) {
|
||||
var script = new Script();
|
||||
script.writeOp(OP_DUP);
|
||||
script.writeOp(OP_HASH160);
|
||||
|
@ -491,8 +462,8 @@ function spec(b) {
|
|||
return script;
|
||||
};
|
||||
|
||||
Script.fromTestData = function (testData) {
|
||||
testData = testData.map(function (chunk) {
|
||||
Script.fromTestData = function(testData) {
|
||||
testData = testData.map(function(chunk) {
|
||||
if ("string" === typeof chunk) {
|
||||
return new Buffer(chunk, 'hex');
|
||||
} else {
|
||||
|
@ -506,14 +477,14 @@ function spec(b) {
|
|||
return script;
|
||||
};
|
||||
|
||||
Script.fromChunks = function (chunks) {
|
||||
Script.fromChunks = function(chunks) {
|
||||
var script = new Script();
|
||||
script.chunks = chunks;
|
||||
script.updateBuffer();
|
||||
return script;
|
||||
};
|
||||
|
||||
Script.chunksToBuffer = function (chunks) {
|
||||
Script.chunksToBuffer = function(chunks) {
|
||||
var buf = new Put();
|
||||
|
||||
for (var i = 0, l = chunks.length; i < l; i++) {
|
||||
|
@ -544,4 +515,3 @@ function spec(b) {
|
|||
return Script;
|
||||
};
|
||||
module.defineClass(spec);
|
||||
|
||||
|
|
|
@ -88,9 +88,10 @@ describe('Script', function() {
|
|||
|
||||
test_data.dataScriptValid.forEach(function(datum) {
|
||||
if (datum.length < 2) throw new Error('Invalid test data');
|
||||
var human = datum[1];
|
||||
var human = datum[0] + ' ' + datum[1];
|
||||
it('should parse script from human readable ' + human, function() {
|
||||
Script.fromStringContent(human).getStringContent(false, null).should.equal(human);
|
||||
var h2 = Script.fromStringContent(human).getStringContent(false, null);
|
||||
Script.fromStringContent(h2).getStringContent(false, null).should.equal(h2);
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ var Out;
|
|||
var Script = bitcore.Script.class();
|
||||
var buffertools = require('buffertools');
|
||||
var test_data = require('./testdata');
|
||||
var async = require('async');
|
||||
|
||||
describe('Transaction', function() {
|
||||
it('should initialze the main object', function() {
|
||||
|
@ -45,7 +44,7 @@ describe('Transaction', function() {
|
|||
var hash = vin[0];
|
||||
var index = vin[1];
|
||||
var scriptPubKey = new Script(new Buffer(vin[2]));
|
||||
map[[hash, index]] = scriptPubKey;//Script.fromStringContent(scriptPubKey);
|
||||
map[[hash, index]] = scriptPubKey; //Script.fromStringContent(scriptPubKey);
|
||||
console.log(scriptPubKey.getStringContent());
|
||||
console.log('********************************');
|
||||
|
||||
|
@ -58,18 +57,10 @@ describe('Transaction', function() {
|
|||
|
||||
var i = 0;
|
||||
var stx = tx.getStandardizedObject();
|
||||
async.eachSeries(tx.ins,
|
||||
function(txin, next) {
|
||||
var scriptPubKey = map[[stx.in[i].prev_out.hash, stx.in[i].prev_out.n]];
|
||||
i += 1;
|
||||
next();
|
||||
|
||||
},
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
done();
|
||||
}
|
||||
);
|
||||
tx.ins.forEach(function(txin) {
|
||||
var scriptPubKey = map[[stx. in [i].prev_out.hash, stx. in [i].prev_out.n]];
|
||||
i += 1;
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -46,4 +46,23 @@ describe('util', function() {
|
|||
});
|
||||
});
|
||||
});
|
||||
describe('#intToBuffer', function() {
|
||||
var data = [
|
||||
[0, '00000000'],
|
||||
[-0, '00000000'],
|
||||
[-1, 'ffffffff'],
|
||||
[1, '01000000'],
|
||||
[18, '12000000'],
|
||||
[878082192, '90785634'],
|
||||
[0x01234567890, '1200000090785634'],
|
||||
[-4294967297, 'feffffffffffffff'],
|
||||
];
|
||||
data.forEach(function(datum) {
|
||||
var integer = datum[0];
|
||||
var result = datum[1];
|
||||
it('should work for ' + integer, function() {
|
||||
buffertools.toHex(coinUtil.intToBuffer(integer)).should.equal(result);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
24
util/util.js
24
util/util.js
|
@ -105,6 +105,30 @@ var bigIntToValue = exports.bigIntToValue = function (valueBigInt) {
|
|||
}
|
||||
};
|
||||
|
||||
var intTo64Bits = function(integer) {
|
||||
return {
|
||||
hi: Math.floor(integer / 4294967296),
|
||||
lo: (integer & 0xFFFFFFFF) >>> 0
|
||||
};
|
||||
};
|
||||
var fitsIn32Bits = function(integer) {
|
||||
// TODO: make this efficient!!!
|
||||
return integer.toString(2).replace('-','').length < 32;
|
||||
}
|
||||
exports.intToBuffer = function(integer) {
|
||||
if (fitsIn32Bits(integer)) {
|
||||
var data = new Buffer(4);
|
||||
data.writeInt32LE(integer, 0);
|
||||
return data;
|
||||
} else {
|
||||
var x = intTo64Bits(integer);
|
||||
var data = new Buffer(8);
|
||||
data.writeInt32LE(x.hi, 0); // high part contains sign information (signed)
|
||||
data.writeUInt32LE(x.lo, 4); // low part encoded as unsigned integer
|
||||
return data;
|
||||
}
|
||||
};
|
||||
|
||||
var formatValue = exports.formatValue = function (valueBuffer) {
|
||||
var value = valueToBigInt(valueBuffer).toString();
|
||||
var integerPart = value.length > 8 ? value.substr(0, value.length-8) : '0';
|
||||
|
|
Loading…
Reference in New Issue