Add BitVec type (#1822)

* Add BitVec type

* Update comments

* Fixup decoding check

* Fix linting
This commit is contained in:
Jaco Greeff
2020-02-08 14:56:08 +01:00
committed by GitHub
parent 866c5769bb
commit 480c0abda8
5 changed files with 86 additions and 12 deletions
+11 -11
View File
@@ -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));
}
/**
+72
View File
@@ -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);
}
}
+1 -1
View File
@@ -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);
}
+1
View File
@@ -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';