| // 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. |
| |
| part of dart.io; |
| |
| class _Platform { |
| external static int _numberOfProcessors(); |
| external static String _pathSeparator(); |
| external static String _operatingSystem(); |
| external static _operatingSystemVersion(); |
| external static _localHostname(); |
| external static _executable(); |
| external static _resolvedExecutable(); |
| |
| /** |
| * Retrieve the entries of the process environment. |
| * |
| * The result is an [Iterable] of strings, where each string represents |
| * an environment entry. |
| * |
| * Environment entries should be strings containing |
| * a non-empty name and a value separated by a '=' character. |
| * The name does not contain a '=' character, |
| * so the name is everything up to the first '=' character. |
| * Values are everything after the first '=' character. |
| * A value may contain further '=' characters, and it may be empty. |
| * |
| * Returns an [OSError] if retrieving the environment fails. |
| */ |
| external static _environment(); |
| external static List<String> _executableArguments(); |
| external static String? _packageConfig(); |
| external static String _version(); |
| external static String _localeName(); |
| external static Uri _script(); |
| |
| static String executable = _executable(); |
| static String resolvedExecutable = _resolvedExecutable(); |
| static String? packageConfig = _packageConfig(); |
| |
| @pragma("vm:entry-point") |
| static String Function()? _localeClosure; |
| static String localeName() { |
| final result = (_localeClosure == null) ? _localeName() : _localeClosure!(); |
| if (result is OSError) { |
| throw result; |
| } |
| return result; |
| } |
| |
| // Cache the OS environment. This can be an OSError instance if |
| // retrieving the environment failed. |
| static var /*OSError?|Map<String,String>?*/ _environmentCache; |
| |
| static int get numberOfProcessors => _numberOfProcessors(); |
| static String get pathSeparator => _pathSeparator(); |
| static String get operatingSystem => _operatingSystem(); |
| static Uri get script => _script(); |
| |
| static String? _cachedOSVersion; |
| static String get operatingSystemVersion { |
| if (_cachedOSVersion == null) { |
| var result = _operatingSystemVersion(); |
| if (result is OSError) { |
| throw result; |
| } |
| _cachedOSVersion = result; |
| } |
| return _cachedOSVersion!; |
| } |
| |
| static String get localHostname { |
| var result = _localHostname(); |
| if (result is OSError) { |
| throw result; |
| } |
| return result; |
| } |
| |
| static List<String> get executableArguments => _executableArguments(); |
| |
| static Map<String, String> get environment { |
| if (_environmentCache == null) { |
| var env = _environment(); |
| if (env is! OSError) { |
| var isWindows = operatingSystem == 'windows'; |
| var result = isWindows |
| ? new _CaseInsensitiveStringMap<String>() |
| : new Map<String, String>(); |
| for (var str in env) { |
| if (str == null) { |
| continue; |
| } |
| // The Strings returned by [_environment()] are expected to be |
| // valid environment entries, but exceptions have been seen |
| // (e.g., an entry of just '=' has been seen on OS/X). |
| // Invalid entries (lines without a '=' or with an empty name) |
| // are discarded. |
| var equalsIndex = str.indexOf('='); |
| if (equalsIndex > 0) { |
| result[str.substring(0, equalsIndex)] = |
| str.substring(equalsIndex + 1); |
| } |
| } |
| _environmentCache = new UnmodifiableMapView<String, String>(result); |
| } else { |
| _environmentCache = env; |
| } |
| } |
| |
| if (_environmentCache is OSError) { |
| throw _environmentCache; |
| } else { |
| return _environmentCache!; |
| } |
| } |
| |
| static String get version => _version(); |
| } |
| |
| // Environment variables are case-insensitive on Windows. In order |
| // to reflect that we use a case-insensitive string map on Windows. |
| class _CaseInsensitiveStringMap<V> extends MapBase<String, V> { |
| final Map<String, V> _map = new Map<String, V>(); |
| |
| bool containsKey(Object? key) => |
| key is String && _map.containsKey(key.toUpperCase()); |
| bool containsValue(Object? value) => _map.containsValue(value); |
| V? operator [](Object? key) => key is String ? _map[key.toUpperCase()] : null; |
| void operator []=(String key, V value) { |
| _map[key.toUpperCase()] = value; |
| } |
| |
| V putIfAbsent(String key, V ifAbsent()) { |
| return _map.putIfAbsent(key.toUpperCase(), ifAbsent); |
| } |
| |
| void addAll(Map<String, V> other) { |
| other.forEach((key, value) => this[key.toUpperCase()] = value); |
| } |
| |
| V? remove(Object? key) => |
| key is String ? _map.remove(key.toUpperCase()) : null; |
| |
| void clear() { |
| _map.clear(); |
| } |
| |
| void forEach(void f(String key, V value)) { |
| _map.forEach(f); |
| } |
| |
| Iterable<String> get keys => _map.keys; |
| Iterable<V> get values => _map.values; |
| int get length => _map.length; |
| bool get isEmpty => _map.isEmpty; |
| bool get isNotEmpty => _map.isNotEmpty; |
| |
| Iterable<MapEntry<String, V>> get entries => _map.entries; |
| |
| Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> transform(String key, V value)) => |
| _map.map(transform); |
| |
| V update(String key, V update(V value), {V ifAbsent()?}) => |
| _map.update(key.toUpperCase(), update, ifAbsent: ifAbsent); |
| |
| void updateAll(V update(String key, V value)) { |
| _map.updateAll(update); |
| } |
| |
| void removeWhere(bool test(String key, V value)) { |
| _map.removeWhere(test); |
| } |
| |
| String toString() => _map.toString(); |
| } |