OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 library mime.bound_multipart_stream; | 4 library mime.bound_multipart_stream; |
5 | 5 |
6 import 'dart:async'; | 6 import 'dart:async'; |
7 import 'dart:convert'; | 7 import 'dart:convert'; |
8 | 8 |
9 import 'mime_shared.dart'; | 9 import 'mime_shared.dart'; |
10 import 'char_code.dart'; | 10 import 'char_code.dart'; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 bool cancelOnError}) { | 47 bool cancelOnError}) { |
48 return _stream.listen(onData, | 48 return _stream.listen(onData, |
49 onDone: onDone, | 49 onDone: onDone, |
50 onError: onError, | 50 onError: onError, |
51 cancelOnError: cancelOnError); | 51 cancelOnError: cancelOnError); |
52 } | 52 } |
53 } | 53 } |
54 | 54 |
55 class BoundMultipartStream { | 55 class BoundMultipartStream { |
56 static const int _START = 0; | 56 static const int _START = 0; |
57 static const int _FIRST_BOUNDARY_ENDING = 111; | |
58 static const int _FIRST_BOUNDARY_END = 112; | |
59 static const int _BOUNDARY_ENDING = 1; | 57 static const int _BOUNDARY_ENDING = 1; |
60 static const int _BOUNDARY_END = 2; | 58 static const int _BOUNDARY_END = 2; |
61 static const int _HEADER_START = 3; | 59 static const int _HEADER_START = 3; |
62 static const int _HEADER_FIELD = 4; | 60 static const int _HEADER_FIELD = 4; |
63 static const int _HEADER_VALUE_START = 5; | 61 static const int _HEADER_VALUE_START = 5; |
64 static const int _HEADER_VALUE = 6; | 62 static const int _HEADER_VALUE = 6; |
65 static const int _HEADER_VALUE_FOLDING_OR_ENDING = 7; | 63 static const int _HEADER_VALUE_FOLDING_OR_ENDING = 7; |
66 static const int _HEADER_VALUE_FOLD_OR_END = 8; | 64 static const int _HEADER_VALUE_FOLD_OR_END = 8; |
67 static const int _HEADER_ENDING = 9; | 65 static const int _HEADER_ENDING = 9; |
68 static const int _CONTENT = 10; | 66 static const int _CONTENT = 10; |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 if (_index < 0) { | 178 if (_index < 0) { |
181 byte = _boundary[boundaryPrefix + _index]; | 179 byte = _boundary[boundaryPrefix + _index]; |
182 } else { | 180 } else { |
183 byte = _buffer[_index]; | 181 byte = _buffer[_index]; |
184 } | 182 } |
185 switch (_state) { | 183 switch (_state) { |
186 case _START: | 184 case _START: |
187 if (byte == _boundary[_boundaryIndex]) { | 185 if (byte == _boundary[_boundaryIndex]) { |
188 _boundaryIndex++; | 186 _boundaryIndex++; |
189 if (_boundaryIndex == _boundary.length) { | 187 if (_boundaryIndex == _boundary.length) { |
190 _state = _FIRST_BOUNDARY_ENDING; | 188 _state = _BOUNDARY_ENDING; |
191 _boundaryIndex = 0; | 189 _boundaryIndex = 0; |
192 } | 190 } |
193 } else { | 191 } else { |
194 // Restart matching of the boundary. | 192 // Restart matching of the boundary. |
195 _index = _index - _boundaryIndex; | 193 _index = _index - _boundaryIndex; |
196 _boundaryIndex = 0; | 194 _boundaryIndex = 0; |
197 } | 195 } |
198 break; | 196 break; |
199 | 197 |
200 case _FIRST_BOUNDARY_ENDING: | |
201 if (byte == CharCode.CR) { | |
202 _state = _FIRST_BOUNDARY_END; | |
203 } else { | |
204 _expectWhitespace(byte); | |
205 } | |
206 break; | |
207 | |
208 case _FIRST_BOUNDARY_END: | |
209 _expectByteValue(byte, CharCode.LF); | |
210 _state = _HEADER_START; | |
211 break; | |
212 | |
213 case _BOUNDARY_ENDING: | 198 case _BOUNDARY_ENDING: |
214 if (byte == CharCode.CR) { | 199 if (byte == CharCode.CR) { |
215 _state = _BOUNDARY_END; | 200 _state = _BOUNDARY_END; |
216 } else if (byte == CharCode.DASH) { | 201 } else if (byte == CharCode.DASH) { |
217 _state = _LAST_BOUNDARY_DASH2; | 202 _state = _LAST_BOUNDARY_DASH2; |
218 } else { | 203 } else { |
219 _expectWhitespace(byte); | 204 _expectWhitespace(byte); |
220 } | 205 } |
221 break; | 206 break; |
222 | 207 |
223 case _BOUNDARY_END: | 208 case _BOUNDARY_END: |
224 _expectByteValue(byte, CharCode.LF); | 209 _expectByteValue(byte, CharCode.LF); |
225 _multipartController.close(); | 210 if (_multipartController != null) { |
226 _multipartController = null; | 211 _multipartController.close(); |
| 212 _multipartController = null; |
| 213 } |
227 _state = _HEADER_START; | 214 _state = _HEADER_START; |
228 break; | 215 break; |
229 | 216 |
230 case _HEADER_START: | 217 case _HEADER_START: |
231 _headers = new Map<String, String>(); | 218 _headers = new Map<String, String>(); |
232 if (byte == CharCode.CR) { | 219 if (byte == CharCode.CR) { |
233 _state = _HEADER_ENDING; | 220 _state = _HEADER_ENDING; |
234 } else { | 221 } else { |
235 // Start of new header field. | 222 // Start of new header field. |
236 _headerField.add(_toLowerCase(byte)); | 223 _headerField.add(_toLowerCase(byte)); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 case _LAST_BOUNDARY_ENDING: | 325 case _LAST_BOUNDARY_ENDING: |
339 if (byte == CharCode.CR) { | 326 if (byte == CharCode.CR) { |
340 _state = _LAST_BOUNDARY_END; | 327 _state = _LAST_BOUNDARY_END; |
341 } else { | 328 } else { |
342 _expectWhitespace(byte); | 329 _expectWhitespace(byte); |
343 } | 330 } |
344 break; | 331 break; |
345 | 332 |
346 case _LAST_BOUNDARY_END: | 333 case _LAST_BOUNDARY_END: |
347 _expectByteValue(byte, CharCode.LF); | 334 _expectByteValue(byte, CharCode.LF); |
348 _multipartController.close(); | 335 if (_multipartController != null) { |
349 _multipartController = null; | 336 _multipartController.close(); |
| 337 _multipartController = null; |
| 338 } |
350 _state = _DONE; | 339 _state = _DONE; |
351 break; | 340 break; |
352 | 341 |
353 default: | 342 default: |
354 // Should be unreachable. | 343 // Should be unreachable. |
355 assert(false); | 344 assert(false); |
356 break; | 345 break; |
357 } | 346 } |
358 | 347 |
359 // Move to the next byte. | 348 // Move to the next byte. |
360 _index++; | 349 _index++; |
361 } | 350 } |
362 | 351 |
363 // Report any known content. | 352 // Report any known content. |
364 if (_state == _CONTENT && contentStartIndex != null) { | 353 if (_state == _CONTENT && contentStartIndex != null) { |
365 reportData(); | 354 reportData(); |
366 } | 355 } |
367 | 356 |
368 // Resume if at end. | 357 // Resume if at end. |
369 if (_index == _buffer.length) { | 358 if (_index == _buffer.length) { |
370 _buffer = null; | 359 _buffer = null; |
371 _index = null; | 360 _index = null; |
372 _resumeStream(); | 361 _resumeStream(); |
373 } | 362 } |
374 } | 363 } |
375 } | 364 } |
OLD | NEW |