byte_consumer.dart 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import 'dart:collection';
  2. class ByteConsumer {
  3. final _queue = ListQueue<List<int>>();
  4. final _consumed = ListQueue<List<int>>();
  5. var _currentOffset = 0;
  6. var _length = 0;
  7. var _totalConsumed = 0;
  8. void add(String data) {
  9. if (data.isEmpty) return;
  10. final runes = data.runes.toList(growable: false);
  11. _queue.addLast(runes);
  12. _length += runes.length;
  13. }
  14. int peek() {
  15. final data = _queue.first;
  16. if (_currentOffset < data.length) {
  17. return data[_currentOffset];
  18. } else {
  19. final result = consume();
  20. rollback();
  21. return result;
  22. }
  23. }
  24. int consume() {
  25. final data = _queue.first;
  26. if (_currentOffset >= data.length) {
  27. _consumed.add(_queue.removeFirst());
  28. _currentOffset -= data.length;
  29. return consume();
  30. }
  31. _length--;
  32. _totalConsumed++;
  33. return data[_currentOffset++];
  34. }
  35. /// Rolls back the last [n] call.
  36. void rollback([int n = 1]) {
  37. _currentOffset -= n;
  38. _totalConsumed -= n;
  39. _length += n;
  40. while (_currentOffset < 0) {
  41. final rollback = _consumed.removeLast();
  42. _queue.addFirst(rollback);
  43. _currentOffset += rollback.length;
  44. }
  45. }
  46. /// Rolls back to the state when this consumer had [length] bytes.
  47. void rollbackTo(int length) {
  48. rollback(length - _length);
  49. }
  50. int get length => _length;
  51. int get totalConsumed => _totalConsumed;
  52. bool get isEmpty => _length == 0;
  53. bool get isNotEmpty => _length != 0;
  54. /// Unreferences data blocks that have been consumed. After calling this
  55. /// method, the consumer will not be able to roll back to consumed blocks.
  56. void unrefConsumedBlocks() {
  57. _consumed.clear();
  58. }
  59. /// Resets the consumer to its initial state.
  60. void reset() {
  61. _queue.clear();
  62. _consumed.clear();
  63. _currentOffset = 0;
  64. _totalConsumed = 0;
  65. _length = 0;
  66. }
  67. }
  68. // void main() {
  69. // final consumer = ByteConsumer();
  70. // consumer.add(Uint8List.fromList([1, 2, 3]));
  71. // consumer.add(Uint8List.fromList([4, 5, 6]));
  72. // while (consumer.isNotEmpty) {
  73. // print(consumer.consume());
  74. // }
  75. // consumer.rollback(5);
  76. // while (consumer.isNotEmpty) {
  77. // print(consumer.consume());
  78. // }
  79. // consumer.rollbackTo(3);
  80. // while (consumer.isNotEmpty) {
  81. // print(consumer.consume());
  82. // }
  83. // }