| Index: mojo/public/dart/third_party/http_parser/lib/src/media_type.dart
|
| diff --git a/mojo/public/dart/third_party/http_parser/lib/src/media_type.dart b/mojo/public/dart/third_party/http_parser/lib/src/media_type.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5bae0ec2ad6cd404afb0c1aeb1575ce44dc0181d
|
| --- /dev/null
|
| +++ b/mojo/public/dart/third_party/http_parser/lib/src/media_type.dart
|
| @@ -0,0 +1,145 @@
|
| +// Copyright (c) 2014, 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 http_parser.media_type;
|
| +
|
| +import 'package:collection/collection.dart';
|
| +import 'package:string_scanner/string_scanner.dart';
|
| +
|
| +import 'scan.dart';
|
| +import 'utils.dart';
|
| +
|
| +/// A regular expression matching a character that needs to be backslash-escaped
|
| +/// in a quoted string.
|
| +final _escapedChar = new RegExp(r'["\x00-\x1F\x7F]');
|
| +
|
| +/// A class representing an HTTP media type, as used in Accept and Content-Type
|
| +/// headers.
|
| +///
|
| +/// This is immutable; new instances can be created based on an old instance by
|
| +/// calling [change].
|
| +class MediaType {
|
| + /// The primary identifier of the MIME type.
|
| + final String type;
|
| +
|
| + /// The secondary identifier of the MIME type.
|
| + final String subtype;
|
| +
|
| + /// The parameters to the media type.
|
| + ///
|
| + /// This map is immutable.
|
| + final Map<String, String> parameters;
|
| +
|
| + /// The media type's MIME type.
|
| + String get mimeType => "$type/$subtype";
|
| +
|
| + /// Parses a media type.
|
| + ///
|
| + /// This will throw a FormatError if the media type is invalid.
|
| + factory MediaType.parse(String mediaType) {
|
| + // This parsing is based on sections 3.6 and 3.7 of the HTTP spec:
|
| + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html.
|
| + return wrapFormatException("media type", mediaType, () {
|
| + var scanner = new StringScanner(mediaType);
|
| + scanner.scan(whitespace);
|
| + scanner.expect(token);
|
| + var type = scanner.lastMatch[0];
|
| + scanner.expect('/');
|
| + scanner.expect(token);
|
| + var subtype = scanner.lastMatch[0];
|
| + scanner.scan(whitespace);
|
| +
|
| + var parameters = {};
|
| + while (scanner.scan(';')) {
|
| + scanner.scan(whitespace);
|
| + scanner.expect(token);
|
| + var attribute = scanner.lastMatch[0];
|
| + scanner.expect('=');
|
| +
|
| + var value;
|
| + if (scanner.scan(token)) {
|
| + value = scanner.lastMatch[0];
|
| + } else {
|
| + value = expectQuotedString(scanner);
|
| + }
|
| +
|
| + scanner.scan(whitespace);
|
| + parameters[attribute] = value;
|
| + }
|
| +
|
| + scanner.expectDone();
|
| + return new MediaType(type, subtype, parameters);
|
| + });
|
| + }
|
| +
|
| + MediaType(this.type, this.subtype, [Map<String, String> parameters])
|
| + : this.parameters = new UnmodifiableMapView(
|
| + parameters == null ? {} : new Map.from(parameters));
|
| +
|
| + /// Returns a copy of this [MediaType] with some fields altered.
|
| + ///
|
| + /// [type] and [subtype] alter the corresponding fields. [mimeType] is parsed
|
| + /// and alters both the [type] and [subtype] fields; it cannot be passed along
|
| + /// with [type] or [subtype].
|
| + ///
|
| + /// [parameters] overwrites and adds to the corresponding field. If
|
| + /// [clearParameters] is passed, it replaces the corresponding field entirely
|
| + /// instead.
|
| + MediaType change({String type, String subtype, String mimeType,
|
| + Map<String, String> parameters, bool clearParameters: false}) {
|
| + if (mimeType != null) {
|
| + if (type != null) {
|
| + throw new ArgumentError("You may not pass both [type] and [mimeType].");
|
| + } else if (subtype != null) {
|
| + throw new ArgumentError("You may not pass both [subtype] and "
|
| + "[mimeType].");
|
| + }
|
| +
|
| + var segments = mimeType.split('/');
|
| + if (segments.length != 2) {
|
| + throw new FormatException('Invalid mime type "$mimeType".');
|
| + }
|
| +
|
| + type = segments[0];
|
| + subtype = segments[1];
|
| + }
|
| +
|
| + if (type == null) type = this.type;
|
| + if (subtype == null) subtype = this.subtype;
|
| + if (parameters == null) parameters = {};
|
| +
|
| + if (!clearParameters) {
|
| + var newParameters = parameters;
|
| + parameters = new Map.from(this.parameters);
|
| + parameters.addAll(newParameters);
|
| + }
|
| +
|
| + return new MediaType(type, subtype, parameters);
|
| + }
|
| +
|
| + /// Converts the media type to a string.
|
| + ///
|
| + /// This will produce a valid HTTP media type.
|
| + String toString() {
|
| + var buffer = new StringBuffer()
|
| + ..write(type)
|
| + ..write("/")
|
| + ..write(subtype);
|
| +
|
| + parameters.forEach((attribute, value) {
|
| + buffer.write("; $attribute=");
|
| + if (nonToken.hasMatch(value)) {
|
| + buffer
|
| + ..write('"')
|
| + ..write(
|
| + value.replaceAllMapped(_escapedChar, (match) => "\\" + match[0]))
|
| + ..write('"');
|
| + } else {
|
| + buffer.write(value);
|
| + }
|
| + });
|
| +
|
| + return buffer.toString();
|
| + }
|
| +}
|
|
|