offsetDecoder<T> function
Moves the offset of a given decoder before and/or after decoding.
The pre-offset function determines where decoding should start, while the post-offset function adjusts where the next decoder should continue.
Implementation
Decoder<T> offsetDecoder<T>(Decoder<T> decoder, OffsetConfig config) {
(T, int) readImpl(Uint8List bytes, int preOffset) {
int wrapBytesImpl(int offset) => _modulo(offset, bytes.length);
final newPreOffset = config.preOffset != null
? config.preOffset!(
PreOffsetScope(
bytes: bytes,
preOffset: preOffset,
wrapBytes: wrapBytesImpl,
),
)
: preOffset;
assertByteArrayOffsetIsNotOutOfRange(
'offsetDecoder',
newPreOffset,
bytes.length,
);
final (value, postOffset) = decoder.read(bytes, newPreOffset);
final newPostOffset = config.postOffset != null
? config.postOffset!(
PostOffsetScope(
bytes: bytes,
preOffset: preOffset,
wrapBytes: wrapBytesImpl,
newPreOffset: newPreOffset,
postOffset: postOffset,
),
)
: postOffset;
assertByteArrayOffsetIsNotOutOfRange(
'offsetDecoder',
newPostOffset,
bytes.length,
);
return (value, newPostOffset);
}
return switch (decoder) {
FixedSizeDecoder<T>() => FixedSizeDecoder<T>(
fixedSize: decoder.fixedSize,
read: readImpl,
),
VariableSizeDecoder<T>() => VariableSizeDecoder<T>(
read: readImpl,
maxSize: decoder.maxSize,
),
};
}