UNPKG

@chainsafe/ssz

Version:

Simple Serialize

113 lines 4.34 kB
import { maxChunksToDepth } from "../util/merkleize.js"; import { namedClass } from "../util/named.js"; import { ArrayBasicTreeView } from "../view/arrayBasic.js"; import { ArrayBasicTreeViewDU } from "../viewDU/arrayBasic.js"; import { ArrayType } from "./array.js"; import { tree_deserializeFromBytesArrayBasic, tree_serializeToBytesArrayBasic, value_deserializeFromBytesArrayBasic, value_serializeToBytesArrayBasic, } from "./arrayBasic.js"; /** * Vector: Ordered fixed-length homogeneous collection, with N values * * Array of Basic type: * - Basic types are max 32 bytes long so multiple values may be packed in the same node. * - Basic types are never returned in a view wrapper, but their value representation */ export class VectorBasicType extends ArrayType { elementType; length; typeName; itemsPerChunk; depth; chunkDepth; maxChunkCount; fixedSize; minSize; maxSize; isList = false; isViewMutable = true; defaultLen; constructor(elementType, length, opts) { super(elementType); this.elementType = elementType; this.length = length; if (!elementType.isBasic) throw Error("elementType must be basic"); if (length === 0) throw Error("Vector length must be > 0"); this.typeName = opts?.typeName ?? `Vector[${elementType.typeName}, ${length}]`; // TODO Check that itemsPerChunk is an integer this.itemsPerChunk = 32 / elementType.byteLength; this.maxChunkCount = Math.ceil((length * elementType.byteLength) / 32); this.chunkDepth = maxChunksToDepth(this.maxChunkCount); this.depth = this.chunkDepth; this.fixedSize = length * elementType.byteLength; this.minSize = this.fixedSize; this.maxSize = this.fixedSize; this.defaultLen = length; this.blocksBuffer = new Uint8Array(Math.ceil(this.maxChunkCount / 2) * 64); } static named(elementType, limit, opts) { return new (namedClass(VectorBasicType, opts.typeName))(elementType, limit, opts); } getView(tree) { return new ArrayBasicTreeView(this, tree); } getViewDU(node, cache) { // cache type should be validated (if applicate) in the view // biome-ignore lint/suspicious/noExplicitAny: We explicity need to use `any` here return new ArrayBasicTreeViewDU(this, node, cache); } commitView(view) { return view.node; } commitViewDU(view, hcOffset = 0, hcByLevel = null) { view.commit(hcOffset, hcByLevel); return view.node; } cacheOfViewDU(view) { return view.cache; } // Serialization + deserialization value_serializedSize() { return this.fixedSize; } value_serializeToBytes(output, offset, value) { return value_serializeToBytesArrayBasic(this.elementType, this.length, output, offset, value); } value_deserializeFromBytes(data, start, end) { return value_deserializeFromBytesArrayBasic(this.elementType, data, start, end, this); } tree_serializedSize() { return this.fixedSize; } tree_serializeToBytes(output, offset, node) { return tree_serializeToBytesArrayBasic(this.elementType, this.length, this.depth, output, offset, node); } tree_deserializeFromBytes(data, start, end) { return tree_deserializeFromBytesArrayBasic(this.elementType, this.depth, data, start, end, this); } // Helpers for TreeView tree_getLength() { return this.length; } tree_setLength() { // Vector's length is immutable, ignore this call } tree_getChunksNode(node) { return node; } tree_chunksNodeOffset() { return 0; } tree_setChunksNode(_rootNode, chunksNode) { return chunksNode; } // Merkleization getBlocksBytes(value) { const uint8Array = this.blocksBuffer.subarray(0, this.fixedSize); const dataView = new DataView(uint8Array.buffer, uint8Array.byteOffset, uint8Array.byteLength); value_serializeToBytesArrayBasic(this.elementType, this.length, { uint8Array, dataView }, 0, value); // remaining bytes from this.fixedSize to this.blocksBuffer.length must be zeroed return this.blocksBuffer; } } //# sourceMappingURL=vectorBasic.js.map