blob: 9da253747c8490c329a7f1828be175d7b0fb3a80 [file] [log] [blame] [edit]
// Copyright (c) 2012, 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.
import 'dart:async';
import 'dart:convert';
import 'package:collection/collection.dart';
import 'http_unmodifiable_map.dart';
/// Returns a [Map] with the values from [original] and the values from
/// [updates].
///
/// For keys that are the same between [original] and [updates], the value in
/// [updates] is used.
///
/// If [updates] is `null` or empty, [original] is returned unchanged.
Map<K, V> updateMap<K, V>(Map<K, V> original, Map<K, V> updates) {
if (updates == null || updates.isEmpty) return original;
return new Map<K, V>.from(original)..addAll(updates);
}
/// Converts a [Map] from parameter names to values to a URL query string.
///
/// mapToQuery({"foo": "bar", "baz": "bang"});
/// //=> "foo=bar&baz=bang"
String mapToQuery(Map<String, String> map, Encoding encoding) {
var pairs = <List<String>>[];
map.forEach((key, value) => pairs.add([
Uri.encodeQueryComponent(key, encoding: encoding),
Uri.encodeQueryComponent(value, encoding: encoding)
]));
return pairs.map((pair) => "${pair[0]}=${pair[1]}").join("&");
}
/// A regular expression that matches strings that are composed entirely of
/// ASCII-compatible characters.
final RegExp _asciiOnly = new RegExp(r"^[\x00-\x7F]+$");
/// Returns whether [string] is composed entirely of ASCII-compatible
/// characters.
bool isPlainAscii(String string) => _asciiOnly.hasMatch(string);
/// Pipes all data and errors from [stream] into [sink].
///
/// Completes [Future] once [stream] is done. [sink] remains open after [stream]
/// is done.
Future writeStreamToSink(Stream stream, EventSink sink) {
var completer = new Completer();
stream.listen(sink.add,
onError: sink.addError, onDone: () => completer.complete());
return completer.future;
}
/// Returns the header with the given [name] in [headers].
///
/// This works even if [headers] is `null`, or if it's not yet a
/// case-insensitive map.
String getHeader(Map<String, String> headers, String name) {
if (headers == null) return null;
if (headers is HttpUnmodifiableMap) return headers[name];
for (var key in headers.keys) {
if (equalsIgnoreAsciiCase(key, name)) return headers[key];
}
return null;
}
/// Returns a [Uri] from the [url], which can be a [Uri] or a [String].
///
/// If the [url] is not a [Uri] or [String] an [ArgumentError] is thrown.
Uri getUrl(url) {
if (url is Uri) {
return url;
} else if (url is String) {
return Uri.parse(url);
} else {
throw new ArgumentError.value(url, 'url', 'Not a Uri or String');
}
}