| // 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. |
| |
| part of dart.io; |
| |
| abstract class _IOResourceInfo { |
| final String type; |
| final int id; |
| String get name; |
| static int _count = 0; |
| |
| static final Stopwatch _sw = Stopwatch()..start(); |
| static final _startTime = DateTime.now().millisecondsSinceEpoch; |
| |
| static int get timestamp => _startTime + _sw.elapsedMicroseconds ~/ 1000; |
| |
| _IOResourceInfo(this.type) : id = _IOResourceInfo.getNextID(); |
| |
| /// Get the full set of values for a specific implementation. This is normally |
| /// looked up based on an id from a referenceValueMap. |
| Map<String, dynamic> get fullValueMap; |
| |
| /// The reference map, used to return a list of values, e.g., getting |
| /// all open sockets. The structure of this is shared among all subclasses. |
| Map<String, dynamic> get referenceValueMap => { |
| // The type for a reference object is prefixed with @ in observatory. |
| 'type': '@$type', |
| 'id': id, |
| 'name': name, |
| }; |
| |
| static int getNextID() => _count++; |
| } |
| |
| abstract class _ReadWriteResourceInfo extends _IOResourceInfo { |
| int readBytes; |
| int writeBytes; |
| int readCount; |
| int writeCount; |
| int lastReadTime; |
| int lastWriteTime; |
| |
| // Not all call sites use this. In some cases, e.g., a socket, a read does |
| // not always mean that we actually read some bytes (we may do a read to see |
| // if there are some bytes available). |
| void addRead(int bytes) { |
| readBytes += bytes; |
| readCount++; |
| lastReadTime = _IOResourceInfo.timestamp; |
| } |
| |
| // In cases where we read but did not necessarily get any bytes, use this to |
| // update the readCount and timestamp. Manually update totalRead if any bytes |
| // where actually read. |
| void didRead() { |
| addRead(0); |
| } |
| |
| void addWrite(int bytes) { |
| writeBytes += bytes; |
| writeCount++; |
| lastWriteTime = _IOResourceInfo.timestamp; |
| } |
| |
| _ReadWriteResourceInfo(String type) |
| : readBytes = 0, |
| writeBytes = 0, |
| readCount = 0, |
| writeCount = 0, |
| lastReadTime = 0, |
| lastWriteTime = 0, |
| super(type); |
| |
| Map<String, dynamic> get fullValueMap => { |
| 'type': type, |
| 'id': id, |
| 'name': name, |
| 'readBytes': readBytes, |
| 'writeBytes': writeBytes, |
| 'readCount': readCount, |
| 'writeCount': writeCount, |
| 'lastReadTime': lastReadTime, |
| 'lastWriteTime': lastWriteTime |
| }; |
| } |
| |
| class _FileResourceInfo extends _ReadWriteResourceInfo { |
| static const String _type = 'OpenFile'; |
| |
| final file; |
| |
| static Map<int, _FileResourceInfo> openFiles = {}; |
| |
| _FileResourceInfo(this.file) : super(_type) { |
| fileOpened(this); |
| } |
| |
| static fileOpened(_FileResourceInfo info) { |
| assert(!openFiles.containsKey(info.id)); |
| openFiles[info.id] = info; |
| } |
| |
| static fileClosed(_FileResourceInfo info) { |
| assert(openFiles.containsKey(info.id)); |
| openFiles.remove(info.id); |
| } |
| |
| static Iterable<Map<String, dynamic>> getOpenFilesList() { |
| return List.from(openFiles.values.map( |
| (e) => e.referenceValueMap, |
| )); |
| } |
| |
| static Future<ServiceExtensionResponse> getOpenFiles(function, params) { |
| assert(function == 'ext.dart.io.getOpenFiles'); |
| final data = { |
| 'type': 'OpenFileList', |
| 'files': getOpenFilesList(), |
| }; |
| final jsonValue = json.encode(data); |
| return Future.value(ServiceExtensionResponse.result(jsonValue)); |
| } |
| |
| Map<String, dynamic> get fileInfoMap => fullValueMap; |
| |
| static Future<ServiceExtensionResponse> getOpenFileInfoMapByID( |
| function, params) { |
| final id = int.parse(params['id']!); |
| final result = openFiles.containsKey(id) ? openFiles[id]!.fileInfoMap : {}; |
| final jsonValue = json.encode(result); |
| return Future.value(ServiceExtensionResponse.result(jsonValue)); |
| } |
| |
| String get name => file.path; |
| } |
| |
| class _SpawnedProcessResourceInfo extends _IOResourceInfo { |
| static const String _type = 'SpawnedProcess'; |
| final process; |
| final int startedAt; |
| |
| static Map<int, _SpawnedProcessResourceInfo> startedProcesses = |
| Map<int, _SpawnedProcessResourceInfo>(); |
| |
| _SpawnedProcessResourceInfo(this.process) |
| : startedAt = _IOResourceInfo.timestamp, |
| super(_type) { |
| processStarted(this); |
| } |
| |
| String get name => process._path; |
| |
| void stopped() => processStopped(this); |
| |
| Map<String, dynamic> get fullValueMap => { |
| 'type': type, |
| 'id': id, |
| 'name': name, |
| 'pid': process.pid, |
| 'startedAt': startedAt, |
| 'arguments': process._arguments, |
| 'workingDirectory': |
| process._workingDirectory == null ? '.' : process._workingDirectory, |
| }; |
| |
| static processStarted(_SpawnedProcessResourceInfo info) { |
| assert(!startedProcesses.containsKey(info.id)); |
| startedProcesses[info.id] = info; |
| } |
| |
| static processStopped(_SpawnedProcessResourceInfo info) { |
| assert(startedProcesses.containsKey(info.id)); |
| startedProcesses.remove(info.id); |
| } |
| |
| static Iterable<Map<String, dynamic>> getStartedProcessesList() => |
| List.from(startedProcesses.values.map( |
| (e) => e.referenceValueMap, |
| )); |
| |
| static Future<ServiceExtensionResponse> getStartedProcesses( |
| String function, Map<String, String> params) { |
| assert(function == 'ext.dart.io.getSpawnedProcesses'); |
| final data = { |
| 'type': 'SpawnedProcessList', |
| 'processes': getStartedProcessesList(), |
| }; |
| final jsonValue = json.encode(data); |
| return Future.value(ServiceExtensionResponse.result(jsonValue)); |
| } |
| |
| static Future<ServiceExtensionResponse> getProcessInfoMapById( |
| String function, Map<String, String> params) { |
| final id = int.parse(params['id']!); |
| final result = startedProcesses.containsKey(id) |
| ? startedProcesses[id]!.fullValueMap |
| : {}; |
| final jsonValue = json.encode(result); |
| return Future.value(ServiceExtensionResponse.result(jsonValue)); |
| } |
| } |