@yubing744/rooch-sdk
Version:
146 lines (115 loc) • 3.88 kB
text/typescript
/**
* Copyright (c) Facebook, Inc. and its affiliates
* SPDX-License-Identifier: MIT OR Apache-2.0
*/
import { Deserializer } from './deserializer'
import * as util from "@kayahr/text-encoding";
export abstract class BinaryDeserializer implements Deserializer {
private static readonly BIG_32: bigint = BigInt(32);
private static readonly BIG_64: bigint = BigInt(64);
private static readonly textDecoder = typeof window === "undefined"
? new util.TextDecoder()
: new TextDecoder();
public buffer: ArrayBuffer;
public offset: number;
constructor(data: Uint8Array) {
// copies data to prevent outside mutation of buffer.
this.buffer = new ArrayBuffer(data.length);
new Uint8Array(this.buffer).set(data, 0);
this.offset = 0;
}
private read(length: number): ArrayBuffer {
const bytes = this.buffer.slice(this.offset, this.offset + length);
this.offset += length;
return bytes;
}
abstract deserializeLen(): number;
abstract deserializeVariantIndex(): number;
abstract checkThatKeySlicesAreIncreasing(
key1: [number, number],
key2: [number, number],
): void;
public deserializeStr(): string {
const value = this.deserializeBytes();
return BinaryDeserializer.textDecoder.decode(value);
}
public deserializeBytes(): Uint8Array {
const len = this.deserializeLen();
if (len < 0) {
throw new Error("Length of a bytes array can't be negative");
}
return new Uint8Array(this.read(len));
}
public deserializeBool(): boolean {
const bool = new Uint8Array(this.read(1))[0];
return bool == 1;
}
public deserializeUnit(): null {
return null;
}
public deserializeU8(): number {
return new DataView(this.read(1)).getUint8(0);
}
public deserializeU16(): number {
return new DataView(this.read(2)).getUint16(0, true);
}
public deserializeU32(): number {
return new DataView(this.read(4)).getUint32(0, true);
}
public deserializeU64(): bigint {
const low = this.deserializeU32();
const high = this.deserializeU32();
// combine the two 32-bit values and return (little endian)
return BigInt(
(BigInt(high.toString()) << BinaryDeserializer.BIG_32) |
BigInt(low.toString()),
);
}
public deserializeU128(): bigint {
const low = this.deserializeU64();
const high = this.deserializeU64();
// combine the two 64-bit values and return (little endian)
return BigInt(
(BigInt(high.toString()) << BinaryDeserializer.BIG_64) |
BigInt(low.toString()),
);
}
public deserializeI8(): number {
return new DataView(this.read(1)).getInt8(0);
}
public deserializeI16(): number {
return new DataView(this.read(2)).getInt16(0, true);
}
public deserializeI32(): number {
return new DataView(this.read(4)).getInt32(0, true);
}
public deserializeI64(): bigint {
const low = this.deserializeI32();
const high = this.deserializeI32();
// combine the two 32-bit values and return (little endian)
return (BigInt(high.toString()) << BinaryDeserializer.BIG_32) |
BigInt(low.toString());
}
public deserializeI128(): bigint {
const low = this.deserializeI64();
const high = this.deserializeI64();
// combine the two 64-bit values and return (little endian)
return (BigInt(high.toString()) << BinaryDeserializer.BIG_64) |
BigInt(low.toString());
}
public deserializeOptionTag(): boolean {
return this.deserializeBool();
}
public getBufferOffset(): number {
return this.offset;
}
public deserializeChar(): string {
throw new Error("Method deserializeChar not implemented.");
}
public deserializeF32(): number {
return new DataView(this.read(4)).getFloat32(0, true);
}
public deserializeF64(): number {
return new DataView(this.read(8)).getFloat64(0, true);
}
}