Skip to content

Commit 928d7a1

Browse files
committed
Add fromValues constructor
1 parent 75be84a commit 928d7a1

File tree

1 file changed

+40
-17
lines changed

1 file changed

+40
-17
lines changed

lib/src/message.dart

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,6 @@ abstract class Message {
4444
/// This can be read via [read] or [readAsString].
4545
final Body _body;
4646

47-
/// The parsed version of the Content-Type header in [headers].
48-
final MediaType _contentType;
49-
5047
/// Creates a new [Message].
5148
///
5249
/// [body] is the message body. It may be either a [String], a [List<int>], a
@@ -61,25 +58,30 @@ abstract class Message {
6158
/// Content-Type header, it will be set to "application/octet-stream".
6259
Message(body,
6360
{Encoding encoding,
64-
Map<String, String> headers,
65-
Map<String, Object> context})
61+
Map<String, String> headers,
62+
Map<String, Object> context})
6663
: this.__(body, _determineMediaType(body, encoding, headers), headers,
67-
context);
64+
context);
6865

6966
Message.__(body, MediaType contentType, Map<String, String> headers,
7067
Map<String, Object> context)
71-
: this._(new Body(body, encodingForMediaType(contentType, null)),
72-
contentType, headers, context);
68+
: this._(new Body(body, encodingForMediaType(contentType, null)), contentType,
69+
headers, context);
7370

7471
Message._(Body body, MediaType contentType, Map<String, String> headers,
7572
Map<String, Object> context)
73+
: this.fromValues(body, _adjustHeaders(headers, body, contentType), context);
74+
75+
/// Creates a new [Message].
76+
///
77+
/// This constructor should be used when no computation is required for the
78+
/// [body], [headers] or [context].
79+
Message.fromValues(
80+
Body body, Map<String, String> headers, Map<String, Object> context)
7681
: _body = body,
77-
headers = new HttpUnmodifiableMap<String>(
78-
_adjustHeaders(headers, body, contentType),
79-
ignoreKeyCase: true),
82+
headers = new HttpUnmodifiableMap<String>(headers, ignoreKeyCase: true),
8083
context =
81-
new HttpUnmodifiableMap<Object>(context, ignoreKeyCase: false),
82-
_contentType = contentType;
84+
new HttpUnmodifiableMap<Object>(context, ignoreKeyCase: false);
8385

8486
/// If `true`, the stream returned by [read] won't emit any bytes.
8587
///
@@ -104,7 +106,11 @@ abstract class Message {
104106
/// the MIME type, without any Content-Type parameters.
105107
///
106108
/// If [headers] doesn't have a Content-Type header, this will be `null`.
107-
String get mimeType => _contentType?.mimeType;
109+
String get mimeType {
110+
var contentType = _contentType;
111+
if (contentType == null) return null;
112+
return contentType.mimeType;
113+
}
108114

109115
/// The encoding of the body returned by [read].
110116
///
@@ -113,7 +119,24 @@ abstract class Message {
113119
///
114120
/// If [headers] doesn't have a Content-Type header or it specifies an
115121
/// encoding that [dart:convert] doesn't support, this will be `null`.
116-
Encoding get encoding => _body.encoding;
122+
Encoding get encoding {
123+
var contentType = _contentType;
124+
if (contentType == null) return null;
125+
if (!contentType.parameters.containsKey('charset')) return null;
126+
return Encoding.getByName(contentType.parameters['charset']);
127+
}
128+
129+
/// The parsed version of the Content-Type header in [headers].
130+
///
131+
/// This is cached for efficient access.
132+
MediaType get _contentType {
133+
if (_contentTypeCache != null) return _contentTypeCache;
134+
if (!headers.containsKey('content-type')) return null;
135+
_contentTypeCache = new MediaType.parse(headers['content-type']);
136+
return _contentTypeCache;
137+
}
138+
139+
MediaType _contentTypeCache;
117140

118141
/// Returns the message body as byte chunks.
119142
///
@@ -139,7 +162,7 @@ abstract class Message {
139162

140163
/// Determines the media type based on the [headers], [encoding] and [body].
141164
static MediaType _determineMediaType(
142-
body, Encoding encoding, Map<String, String> headers) =>
165+
body, Encoding encoding, Map<String, String> headers) =>
143166
_headerMediaType(headers, encoding) ?? _defaultMediaType(body, encoding);
144167

145168
static MediaType _defaultMediaType(body, Encoding encoding) {
@@ -166,7 +189,7 @@ abstract class Message {
166189
var contentType = new MediaType.parse(contentTypeHeader);
167190
var parameters = {
168191
'charset':
169-
encoding?.name ?? contentType.parameters['charset'] ?? UTF8.name
192+
encoding?.name ?? contentType.parameters['charset'] ?? UTF8.name
170193
};
171194

172195
return contentType.change(parameters: parameters);

0 commit comments

Comments
 (0)