int64.js
1.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
var util = require('../core').util;
var toBuffer = util.buffer.toBuffer;
/**
* A lossless representation of a signed, 64-bit integer. Instances of this
* class may be used in arithmetic expressions as if they were numeric
* primitives, but the binary representation will be preserved unchanged as the
* `bytes` property of the object. The bytes should be encoded as big-endian,
* two's complement integers.
* @param {Buffer} bytes
*
* @api private
*/
function Int64(bytes) {
if (bytes.length !== 8) {
throw new Error('Int64 buffers must be exactly 8 bytes');
}
if (!util.Buffer.isBuffer(bytes)) bytes = toBuffer(bytes);
this.bytes = bytes;
}
/**
* @param {number} number
* @returns {Int64}
*
* @api private
*/
Int64.fromNumber = function(number) {
if (number > 9223372036854775807 || number < -9223372036854775808) {
throw new Error(
number + ' is too large (or, if negative, too small) to represent as an Int64'
);
}
var bytes = new Uint8Array(8);
for (
var i = 7, remaining = Math.abs(Math.round(number));
i > -1 && remaining > 0;
i--, remaining /= 256
) {
bytes[i] = remaining;
}
if (number < 0) {
negate(bytes);
}
return new Int64(bytes);
};
/**
* @returns {number}
*
* @api private
*/
Int64.prototype.valueOf = function() {
var bytes = this.bytes.slice(0);
var negative = bytes[0] & 128;
if (negative) {
negate(bytes);
}
return parseInt(bytes.toString('hex'), 16) * (negative ? -1 : 1);
};
Int64.prototype.toString = function() {
return String(this.valueOf());
};
/**
* @param {Buffer} bytes
*
* @api private
*/
function negate(bytes) {
for (var i = 0; i < 8; i++) {
bytes[i] ^= 0xFF;
}
for (var i = 7; i > -1; i--) {
bytes[i]++;
if (bytes[i] !== 0) {
break;
}
}
}
/**
* @api private
*/
module.exports = {
Int64: Int64
};