mirror of
https://github.com/github/codeql-action.git
synced 2025-12-30 11:10:22 +08:00
Co-authored-by: Andrew Eisenberg <aeisenberg@github.com> Co-authored-by: Henry Mercer <henrymercer@github.com>
239 lines
8.0 KiB
JavaScript
239 lines
8.0 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.PbLong = exports.PbULong = exports.detectBi = void 0;
|
|
const goog_varint_1 = require("./goog-varint");
|
|
let BI;
|
|
function detectBi() {
|
|
const dv = new DataView(new ArrayBuffer(8));
|
|
const ok = globalThis.BigInt !== undefined
|
|
&& typeof dv.getBigInt64 === "function"
|
|
&& typeof dv.getBigUint64 === "function"
|
|
&& typeof dv.setBigInt64 === "function"
|
|
&& typeof dv.setBigUint64 === "function";
|
|
BI = ok ? {
|
|
MIN: BigInt("-9223372036854775808"),
|
|
MAX: BigInt("9223372036854775807"),
|
|
UMIN: BigInt("0"),
|
|
UMAX: BigInt("18446744073709551615"),
|
|
C: BigInt,
|
|
V: dv,
|
|
} : undefined;
|
|
}
|
|
exports.detectBi = detectBi;
|
|
detectBi();
|
|
function assertBi(bi) {
|
|
if (!bi)
|
|
throw new Error("BigInt unavailable, see https://github.com/timostamm/protobuf-ts/blob/v1.0.8/MANUAL.md#bigint-support");
|
|
}
|
|
// used to validate from(string) input (when bigint is unavailable)
|
|
const RE_DECIMAL_STR = /^-?[0-9]+$/;
|
|
// constants for binary math
|
|
const TWO_PWR_32_DBL = 0x100000000;
|
|
const HALF_2_PWR_32 = 0x080000000;
|
|
// base class for PbLong and PbULong provides shared code
|
|
class SharedPbLong {
|
|
/**
|
|
* Create a new instance with the given bits.
|
|
*/
|
|
constructor(lo, hi) {
|
|
this.lo = lo | 0;
|
|
this.hi = hi | 0;
|
|
}
|
|
/**
|
|
* Is this instance equal to 0?
|
|
*/
|
|
isZero() {
|
|
return this.lo == 0 && this.hi == 0;
|
|
}
|
|
/**
|
|
* Convert to a native number.
|
|
*/
|
|
toNumber() {
|
|
let result = this.hi * TWO_PWR_32_DBL + (this.lo >>> 0);
|
|
if (!Number.isSafeInteger(result))
|
|
throw new Error("cannot convert to safe number");
|
|
return result;
|
|
}
|
|
}
|
|
/**
|
|
* 64-bit unsigned integer as two 32-bit values.
|
|
* Converts between `string`, `number` and `bigint` representations.
|
|
*/
|
|
class PbULong extends SharedPbLong {
|
|
/**
|
|
* Create instance from a `string`, `number` or `bigint`.
|
|
*/
|
|
static from(value) {
|
|
if (BI)
|
|
// noinspection FallThroughInSwitchStatementJS
|
|
switch (typeof value) {
|
|
case "string":
|
|
if (value == "0")
|
|
return this.ZERO;
|
|
if (value == "")
|
|
throw new Error('string is no integer');
|
|
value = BI.C(value);
|
|
case "number":
|
|
if (value === 0)
|
|
return this.ZERO;
|
|
value = BI.C(value);
|
|
case "bigint":
|
|
if (!value)
|
|
return this.ZERO;
|
|
if (value < BI.UMIN)
|
|
throw new Error('signed value for ulong');
|
|
if (value > BI.UMAX)
|
|
throw new Error('ulong too large');
|
|
BI.V.setBigUint64(0, value, true);
|
|
return new PbULong(BI.V.getInt32(0, true), BI.V.getInt32(4, true));
|
|
}
|
|
else
|
|
switch (typeof value) {
|
|
case "string":
|
|
if (value == "0")
|
|
return this.ZERO;
|
|
value = value.trim();
|
|
if (!RE_DECIMAL_STR.test(value))
|
|
throw new Error('string is no integer');
|
|
let [minus, lo, hi] = goog_varint_1.int64fromString(value);
|
|
if (minus)
|
|
throw new Error('signed value for ulong');
|
|
return new PbULong(lo, hi);
|
|
case "number":
|
|
if (value == 0)
|
|
return this.ZERO;
|
|
if (!Number.isSafeInteger(value))
|
|
throw new Error('number is no integer');
|
|
if (value < 0)
|
|
throw new Error('signed value for ulong');
|
|
return new PbULong(value, value / TWO_PWR_32_DBL);
|
|
}
|
|
throw new Error('unknown value ' + typeof value);
|
|
}
|
|
/**
|
|
* Convert to decimal string.
|
|
*/
|
|
toString() {
|
|
return BI ? this.toBigInt().toString() : goog_varint_1.int64toString(this.lo, this.hi);
|
|
}
|
|
/**
|
|
* Convert to native bigint.
|
|
*/
|
|
toBigInt() {
|
|
assertBi(BI);
|
|
BI.V.setInt32(0, this.lo, true);
|
|
BI.V.setInt32(4, this.hi, true);
|
|
return BI.V.getBigUint64(0, true);
|
|
}
|
|
}
|
|
exports.PbULong = PbULong;
|
|
/**
|
|
* ulong 0 singleton.
|
|
*/
|
|
PbULong.ZERO = new PbULong(0, 0);
|
|
/**
|
|
* 64-bit signed integer as two 32-bit values.
|
|
* Converts between `string`, `number` and `bigint` representations.
|
|
*/
|
|
class PbLong extends SharedPbLong {
|
|
/**
|
|
* Create instance from a `string`, `number` or `bigint`.
|
|
*/
|
|
static from(value) {
|
|
if (BI)
|
|
// noinspection FallThroughInSwitchStatementJS
|
|
switch (typeof value) {
|
|
case "string":
|
|
if (value == "0")
|
|
return this.ZERO;
|
|
if (value == "")
|
|
throw new Error('string is no integer');
|
|
value = BI.C(value);
|
|
case "number":
|
|
if (value === 0)
|
|
return this.ZERO;
|
|
value = BI.C(value);
|
|
case "bigint":
|
|
if (!value)
|
|
return this.ZERO;
|
|
if (value < BI.MIN)
|
|
throw new Error('signed long too small');
|
|
if (value > BI.MAX)
|
|
throw new Error('signed long too large');
|
|
BI.V.setBigInt64(0, value, true);
|
|
return new PbLong(BI.V.getInt32(0, true), BI.V.getInt32(4, true));
|
|
}
|
|
else
|
|
switch (typeof value) {
|
|
case "string":
|
|
if (value == "0")
|
|
return this.ZERO;
|
|
value = value.trim();
|
|
if (!RE_DECIMAL_STR.test(value))
|
|
throw new Error('string is no integer');
|
|
let [minus, lo, hi] = goog_varint_1.int64fromString(value);
|
|
if (minus) {
|
|
if (hi > HALF_2_PWR_32 || (hi == HALF_2_PWR_32 && lo != 0))
|
|
throw new Error('signed long too small');
|
|
}
|
|
else if (hi >= HALF_2_PWR_32)
|
|
throw new Error('signed long too large');
|
|
let pbl = new PbLong(lo, hi);
|
|
return minus ? pbl.negate() : pbl;
|
|
case "number":
|
|
if (value == 0)
|
|
return this.ZERO;
|
|
if (!Number.isSafeInteger(value))
|
|
throw new Error('number is no integer');
|
|
return value > 0
|
|
? new PbLong(value, value / TWO_PWR_32_DBL)
|
|
: new PbLong(-value, -value / TWO_PWR_32_DBL).negate();
|
|
}
|
|
throw new Error('unknown value ' + typeof value);
|
|
}
|
|
/**
|
|
* Do we have a minus sign?
|
|
*/
|
|
isNegative() {
|
|
return (this.hi & HALF_2_PWR_32) !== 0;
|
|
}
|
|
/**
|
|
* Negate two's complement.
|
|
* Invert all the bits and add one to the result.
|
|
*/
|
|
negate() {
|
|
let hi = ~this.hi, lo = this.lo;
|
|
if (lo)
|
|
lo = ~lo + 1;
|
|
else
|
|
hi += 1;
|
|
return new PbLong(lo, hi);
|
|
}
|
|
/**
|
|
* Convert to decimal string.
|
|
*/
|
|
toString() {
|
|
if (BI)
|
|
return this.toBigInt().toString();
|
|
if (this.isNegative()) {
|
|
let n = this.negate();
|
|
return '-' + goog_varint_1.int64toString(n.lo, n.hi);
|
|
}
|
|
return goog_varint_1.int64toString(this.lo, this.hi);
|
|
}
|
|
/**
|
|
* Convert to native bigint.
|
|
*/
|
|
toBigInt() {
|
|
assertBi(BI);
|
|
BI.V.setInt32(0, this.lo, true);
|
|
BI.V.setInt32(4, this.hi, true);
|
|
return BI.V.getBigInt64(0, true);
|
|
}
|
|
}
|
|
exports.PbLong = PbLong;
|
|
/**
|
|
* long 0 singleton.
|
|
*/
|
|
PbLong.ZERO = new PbLong(0, 0);
|