Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# ⏩ vNext
- Add support for custom transformers on parsed values

# v4.2.2
- Fix an issue where the new 53-bit oversize error is emitted when the `float` format is selected, even though it is
Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,20 @@ class Type2Element extends BaseElement {
Here `count` and `items.length` will always agree at all times, with the bonus that assigning `undefined` to the array
is forbidden.

### Transformers

It can be useful to have custom function that transforms the field value after deserialize or before serialize.
Use the `transformers` option to specify read or/and write function:

```typescript
class Type2Element extends BaseElement {
@Field(version, { transformers: {read: v => v/100, write: v => v * 100 })
version : number;
}
```

In this example version value `1.20` is the integer `120` on the stream.

### Measurement

It can be useful to measure the bitlength of a portion of a BitstreamElement. Such a measurement could be used when
Expand Down
14 changes: 14 additions & 0 deletions src/elements/array-serializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ export class ArraySerializer implements Serializer {
readNumber();
}
}
if(field.options?.transformers?.read) {
elements.forEach((element, index) => {
elements[index] = field.options.transformers.read(element, field, parent);
})
}
} else {
if (field.options.array.hasMore) {
let i = 0;
Expand Down Expand Up @@ -167,10 +172,15 @@ export class ArraySerializer implements Serializer {
}
}


for (let i = 0; i < length; ++i) {
if (field?.options?.array?.type === Number) {
let type = field.options?.number?.format ?? 'unsigned';

if(field.options?.transformers?.write) {
value[i] = field.options.transformers.write(value[i],field,parent);
}

if (type === 'unsigned')
writer.write(field.options.array.elementLength, value[i]);
else if (type === 'signed')
Expand All @@ -179,6 +189,10 @@ export class ArraySerializer implements Serializer {
writer.writeFloat(field.options.array.elementLength, value[i]);

} else {
if(field.options?.transformers?.write) {
Object.assign(value[i], field.options.transformers.write(value[i],field,parent));
}

(value[i] as BitstreamElement).write(writer, { context: parent?.context });
}
}
Expand Down
21 changes: 17 additions & 4 deletions src/elements/boolean-serializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,26 @@ export class BooleanSerializer implements Serializer {
if (!reader.isAvailable(length))
yield { remaining: length, contextHint: () => summarizeField(field) };

const numericValue = reader.readSync(length);
let numericValue = reader.readSync(length);

const trueValue = field?.options?.boolean?.true ?? 1;
const falseValue = field?.options?.boolean?.false ?? 0;
const mode = field?.options?.boolean?.mode ?? 'true-unless';

let boolValue;
if (mode === 'true-unless')
return numericValue !== falseValue;
boolValue = numericValue !== falseValue;
else if (mode === 'false-unless')
return numericValue === trueValue;
boolValue = numericValue === trueValue;
else if (mode === 'undefined')
return numericValue === trueValue ? true : numericValue === falseValue ? false : undefined;
boolValue = numericValue === trueValue ? true : numericValue === falseValue ? false : undefined;

if ( field?.options?.transformers?.read ){
boolValue = field.options.transformers.read(boolValue,field, parent);
}

return boolValue;

}

write(writer: BitstreamWriter, type : any, instance: any, field: FieldDefinition, value: any) {
Expand All @@ -35,6 +44,10 @@ export class BooleanSerializer implements Serializer {
const undefinedValue = field?.options?.boolean?.undefined ?? 0;
let numericValue : number;

if ( field?.options?.transformers?.write ){
value = field.options.transformers.write(value,field, instance);
}

if (value === void 0)
numericValue = undefinedValue;
else if (value)
Expand Down
10 changes: 10 additions & 0 deletions src/elements/buffer-serializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ import { summarizeField } from "./utils";
break;
}

if ( field?.options?.transformers?.read ){
buffer = field.options.transformers.read(buffer,field, parent);
}


return buffer;
}

Expand All @@ -56,6 +61,11 @@ import { summarizeField } from "./utils";
throw new Error(`BufferSerializer: Field ${String(field.name)}: Cannot encode a null buffer`);
}

if ( field?.options?.transformers?.write ){
value = field.options.transformers.write(value,field, parent);
}


if (value.length > fieldLength) {
if (truncate) {
writer.writeBuffer(value.subarray(0, fieldLength));
Expand Down
Loading