| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 part of dart._vmservice; | 5 part of dart._vmservice; |
| 6 | 6 |
| 7 String _encodeDevFSDisabledError(Message message) { | 7 String _encodeDevFSDisabledError(Message message) { |
| 8 return encodeRpcError( | 8 return encodeRpcError(message, kFeatureDisabled, |
| 9 message, kFeatureDisabled, | |
| 10 details: "DevFS is not supported by this Dart implementation"); | 9 details: "DevFS is not supported by this Dart implementation"); |
| 11 } | 10 } |
| 12 | 11 |
| 13 String _encodeFileSystemAlreadyExistsError(Message message, String fsName) { | 12 String _encodeFileSystemAlreadyExistsError(Message message, String fsName) { |
| 14 return encodeRpcError( | 13 return encodeRpcError(message, kFileSystemAlreadyExists, |
| 15 message, kFileSystemAlreadyExists, | |
| 16 details: "${message.method}: file system '${fsName}' already exists"); | 14 details: "${message.method}: file system '${fsName}' already exists"); |
| 17 } | 15 } |
| 18 | 16 |
| 19 String _encodeFileSystemDoesNotExistError(Message message, String fsName) { | 17 String _encodeFileSystemDoesNotExistError(Message message, String fsName) { |
| 20 return encodeRpcError( | 18 return encodeRpcError(message, kFileSystemDoesNotExist, |
| 21 message, kFileSystemDoesNotExist, | |
| 22 details: "${message.method}: file system '${fsName}' does not exist"); | 19 details: "${message.method}: file system '${fsName}' does not exist"); |
| 23 } | 20 } |
| 24 | 21 |
| 25 class _FileSystem { | 22 class _FileSystem { |
| 26 _FileSystem(this.name, this.uri); | 23 _FileSystem(this.name, this.uri); |
| 27 | 24 |
| 28 final String name; | 25 final String name; |
| 29 final Uri uri; | 26 final Uri uri; |
| 30 | 27 |
| 31 Uri resolvePath(String path) { | 28 Uri resolvePath(String path) { |
| 32 if (path.startsWith('/')) { | 29 if (path.startsWith('/')) { |
| 33 path = path.substring(1); | 30 path = path.substring(1); |
| 34 } | 31 } |
| 35 if (path.isEmpty) { | 32 if (path.isEmpty) { |
| 36 return null; | 33 return null; |
| 37 } | 34 } |
| 38 Uri pathUri; | 35 Uri pathUri; |
| 39 try { | 36 try { |
| 40 pathUri = new Uri.file(path); | 37 pathUri = new Uri.file(path); |
| 41 } on FormatException catch(e) { | 38 } on FormatException catch (e) { |
| 42 return null; | 39 return null; |
| 43 } | 40 } |
| 44 | 41 |
| 45 return resolve(pathUri); | 42 return resolve(pathUri); |
| 46 } | 43 } |
| 47 | 44 |
| 48 Uri resolve(Uri pathUri) { | 45 Uri resolve(Uri pathUri) { |
| 49 try { | 46 try { |
| 50 // Make sure that this pathUri can be converted to a file path. | 47 // Make sure that this pathUri can be converted to a file path. |
| 51 pathUri.toFilePath(); | 48 pathUri.toFilePath(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 69 }; | 66 }; |
| 70 } | 67 } |
| 71 } | 68 } |
| 72 | 69 |
| 73 class DevFS { | 70 class DevFS { |
| 74 DevFS(); | 71 DevFS(); |
| 75 | 72 |
| 76 Map<String, _FileSystem> _fsMap = {}; | 73 Map<String, _FileSystem> _fsMap = {}; |
| 77 | 74 |
| 78 final Set _rpcNames = new Set.from([ | 75 final Set _rpcNames = new Set.from([ |
| 79 '_listDevFS', | 76 '_listDevFS', |
| 80 '_createDevFS', | 77 '_createDevFS', |
| 81 '_deleteDevFS', | 78 '_deleteDevFS', |
| 82 '_readDevFSFile', | 79 '_readDevFSFile', |
| 83 '_writeDevFSFile', | 80 '_writeDevFSFile', |
| 84 '_writeDevFSFiles', | 81 '_writeDevFSFiles', |
| 85 '_listDevFSFiles', | 82 '_listDevFSFiles', |
| 86 ]); | 83 ]); |
| 87 | 84 |
| 88 void cleanup() { | 85 void cleanup() { |
| 89 var deleteDir = VMServiceEmbedderHooks.deleteDir; | 86 var deleteDir = VMServiceEmbedderHooks.deleteDir; |
| 90 if (deleteDir == null) { | 87 if (deleteDir == null) { |
| 91 return; | 88 return; |
| 92 } | 89 } |
| 93 var deletions = []; | 90 var deletions = []; |
| 94 for (var fs in _fsMap.values) { | 91 for (var fs in _fsMap.values) { |
| 95 deletions.add(deleteDir(fs.uri)); | 92 deletions.add(deleteDir(fs.uri)); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 112 return _deleteDevFS(message); | 109 return _deleteDevFS(message); |
| 113 case '_readDevFSFile': | 110 case '_readDevFSFile': |
| 114 return _readDevFSFile(message); | 111 return _readDevFSFile(message); |
| 115 case '_writeDevFSFile': | 112 case '_writeDevFSFile': |
| 116 return _writeDevFSFile(message); | 113 return _writeDevFSFile(message); |
| 117 case '_writeDevFSFiles': | 114 case '_writeDevFSFiles': |
| 118 return _writeDevFSFiles(message); | 115 return _writeDevFSFiles(message); |
| 119 case '_listDevFSFiles': | 116 case '_listDevFSFiles': |
| 120 return _listDevFSFiles(message); | 117 return _listDevFSFiles(message); |
| 121 default: | 118 default: |
| 122 return encodeRpcError( | 119 return encodeRpcError(message, kInternalError, |
| 123 message, kInternalError, | |
| 124 details: 'Unexpected rpc ${message.method}'); | 120 details: 'Unexpected rpc ${message.method}'); |
| 125 } | 121 } |
| 126 } | 122 } |
| 127 | 123 |
| 128 Future<String> handlePutStream(Object fsName, | 124 Future<String> handlePutStream( |
| 129 Object path, | 125 Object fsName, Object path, Uri fsUri, Stream<List<int>> bytes) async { |
| 130 Uri fsUri, | |
| 131 Stream<List<int>> bytes) async { | |
| 132 // A dummy Message for error message construction. | 126 // A dummy Message for error message construction. |
| 133 Message message = new Message.forMethod('_writeDevFSFile'); | 127 Message message = new Message.forMethod('_writeDevFSFile'); |
| 134 var writeStreamFile = VMServiceEmbedderHooks.writeStreamFile; | 128 var writeStreamFile = VMServiceEmbedderHooks.writeStreamFile; |
| 135 if (writeStreamFile == null) { | 129 if (writeStreamFile == null) { |
| 136 return _encodeDevFSDisabledError(message); | 130 return _encodeDevFSDisabledError(message); |
| 137 } | 131 } |
| 138 if (fsName == null) { | 132 if (fsName == null) { |
| 139 return encodeMissingParamError(message, 'fsName'); | 133 return encodeMissingParamError(message, 'fsName'); |
| 140 } | 134 } |
| 141 if (fsName is! String) { | 135 if (fsName is! String) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 163 return encodeInvalidParamError(message, 'uri'); | 157 return encodeInvalidParamError(message, 'uri'); |
| 164 } | 158 } |
| 165 } | 159 } |
| 166 await writeStreamFile(uri, bytes); | 160 await writeStreamFile(uri, bytes); |
| 167 return encodeSuccess(message); | 161 return encodeSuccess(message); |
| 168 } | 162 } |
| 169 | 163 |
| 170 Future<String> _listDevFS(Message message) async { | 164 Future<String> _listDevFS(Message message) async { |
| 171 var result = {}; | 165 var result = {}; |
| 172 result['type'] = 'FileSystemList'; | 166 result['type'] = 'FileSystemList'; |
| 173 result['fsNames'] = _fsMap.keys.toList(); | 167 result['fsNames'] = _fsMap.keys.toList(); |
| 174 return encodeResult(message, result); | 168 return encodeResult(message, result); |
| 175 } | 169 } |
| 176 | 170 |
| 177 Future<String> _createDevFS(Message message) async { | 171 Future<String> _createDevFS(Message message) async { |
| 178 var createTempDir = VMServiceEmbedderHooks.createTempDir; | 172 var createTempDir = VMServiceEmbedderHooks.createTempDir; |
| 179 if (createTempDir == null) { | 173 if (createTempDir == null) { |
| 180 return _encodeDevFSDisabledError(message); | 174 return _encodeDevFSDisabledError(message); |
| 181 } | 175 } |
| 182 var fsName = message.params['fsName']; | 176 var fsName = message.params['fsName']; |
| 183 if (fsName == null) { | 177 if (fsName == null) { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 if (path is! String) { | 249 if (path is! String) { |
| 256 return encodeInvalidParamError(message, 'path'); | 250 return encodeInvalidParamError(message, 'path'); |
| 257 } | 251 } |
| 258 uri = fs.resolvePath(path); | 252 uri = fs.resolvePath(path); |
| 259 if (uri == null) { | 253 if (uri == null) { |
| 260 return encodeInvalidParamError(message, 'path'); | 254 return encodeInvalidParamError(message, 'path'); |
| 261 } | 255 } |
| 262 } | 256 } |
| 263 try { | 257 try { |
| 264 List<int> bytes = await readFile(uri); | 258 List<int> bytes = await readFile(uri); |
| 265 var result = { | 259 var result = {'type': 'FSFile', 'fileContents': BASE64.encode(bytes)}; |
| 266 'type': 'FSFile', | |
| 267 'fileContents': BASE64.encode(bytes) | |
| 268 }; | |
| 269 return encodeResult(message, result); | 260 return encodeResult(message, result); |
| 270 } catch (e) { | 261 } catch (e) { |
| 271 return encodeRpcError( | 262 return encodeRpcError(message, kFileDoesNotExist, |
| 272 message, kFileDoesNotExist, | |
| 273 details: "_readDevFSFile: $e"); | 263 details: "_readDevFSFile: $e"); |
| 274 } | 264 } |
| 275 } | 265 } |
| 276 | 266 |
| 277 Future<String> _writeDevFSFile(Message message) async { | 267 Future<String> _writeDevFSFile(Message message) async { |
| 278 var writeFile = VMServiceEmbedderHooks.writeFile; | 268 var writeFile = VMServiceEmbedderHooks.writeFile; |
| 279 if (writeFile == null) { | 269 if (writeFile == null) { |
| 280 return _encodeDevFSDisabledError(message); | 270 return _encodeDevFSDisabledError(message); |
| 281 } | 271 } |
| 282 var fsName = message.params['fsName']; | 272 var fsName = message.params['fsName']; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 return encodeMissingParamError(message, 'files'); | 342 return encodeMissingParamError(message, 'files'); |
| 353 } | 343 } |
| 354 if (files is! List) { | 344 if (files is! List) { |
| 355 return encodeInvalidParamError(message, 'files'); | 345 return encodeInvalidParamError(message, 'files'); |
| 356 } | 346 } |
| 357 var uris = []; | 347 var uris = []; |
| 358 for (int i = 0; i < files.length; i++) { | 348 for (int i = 0; i < files.length; i++) { |
| 359 var fileInfo = files[i]; | 349 var fileInfo = files[i]; |
| 360 if (fileInfo is! List || | 350 if (fileInfo is! List || |
| 361 fileInfo.length != 2 || | 351 fileInfo.length != 2 || |
| 362 fileInfo[0] is! String || fileInfo[1] is! String) { | 352 fileInfo[0] is! String || |
| 363 return encodeRpcError( | 353 fileInfo[1] is! String) { |
| 364 message, kInvalidParams, | 354 return encodeRpcError(message, kInvalidParams, |
| 365 details: "${message.method}: invalid 'files' parameter " | 355 details: "${message.method}: invalid 'files' parameter " |
| 366 "at index ${i}: ${fileInfo}"); | 356 "at index ${i}: ${fileInfo}"); |
| 367 } | 357 } |
| 368 var uri = fs.resolvePath(fileInfo[0]); | 358 var uri = fs.resolvePath(fileInfo[0]); |
| 369 if (uri == null) { | 359 if (uri == null) { |
| 370 return encodeRpcError( | 360 return encodeRpcError(message, kInvalidParams, |
| 371 message, kInvalidParams, | |
| 372 details: "${message.method}: invalid 'files' parameter " | 361 details: "${message.method}: invalid 'files' parameter " |
| 373 "at index ${i}: ${fileInfo}"); | 362 "at index ${i}: ${fileInfo}"); |
| 374 } | 363 } |
| 375 uris.add(uri); | 364 uris.add(uri); |
| 376 } | 365 } |
| 377 var pendingWrites = []; | 366 var pendingWrites = []; |
| 378 for (int i = 0; i < uris.length; i++) { | 367 for (int i = 0; i < uris.length; i++) { |
| 379 List<int> decodedFileContents = BASE64.decode(files[i][1]); | 368 List<int> decodedFileContents = BASE64.decode(files[i][1]); |
| 380 pendingWrites.add(writeFile(uris[i], decodedFileContents)); | 369 pendingWrites.add(writeFile(uris[i], decodedFileContents)); |
| 381 } | 370 } |
| 382 await Future.wait(pendingWrites); | 371 await Future.wait(pendingWrites); |
| 383 return encodeSuccess(message); | 372 return encodeSuccess(message); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 397 } | 386 } |
| 398 var fs = _fsMap[fsName]; | 387 var fs = _fsMap[fsName]; |
| 399 if (fs == null) { | 388 if (fs == null) { |
| 400 return _encodeFileSystemDoesNotExistError(message, fsName); | 389 return _encodeFileSystemDoesNotExistError(message, fsName); |
| 401 } | 390 } |
| 402 var fileList = await listFiles(fs.uri); | 391 var fileList = await listFiles(fs.uri); |
| 403 // Remove any url-encoding in the filenames. | 392 // Remove any url-encoding in the filenames. |
| 404 for (int i = 0; i < fileList.length; i++) { | 393 for (int i = 0; i < fileList.length; i++) { |
| 405 fileList[i]['name'] = Uri.decodeFull(fileList[i]['name']); | 394 fileList[i]['name'] = Uri.decodeFull(fileList[i]['name']); |
| 406 } | 395 } |
| 407 var result = { 'type': 'FSFileList', 'files': fileList }; | 396 var result = {'type': 'FSFileList', 'files': fileList}; |
| 408 return encodeResult(message, result); | 397 return encodeResult(message, result); |
| 409 } | 398 } |
| 410 } | 399 } |
| OLD | NEW |