Skip to content

Commit

Permalink
fix reading/writing BigInts in browsers that don't support BigInt at all
Browse files Browse the repository at this point in the history
  • Loading branch information
KurtThiemann committed Nov 7, 2022
1 parent b0a54d0 commit cec4d22
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 8 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "armarius",
"version": "1.7.0",
"version": "1.7.1",
"description": "A JavaScript library to read, write, and merge ZIP archives in web browsers.",
"repository": "github:aternosorg/armarius",
"type": "module",
Expand Down
5 changes: 4 additions & 1 deletion src/Util/BigInt.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@

export const nativeBigIntSupport = typeof BigInt === 'function';

/*
Simply replacing BigInt works in the context of this library,
as all the values read as BigInt can only be used as regular Numbers anyway,
since both DataView and FileReader do not support BigInt offset and length parameters.
*/
export default (typeof BigInt === 'function' ? BigInt : Number);
export default (nativeBigIntSupport ? BigInt : Number);
24 changes: 18 additions & 6 deletions src/Util/BigIntUtils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import BigInt from "./BigInt.js";
import BigInt, {nativeBigIntSupport} from './BigInt.js';
import Constants from '../Constants.js';

export default class BigIntUtils {
/**
Expand All @@ -9,13 +10,17 @@ export default class BigIntUtils {
* @return {number|BigInt}
*/
static getBigUint64FromView(dataView, byteOffset, littleEndian, native = true) {
if(DataView.prototype.getBigUint64 && native) {
if (DataView.prototype.getBigUint64 && native) {
return dataView.getBigUint64(byteOffset, littleEndian);
}
const [h, l] = littleEndian ? [4, 0] : [0, 4];
const wh = BigInt(dataView.getUint32(byteOffset + h, littleEndian));
const wl = BigInt(dataView.getUint32(byteOffset + l, littleEndian));
return (wh << BigInt(32)) + wl;

if (nativeBigIntSupport) {
return (wh << BigInt(32)) + wl;
}
return wh * BigInt(Constants.MAX_UINT32) + wl;
}

/**
Expand All @@ -27,11 +32,18 @@ export default class BigIntUtils {
* @returns {void}
*/
static setBigUint64InView(dataView, byteOffset, value, littleEndian, native = true) {
if(DataView.prototype.setBigUint64 && native) {
if (DataView.prototype.setBigUint64 && native) {
return dataView.setBigUint64(byteOffset, value, littleEndian);
}
const wh = Number((value >> BigInt(32)) & BigInt(0xFFFFFFFF));
const wl = Number(value & BigInt(0xFFFFFFFF));

let wh, wl;
if (nativeBigIntSupport) {
wh = Number((value >> BigInt(32)) & BigInt(0xFFFFFFFF));
wl = Number(value & BigInt(0xFFFFFFFF));
} else {
wh = Math.floor(Number(value) / Constants.MAX_UINT32);
wl = Number(value) - wh * Constants.MAX_UINT32;
}
const [h, l] = littleEndian ? [4, 0] : [0, 4];
dataView.setUint32(byteOffset + h, wh, littleEndian);
dataView.setUint32(byteOffset + l, wl, littleEndian);
Expand Down

0 comments on commit cec4d22

Please sign in to comment.