| "use strict"; |
| module.exports = LongBits; |
| |
| var util = require("../util/minimal"); |
| |
| /** |
| * Constructs new long bits. |
| * @classdesc Helper class for working with the low and high bits of a 64 bit value. |
| * @memberof util |
| * @constructor |
| * @param {number} lo Low 32 bits, unsigned |
| * @param {number} hi High 32 bits, unsigned |
| */ |
| function LongBits(lo, hi) { |
| |
| // note that the casts below are theoretically unnecessary as of today, but older statically |
| // generated converter code might still call the ctor with signed 32bits. kept for compat. |
| |
| /** |
| * Low bits. |
| * @type {number} |
| */ |
| this.lo = lo >>> 0; |
| |
| /** |
| * High bits. |
| * @type {number} |
| */ |
| this.hi = hi >>> 0; |
| } |
| |
| /** |
| * Zero bits. |
| * @memberof util.LongBits |
| * @type {util.LongBits} |
| */ |
| var zero = LongBits.zero = new LongBits(0, 0); |
| |
| zero.toNumber = function() { return 0; }; |
| zero.zzEncode = zero.zzDecode = function() { return this; }; |
| zero.length = function() { return 1; }; |
| |
| /** |
| * Zero hash. |
| * @memberof util.LongBits |
| * @type {string} |
| */ |
| var zeroHash = LongBits.zeroHash = "\0\0\0\0\0\0\0\0"; |
| |
| /** |
| * Constructs new long bits from the specified number. |
| * @param {number} value Value |
| * @returns {util.LongBits} Instance |
| */ |
| LongBits.fromNumber = function fromNumber(value) { |
| if (value === 0) |
| return zero; |
| var sign = value < 0; |
| if (sign) |
| value = -value; |
| var lo = value >>> 0, |
| hi = (value - lo) / 4294967296 >>> 0; |
| if (sign) { |
| hi = ~hi >>> 0; |
| lo = ~lo >>> 0; |
| if (++lo > 4294967295) { |
| lo = 0; |
| if (++hi > 4294967295) |
| hi = 0; |
| } |
| } |
| return new LongBits(lo, hi); |
| }; |
| |
| /** |
| * Constructs new long bits from a number, long or string. |
| * @param {Long|number|string} value Value |
| * @returns {util.LongBits} Instance |
| */ |
| LongBits.from = function from(value) { |
| if (typeof value === "number") |
| return LongBits.fromNumber(value); |
| if (util.isString(value)) { |
| /* istanbul ignore else */ |
| if (util.Long) |
| value = util.Long.fromString(value); |
| else |
| return LongBits.fromNumber(parseInt(value, 10)); |
| } |
| return value.low || value.high ? new LongBits(value.low >>> 0, value.high >>> 0) : zero; |
| }; |
| |
| /** |
| * Converts this long bits to a possibly unsafe JavaScript number. |
| * @param {boolean} [unsigned=false] Whether unsigned or not |
| * @returns {number} Possibly unsafe number |
| */ |
| LongBits.prototype.toNumber = function toNumber(unsigned) { |
| if (!unsigned && this.hi >>> 31) { |
| var lo = ~this.lo + 1 >>> 0, |
| hi = ~this.hi >>> 0; |
| if (!lo) |
| hi = hi + 1 >>> 0; |
| return -(lo + hi * 4294967296); |
| } |
| return this.lo + this.hi * 4294967296; |
| }; |
| |
| /** |
| * Converts this long bits to a long. |
| * @param {boolean} [unsigned=false] Whether unsigned or not |
| * @returns {Long} Long |
| */ |
| LongBits.prototype.toLong = function toLong(unsigned) { |
| return util.Long |
| ? new util.Long(this.lo | 0, this.hi | 0, Boolean(unsigned)) |
| /* istanbul ignore next */ |
| : { low: this.lo | 0, high: this.hi | 0, unsigned: Boolean(unsigned) }; |
| }; |
| |
| var charCodeAt = String.prototype.charCodeAt; |
| |
| /** |
| * Constructs new long bits from the specified 8 characters long hash. |
| * @param {string} hash Hash |
| * @returns {util.LongBits} Bits |
| */ |
| LongBits.fromHash = function fromHash(hash) { |
| if (hash === zeroHash) |
| return zero; |
| return new LongBits( |
| ( charCodeAt.call(hash, 0) |
| | charCodeAt.call(hash, 1) << 8 |
| | charCodeAt.call(hash, 2) << 16 |
| | charCodeAt.call(hash, 3) << 24) >>> 0 |
| , |
| ( charCodeAt.call(hash, 4) |
| | charCodeAt.call(hash, 5) << 8 |
| | charCodeAt.call(hash, 6) << 16 |
| | charCodeAt.call(hash, 7) << 24) >>> 0 |
| ); |
| }; |
| |
| /** |
| * Converts this long bits to a 8 characters long hash. |
| * @returns {string} Hash |
| */ |
| LongBits.prototype.toHash = function toHash() { |
| return String.fromCharCode( |
| this.lo & 255, |
| this.lo >>> 8 & 255, |
| this.lo >>> 16 & 255, |
| this.lo >>> 24 , |
| this.hi & 255, |
| this.hi >>> 8 & 255, |
| this.hi >>> 16 & 255, |
| this.hi >>> 24 |
| ); |
| }; |
| |
| /** |
| * Zig-zag encodes this long bits. |
| * @returns {util.LongBits} `this` |
| */ |
| LongBits.prototype.zzEncode = function zzEncode() { |
| var mask = this.hi >> 31; |
| this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0; |
| this.lo = ( this.lo << 1 ^ mask) >>> 0; |
| return this; |
| }; |
| |
| /** |
| * Zig-zag decodes this long bits. |
| * @returns {util.LongBits} `this` |
| */ |
| LongBits.prototype.zzDecode = function zzDecode() { |
| var mask = -(this.lo & 1); |
| this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0; |
| this.hi = ( this.hi >>> 1 ^ mask) >>> 0; |
| return this; |
| }; |
| |
| /** |
| * Calculates the length of this longbits when encoded as a varint. |
| * @returns {number} Length |
| */ |
| LongBits.prototype.length = function length() { |
| var part0 = this.lo, |
| part1 = (this.lo >>> 28 | this.hi << 4) >>> 0, |
| part2 = this.hi >>> 24; |
| return part2 === 0 |
| ? part1 === 0 |
| ? part0 < 16384 |
| ? part0 < 128 ? 1 : 2 |
| : part0 < 2097152 ? 3 : 4 |
| : part1 < 16384 |
| ? part1 < 128 ? 5 : 6 |
| : part1 < 2097152 ? 7 : 8 |
| : part2 < 128 ? 9 : 10; |
| }; |