diff --git a/lib/transaction.dart b/lib/transaction.dart index f136970..e7747d7 100644 --- a/lib/transaction.dart +++ b/lib/transaction.dart @@ -65,6 +65,20 @@ class Transaction { header: header, maxLen: maxLen)); } + /// Create a transaction that uses MagicHeaderFixedLengthByteTransformer + /// + /// ```dart + /// Transaction.magicHeaderFixedLength(p.inputStream, Uint8List.fromList([65,65,65]), len: 10); // expects magic header AAA and fixed length 10. + /// ``` + static Transaction magicHeaderFixedLength( + Stream stream, List header, int len, + {int maxLen = 1024}) { + return Transaction( + stream, + MagicHeaderFixedLengthByteTransformer.broadcast( + header: header, len: len, maxLen: maxLen)); + } + /// Create a transaction that transforms the incoming stream into /// events delimited by 'terminator', returning Strings. /// diff --git a/lib/transformers.dart b/lib/transformers.dart index 0b36dbb..bb70f6e 100644 --- a/lib/transformers.dart +++ b/lib/transformers.dart @@ -385,3 +385,66 @@ class MagicHeaderAndLengthByteTransformer _controller.close(); } } + +class MagicHeaderFixedLengthByteTransformer + extends MagicHeaderAndLengthByteTransformer { + final int len; + + MagicHeaderFixedLengthByteTransformer( + {bool sync = false, + bool? cancelOnError, + List? header, + required this.len, + int maxLen = 1024, + Duration clearTimeout = const Duration(seconds: 1)}) + : super( + sync: sync, + cancelOnError: cancelOnError, + header: header, + maxLen: maxLen, + clearTimeout: clearTimeout); + + MagicHeaderFixedLengthByteTransformer.broadcast( + {bool sync = false, + bool? cancelOnError, + List? header, + required this.len, + int maxLen = 1024, + Duration clearTimeout = const Duration(seconds: 1)}) + : super.broadcast( + sync: sync, + cancelOnError: cancelOnError, + header: header, + maxLen: maxLen, + clearTimeout: clearTimeout); + + @override + void onData(Uint8List data) { + _dataSinceLastTick = true; + if (_partial.length > maxLen) { + _partial = _partial.sublist(_partial.length - maxLen); + } + + _partial.addAll(data); + + while (_partial.length > 0) { + int index = wildcardFind(header, _partial); + if (index < 0) { + return; + } + + if (index > 0) { + _partial = _partial.sublist(index); + } + + if (_partial.length < header!.length + len + 1) { + // not completely arrived yet. + return; + } + + _controller + .add(Uint8List.fromList(_partial.sublist(0, len + header!.length + 1))); + _partial = _partial.sublist(len + header!.length + 1); + } + } +} \ No newline at end of file