| 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 |