From a4bbef251e51e80a579e32d147515ee38c518e20 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 31 Jan 2025 22:19:51 +0100 Subject: [PATCH] add support for specifying number or bigint serialization format --- zenoh-ts/examples/deno/src/z_bytes.ts | 42 ++- zenoh-ts/src/ext/index.ts | 6 +- zenoh-ts/src/ext/serialization.ts | 508 ++++++++++++++++++++++---- 3 files changed, 475 insertions(+), 81 deletions(-) diff --git a/zenoh-ts/examples/deno/src/z_bytes.ts b/zenoh-ts/examples/deno/src/z_bytes.ts index 03af76a..6e30d2f 100644 --- a/zenoh-ts/examples/deno/src/z_bytes.ts +++ b/zenoh-ts/examples/deno/src/z_bytes.ts @@ -13,19 +13,19 @@ // import { ZBytes } from "@eclipse-zenoh/zenoh-ts"; -import { ZBytesSerializer, ZBytesDeserializer, ZSerializeable, ZDeserializeable, zserialize, zdeserialize, ZSerDe } from "@eclipse-zenoh/zenoh-ts/ext"; +import { ZBytesSerializer, ZBytesDeserializer, ZSerializeable, ZDeserializeable, zserialize, zdeserialize, ZS, ZD, NumberFormat, BigIntFormat } from "@eclipse-zenoh/zenoh-ts/ext"; class MyStruct implements ZSerializeable, ZDeserializeable { - v1: bigint; + v1: number; v2: string; v3: number[]; - constructor(v1?: bigint, v2?: string, v3?: number[]) { + constructor(v1?: number, v2?: string, v3?: number[]) { if (typeof v1 !== `undefined`) { this.v1 = v1; } else { - this.v1 = 0n; + this.v1 = 0; } if (typeof v2 !== `undefined`) { this.v2 = v2; @@ -40,19 +40,19 @@ class MyStruct implements ZSerializeable, ZDeserializeable { } serialize_with_zserializer(serializer: ZBytesSerializer): void { - serializer.serialize(this.v1) + serializer.serialize(this.v1, ZS.number(NumberFormat.Int32)) serializer.serialize(this.v2) - serializer.serialize(this.v3) + serializer.serialize(this.v3, ZS.array(ZS.number(NumberFormat.Int8))) } deserialize_with_zdeserializer(deserializer: ZBytesDeserializer): void { - this.v1 = deserializer.deserialize(ZSerDe.bigint()) - this.v2 = deserializer.deserialize(ZSerDe.string()) - this.v3 = deserializer.deserialize(ZSerDe.array(ZSerDe.number())) + this.v1 = deserializer.deserialize(ZD.number(NumberFormat.Uint32)) + this.v2 = deserializer.deserialize(ZD.string()) + this.v3 = deserializer.deserialize(ZD.array(ZD.number(NumberFormat.Int8))) } to_string(): string { - return JSON.stringify(this, (_, v) => typeof v === 'bigint' ? v.toString() : v) + return JSON.stringify(this) } } @@ -77,9 +77,13 @@ export async function main() { // serialization // array { - let input = [0.5, 1.0, 3.0, 5.5] - let payload = zserialize(input) - let output = zdeserialize(ZSerDe.array(ZSerDe.number()), payload) + let input = [1, 2, 3, 5] + // by default number is serialized/deserialized as 64-bit float, + // other formats, like Int32, for example, must be specified explicitly + let payload = zserialize(input, ZS.array(ZS.number(NumberFormat.Int32))) + let output = zdeserialize(ZD.array(ZD.number(NumberFormat.Int32)), payload) + // let payload = zserialize(input) + // let output = zdeserialize(ZD.array(ZD.number()), payload) console.log(`Input: ${input}, Output: ${output}`) } // map @@ -87,8 +91,12 @@ export async function main() { let input = new Map() input.set(0n, "abc") input.set(1n, "def") - let payload = zserialize(input) - let output = zdeserialize(ZSerDe.map(ZSerDe.bigint(), ZSerDe.string()), payload) + // by default bigint is serialized/deserialized as 64-bit signed integer, + // other formats, like UInt64, for example, must be specified explicitly + let payload = zserialize(input, ZS.map(ZS.bigint(BigIntFormat.Uint64), ZS.string())) + let output = zdeserialize(ZD.map(ZD.bigint(BigIntFormat.Uint64), ZD.string()), payload) + // let payload = zserialize(input) + // let output = zdeserialize(ZD.map(ZD.bigint(), ZD.string()), payload) console.log(`Input:`) console.table(input) console.log(`Output:`) @@ -96,9 +104,9 @@ export async function main() { } // Custom class { - let input = new MyStruct(1234n, "test", [1, 2, 3, 4]) + let input = new MyStruct(1234, "test", [1, 2, 3, 4]) let payload = zserialize(input) - let output = zdeserialize(ZSerDe.object(MyStruct), payload) + let output = zdeserialize(ZD.object(MyStruct), payload) console.log(`Input: ${input.to_string()}, Output: ${output.to_string()}`) } } diff --git a/zenoh-ts/src/ext/index.ts b/zenoh-ts/src/ext/index.ts index be6c01b..b25c0b3 100644 --- a/zenoh-ts/src/ext/index.ts +++ b/zenoh-ts/src/ext/index.ts @@ -12,10 +12,10 @@ // ZettaScale Zenoh Team, // -// Serialziation -import { ZBytesSerializer, ZBytesDeserializer, ZSerializeable, ZDeserializeable, zserialize, zdeserialize, ZSerDe } from "./serialization.js" +// Serialization +import { ZBytesSerializer, ZBytesDeserializer, ZSerializeable, ZDeserializeable, zserialize, zdeserialize, NumberFormat, BigIntFormat, ZS, ZD } from "./serialization.js" // Exports -export { ZBytesSerializer, ZBytesDeserializer, ZSerializeable, ZDeserializeable, zserialize, zdeserialize, ZSerDe } \ No newline at end of file +export { ZBytesSerializer, ZBytesDeserializer, ZSerializeable, ZDeserializeable, zserialize, zdeserialize, NumberFormat, BigIntFormat, ZS, ZD } \ No newline at end of file diff --git a/zenoh-ts/src/ext/serialization.ts b/zenoh-ts/src/ext/serialization.ts index 9a98490..970b03b 100644 --- a/zenoh-ts/src/ext/serialization.ts +++ b/zenoh-ts/src/ext/serialization.ts @@ -99,23 +99,103 @@ export class ZBytesSerializer { /** * Serializes bigint as 64 bit signed integer. */ - public serialize_bigint64(val: bigint) { + public serialize_bigint_int64(val: bigint) { let data = new Uint8Array(8); let view = new DataView(data.buffer); view.setBigInt64(0, val, true); this.append(data) } + /** + * Serializes bigint as 64 bit unsigned integer. + */ + public serialize_bigint_uint64(val: bigint) { + let data = new Uint8Array(8); + let view = new DataView(data.buffer); + view.setBigUint64(0, val, true); + this.append(data) + } + /** * Serializes number as 64 bit floating point number. */ - public serialize_float64(val: number) { + public serialize_number_float64(val: number) { let data = new Uint8Array(8); let view = new DataView(data.buffer); view.setFloat64(0, val, true); this.append(data) } + /** + * Serializes number as 32 bit floating point number. + */ + public serialize_number_float32(val: number) { + let data = new Uint8Array(4); + let view = new DataView(data.buffer); + view.setFloat32(0, val, true); + this.append(data) + } + + /** + * Serializes number as 32 bit integer. + */ + public serialize_number_int32(val: number) { + let data = new Uint8Array(4); + let view = new DataView(data.buffer); + view.setInt32(0, val, true); + this.append(data) + } + + /** + * Serializes number as 32 bit unsigned integer. + */ + public serialize_number_uint32(val: number) { + let data = new Uint8Array(4); + let view = new DataView(data.buffer); + view.setUint32(0, val, true); + this.append(data) + } + + /** + * Serializes number as 16 bit integer. + */ + public serialize_number_int16(val: number) { + let data = new Uint8Array(2); + let view = new DataView(data.buffer); + view.setInt16(0, val, true); + this.append(data) + } + + /** + * Serializes number as 16 bit unsigned integer. + */ + public serialize_number_uint16(val: number) { + let data = new Uint8Array(2); + let view = new DataView(data.buffer); + view.setUint16(0, val, true); + this.append(data) + } + + /** + * Serializes number as 8 bit integer. + */ + public serialize_number_int8(val: number) { + let data = new Uint8Array(1); + let view = new DataView(data.buffer); + view.setInt8(0, val); + this.append(data) + } + + /** + * Serializes number as 8 bit unsigned integer. + */ + public serialize_number_uint8(val: number) { + let data = new Uint8Array(1); + let view = new DataView(data.buffer); + view.setUint8(0, val); + this.append(data) + } + /** * Serializes boolean. */ @@ -128,41 +208,67 @@ export class ZBytesSerializer { /** * Serializes an array. */ - public serialize_array(val: EnsureSerializeable[]) { + public serialize_array(val: EnsureSerializeable[], t?: ZSTypeInfo>) { this.write_sequence_length(val.length) - val.forEach( (element) => this._serialize_inner(element)); + if (val.length > 0 && t === undefined) { + t = this._get_default_serialization_tag(val[0] as any) as ZSTypeInfo> + } + val.forEach( (element) => (t as ZSTypeInfo>).serialize(this, element)); } /** * Serializes a map. */ - public serialize_map(m: Map, EnsureSerializeable>) { + public serialize_map(m: Map, EnsureSerializeable>, t_key?:ZSTypeInfo>, t_value?: ZSTypeInfo>) { this.write_sequence_length(m.size) - m.forEach( (v, k) => { - this._serialize_inner(k); - this._serialize_inner(v); + if (m.size > 0) { + let val = m.entries().next() + if (val !== undefined ) { + let value = val.value + if (value !== undefined) { + t_key ??= this._get_default_serialization_tag(value[0] as any) as ZSTypeInfo> + t_value ??= this._get_default_serialization_tag(value[1] as any) as ZSTypeInfo> + } } - ); + } + m.forEach( (v, k) => { + (t_key as ZSTypeInfo>).serialize(this, k); + (t_value as ZSTypeInfo>).serialize(this, v); + } + ); } - - private _serialize_inner(data: any) { + private _get_default_serialization_tag(data: EnsureSerializeable): ZSTypeInfo> { if (is_serializeable(data)) { - data.serialize_with_zserializer(this); + type R = typeof data + return ZS.object() as ZSTypeInfo> } else if (typeof data == "number") { - this.serialize_float64(data) + return ZS.number() as ZSTypeInfo> } else if (typeof data == "bigint") { - this.serialize_bigint64(data) + return ZS.bigint() as ZSTypeInfo> } else if (typeof data == "string") { - this.serialize_string(data) + return ZS.string() as ZSTypeInfo> } else if (typeof data == "boolean") { - this.serialize_boolean(data) + return ZS.boolean() as ZSTypeInfo> } else if (Array.isArray(data)) { - this.serialize_array(data) + let t = undefined + if (data.length > 0) { + t = this._get_default_serialization_tag(data[0]) + } + return ZS.array(t) as ZSTypeInfo> } else if (data instanceof Map) { - this.serialize_map(data) - } else { - // should never happen + let t_key = undefined + let t_value = undefined + let val = data.entries().next() + if (val !== undefined ) { + let value = val.value + if (value !== undefined) { + t_key = this._get_default_serialization_tag(value[0] as any) + t_value = this._get_default_serialization_tag(value[1] as any) + } + } + return ZS.map(t_key, t_value) as ZSTypeInfo> + } else { // should never happen throw new Error(`Non-ZSerializeable type`); } } @@ -173,9 +279,15 @@ export class ZBytesSerializer { * - built-in types: number, bigint, string, boolean, * - types that implement ZSerializeable interface, * - arrays and maps of supported types. + * @param val Value to serialize. + * @param t An optional serialization tag (if ommited, the default one will be used). */ - public serialize(val: EnsureSerializeable) { - this._serialize_inner(val); + public serialize(val: EnsureSerializeable, t?: ZSTypeInfo>) { + if (t === undefined) { + this._get_default_serialization_tag(val).serialize(this, val) + } else { + t.serialize(this, val) + } } /** @@ -190,50 +302,132 @@ export class ZBytesSerializer { } } -class ZPartialDeserializer { - private _call: (deserializer: ZBytesDeserializer) => T +/** + * Format for `number` type serialization/deserialzation. + */ +export enum NumberFormat { + Float64 = 1, + Float32, + Int32, + Uint32, + Int16, + Uint16, + Int8, + Uint8 +} + +/** + * Format for `bigint` type serialization/deserialzation. + */ +export enum BigIntFormat { + Int64 = 1, + Uint64 +} + + +class ZDTypeInfo { + private _deserialize: (deserializer: ZBytesDeserializer) => T + + constructor(deserialize: (deserializer: ZBytesDeserializer) => T ) { + this._deserialize = deserialize + } + + /** @internal */ + deserialize(deserializer: ZBytesDeserializer): T { + return this._deserialize(deserializer) + } +} + +class ZSTypeInfo { + private _serialize: (serializer: ZBytesSerializer, val: T) => void - constructor(call: (deserializer: ZBytesDeserializer) => T ) { - this._call = call + constructor(serialize: (serializer: ZBytesSerializer, val: T) => void) { + this._serialize = serialize } /** @internal */ - call(deserializer: ZBytesDeserializer): T { - return this._call(deserializer) + serialize(serializer: ZBytesSerializer, val: T): void { + this._serialize(serializer, val) } } -export namespace ZSerDe{ +export namespace ZD{ /** - * Indicates that value should be deserialized as a number. + * Indicates that value should be deserialized as a number in specified format. * @returns Number deserialization tag. */ - export function number(): ZPartialDeserializer { - return new ZPartialDeserializer((z: ZBytesDeserializer) => { return z.deserialize_float64() }); + export function number(format: NumberFormat = NumberFormat.Float64): ZDTypeInfo { + switch(format) { + case NumberFormat.Float64: + return new ZDTypeInfo( + (z: ZBytesDeserializer) => { return z.deserialize_number_float64() } + ); + case NumberFormat.Float32: + return new ZDTypeInfo( + (z: ZBytesDeserializer) => { return z.deserialize_number_float32() } + ); + case NumberFormat.Int32: + return new ZDTypeInfo( + (z: ZBytesDeserializer) => { return z.deserialize_number_int32() } + ); + case NumberFormat.Uint32: + return new ZDTypeInfo( + (z: ZBytesDeserializer) => { return z.deserialize_number_uint32() } + ); + case NumberFormat.Int16: + return new ZDTypeInfo( + (z: ZBytesDeserializer) => { return z.deserialize_number_int16() } + ); + case NumberFormat.Uint16: + return new ZDTypeInfo( + (z: ZBytesDeserializer) => { return z.deserialize_number_uint16() } + ); + case NumberFormat.Int8: + return new ZDTypeInfo( + (z: ZBytesDeserializer) => { return z.deserialize_number_int8() } + ); + case NumberFormat.Uint8: + return new ZDTypeInfo( + (z: ZBytesDeserializer) => { return z.deserialize_number_int16() } + ); + } } /** - * Indicates that data should be deserialized as a bigint. + * Indicates that data should be deserialized as a bigint in specified format. * @returns Bigint deserialization tag. */ - export function bigint(): ZPartialDeserializer { - return new ZPartialDeserializer((z: ZBytesDeserializer) => { return z.deserialize_bigint64() }); + export function bigint(format:BigIntFormat = BigIntFormat.Int64): ZDTypeInfo { + switch (format) { + case BigIntFormat.Int64: + return new ZDTypeInfo( + (z: ZBytesDeserializer) => { return z.deserialize_bigint_int64() } + ); + case BigIntFormat.Uint64: + return new ZDTypeInfo( + (z: ZBytesDeserializer) => { return z.deserialize_bigint_uint64() } + ); + } } /** * Indicates that data should be deserialized as a string. * @returns String deserialization tag. */ - export function string(): ZPartialDeserializer { - return new ZPartialDeserializer((z: ZBytesDeserializer) => { return z.deserialize_string() }); + export function string(): ZDTypeInfo { + return new ZDTypeInfo( + (z: ZBytesDeserializer) => { return z.deserialize_string() } + ); } /** * Indicates that data should be deserialized as a boolean. * @returns Boolean deserialization tag. */ - export function boolean(): ZPartialDeserializer { - return new ZPartialDeserializer((z: ZBytesDeserializer) => { return z.deserialize_boolean() }); + export function boolean(): ZDTypeInfo { + return new ZDTypeInfo( + (z: ZBytesDeserializer) => { return z.deserialize_boolean() } + ); } /** @@ -241,29 +435,148 @@ export namespace ZSerDe{ * @param create A new function to create an object instance where data will be deserialized. * @returns Object deserialization tag. */ - export function object(create: new() => T): ZPartialDeserializer { - return new ZPartialDeserializer((z: ZBytesDeserializer) => { return z.deserialize_object(create)}) + export function object(create: new() => T): ZDTypeInfo { + return new ZDTypeInfo( + (z: ZBytesDeserializer) => { return z.deserialize_object(create) } + ); } /** * Indicates that data should be deserialized as an array. - * @param p An array element deserialization tag. + * @param t An array element deserialization tag. * @returns Array deserialization tag. */ - export function array(p: ZPartialDeserializer): ZPartialDeserializer { - return new ZPartialDeserializer((z: ZBytesDeserializer) => { return z.deserialize_array(p)}) + export function array(t: ZDTypeInfo): ZDTypeInfo { + return new ZDTypeInfo( + (z: ZBytesDeserializer) => { return z.deserialize_array(t) } + ); } /** * Indicates that data should be deserialized as a map. - * @param p An array element deserialization tag. + * @param t_key A key type deserialization tag. + * @param t_value A value type deserialization tag. * @returns Array deserialization tag. */ - export function map(p_key: ZPartialDeserializer, p_value: ZPartialDeserializer): ZPartialDeserializer> { - return new ZPartialDeserializer((z: ZBytesDeserializer) => { return z.deserialize_map(p_key, p_value)}) + export function map(t_key: ZDTypeInfo, t_value: ZDTypeInfo): ZDTypeInfo> { + return new ZDTypeInfo( + (z: ZBytesDeserializer) => { return z.deserialize_map(t_key, t_value) } + ); } } +export namespace ZS{ + /** + * Indicates that value should be serialized as a number in specified format. + * @returns Number serialization tag. + */ + export function number(format: NumberFormat = NumberFormat.Float64): ZSTypeInfo { + switch(format) { + case NumberFormat.Float64: + return new ZSTypeInfo( + (z: ZBytesSerializer, val: number) => {z.serialize_number_float64(val);} + ); + case NumberFormat.Float32: + return new ZSTypeInfo( + (z: ZBytesSerializer, val: number) => {z.serialize_number_float32(val);} + ); + case NumberFormat.Int32: + return new ZSTypeInfo( + (z: ZBytesSerializer, val: number) => {z.serialize_number_int32(val);} + ); + case NumberFormat.Uint32: + return new ZSTypeInfo( + (z: ZBytesSerializer, val: number) => {z.serialize_number_uint32(val);} + ); + case NumberFormat.Int16: + return new ZSTypeInfo( + (z: ZBytesSerializer, val: number) => {z.serialize_number_int16(val);} + ); + case NumberFormat.Uint16: + return new ZSTypeInfo( + (z: ZBytesSerializer, val: number) => {z.serialize_number_uint16(val);} + ); + case NumberFormat.Int8: + return new ZSTypeInfo( + (z: ZBytesSerializer, val: number) => {z.serialize_number_int8(val);} + ); + case NumberFormat.Uint8: + return new ZSTypeInfo( + (z: ZBytesSerializer, val: number) => {z.serialize_number_int16(val);} + ); + } + } + + /** + * Indicates that data should be serialized as a bigint in specified format. + * @returns Bigint serialization tag. + */ + export function bigint(format:BigIntFormat = BigIntFormat.Int64): ZSTypeInfo { + switch (format) { + case BigIntFormat.Int64: + return new ZSTypeInfo( + (z: ZBytesSerializer, val: bigint) => {z.serialize_bigint_int64(val);} + ); + case BigIntFormat.Uint64: + return new ZSTypeInfo( + (z: ZBytesSerializer, val: bigint) => {z.serialize_bigint_uint64(val);} + ); + } + } + + /** + * Indicates that data should be serialized as a string. + * @returns String serialization tag. + */ + export function string(): ZSTypeInfo { + return new ZSTypeInfo( + (z: ZBytesSerializer, val: string) => {z.serialize_string(val);} + ); + } + + /** + * Indicates that data should be serialized as a boolean. + * @returns Boolean serialization tag. + */ + export function boolean(): ZSTypeInfo { + return new ZSTypeInfo( + (z: ZBytesSerializer, val: boolean) => {z.serialize_boolean(val);} + ); + } + + /** + * Indicates that data should be deserialized as an object. + * @returns Object serialization tag. + */ + export function object(): ZSTypeInfo { + return new ZSTypeInfo( + (z: ZBytesSerializer, val: T) => {val.serialize_with_zserializer(z)} + ); + } + + /** + * Indicates that data should be serialized as an array. + * @param t An optional array element serialization tag (if omitted the default one will be used). + * @returns Array serialization tag. + */ + export function array(t?: ZSTypeInfo>): ZSTypeInfo[]> { + return new ZSTypeInfo( + (z: ZBytesSerializer, val: EnsureSerializeable[]) => {z.serialize_array(val, t)} + ); + } + + /** + * Indicates that data should be serialized as a map. + * @param t_key An optional key type serialization tag (if omitted the default one will be used). + * @param t_value An optional value type serialization tag (if omitted the default one will be used). + * @returns Array serialization tag. + */ + export function map(t_key?: ZSTypeInfo>, t_value?: ZSTypeInfo>): ZSTypeInfo, EnsureSerializeable>> { + return new ZSTypeInfo( + (z: ZBytesSerializer, val: Map, EnsureSerializeable>) => {z.serialize_map(val, t_key, t_value)}, + ); + } +} export class ZBytesDeserializer { private _buffer: Uint8Array; @@ -312,21 +625,93 @@ export class ZBytesDeserializer { /** * Deserializes next portion of data (serialized as 64 bit signed integer) as bigint and advance the reading position. */ - public deserialize_bigint64(): bigint { + public deserialize_bigint_int64(): bigint { let data = this._read_slice(8); let view = new DataView(data.buffer); return view.getBigInt64(0, true); } + /** + * Deserializes next portion of data (serialized as 64 bit unsigned integer) as bigint and advance the reading position. + */ + public deserialize_bigint_uint64(): bigint { + let data = this._read_slice(8); + let view = new DataView(data.buffer); + return view.getBigUint64(0, true); + } + /** * Deserializes next portion of data (serialized as 64 bit floating point number) as number and advance the reading position. */ - public deserialize_float64(): number { + public deserialize_number_float64(): number { let data = this._read_slice(8); let view = new DataView(data.buffer); return view.getFloat64(0, true); } + /** + * Deserializes next portion of data (serialized as 32 bit floating point number) as number and advance the reading position. + */ + public deserialize_number_float32(): number { + let data = this._read_slice(4); + let view = new DataView(data.buffer); + return view.getFloat32(0, true); + } + + /** + * Deserializes next portion of data (serialized as 32 bit signed integer) as number and advance the reading position. + */ + public deserialize_number_int32(): number { + let data = this._read_slice(4); + let view = new DataView(data.buffer); + return view.getInt32(0, true); + } + + /** + * Deserializes next portion of data (serialized as 32 bit unsigned integer) as number and advance the reading position. + */ + public deserialize_number_uint32(): number { + let data = this._read_slice(4); + let view = new DataView(data.buffer); + return view.getUint32(0, true); + } + + /** + * Deserializes next portion of data (serialized as 16 bit signed integer) as number and advance the reading position. + */ + public deserialize_number_int16(): number { + let data = this._read_slice(2); + let view = new DataView(data.buffer); + return view.getInt16(0, true); + } + + /** + * Deserializes next portion of data (serialized as 16 bit unsigned integer) as number and advance the reading position. + */ + public deserialize_number_uint16(): number { + let data = this._read_slice(2); + let view = new DataView(data.buffer); + return view.getUint16(0, true); + } + + /** + * Deserializes next portion of data (serialized as 8 bit signed integer) as number and advance the reading position. + */ + public deserialize_number_int8(): number { + let data = this._read_slice(1); + let view = new DataView(data.buffer); + return view.getInt8(0); + } + + /** + * Deserializes next portion of data (serialized as 8 bit unsigned integer) as number and advance the reading position. + */ + public deserialize_number_uint8(): number { + let data = this._read_slice(1); + let view = new DataView(data.buffer); + return view.getInt8(0); + } + /** * Deserializes next portion of data as a boolean and advance the reading position. */ @@ -349,11 +734,11 @@ export class ZBytesDeserializer { * Deserializes next portion of data as an array of specified type and advance the reading position. * @param p Deserialization tag for array element. */ - public deserialize_array(p: ZPartialDeserializer): T[] { + public deserialize_array(p: ZDTypeInfo): T[] { const len = this.read_sequence_length() let out = new Array(len) for (let i = 0; i < len; i++) { - out[i] = p.call(this) + out[i] = p.deserialize(this) } return out } @@ -363,12 +748,12 @@ export class ZBytesDeserializer { * @param p_key Deserialization tag for map key. * @param p_value Deserialization tag for map value. */ - public deserialize_map(p_key: ZPartialDeserializer, p_value: ZPartialDeserializer): Map { + public deserialize_map(p_key: ZDTypeInfo, p_value: ZDTypeInfo): Map { const len = this.read_sequence_length() let out = new Map() for (let i = 0; i < len; i++) { - const key = p_key.call(this) - const value = p_value.call(this) + const key = p_key.deserialize(this) + const value = p_value.deserialize(this) out.set(key, value) } return out @@ -393,8 +778,8 @@ export class ZBytesDeserializer { * @param p Deserialization tag. * @returns Deserialized value. */ - public deserialize(p: ZPartialDeserializer): T { - return p.call(this) + public deserialize(p: ZDTypeInfo): T { + return p.deserialize(this) } /** @@ -412,11 +797,12 @@ export class ZBytesDeserializer { * - types that implement ZSerializeable interface, * - arrays and maps of supported types. * @param val Value to serialize. + * @param t An optional serialization tag (if ommited, the default one will be used). * @returns Payload. */ -export function zserialize(val: EnsureSerializeable): ZBytes { +export function zserialize(val: EnsureSerializeable, t?: ZSTypeInfo>): ZBytes { const s = new ZBytesSerializer() - s.serialize(val) + s.serialize(val, t) return s.finish() } @@ -426,13 +812,13 @@ export function zserialize(val: EnsureSerializeable): ZBytes { * - built-in types: number, bigint, string, boolean, * - types that implement ZDeserializeable interface, * - arrays and maps of supported types. - * @param p Deserialization tag. + * @param t Deserialization tag. * @param data Payload to deserialize. * @returns Deserialized value. */ -export function zdeserialize(p: ZPartialDeserializer, data: ZBytes): T { +export function zdeserialize(t: ZDTypeInfo, data: ZBytes): T { const d = new ZBytesDeserializer(data) - const res = d.deserialize(p) + const res = d.deserialize(t) if (!d.is_done()) { throw new Error(`Payload contains more bytes than required for deserialization`); }