OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'dart:convert'; | 6 import 'dart:convert'; |
7 import 'dart:math' as math; | 7 import 'dart:math' as math; |
| 8 import 'dart:typed_data'; |
8 | 9 |
9 import 'package:async/async.dart' hide StreamQueue; | 10 import 'package:async/async.dart' hide StreamQueue; |
10 import 'package:path/path.dart' as p; | 11 import 'package:path/path.dart' as p; |
11 import 'package:shelf/shelf.dart' as shelf; | 12 import 'package:shelf/shelf.dart' as shelf; |
12 import 'package:stack_trace/stack_trace.dart'; | 13 import 'package:stack_trace/stack_trace.dart'; |
13 | 14 |
14 import 'backend/operating_system.dart'; | 15 import 'backend/operating_system.dart'; |
15 import 'util/path_handler.dart'; | 16 import 'util/path_handler.dart'; |
16 import 'util/stream_queue.dart'; | 17 import 'util/stream_queue.dart'; |
17 | 18 |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 result.add(element); | 187 result.add(element); |
187 } | 188 } |
188 } | 189 } |
189 } | 190 } |
190 helper(nested); | 191 helper(nested); |
191 return result; | 192 return result; |
192 } | 193 } |
193 | 194 |
194 /// Creates a new map from [map] with new keys and values. | 195 /// Creates a new map from [map] with new keys and values. |
195 /// | 196 /// |
196 /// The return values of [key] are used as the keys and the return values of | 197 /// The return values of [keyFn] are used as the keys and the return values of |
197 /// [value] are used as the values for the new map. | 198 /// [valueFn] are used as the values for the new map. |
198 /// | 199 Map/*<K2, V2>*/ mapMap/*<K1, V1, K2, V2>*/(Map/*<K1, V1>*/ map, |
199 /// [key] defaults to returning the original key and [value] defaults to | 200 {/*=K2*/ key(/*=K1*/ key, /*=V1*/ value), |
200 /// returning the original value. | 201 /*=V2*/ value(/*=K1*/ key, /*=V1*/ value)}) { |
201 Map mapMap(Map map, {key(key, value), value(key, value)}) { | 202 key ??= (key, _) => key as dynamic/*=K2*/; |
202 if (key == null) key = (key, _) => key; | 203 value ??= (_, value) => value as dynamic/*=V2*/; |
203 if (value == null) value = (_, value) => value; | |
204 | 204 |
205 var result = {}; | 205 return new Map.fromIterable(map.keys, |
206 map.forEach((mapKey, mapValue) { | 206 key: (mapKey) => key(mapKey as dynamic/*=K1*/, map[mapKey]), |
207 result[key(mapKey, mapValue)] = value(mapKey, mapValue); | 207 value: (mapKey) => value(mapKey as dynamic/*=K1*/, map[mapKey])); |
208 }); | |
209 return result; | |
210 } | 208 } |
211 | 209 |
212 /// Returns a new map with all values in both [map1] and [map2]. | 210 /// Returns a new map with all values in both [map1] and [map2]. |
213 /// | 211 /// |
214 /// If there are conflicting keys, [value] is used to merge them. If it's | 212 /// If there are conflicting keys, [value] is used to merge them. If it's |
215 /// not passed, [map2]'s value wins. | 213 /// not passed, [map2]'s value wins. |
216 Map mergeMaps(Map map1, Map map2, {value(value1, value2)}) { | 214 Map/*<K, V>*/ mergeMaps/*<K, V>*/(Map/*<K, V>*/ map1, Map/*<K, V>*/ map2, |
217 var result = new Map.from(map1); | 215 {/*=V*/ value(/*=V*/ value1, /*=V*/ value2)}) { |
| 216 var result = new Map/*<K, V>*/.from(map1); |
218 map2.forEach((key, mapValue) { | 217 map2.forEach((key, mapValue) { |
219 if (value == null || !result.containsKey(key)) { | 218 if (value == null || !result.containsKey(key)) { |
220 result[key] = mapValue; | 219 result[key] = mapValue; |
221 } else { | 220 } else { |
222 result[key] = value(result[key], mapValue); | 221 result[key] = value(result[key], mapValue); |
223 } | 222 } |
224 }); | 223 }); |
225 return result; | 224 return result; |
226 } | 225 } |
227 | 226 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 if (minutes == 0 || seconds != 0) { | 287 if (minutes == 0 || seconds != 0) { |
289 if (minutes != 0) buffer.write(", "); | 288 if (minutes != 0) buffer.write(", "); |
290 buffer.write(seconds); | 289 buffer.write(seconds); |
291 if (decaseconds != 0) buffer.write(".$decaseconds"); | 290 if (decaseconds != 0) buffer.write(".$decaseconds"); |
292 buffer.write(" seconds"); | 291 buffer.write(" seconds"); |
293 } | 292 } |
294 | 293 |
295 return buffer.toString(); | 294 return buffer.toString(); |
296 } | 295 } |
297 | 296 |
298 /// Merges [streams] into a single stream that emits events from all sources. | |
299 Stream mergeStreams(Iterable<Stream> streamIter) { | |
300 var streams = streamIter.toList(); | |
301 | |
302 var subscriptions = new Set(); | |
303 var controller; | |
304 controller = new StreamController(sync: true, onListen: () { | |
305 for (var stream in streams) { | |
306 var subscription; | |
307 subscription = stream.listen( | |
308 controller.add, | |
309 onError: controller.addError, | |
310 onDone: () { | |
311 subscriptions.remove(subscription); | |
312 if (subscriptions.isEmpty) controller.close(); | |
313 }); | |
314 subscriptions.add(subscription); | |
315 } | |
316 }, onPause: () { | |
317 for (var subscription in subscriptions) { | |
318 subscription.pause(); | |
319 } | |
320 }, onResume: () { | |
321 for (var subscription in subscriptions) { | |
322 subscription.resume(); | |
323 } | |
324 }, onCancel: () { | |
325 for (var subscription in subscriptions) { | |
326 subscription.cancel(); | |
327 } | |
328 }); | |
329 | |
330 return controller.stream; | |
331 } | |
332 | |
333 /// Returns the first value [stream] emits, or `null` if [stream] closes before | 297 /// Returns the first value [stream] emits, or `null` if [stream] closes before |
334 /// emitting a value. | 298 /// emitting a value. |
335 Future maybeFirst(Stream stream) { | 299 Future maybeFirst(Stream stream) { |
336 var completer = new Completer(); | 300 var completer = new Completer(); |
337 | 301 |
338 var subscription; | 302 var subscription; |
339 subscription = stream.listen((data) { | 303 subscription = stream.listen((data) { |
340 completer.complete(data); | 304 completer.complete(data); |
341 subscription.cancel(); | 305 subscription.cancel(); |
342 }, onError: (error, stackTrace) { | 306 }, onError: (error, stackTrace) { |
(...skipping 26 matching lines...) Expand all Loading... |
369 })); | 333 })); |
370 | 334 |
371 return completer.operation; | 335 return completer.operation; |
372 } | 336 } |
373 | 337 |
374 /// Returns a single-subscription stream that emits the results of [operations] | 338 /// Returns a single-subscription stream that emits the results of [operations] |
375 /// in the order they complete. | 339 /// in the order they complete. |
376 /// | 340 /// |
377 /// If the subscription is canceled, any pending operations are canceled as | 341 /// If the subscription is canceled, any pending operations are canceled as |
378 /// well. | 342 /// well. |
379 Stream inCompletionOrder(Iterable<CancelableOperation> operations) { | 343 Stream/*<T>*/ inCompletionOrder/*<T>*/( |
| 344 Iterable<CancelableOperation/*<T>*/> operations) { |
380 var operationSet = operations.toSet(); | 345 var operationSet = operations.toSet(); |
381 var controller = new StreamController(sync: true, onCancel: () { | 346 var controller = new StreamController/*<T>*/(sync: true, onCancel: () { |
382 return Future.wait(operationSet.map((operation) => operation.cancel())); | 347 return Future.wait(operationSet.map((operation) => operation.cancel())); |
383 }); | 348 }); |
384 | 349 |
385 for (var operation in operationSet) { | 350 for (var operation in operationSet) { |
386 operation.value.then(controller.add).catchError(controller.addError) | 351 operation.value.then((value) => controller.add(value)) |
| 352 .catchError(controller.addError) |
387 .whenComplete(() { | 353 .whenComplete(() { |
388 operationSet.remove(operation); | 354 operationSet.remove(operation); |
389 if (operationSet.isEmpty) controller.close(); | 355 if (operationSet.isEmpty) controller.close(); |
390 }); | 356 }); |
391 } | 357 } |
392 | 358 |
393 return controller.stream; | 359 return controller.stream; |
394 } | 360 } |
395 | 361 |
396 /// Returns a stream that emits [error] and [stackTrace], then closes. | 362 /// Returns a stream that emits [error] and [stackTrace], then closes. |
(...skipping 13 matching lines...) Expand all Loading... |
410 void invoke(fn()) { | 376 void invoke(fn()) { |
411 fn(); | 377 fn(); |
412 } | 378 } |
413 | 379 |
414 /// Returns a random base64 string containing [bytes] bytes of data. | 380 /// Returns a random base64 string containing [bytes] bytes of data. |
415 /// | 381 /// |
416 /// [seed] is passed to [math.Random]; [urlSafe] and [addLineSeparator] are | 382 /// [seed] is passed to [math.Random]; [urlSafe] and [addLineSeparator] are |
417 /// passed to [CryptoUtils.bytesToBase64]. | 383 /// passed to [CryptoUtils.bytesToBase64]. |
418 String randomBase64(int bytes, {int seed}) { | 384 String randomBase64(int bytes, {int seed}) { |
419 var random = new math.Random(seed); | 385 var random = new math.Random(seed); |
420 var data = []; | 386 var data = new Uint8List(bytes); |
421 for (var i = 0; i < bytes; i++) { | 387 for (var i = 0; i < bytes; i++) { |
422 data.add(random.nextInt(256)); | 388 data[i] = random.nextInt(256); |
423 } | 389 } |
424 return BASE64.encode(data); | 390 return BASE64.encode(data); |
425 } | 391 } |
426 | 392 |
427 /// Returns middleware that nests all requests beneath the URL prefix [beneath]. | 393 /// Returns middleware that nests all requests beneath the URL prefix [beneath]. |
428 shelf.Middleware nestingMiddleware(String beneath) { | 394 shelf.Middleware nestingMiddleware(String beneath) { |
429 return (handler) { | 395 return (handler) { |
430 var pathHandler = new PathHandler()..add(beneath, handler); | 396 var pathHandler = new PathHandler()..add(beneath, handler); |
431 return pathHandler.handler; | 397 return pathHandler.handler; |
432 }; | 398 }; |
433 } | 399 } |
OLD | NEW |