Skip to content

Commit

Permalink
feat(tlv)!: simplify value type selection in TlvIo
Browse files Browse the repository at this point in the history
BREAKING CHANGE: The value type callback mechanism for TlvIo has been
simplified: tag-to-value-type mappings should now be provided as
properties on a plain JavaScript object.
  • Loading branch information
fallenoak committed Dec 19, 2023
1 parent c4e51ba commit 4768072
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 16 deletions.
6 changes: 3 additions & 3 deletions src/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import ArrayIo, { ArrayOptions } from './type/ArrayIo.js';
import StringIo, { StringOptions } from './type/StringIo.js';
import StructIo, { StructFields, StructOptions } from './type/StructIo.js';
import TlvIo, { TlvValueCallback } from './type/TlvIo.js';
import TlvIo from './type/TlvIo.js';
import { IoMode, validateType } from './util.js';
import { openStream } from './stream/util.js';
import { IoContext, IoSource, IoStream, IoType } from './types.js';
Expand All @@ -17,8 +17,8 @@ const struct = (fields: StructFields, options: StructOptions = {}) =>
const tlv = (
tagType: IoType,
lengthType: IoType,
valueCallback: TlvValueCallback,
) => new TlvIo(tagType, lengthType, valueCallback);
valueTypes: Record<string | number, IoType>,
) => new TlvIo(tagType, lengthType, valueTypes);

const int8 = {
getSize: (_value: number) => 1,
Expand Down
20 changes: 7 additions & 13 deletions src/lib/type/TlvIo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ import { Endianness, IoMode } from '../util.js';
import { openStream } from '../stream/util.js';
import { IoContext, IoSource, IoType } from '../types.js';

type TlvValueCallback = (
type: string | number,
length: number,
) => IoType | undefined | null;

type TlvOptions = {
endianness?: Endianness;
};
Expand All @@ -25,27 +20,27 @@ type Tlv = {
class TlvIo implements IoType {
#tagType: IoType;
#lengthType: IoType;
#valueCallback: TlvValueCallback;
#valueTypes: Record<string | number, IoType>;
#options: TlvOptions;

/**
* The TlvIo() constructor creates new TlvIo objects.
*
* @param tagType - An IoType that resolves to a string or number.
* @param lengthType - An IoType that resolves to a number.
* @param valueCallback - A function that returns any IoType from the given tag and length. If the callback returns
* undefined or null, the value will be read as a Uint8Array.
* @param valueTypes - A record containing keys mapping possible tags to an appropriate IoType for use in reading the
* value. If the record does not contain a corresponding IoType for a tag, the value will be read as a Uint8Array.
* @param options
*/
constructor(
tagType: IoType,
lengthType: IoType,
valueCallback: TlvValueCallback,
valueTypes: Record<string | number, IoType>,
options: TlvOptions = {},
) {
this.#tagType = tagType;
this.#lengthType = lengthType;
this.#valueCallback = valueCallback;
this.#valueTypes = valueTypes;
this.#options = options;
}

Expand Down Expand Up @@ -75,7 +70,7 @@ class TlvIo implements IoType {
};
}

const valueType = this.#valueCallback(tagValue, lengthValue);
const valueType = this.#valueTypes[tagValue];
const valueBytes = stream.readBytes(lengthValue);

let valueValue = valueBytes;
Expand Down Expand Up @@ -108,7 +103,7 @@ class TlvIo implements IoType {

// Skip writing values for zero-length TLVs
if (value.length !== 0) {
const valueType = this.#valueCallback(value.tag, value.length);
const valueType = this.#valueTypes[value.tag];
if (valueType && valueType.write) {
valueType.write(stream, value.value, context);
} else {
Expand All @@ -124,4 +119,3 @@ class TlvIo implements IoType {
}

export default TlvIo;
export { TlvValueCallback };

0 comments on commit 4768072

Please sign in to comment.