Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 library multipart_file; | |
| 6 | |
| 7 import 'dart:io'; | |
| 8 | |
| 9 import 'utils.dart'; | |
| 10 | |
| 11 /// A file to be uploaded as part of a [MultipartRequest]. This doesn't need to | |
| 12 /// correspond to a physical file. | |
| 13 class MultipartFile { | |
| 14 /// The name of the form field for the file. | |
| 15 final String field; | |
| 16 | |
| 17 /// The size of the file in bytes. This must be known in advance, even if this | |
| 18 /// file is created from an [InputStream]. | |
| 19 final int length; | |
| 20 | |
| 21 /// The basename of the file. May be null. | |
| 22 final String filename; | |
| 23 | |
| 24 /// The content-type of the file. Defaults to `application/octet-stream`. | |
| 25 final ContentType contentType; | |
| 26 | |
| 27 /// The stream that will emit the file's contents. | |
| 28 final InputStream _stream; | |
| 29 | |
| 30 /// Whether [finalize] has been called. | |
| 31 bool get finalized => _finalized; | |
|
Bob Nystrom
2012/11/06 22:00:08
How about "isFinalized" here? I think "if (file.is
nweiz
2012/11/06 23:15:56
Done.
| |
| 32 bool _finalized = false; | |
| 33 | |
| 34 /// Creates a new [MultipartFile] from an [InputStream]. The length of the | |
| 35 /// file in bytes must be known in advance. If it's not, read the data from | |
| 36 /// the stream and use [MultipartFile.fromBytes] instead. | |
| 37 /// | |
| 38 /// [contentType] currently defaults to `application/octet-stream`, but in the | |
|
Bob Nystrom
2012/11/06 22:00:08
I try to avoid sentences that start with identifie
nweiz
2012/11/06 23:15:56
I think using the definite article only for identi
Bob Nystrom
2012/11/07 00:50:26
Fair enough.
| |
| 39 /// future may be inferred from [filename]. | |
| 40 MultipartFile(this.field, this._stream, this.length, | |
| 41 {this.filename, ContentType contentType}) | |
| 42 : this.contentType = contentType != null ? contentType : | |
| 43 new ContentType("application", "octet-stream"); | |
| 44 | |
| 45 /// Creates a new [MultipartFile] from a byte array. | |
| 46 /// | |
| 47 /// [contentType] currently defaults to `application/octet-stream`, but in the | |
| 48 /// future may be inferred from [filename]. | |
| 49 factory MultipartFile.fromBytes(String field, List<int> value, | |
| 50 {String filename, ContentType contentType}) { | |
| 51 var stream = new ListInputStream(); | |
| 52 stream.write(value); | |
| 53 stream.markEndOfStream(); | |
| 54 return new MultipartFile( | |
| 55 field, stream, value.length, | |
| 56 filename: filename, | |
| 57 contentType: contentType); | |
|
Bob Nystrom
2012/11/06 22:00:08
Style nit. Put the positional args on the same lin
nweiz
2012/11/06 23:15:56
Done.
| |
| 58 } | |
| 59 | |
| 60 /// Creates a new [MultipartFile] from a string. | |
| 61 /// | |
| 62 /// The encoding to use when translating [value] into bytes is taken from | |
| 63 /// [contentType] if it has a charset set. Otherwise, it defaults to UTF-8. | |
| 64 /// [contentType] currently defaults to `text/plain; charset=utf-8`, but in th e | |
|
Bob Nystrom
2012/11/06 22:00:08
Long line.
nweiz
2012/11/06 23:15:56
Done.
| |
| 65 /// future may be inferred from [filename]. | |
| 66 factory MultipartFile.fromString(String field, String value, | |
| 67 {String filename, ContentType contentType}) { | |
| 68 contentType = contentType == null ? new ContentType("text", "plain") : | |
| 69 new ContentType.fromString(contentType.toString()); | |
|
Bob Nystrom
2012/11/06 22:00:08
Why the toString / fromString dance here?
nweiz
2012/11/06 23:15:56
We want to be able to modify the charset below wit
| |
| 70 var charset = contentType.charset; | |
| 71 var encoding = encodingForCharset(contentType.charset, Encoding.UTF_8); | |
| 72 contentType.charset = encoding.name; | |
| 73 | |
| 74 return new MultipartFile.fromBytes( | |
| 75 field, | |
| 76 encodeString(value, encoding), | |
| 77 filename: filename, | |
| 78 contentType: contentType); | |
| 79 } | |
| 80 | |
| 81 // TODO(nweiz): infer the content-type from the filename | |
|
Bob Nystrom
2012/11/06 22:00:08
Should be a sentence: "Infer ... filename."
nweiz
2012/11/06 23:15:56
Done.
| |
| 82 /// Creates a new [MultipartFile] from a [File]. | |
| 83 /// | |
| 84 /// [filename] defaults to the name of the file on disk. [contentType] | |
| 85 /// currently defaults to `application/octet-stream`, but in the future may be | |
| 86 /// inferred from [filename]. | |
| 87 static Future<MultipartFile> fromFile(String field, File file, | |
| 88 {String filename, ContentType contentType}) { | |
| 89 if (filename == null) filename = new Path(file.name).filename; | |
| 90 return file.length().transform((length) { | |
|
Bob Nystrom
2012/11/06 22:00:08
You could do lengthSync() here. Do you think it's
nweiz
2012/11/06 23:15:56
Yeah, I don't like using synchronous IO in library
| |
| 91 return new MultipartFile( | |
| 92 field, file.openInputStream(), length, | |
| 93 filename: filename, | |
| 94 contentType: contentType); | |
| 95 }); | |
| 96 } | |
| 97 | |
| 98 // Finalizes the file in preparation for it being sent as part of a | |
| 99 // [MultipartRequest]. This returns an [InputStream] that should emit the body | |
| 100 // of the file. The stream may be closed to indicate an empty file. | |
| 101 InputStream finalize() { | |
| 102 if (finalized) { | |
| 103 throw new StateError("Can't finalize a finalized MultipartFile."); | |
| 104 } | |
| 105 _finalized = true; | |
| 106 return _stream; | |
| 107 } | |
| 108 } | |
| OLD | NEW |