@@ -98,39 +98,11 @@ class DaemonInputStreamConverter {
9898
9999 // Processes a single chunk received in the input stream.
100100 void _processChunk (List <int > chunk) {
101- const int LF = 10 ; // The '\n' character
102101
103102 int start = 0 ;
104103 while (start < chunk.length) {
105104 if (state == _InputStreamParseState .json) {
106- // Search for newline character.
107- final int indexOfNewLine = chunk.indexOf (LF , start);
108- if (indexOfNewLine < 0 ) {
109- bytesBuilder.add (chunk.sublist (start));
110- start = chunk.length;
111- } else {
112- bytesBuilder.add (chunk.sublist (start, indexOfNewLine + 1 ));
113- start = indexOfNewLine + 1 ;
114-
115- // Process chunk here
116- final Uint8List combinedChunk = bytesBuilder.takeBytes ();
117- String jsonString = utf8.decode (combinedChunk).trim ();
118- if (jsonString.startsWith ('[{' ) && jsonString.endsWith ('}]' )) {
119- jsonString = jsonString.substring (1 , jsonString.length - 1 );
120- final Map <String , Object ?>? value = castStringKeyedMap (json.decode (jsonString));
121- if (value != null ) {
122- // Check if we need to consume another binary blob.
123- if (value[_binaryLengthKey] != null ) {
124- remainingBinaryLength = value[_binaryLengthKey]! as int ;
125- currentBinaryStream = StreamController <List <int >>();
126- state = _InputStreamParseState .binary;
127- _controller.add (DaemonMessage (value, currentBinaryStream.stream));
128- } else {
129- _controller.add (DaemonMessage (value));
130- }
131- }
132- }
133- }
105+ start += _processChunkInJsonMode (chunk, start);
134106 } else if (state == _InputStreamParseState .binary) {
135107 final int bytesSent = _addBinaryChunk (chunk, start, remainingBinaryLength);
136108 start += bytesSent;
@@ -146,6 +118,41 @@ class DaemonInputStreamConverter {
146118 }
147119 }
148120
121+ /// Processes a chunk in JSON mode, and returns the number of bytes processed.
122+ int _processChunkInJsonMode (List <int > chunk, int start) {
123+ const int LF = 10 ; // The '\n' character
124+
125+ // Search for newline character.
126+ final int indexOfNewLine = chunk.indexOf (LF , start);
127+ if (indexOfNewLine < 0 ) {
128+ bytesBuilder.add (chunk.sublist (start));
129+ return chunk.length - start;
130+ }
131+
132+ bytesBuilder.add (chunk.sublist (start, indexOfNewLine + 1 ));
133+
134+ // Process chunk here
135+ final Uint8List combinedChunk = bytesBuilder.takeBytes ();
136+ String jsonString = utf8.decode (combinedChunk).trim ();
137+ if (jsonString.startsWith ('[{' ) && jsonString.endsWith ('}]' )) {
138+ jsonString = jsonString.substring (1 , jsonString.length - 1 );
139+ final Map <String , Object ?>? value = castStringKeyedMap (json.decode (jsonString));
140+ if (value != null ) {
141+ // Check if we need to consume another binary blob.
142+ if (value[_binaryLengthKey] != null ) {
143+ remainingBinaryLength = value[_binaryLengthKey]! as int ;
144+ currentBinaryStream = StreamController <List <int >>();
145+ state = _InputStreamParseState .binary;
146+ _controller.add (DaemonMessage (value, currentBinaryStream.stream));
147+ } else {
148+ _controller.add (DaemonMessage (value));
149+ }
150+ }
151+ }
152+
153+ return indexOfNewLine + 1 - start;
154+ }
155+
149156 int _addBinaryChunk (List <int > chunk, int start, int maximumSizeToRead) {
150157 if (start == 0 && chunk.length <= remainingBinaryLength) {
151158 currentBinaryStream.add (chunk);
@@ -170,6 +177,32 @@ class DaemonStreams {
170177 inputStream = DaemonInputStreamConverter (rawInputStream).convertedStream,
171178 _logger = logger;
172179
180+ /// Creates a [DaemonStreams] that uses stdin and stdout as the underlying streams.
181+ DaemonStreams .fromStdio (Stdio stdio, { required Logger logger })
182+ : this (stdio.stdin, stdio.stdout, logger: logger);
183+
184+ /// Creates a [DaemonStreams] that uses [Socket] as the underlying streams.
185+ DaemonStreams .fromSocket (Socket socket, { required Logger logger })
186+ : this (socket, socket, logger: logger);
187+
188+ /// Connects to a server and creates a [DaemonStreams] from the connection as the underlying streams.
189+ factory DaemonStreams .connect (String host, int port, { required Logger logger }) {
190+ final Future <Socket > socketFuture = Socket .connect (host, port);
191+ final StreamController <List <int >> inputStreamController = StreamController <List <int >>();
192+ final StreamController <List <int >> outputStreamController = StreamController <List <int >>();
193+ socketFuture.then ((Socket socket) {
194+ inputStreamController.addStream (socket);
195+ socket.addStream (outputStreamController.stream);
196+ }).onError ((Object error, StackTrace stackTrace) {
197+ logger.printError ('Socket error: $error ' );
198+ logger.printTrace ('$stackTrace ' );
199+ // Propagate the error to the streams.
200+ inputStreamController.addError (error, stackTrace);
201+ unawaited (outputStreamController.close ());
202+ });
203+ return DaemonStreams (inputStreamController.stream, outputStreamController.sink, logger: logger);
204+ }
205+
173206 final StreamSink <List <int >> _outputSink;
174207 final Logger _logger;
175208
@@ -197,28 +230,6 @@ class DaemonStreams {
197230 Future <void > dispose () async {
198231 unawaited (_outputSink.close ());
199232 }
200-
201- /// Creates a [DaemonStreams] that uses stdin and stdout as the underlying streams.
202- static DaemonStreams fromStdio (Stdio stdio, { required Logger logger }) {
203- return DaemonStreams (stdio.stdin, stdio.stdout, logger: logger);
204- }
205-
206- /// Creates a [DaemonStreams] that uses [Socket] as the underlying streams.
207- static DaemonStreams fromSocket (Socket socket, { required Logger logger }) {
208- return DaemonStreams (socket, socket, logger: logger);
209- }
210-
211- /// Connects to a server and creates a [DaemonStreams] from the connection as the underlying streams.
212- static DaemonStreams connect (String host, int port, { required Logger logger }) {
213- final Future <Socket > socketFuture = Socket .connect (host, port);
214- final StreamController <List <int >> inputStreamController = StreamController <List <int >>();
215- final StreamController <List <int >> outputStreamController = StreamController <List <int >>();
216- socketFuture.then ((Socket socket) {
217- inputStreamController.addStream (socket);
218- socket.addStream (outputStreamController.stream);
219- });
220- return DaemonStreams (inputStreamController.stream, outputStreamController.sink, logger: logger);
221- }
222233}
223234
224235/// Connection between a flutter daemon and a client.
0 commit comments