| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 | 4 |
| 5 part of mime; | 5 library mime.multipart_transformer; |
| 6 | 6 |
| 7 import 'dart:async'; |
| 8 import 'dart:convert'; |
| 9 import 'dart:typed_data'; |
| 7 | 10 |
| 8 /** | 11 /** |
| 9 * A Mime Multipart class representing each part parsed by | 12 * A Mime Multipart class representing each part parsed by |
| 10 * [MimeMultipartTransformer]. The data is streamed in as it become available. | 13 * [MimeMultipartTransformer]. The data is streamed in as it become available. |
| 11 */ | 14 */ |
| 12 abstract class MimeMultipart extends Stream<List<int>> { | 15 abstract class MimeMultipart extends Stream<List<int>> { |
| 13 Map<String, String> get headers; | 16 Map<String, String> get headers; |
| 14 } | 17 } |
| 15 | 18 |
| 16 class _MimeMultipart extends MimeMultipart { | 19 class _MimeMultipart extends MimeMultipart { |
| 17 final Map<String, String> headers; | 20 final Map<String, String> headers; |
| 18 final Stream<List<int>> _stream; | 21 final Stream<List<int>> _stream; |
| 19 | 22 |
| 20 _MimeMultipart(this.headers, this._stream); | 23 _MimeMultipart(this.headers, this._stream); |
| 21 | 24 |
| 22 StreamSubscription<List<int>> listen(void onData(List<int> data), | 25 StreamSubscription<List<int>> listen(void onData(List<int> data), |
| 23 {void onDone(), | 26 {void onDone(), |
| 24 Function onError, | 27 Function onError, |
| 25 bool cancelOnError}) { | 28 bool cancelOnError}) { |
| 26 return _stream.listen(onData, | 29 return _stream.listen(onData, |
| 27 onDone: onDone, | 30 onDone: onDone, |
| 28 onError: onError, | 31 onError: onError, |
| 29 cancelOnError: cancelOnError); | 32 cancelOnError: cancelOnError); |
| 30 } | 33 } |
| 31 } | 34 } |
| 32 | 35 |
| 33 class _Const { | |
| 34 // Bytes for '()<>@,;:\\"/[]?={} \t'. | |
| 35 static const SEPARATORS = const [40, 41, 60, 62, 64, 44, 59, 58, 92, 34, 47, | |
| 36 91, 93, 63, 61, 123, 125, 32, 9]; | |
| 37 } | |
| 38 | |
| 39 class _CharCode { | 36 class _CharCode { |
| 40 static const int HT = 9; | 37 static const int HT = 9; |
| 41 static const int LF = 10; | 38 static const int LF = 10; |
| 42 static const int CR = 13; | 39 static const int CR = 13; |
| 43 static const int SP = 32; | 40 static const int SP = 32; |
| 44 static const int DASH = 45; | 41 static const int DASH = 45; |
| 45 static const int COLON = 58; | 42 static const int COLON = 58; |
| 46 } | 43 } |
| 47 | 44 |
| 48 /** | 45 /** |
| (...skipping 15 matching lines...) Expand all Loading... |
| 64 static const int _HEADER_VALUE_FOLDING_OR_ENDING = 7; | 61 static const int _HEADER_VALUE_FOLDING_OR_ENDING = 7; |
| 65 static const int _HEADER_VALUE_FOLD_OR_END = 8; | 62 static const int _HEADER_VALUE_FOLD_OR_END = 8; |
| 66 static const int _HEADER_ENDING = 9; | 63 static const int _HEADER_ENDING = 9; |
| 67 static const int _CONTENT = 10; | 64 static const int _CONTENT = 10; |
| 68 static const int _LAST_BOUNDARY_DASH2 = 11; | 65 static const int _LAST_BOUNDARY_DASH2 = 11; |
| 69 static const int _LAST_BOUNDARY_ENDING = 12; | 66 static const int _LAST_BOUNDARY_ENDING = 12; |
| 70 static const int _LAST_BOUNDARY_END = 13; | 67 static const int _LAST_BOUNDARY_END = 13; |
| 71 static const int _DONE = 14; | 68 static const int _DONE = 14; |
| 72 static const int _FAILURE = 15; | 69 static const int _FAILURE = 15; |
| 73 | 70 |
| 71 // Bytes for '()<>@,;:\\"/[]?={} \t'. |
| 72 static const _SEPARATORS = const [40, 41, 60, 62, 64, 44, 59, 58, 92, 34, 47, |
| 73 91, 93, 63, 61, 123, 125, 32, 9]; |
| 74 |
| 74 StreamController _controller; | 75 StreamController _controller; |
| 75 StreamSubscription _subscription; | 76 StreamSubscription _subscription; |
| 76 | 77 |
| 77 StreamController _multipartController; | 78 StreamController _multipartController; |
| 78 Map<String, String> _headers; | 79 Map<String, String> _headers; |
| 79 | 80 |
| 80 List<int> _boundary; | 81 List<int> _boundary; |
| 81 int _state = _START; | 82 int _state = _START; |
| 82 int _boundaryIndex = 2; | 83 int _boundaryIndex = 2; |
| 83 | 84 |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 | 381 |
| 381 // Resume if at end. | 382 // Resume if at end. |
| 382 if (_index == _buffer.length) { | 383 if (_index == _buffer.length) { |
| 383 _buffer = null; | 384 _buffer = null; |
| 384 _index = null; | 385 _index = null; |
| 385 _resumeStream(); | 386 _resumeStream(); |
| 386 } | 387 } |
| 387 } | 388 } |
| 388 | 389 |
| 389 bool _isTokenChar(int byte) { | 390 bool _isTokenChar(int byte) { |
| 390 return byte > 31 && byte < 128 && _Const.SEPARATORS.indexOf(byte) == -1; | 391 return byte > 31 && byte < 128 && _SEPARATORS.indexOf(byte) == -1; |
| 391 } | 392 } |
| 392 | 393 |
| 393 int _toLowerCase(int byte) { | 394 int _toLowerCase(int byte) { |
| 394 final int aCode = "A".codeUnitAt(0); | 395 final int aCode = "A".codeUnitAt(0); |
| 395 final int zCode = "Z".codeUnitAt(0); | 396 final int zCode = "Z".codeUnitAt(0); |
| 396 final int delta = "a".codeUnitAt(0) - aCode; | 397 final int delta = "a".codeUnitAt(0) - aCode; |
| 397 return (aCode <= byte && byte <= zCode) ? byte + delta : byte; | 398 return (aCode <= byte && byte <= zCode) ? byte + delta : byte; |
| 398 } | 399 } |
| 399 | 400 |
| 400 void _expect(int val1, int val2) { | 401 void _expect(int val1, int val2) { |
| 401 if (val1 != val2) { | 402 if (val1 != val2) { |
| 402 throw new MimeMultipartException("Failed to parse multipart mime 1"); | 403 throw new MimeMultipartException("Failed to parse multipart mime 1"); |
| 403 } | 404 } |
| 404 } | 405 } |
| 405 | 406 |
| 406 void _expectWS(int byte) { | 407 void _expectWS(int byte) { |
| 407 if (byte != _CharCode.SP && byte != _CharCode.HT) { | 408 if (byte != _CharCode.SP && byte != _CharCode.HT) { |
| 408 throw new MimeMultipartException("Failed to parse multipart mime 2"); | 409 throw new MimeMultipartException("Failed to parse multipart mime 2"); |
| 409 } | 410 } |
| 410 } | 411 } |
| 411 } | 412 } |
| 412 | 413 |
| 413 | 414 |
| 414 class MimeMultipartException implements Exception { | 415 class MimeMultipartException implements Exception { |
| 416 final String message; |
| 417 |
| 415 const MimeMultipartException([String this.message = ""]); | 418 const MimeMultipartException([String this.message = ""]); |
| 419 |
| 416 String toString() => "MimeMultipartException: $message"; | 420 String toString() => "MimeMultipartException: $message"; |
| 417 final String message; | |
| 418 } | 421 } |
| OLD | NEW |