Skip to content

Commit 5234076

Browse files
scheglovCommit Bot
authored and
Commit Bot
committed
Tweaks for MessageGrouper.
Change-Id: I1be1d7e998ee28414a455816383e5d0810d4ad9e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/239403 Reviewed-by: Jake Macdonald <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent 8a280c9 commit 5234076

File tree

1 file changed

+52
-45
lines changed

1 file changed

+52
-45
lines changed

pkg/_fe_analyzer_shared/lib/src/macros/executor/message_grouper.dart

Lines changed: 52 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'dart:async';
6-
import 'dart:math';
76
import 'dart:typed_data';
87

98
/// Collects messages from an input stream of bytes.
@@ -14,18 +13,11 @@ class MessageGrouper {
1413
/// The input bytes stream subscription.
1514
late final StreamSubscription _inputStreamSubscription;
1615

17-
/// The length of the current message to read, or `-1` if we are currently
18-
/// reading the length.
19-
int _length = -1;
20-
2116
/// The buffer to store the length bytes in.
22-
BytesBuilder _lengthBuffer = new BytesBuilder();
17+
final _FixedBuffer _lengthBuffer = new _FixedBuffer(4);
2318

2419
/// If reading raw data, buffer for the data.
25-
Uint8List _messageBuffer = new Uint8List(0);
26-
27-
/// The position to write the next byte in [_messageBuffer].
28-
int _messagePos = 0;
20+
_FixedBuffer? _messageBuffer;
2921

3022
late StreamController<Uint8List> _messageStreamController =
3123
new StreamController<Uint8List>(onCancel: () {
@@ -38,45 +30,36 @@ class MessageGrouper {
3830
}
3931

4032
void _handleBytes(List<int> bytes, [int offset = 0]) {
41-
if (_length == -1) {
42-
while (_lengthBuffer.length < 4 && offset < bytes.length) {
33+
final _FixedBuffer? messageBuffer = _messageBuffer;
34+
if (messageBuffer == null) {
35+
while (offset < bytes.length && !_lengthBuffer.isReady) {
4336
_lengthBuffer.addByte(bytes[offset++]);
4437
}
45-
if (_lengthBuffer.length >= 4) {
46-
Uint8List lengthBytes = _lengthBuffer.takeBytes();
47-
_length = lengthBytes[0] << 24 |
48-
lengthBytes[1] << 16 |
49-
lengthBytes[2] << 8 |
50-
lengthBytes[3];
38+
if (_lengthBuffer.isReady) {
39+
int length = _lengthBuffer[0] << 24 |
40+
_lengthBuffer[1] << 16 |
41+
_lengthBuffer[2] << 8 |
42+
_lengthBuffer[3];
43+
// Reset the length reading state.
44+
_lengthBuffer.reset();
45+
// Switch to the message payload reading state.
46+
_messageBuffer = new _FixedBuffer(length);
47+
_handleBytes(bytes, offset);
48+
} else {
49+
// Continue reading the length.
50+
return;
51+
}
52+
} else {
53+
// Read the data from `bytes`.
54+
while (offset < bytes.length && !messageBuffer.isReady) {
55+
messageBuffer.addByte(bytes[offset++]);
5156
}
52-
}
53-
54-
// Just pass along `bytes` without a copy if we can, and reset our state
55-
if (offset == 0 && bytes.length == _length && bytes is Uint8List) {
56-
_length = -1;
57-
_messageStreamController.add(bytes);
58-
return;
59-
}
60-
61-
// Initialize a new buffer.
62-
if (_messagePos == 0) {
63-
_messageBuffer = new Uint8List(_length);
64-
}
65-
66-
// Read the data from `bytes`.
67-
int lenToRead = min(_length - _messagePos, bytes.length - offset);
68-
while (lenToRead-- > 0) {
69-
_messageBuffer[_messagePos++] = bytes[offset++];
70-
}
71-
72-
// If we completed a message, add it to the output stream, reset our state,
73-
// and call ourselves again if we have more data to read.
74-
if (_messagePos >= _length) {
75-
_messageStreamController.add(_messageBuffer);
76-
_length = -1;
77-
_messagePos = 0;
7857

79-
if (offset < bytes.length) {
58+
// If we completed a message, add it to the output stream.
59+
if (messageBuffer.isReady) {
60+
_messageStreamController.add(messageBuffer.bytes);
61+
// Switch to the length reading state.
62+
_messageBuffer = null;
8063
_handleBytes(bytes, offset);
8164
}
8265
}
@@ -89,3 +72,27 @@ class MessageGrouper {
8972
_messageStreamController.close();
9073
}
9174
}
75+
76+
/// A buffer of fixed length.
77+
class _FixedBuffer {
78+
final Uint8List bytes;
79+
80+
/// The offset in [bytes].
81+
int _offset = 0;
82+
83+
_FixedBuffer(int length) : bytes = new Uint8List(length);
84+
85+
/// Return `true` when the required number of bytes added.
86+
bool get isReady => _offset == bytes.length;
87+
88+
int operator [](int index) => bytes[index];
89+
90+
void addByte(int byte) {
91+
bytes[_offset++] = byte;
92+
}
93+
94+
/// Reset the number of added bytes to zero.
95+
void reset() {
96+
_offset = 0;
97+
}
98+
}

0 commit comments

Comments
 (0)