Add BitVec type (#1822)
* Add BitVec type * Update comments * Fixup decoding check * Fix linting
This commit is contained in:
@@ -7,6 +7,15 @@ import { AnyU8a, IHash, IU8a, Registry } from '../types';
|
||||
import { isU8a, isUndefined, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
import { blake2AsU8a } from '@polkadot/util-crypto';
|
||||
|
||||
/** @internal */
|
||||
function decodeU8a (value?: any): Uint8Array {
|
||||
if (isU8a(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return u8aToU8a(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Raw
|
||||
* @description
|
||||
@@ -20,20 +29,11 @@ export default class Raw extends Uint8Array implements IU8a {
|
||||
public readonly registry: Registry;
|
||||
|
||||
constructor (registry: Registry, value?: AnyU8a) {
|
||||
super(Raw.decodeU8a(value));
|
||||
super(decodeU8a(value));
|
||||
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
private static decodeU8a (value?: any): Uint8Array {
|
||||
if (isU8a(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return u8aToU8a(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The length of the value when encoded as a Uint8Array
|
||||
*/
|
||||
@@ -79,7 +79,7 @@ export default class Raw extends Uint8Array implements IU8a {
|
||||
!this.some((value, index): boolean => value !== other[index]);
|
||||
}
|
||||
|
||||
return this.eq(Raw.decodeU8a(other));
|
||||
return this.eq(decodeU8a(other));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
// Copyright 2017-2020 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AnyU8a, Registry } from '../types';
|
||||
|
||||
import { assert, isString, u8aConcat, u8aToU8a } from '@polkadot/util';
|
||||
|
||||
import Compact from '../codec/Compact';
|
||||
import Raw from '../codec/Raw';
|
||||
|
||||
/** @internal */
|
||||
function decodeBitVecU8a (value?: Uint8Array): Uint8Array {
|
||||
if (!value || !value.length) {
|
||||
return new Uint8Array();
|
||||
}
|
||||
|
||||
// handle all other Uint8Array inputs, these do have a length prefix which is the number of bits encoded
|
||||
const [offset, length] = Compact.decodeU8a(value);
|
||||
const total = offset + Math.ceil(length.toNumber() / 8);
|
||||
|
||||
assert(total <= value.length, `BitVec: required length less than remainder, expected at least ${total}, found ${value.length}`);
|
||||
|
||||
return value.subarray(offset, total);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function decodeBitVec (value?: AnyU8a): Uint8Array | undefined {
|
||||
if (Array.isArray(value) || isString(value)) {
|
||||
return u8aToU8a(value);
|
||||
}
|
||||
|
||||
return decodeBitVecU8a(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name BitVec
|
||||
* @description
|
||||
* A BitVec that represents an array of bits. The bits are however stored encoded. The difference between this
|
||||
* and a normal Bytes would be that the length prefix indicates the number of bits encoded, not the bytes
|
||||
*/
|
||||
export default class BitVec extends Raw {
|
||||
constructor (registry: Registry, value?: AnyU8a) {
|
||||
super(registry, decodeBitVec(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The length of the value when encoded as a Uint8Array
|
||||
*/
|
||||
public get encodedLength (): number {
|
||||
return this.length + Compact.encodeU8a(this.bitLength()).length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Returns the base runtime type name for this instance
|
||||
*/
|
||||
public toRawType (): string {
|
||||
return 'BitVec';
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Encodes the value as a Uint8Array as per the SCALE specifications
|
||||
* @param isBare true when the value has none of the type-specific prefixes (internal)
|
||||
*/
|
||||
public toU8a (isBare?: boolean): Uint8Array {
|
||||
const bitVec = super.toU8a();
|
||||
|
||||
return isBare
|
||||
? bitVec
|
||||
: u8aConcat(Compact.encodeU8a(this.bitLength()), bitVec);
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ function decodeBytes (value?: AnyU8a): Uint8Array | undefined {
|
||||
if (Array.isArray(value) || isString(value)) {
|
||||
return u8aToU8a(value);
|
||||
} else if (!(value instanceof Raw) && isU8a(value)) {
|
||||
// We are ensuring we are not a Rawv instance. In the case of a Raw we already have gotten
|
||||
// We are ensuring we are not a Raw instance. In the case of a Raw we already have gotten
|
||||
// rid of the length, i.e. new Bytes(new Bytes(...)) will work as expected
|
||||
return decodeBytesU8a(value);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
* @summary Type definitions that are used in the system
|
||||
*/
|
||||
export { default as bool } from './Bool';
|
||||
export { default as BitVec } from './BitVec';
|
||||
export { default as Bytes } from './Bytes';
|
||||
export { default as Data } from './Data';
|
||||
export { default as H160 } from './H160';
|
||||
|
||||
Reference in New Issue
Block a user