From 8834a385e914fcb49d7b69c0d7663d73a533bfa1 Mon Sep 17 00:00:00 2001 From: Yan Chen Date: Wed, 25 May 2022 11:38:05 -0700 Subject: [PATCH 1/3] fix: Candid UI cannot encode nat8 --- packages/candid/src/candid-ui.ts | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/packages/candid/src/candid-ui.ts b/packages/candid/src/candid-ui.ts index a5ea95de5..83e8b252e 100644 --- a/packages/candid/src/candid-ui.ts +++ b/packages/candid/src/candid-ui.ts @@ -117,6 +117,20 @@ class Parse extends IDL.Visitor { public visitFloat(t: IDL.FloatClass, v: string): number { return parseFloat(v); } + public visitFixedInt(t: FixedIntClass, v: string): number | bigint { + if (t._bits <= 32) { + return parseInt(v, 10); + } else { + return BigInt(v); + } + } + public visitFixedNat(t: FixedNatClass, v: string): number | bigint { + if (t._bits <= 32) { + return parseInt(v, 10); + } else { + return BigInt(v); + } + } public visitNumber(t: IDL.PrimitiveType, v: string): bigint { return BigInt(v); } @@ -151,11 +165,21 @@ class Random extends IDL.Visitor { public visitNat(t: IDL.NatClass, v: string): bigint { return BigInt(this.generateNumber(false)); } - public visitFixedInt(t: IDL.FixedIntClass, v: string): bigint { - return BigInt(this.generateNumber(true)); + public visitFixedInt(t: IDL.FixedIntClass, v: string): number | bigint { + const v = this.generateNumber(true); + if (t._bits <= 32) { + return v; + } else { + return BigInt(v); + } } - public visitFixedNat(t: IDL.FixedNatClass, v: string): bigint { - return BigInt(this.generateNumber(false)); + public visitFixedNat(t: IDL.FixedNatClass, v: string): number | bigint { + const v = this.generateNumber(false); + if (t._bits <= 32) { + return v; + } else { + return BigInt(v); + } } private generateNumber(signed: boolean): number { const num = Math.floor(Math.random() * 100); From 4f5e48b0ebd95e1310755015da9ef403ab9b9fbc Mon Sep 17 00:00:00 2001 From: Yan Chen Date: Wed, 25 May 2022 11:47:22 -0700 Subject: [PATCH 2/3] fix --- packages/candid/src/candid-ui.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/candid/src/candid-ui.ts b/packages/candid/src/candid-ui.ts index 83e8b252e..4c504ce69 100644 --- a/packages/candid/src/candid-ui.ts +++ b/packages/candid/src/candid-ui.ts @@ -117,14 +117,14 @@ class Parse extends IDL.Visitor { public visitFloat(t: IDL.FloatClass, v: string): number { return parseFloat(v); } - public visitFixedInt(t: FixedIntClass, v: string): number | bigint { + public visitFixedInt(t: IDL.FixedIntClass, v: string): number | bigint { if (t._bits <= 32) { return parseInt(v, 10); } else { return BigInt(v); } } - public visitFixedNat(t: FixedNatClass, v: string): number | bigint { + public visitFixedNat(t: IDL.FixedNatClass, v: string): number | bigint { if (t._bits <= 32) { return parseInt(v, 10); } else { @@ -166,17 +166,17 @@ class Random extends IDL.Visitor { return BigInt(this.generateNumber(false)); } public visitFixedInt(t: IDL.FixedIntClass, v: string): number | bigint { - const v = this.generateNumber(true); + const x = this.generateNumber(true); if (t._bits <= 32) { - return v; + return x; } else { return BigInt(v); } } public visitFixedNat(t: IDL.FixedNatClass, v: string): number | bigint { - const v = this.generateNumber(false); + const x = this.generateNumber(false); if (t._bits <= 32) { - return v; + return x; } else { return BigInt(v); } From 53b550acfb7043cfceac1347d65711fb5a0d6380 Mon Sep 17 00:00:00 2001 From: Yan Chen Date: Wed, 25 May 2022 11:54:12 -0700 Subject: [PATCH 3/3] fix --- packages/candid/src/idl.ts | 39 ++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/packages/candid/src/idl.ts b/packages/candid/src/idl.ts index 9b62d8388..c8953c434 100644 --- a/packages/candid/src/idl.ts +++ b/packages/candid/src/idl.ts @@ -621,7 +621,7 @@ export class FloatClass extends PrimitiveType { * Represents an IDL fixed-width Int(n) */ export class FixedIntClass extends PrimitiveType { - constructor(public _bits: number) { + constructor(public readonly _bits: number) { super(); } @@ -674,7 +674,7 @@ export class FixedIntClass extends PrimitiveType { * Represents an IDL fixed-width Nat(n) */ export class FixedNatClass extends PrimitiveType { - constructor(public readonly bits: number) { + constructor(public readonly _bits: number) { super(); } @@ -683,7 +683,7 @@ export class FixedNatClass extends PrimitiveType { } public covariant(x: any): x is bigint { - const max = BigInt(2) ** BigInt(this.bits); + const max = BigInt(2) ** BigInt(this._bits); if (typeof x === 'bigint' && x >= BigInt(0)) { return x < max; } else if (Number.isInteger(x) && x >= 0) { @@ -695,18 +695,18 @@ export class FixedNatClass extends PrimitiveType { } public encodeValue(x: bigint | number) { - return writeUIntLE(x, this.bits / 8); + return writeUIntLE(x, this._bits / 8); } public encodeType() { - const offset = Math.log2(this.bits) - 3; + const offset = Math.log2(this._bits) - 3; return slebEncode(-5 - offset); } public decodeValue(b: Pipe, t: Type) { this.checkType(t); - const num = readUIntLE(b, this.bits / 8); - if (this.bits <= 32) { + const num = readUIntLE(b, this._bits / 8); + if (this._bits <= 32) { return Number(num); } else { return num; @@ -714,7 +714,7 @@ export class FixedNatClass extends PrimitiveType { } get name() { - return `nat${this.bits}`; + return `nat${this._bits}`; } public valueToString(x: bigint | number) { @@ -741,7 +741,7 @@ export class VecClass extends ConstructType { constructor(protected _type: Type) { super(); - if (_type instanceof FixedNatClass && _type.bits === 8) { + if (_type instanceof FixedNatClass && _type._bits === 8) { this._blobOptimization = true; } } @@ -752,9 +752,16 @@ export class VecClass extends ConstructType { public covariant(x: any): x is T[] { // Special case for ArrayBuffer - const bits = this._type instanceof FixedNatClass ? this._type.bits : (this._type instanceof FixedIntClass ? this._type._bits : 0); - return (ArrayBuffer.isView(x) && bits == (x as any).BYTES_PER_ELEMENT * 8) - || (Array.isArray(x) && x.every(v => this._type.covariant(v))); + const bits = + this._type instanceof FixedNatClass + ? this._type._bits + : this._type instanceof FixedIntClass + ? this._type._bits + : 0; + return ( + (ArrayBuffer.isView(x) && bits == (x as any).BYTES_PER_ELEMENT * 8) || + (Array.isArray(x) && x.every(v => this._type.covariant(v))) + ); } public encodeValue(x: T[]) { @@ -790,16 +797,16 @@ export class VecClass extends ConstructType { const len = Number(lebDecode(b)); if (this._type instanceof FixedNatClass) { - if (this._type.bits == 8) { + if (this._type._bits == 8) { return new Uint8Array(b.read(len)) as unknown as T[]; } - if (this._type.bits == 16) { + if (this._type._bits == 16) { return new Uint16Array(b.read(len * 2)) as unknown as T[]; } - if (this._type.bits == 32) { + if (this._type._bits == 32) { return new Uint32Array(b.read(len * 4)) as unknown as T[]; } - if (this._type.bits == 64) { + if (this._type._bits == 64) { return new BigUint64Array(b.read(len * 8)) as unknown as T[]; } }