From d51ddc70f9a7cd58d670f379af6b2e996a31f342 Mon Sep 17 00:00:00 2001 From: Jaco Date: Fri, 7 Apr 2023 09:24:11 +0300 Subject: [PATCH] Add `BitVec.toBoolArray()` helper function (#5585) --- CHANGELOG.md | 8 ++++ .../types-codec/src/extended/BitVec.spec.ts | 38 +++++++++++++++++++ packages/types-codec/src/extended/BitVec.ts | 30 +++++++++++++++ .../PortableRegistry/PortableRegistry.ts | 15 ++++++-- 4 files changed, 87 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2585f8e69..78e7c52bf5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # CHANGELOG +## master + +Changes: + +- Add `BitVec.toBoolArray()` helper function +- Tie down `BitVec` from metadata to only allow (default) Lsb + + ## 10.2.2 Apr 1, 2023 Contributed: diff --git a/packages/types-codec/src/extended/BitVec.spec.ts b/packages/types-codec/src/extended/BitVec.spec.ts index 581fc2fd7e..8fdabfd608 100644 --- a/packages/types-codec/src/extended/BitVec.spec.ts +++ b/packages/types-codec/src/extended/BitVec.spec.ts @@ -48,6 +48,44 @@ describe('BitVec', (): void => { }); }); + describe('toBoolArray() ordering', (): void => { + it('defaults to Lsb', (): void => { + expect( + new BitVec(registry, '0x0100010500').toBoolArray() + ).toEqual([ + true, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, + true, false, false, false, false, false, false, false, + true, false, true, false, false, false, false, false, + false, false, false, false, false, false, false, false + ]); + }); + + it('can output to Msb', (): void => { + expect( + new BitVec(registry, '0x0100010500', true).toBoolArray() + ).toEqual([ + false, false, false, false, false, false, false, true, + false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, true, + false, false, false, false, false, true, false, true, + false, false, false, false, false, false, false, false + ]); + }); + + it('outputs all LSB bits', (): void => { + expect( + new BitVec(registry, '0x01000105ff').toBoolArray() + ).toEqual([ + true, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, + true, false, false, false, false, false, false, false, + true, false, true, false, false, false, false, false, + true, true, true, true, true, true, true, true + ]); + }); + }); + it('has a sane inspect', (): void => { expect( new BitVec(registry, '0x0837').inspect() diff --git a/packages/types-codec/src/extended/BitVec.ts b/packages/types-codec/src/extended/BitVec.ts index e2d0c42ec4..04e4ff5b3c 100644 --- a/packages/types-codec/src/extended/BitVec.ts +++ b/packages/types-codec/src/extended/BitVec.ts @@ -73,6 +73,36 @@ export class BitVec extends Raw { }; } + /** + * @description Creates a boolean array of the bit values + */ + public toBoolArray (): boolean[] { + const map = [...this.toU8a(true)].map((v) => [ + !!(v & 0b1000_0000), + !!(v & 0b0100_0000), + !!(v & 0b0010_0000), + !!(v & 0b0001_0000), + !!(v & 0b0000_1000), + !!(v & 0b0000_0100), + !!(v & 0b0000_0010), + !!(v & 0b0000_0001) + ]); + const result = new Array(8 * map.length); + + for (let i = 0; i < map.length; i++) { + const off = i * 8; + const v = map[i]; + + for (let j = 0; j < 8; j++) { + result[off + j] = this.#isMsb + ? v[j] + : v[7 - j]; + } + } + + return result; + } + /** * @description Converts the Object to to a human-friendly JSON, with additional fields, expansion and formatting of information */ diff --git a/packages/types/src/metadata/PortableRegistry/PortableRegistry.ts b/packages/types/src/metadata/PortableRegistry/PortableRegistry.ts index 03817830f7..701490109c 100644 --- a/packages/types/src/metadata/PortableRegistry/PortableRegistry.ts +++ b/packages/types/src/metadata/PortableRegistry/PortableRegistry.ts @@ -722,15 +722,22 @@ export class PortableRegistry extends Struct implements ILookup { ? [a, b] : [b, a]; - // NOTE: Currently the BitVec type is one-way only, i.e. we only use it to decode, not - // re-encode stuff. As such we ignore the msb/lsb identifier given by bitOrderType, or rather - // we don't pass it though at all (all displays in LSB) - if (!BITVEC_NS.includes(bitOrder.namespace || '')) { + if (!bitOrder.namespace || !BITVEC_NS.includes(bitOrder.namespace)) { throw new Error(`Unexpected bitOrder found as ${bitOrder.namespace || ''}`); } else if (bitStore.info !== TypeDefInfo.Plain || bitStore.type !== 'u8') { throw new Error(`Only u8 bitStore is currently supported, found ${bitStore.type}`); } + const isLsb = BITVEC_NS_LSB.includes(bitOrder.namespace); + + if (!isLsb) { + // TODO To remove this limitation, we need to pass an extra info flag + // through to the TypeDef (Here we could potentially re-use something + // like index (???) to indicate and ensure we use it to pass to the + // BitVec constructor - which does handle this type) + throw new Error(`Only LSB BitVec is currently supported, found ${bitOrder.namespace}`); + } + return { info: TypeDefInfo.Plain, type: 'BitVec'