Small decoding cleanups (#4823)

* Small decoding cleanups

* isHex

* Adjust struct

* Additional
This commit is contained in:
Jaco
2022-05-13 16:55:13 +03:00
committed by GitHub
parent 6159270465
commit 8dc0f0486d
13 changed files with 63 additions and 84 deletions
@@ -25,10 +25,8 @@ function toPercentage (value: BN, divisor: BN): string {
}
/** @internal */
function decodeAbstractInt (value: AnyNumber, bitLength: UIntBitLength, isNegative: boolean): string {
if (isU8a(value)) {
return u8aToBn(value.subarray(0, bitLength / 8), { isLe: true, isNegative }).toString();
} else if (isBn(value)) {
function decodeAbstractInt (value: Exclude<AnyNumber, Uint8Array>, isNegative: boolean): string {
if (isBn(value)) {
return value.toString();
} else if (isHex(value, -1, true)) {
return hexToBn(value, { isLe: false, isNegative }).toString();
@@ -65,7 +63,7 @@ export abstract class AbstractInt extends BN implements INumber {
// shortcut isU8a as used in SCALE decoding
isU8a(value)
? u8aToBn(value.subarray(0, bitLength / 8), { isLe: true, isNegative: isSigned }).toString()
: decodeAbstractInt(value, bitLength, isSigned)
: decodeAbstractInt(value, isSigned)
);
this.registry = registry;
+5 -5
View File
@@ -4,7 +4,7 @@
import type { HexString } from '@polkadot/util/types';
import type { AnyJson, Codec, CodecClass, IEnum, Inspect, IU8a, Registry } from '../types';
import { assert, isHex, isNumber, isObject, isString, isU8a, isUndefined, objectProperties, stringCamelCase, stringify, stringPascalCase, u8aConcat, u8aToHex, u8aToU8a } from '@polkadot/util';
import { assert, isCodec, isHex, isNumber, isObject, isString, isU8a, isUndefined, objectProperties, stringCamelCase, stringify, stringPascalCase, u8aConcat, u8aToHex, u8aToU8a } from '@polkadot/util';
import { mapToTypeMap, typesToMap } from '../utils';
import { Null } from './Null';
@@ -88,7 +88,7 @@ function createFromValue (registry: Registry, def: TypesDef, index = 0, value?:
return {
index,
value: value instanceof entry.Type
value: isCodec(value) && value instanceof entry.Type
? value
: new entry.Type(registry, value)
};
@@ -266,7 +266,7 @@ export class Enum implements IEnum {
* @deprecated use isNone
*/
public get isNull (): boolean {
return this.#raw instanceof Null;
return this.isNone;
}
/**
@@ -310,7 +310,7 @@ export class Enum implements IEnum {
return this.type === other;
} else if (isHex(other)) {
return this.toHex() === other;
} else if (other instanceof Enum) {
} else if (isCodec(other) && other instanceof Enum) {
return this.index === other.index && this.value.eq(other.value);
} else if (isObject(other)) {
return this.value.eq(other[this.type]);
@@ -404,7 +404,7 @@ export class Enum implements IEnum {
* @description Returns the string representation of the value
*/
public toString (): string {
return this.isNull
return this.isNone
? this.type
: stringify(this.toJSON());
}
+1 -1
View File
@@ -19,7 +19,7 @@ type TupleTypes = TupleType[] | {
};
/** @internal */
function decodeTuple (registry: Registry, Classes: TupleCodecClasss, value?: AnyTupleValue): [Codec[], number] {
function decodeTuple (registry: Registry, Classes: TupleCodecClasss, value?: Exclude<AnyTupleValue, Uint8Array>): [Codec[], number] {
if (isU8a(value) || isHex(value)) {
return decodeU8a(registry, u8aToU8a(value), Classes);
}
+1 -1
View File
@@ -11,7 +11,7 @@ import { decodeU8aVec, typeToConstructor } from '../utils';
import { decodeVec } from './Vec';
/** @internal */
function decodeVecFixed<T extends Codec> (registry: Registry, value: Uint8Array | HexString | unknown[], Type: CodecClass<T>, length: number): [T[], number, number] {
function decodeVecFixed<T extends Codec> (registry: Registry, value: HexString | unknown[], Type: CodecClass<T>, length: number): [T[], number, number] {
const [values, decodedLength, decodedLengthNoOffset] = decodeVec(registry, Type, value, length);
while (values.length < length) {
+10 -12
View File
@@ -11,7 +11,7 @@ import { compareSet, decodeU8aVec, sortSet, typeToConstructor } from '../utils';
const l = logger('BTreeSet');
/** @internal */
function decodeSetFromU8a<V extends Codec> (registry: Registry, ValClass: CodecClass<V>, u8a: Uint8Array): [Set<V>, number] {
function decodeSetFromU8a<V extends Codec> (registry: Registry, ValClass: CodecClass<V>, u8a: Uint8Array): [CodecClass<V>, Set<V>, number] {
const output = new Set<V>();
const [offset, length] = compactFromU8a(u8a);
const [values, decodedLength] = decodeU8aVec(registry, u8a, offset, ValClass, length.toNumber());
@@ -20,11 +20,11 @@ function decodeSetFromU8a<V extends Codec> (registry: Registry, ValClass: CodecC
output.add(values[i]);
}
return [output, decodedLength];
return [ValClass, output, decodedLength];
}
/** @internal */
function decodeSetFromSet<V extends Codec> (registry: Registry, ValClass: CodecClass<V>, value: Set<any> | string[]): [Set<V>, number] {
function decodeSetFromSet<V extends Codec> (registry: Registry, ValClass: CodecClass<V>, value: Set<any> | string[]): [CodecClass<V>, Set<V>, number] {
const output = new Set<V>();
value.forEach((val: any) => {
@@ -37,7 +37,7 @@ function decodeSetFromSet<V extends Codec> (registry: Registry, ValClass: CodecC
}
});
return [output, 0];
return [ValClass, output, 0];
}
/**
@@ -54,14 +54,12 @@ function decodeSetFromSet<V extends Codec> (registry: Registry, ValClass: CodecC
* @param jsonSet
* @internal
*/
function decodeSet<V extends Codec> (registry: Registry, valType: CodecClass<V> | string, value?: Uint8Array | string | string[] | Set<any>): [Set<V>, number] {
if (!value) {
return [new Set<V>(), 0];
}
function decodeSet<V extends Codec> (registry: Registry, valType: CodecClass<V> | string, value?: Uint8Array | string | string[] | Set<any>): [CodecClass<V>, Set<V>, number] {
const ValClass = typeToConstructor(registry, valType);
if (isU8a(value) || isHex(value)) {
if (!value) {
return [ValClass, new Set<V>(), 0];
} else if (isU8a(value) || isHex(value)) {
return decodeSetFromU8a<V>(registry, ValClass, u8aToU8a(value));
} else if (Array.isArray(value) || value instanceof Set) {
return decodeSetFromSet<V>(registry, ValClass, value);
@@ -80,13 +78,13 @@ export class BTreeSet<V extends Codec = Codec> extends Set<V> implements ISet<V>
readonly #ValClass: CodecClass<V>;
constructor (registry: Registry, valType: CodecClass<V> | string, rawValue?: Uint8Array | string | string[] | Set<any>) {
const [values, decodedLength] = decodeSet(registry, valType, rawValue);
const [ValClass, values, decodedLength] = decodeSet(registry, valType, rawValue);
super(sortSet(values));
this.registry = registry;
this.initialU8aLength = decodedLength;
this.#ValClass = typeToConstructor(registry, valType);
this.#ValClass = ValClass;
}
public static with<V extends Codec> (valType: CodecClass<V> | string): CodecClass<BTreeSet<V>> {
+6 -15
View File
@@ -3,7 +3,7 @@
import type { AnyU8a, Inspect, Registry } from '../types';
import { assert, compactAddLength, compactFromU8a, compactToU8a, isString, isU8a, u8aToU8a } from '@polkadot/util';
import { assert, compactAddLength, compactFromU8a, compactToU8a, isCodec, isString, isU8a, u8aToU8a } from '@polkadot/util';
import { Raw } from '../native/Raw';
@@ -26,19 +26,6 @@ function decodeBytesU8a (value: Uint8Array): [Uint8Array, number] {
return [value.subarray(offset, total), total];
}
/** @internal */
function decodeBytes (value?: AnyU8a): [Uint8Array | undefined, number] {
if (Array.isArray(value) || isString(value)) {
return [u8aToU8a(value), 0];
} else if (!(value instanceof Raw) && isU8a(value)) {
// 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);
}
return [value, 0];
}
/**
* @name Bytes
* @description
@@ -48,7 +35,11 @@ function decodeBytes (value?: AnyU8a): [Uint8Array | undefined, number] {
*/
export class Bytes extends Raw {
constructor (registry: Registry, value?: AnyU8a) {
const [u8a, decodedLength] = decodeBytes(value);
const [u8a, decodedLength] = isU8a(value) && !(isCodec(value) && value instanceof Raw)
? decodeBytesU8a(value)
: Array.isArray(value) || isString(value)
? [u8aToU8a(value), 0]
: [value, 0];
super(registry, u8a, decodedLength);
}
+9 -9
View File
@@ -14,7 +14,7 @@ import { compareMap, decodeU8a, sortMap, typeToConstructor } from '../utils';
const l = logger('Map');
/** @internal */
function decodeMapFromU8a<K extends Codec, V extends Codec> (registry: Registry, KeyClass: CodecClass<K>, ValClass: CodecClass<V>, u8a: Uint8Array): [Map<K, V>, number] {
function decodeMapFromU8a<K extends Codec, V extends Codec> (registry: Registry, KeyClass: CodecClass<K>, ValClass: CodecClass<V>, u8a: Uint8Array): [CodecClass<K>, CodecClass<V>, Map<K, V>, number] {
const output = new Map<K, V>();
const [offset, length] = compactFromU8a(u8a);
const count = length.toNumber();
@@ -30,11 +30,11 @@ function decodeMapFromU8a<K extends Codec, V extends Codec> (registry: Registry,
output.set(values[i] as K, values[i + 1] as V);
}
return [output, offset + decodedLength];
return [KeyClass, ValClass, output, offset + decodedLength];
}
/** @internal */
function decodeMapFromMap<K extends Codec, V extends Codec> (registry: Registry, KeyClass: CodecClass<K>, ValClass: CodecClass<V>, value: Map<any, any>): [Map<K, V>, number] {
function decodeMapFromMap<K extends Codec, V extends Codec> (registry: Registry, KeyClass: CodecClass<K>, ValClass: CodecClass<V>, value: Map<any, any>): [CodecClass<K>, CodecClass<V>, Map<K, V>, number] {
const output = new Map<K, V>();
for (const [key, val] of value.entries()) {
@@ -58,7 +58,7 @@ function decodeMapFromMap<K extends Codec, V extends Codec> (registry: Registry,
}
}
return [output, 0];
return [KeyClass, ValClass, output, 0];
}
/**
@@ -76,12 +76,12 @@ function decodeMapFromMap<K extends Codec, V extends Codec> (registry: Registry,
* @param jsonMap
* @internal
*/
function decodeMap<K extends Codec, V extends Codec> (registry: Registry, keyType: CodecClass<K> | string, valType: CodecClass<V> | string, value?: Uint8Array | string | Map<any, any>): [Map<K, V>, number] {
function decodeMap<K extends Codec, V extends Codec> (registry: Registry, keyType: CodecClass<K> | string, valType: CodecClass<V> | string, value?: Uint8Array | string | Map<any, any>): [CodecClass<K>, CodecClass<V>, Map<K, V>, number] {
const KeyClass = typeToConstructor(registry, keyType);
const ValClass = typeToConstructor(registry, valType);
if (!value) {
return [new Map<K, V>(), 0];
return [KeyClass, ValClass, new Map<K, V>(), 0];
} else if (isU8a(value) || isHex(value)) {
return decodeMapFromU8a<K, V>(registry, KeyClass, ValClass, u8aToU8a(value));
} else if (value instanceof Map) {
@@ -107,14 +107,14 @@ export class CodecMap<K extends Codec = Codec, V extends Codec = Codec> extends
readonly #type: string;
constructor (registry: Registry, keyType: CodecClass<K> | string, valType: CodecClass<V> | string, rawValue: Uint8Array | string | Map<any, any> | undefined, type: 'BTreeMap' | 'HashMap' = 'HashMap') {
const [decoded, decodedLength] = decodeMap(registry, keyType, valType, rawValue);
const [KeyClass, ValClass, decoded, decodedLength] = decodeMap(registry, keyType, valType, rawValue);
super(type === 'BTreeMap' ? sortMap(decoded) : decoded);
this.registry = registry;
this.initialU8aLength = decodedLength;
this.#KeyClass = typeToConstructor(registry, keyType);
this.#ValClass = typeToConstructor(registry, valType);
this.#KeyClass = KeyClass;
this.#ValClass = ValClass;
this.#type = type;
}
+7 -12
View File
@@ -6,17 +6,6 @@ import type { Codec, Inspect, IU8a, Registry } from '../types';
import { isU8a, u8aToHex } from '@polkadot/util';
/** @internal */
function decodeBool (value: any): boolean {
if (isU8a(value)) {
return value[0] === 1;
} else if (value instanceof Boolean) {
return value.valueOf();
}
return !!value;
}
/**
* @name bool
* @description
@@ -30,7 +19,13 @@ export class bool extends Boolean implements Codec {
// eslint-disable-next-line @typescript-eslint/ban-types
constructor (registry: Registry, value: bool | Boolean | Uint8Array | boolean | number = false) {
super(decodeBool(value));
super(
isU8a(value)
? value[0] === 1
: value instanceof Boolean
? value.valueOf()
: !!value
);
this.registry = registry;
}
+1 -1
View File
@@ -10,7 +10,7 @@ const BITLENGTH: UIntBitLength = 64;
function decodeDate (value: CodecDate | Date | AnyNumber): Date {
if (isU8a(value)) {
value = u8aToBn(value.subarray(0, BITLENGTH / 8), true);
value = u8aToBn(value.subarray(0, BITLENGTH / 8));
} else if (value instanceof Date) {
return value;
} else if (isString(value)) {
+2 -2
View File
@@ -111,8 +111,8 @@ export class CodecSet extends Set<string> implements ISet<string> {
}
return class extends CodecSet {
constructor (registry: Registry, value?: unknown) {
super(registry, values, value as undefined, bitLength);
constructor (registry: Registry, value?: string[] | Set<string> | Uint8Array | BN | number | string) {
super(registry, values, value, bitLength);
objectProperties(this, isKeys, (_, i) => this.strings.includes(keys[i]));
}
-2
View File
@@ -45,8 +45,6 @@ function decodeText (value?: null | Text | string | AnyU8a | { toString: () => s
* object, inheriting all methods exposed from `String`.
* @noInheritDoc
*/
// TODO
// - Strings should probably be trimmed (docs do come through with extra padding)
export class Text extends String implements IText {
public readonly registry: Registry;