Chromium Code Reviews| Index: lib/src/body.dart |
| diff --git a/lib/src/body.dart b/lib/src/body.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..e6bb26d03eaa916245e25479f5b5d940e7290b8c |
| --- /dev/null |
| +++ b/lib/src/body.dart |
| @@ -0,0 +1,62 @@ |
| +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +library shelf.body; |
| + |
| +import 'dart:async'; |
| +import 'dart:convert'; |
| + |
| +/// The body of a request or response. |
| +/// |
| +/// This tracks whether the body has been read. It's separate from [Message] |
| +/// because the message may be changed with [Message.change], but each instance |
| +/// should share a notion of whether the body was read. |
| +class Body { |
| + /// The contents of the message body. |
| + final Stream<List<int>> _stream; |
| + |
| + /// Whether [_body] has been read. |
| + /// |
| + /// After calling [read], this will be `true`. |
| + bool _wasRead = false; |
|
Bob Nystrom
2015/08/31 21:05:32
How about just making _stream writable, and settin
nweiz
2015/08/31 21:16:05
Done.
|
| + |
| + Body._(this._stream); |
| + |
| + /// Converts [body] to a byte stream and wraps it in a [Body]. |
| + /// |
| + /// [body] may be either a [Body], a [String], a [Stream<List<int>>], or |
| + /// `null`. If it's a [String], [encoding] will be used to convert it to a |
| + /// [Stream<List<int>>]. |
| + factory Body(body, [Encoding encoding]) { |
| + if (encoding == null) encoding = UTF8; |
| + |
| + if (body is Body) return body; |
|
Bob Nystrom
2015/08/31 21:05:32
This means doing new Body(previouslyReadBody) does
nweiz
2015/08/31 21:16:05
Yeah, I think that matches the expected semantics
|
| + |
|
Bob Nystrom
2015/08/31 21:05:32
Should this throw if an encoding is prodivided but
nweiz
2015/08/31 21:16:04
I think it's probably fine. Definitely not worth
|
| + var stream; |
| + if (body == null) { |
| + stream = new Stream.fromIterable([]); |
| + } else if (body is String) { |
| + stream = new Stream.fromIterable([encoding.encode(body)]); |
| + } else if (body is Stream) { |
| + stream = body; |
| + } else { |
| + throw new ArgumentError('Response body "$body" must be a String or a ' |
| + 'Stream.'); |
| + } |
| + |
| + return new Body._(stream); |
| + } |
| + |
| + /// Returns a [Stream] representing the body. |
| + /// |
| + /// Can only be called once. |
| + Stream<List<int>> read() { |
| + if (_wasRead) { |
| + throw new StateError("The 'read' method can only be called once on a " |
| + "shelf.Request/shelf.Response object."); |
| + } |
| + _wasRead = true; |
| + return _stream; |
| + } |
| +} |