| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 | 5 |
| 6 class _Directory implements Directory { | 6 class _Directory implements Directory { |
| 7 static final kCreateRequest = 0; | 7 static final kCreateRequest = 0; |
| 8 static final kDeleteRequest = 1; | 8 static final kDeleteRequest = 1; |
| 9 static final kExistsRequest = 2; | 9 static final kExistsRequest = 2; |
| 10 static final kCreateTempRequest = 3; | 10 static final kCreateTempRequest = 3; |
| 11 static final kListRequest = 4; | 11 static final kListRequest = 4; |
| 12 | 12 |
| 13 static final kSuccessResponse = 0; |
| 14 static final kIllegalArgumentResponse = 1; |
| 15 static final kOSErrorResponse = 2; |
| 16 |
| 13 _Directory(String this._path); | 17 _Directory(String this._path); |
| 14 _Directory.current() : _path = _current(); | 18 _Directory.current() : _path = _current(); |
| 15 | 19 |
| 16 static String _current() native "Directory_Current"; | 20 static String _current() native "Directory_Current"; |
| 17 static _createTemp(String template) native "Directory_CreateTemp"; | 21 static _createTemp(String template) native "Directory_CreateTemp"; |
| 18 static int _exists(String path) native "Directory_Exists"; | 22 static int _exists(String path) native "Directory_Exists"; |
| 19 static bool _create(String path) native "Directory_Create"; | 23 static _create(String path) native "Directory_Create"; |
| 20 static bool _delete(String path, bool recursive) native "Directory_Delete"; | 24 static _delete(String path, bool recursive) native "Directory_Delete"; |
| 21 static SendPort _newServicePort() native "Directory_NewServicePort"; | 25 static SendPort _newServicePort() native "Directory_NewServicePort"; |
| 22 | 26 |
| 23 void exists(void callback(bool exists)) { | 27 void exists(void callback(bool exists)) { |
| 24 _ensureDirectoryService(); | 28 _ensureDirectoryService(); |
| 25 List request = new List(2); | 29 List request = new List(2); |
| 26 request[0] = kExistsRequest; | 30 request[0] = kExistsRequest; |
| 27 request[1] = _path; | 31 request[1] = _path; |
| 28 _directoryService.call(request).then((result) { | 32 _directoryService.call(request).then((response) { |
| 29 if (result < 0) { | 33 if (_isErrorResponse(response)) { |
| 30 if (_onError != null) { | 34 _reportError(response, "Exists failed"); |
| 31 _onError("Diretory exists test failed: $_path"); | |
| 32 } | |
| 33 } else { | 35 } else { |
| 34 callback(result == 1); | 36 callback(response == 1); |
| 35 } | 37 } |
| 36 }); | 38 }); |
| 37 } | 39 } |
| 38 | 40 |
| 39 bool existsSync() { | 41 bool existsSync() { |
| 40 int exists = _exists(_path); | 42 if (_path is !String) { |
| 41 if (exists < 0) { | 43 throw new IllegalArgumentException(); |
| 42 throw new DirectoryIOException("Diretory exists test failed: $_path"); | |
| 43 } | 44 } |
| 44 return (exists == 1); | 45 var result = _exists(_path); |
| 46 if (result is OSError) { |
| 47 throw new DirectoryIOException("Exists failed", _path, result); |
| 48 } |
| 49 return (result == 1); |
| 45 } | 50 } |
| 46 | 51 |
| 47 void create(void callback()) { | 52 void create(void callback()) { |
| 48 _ensureDirectoryService(); | 53 _ensureDirectoryService(); |
| 49 List request = new List(2); | 54 List request = new List(2); |
| 50 request[0] = kCreateRequest; | 55 request[0] = kCreateRequest; |
| 51 request[1] = _path; | 56 request[1] = _path; |
| 52 _directoryService.call(request).then((result) { | 57 _directoryService.call(request).then((response) { |
| 53 if (result) { | 58 if (_isErrorResponse(response)) { |
| 59 _reportError(response, "Creation failed"); |
| 60 } else { |
| 54 callback(); | 61 callback(); |
| 55 } else if (_onError != null) { | |
| 56 _onError("Directory creation failed: $_path"); | |
| 57 } | 62 } |
| 58 }); | 63 }); |
| 59 } | 64 } |
| 60 | 65 |
| 61 void createSync() { | 66 void createSync() { |
| 62 if (!_create(_path)) { | 67 if (_path is !String) { |
| 63 throw new DirectoryIOException("Directory creation failed: $_path"); | 68 throw new IllegalArgumentException(); |
| 69 } |
| 70 var result = _create(_path); |
| 71 if (result is OSError) { |
| 72 throw new DirectoryIOException("Creation failed", _path, result); |
| 64 } | 73 } |
| 65 } | 74 } |
| 66 | 75 |
| 67 void createTemp(void callback()) { | 76 void createTemp(void callback()) { |
| 68 _ensureDirectoryService(); | 77 _ensureDirectoryService(); |
| 69 List request = new List(2); | 78 List request = new List(2); |
| 70 request[0] = kCreateTempRequest; | 79 request[0] = kCreateTempRequest; |
| 71 request[1] = _path; | 80 request[1] = _path; |
| 72 _directoryService.call(request).then((result) { | 81 _directoryService.call(request).then((response) { |
| 73 if (result is !List) { | 82 if (_isErrorResponse(response)) { |
| 74 _path = result; | 83 _reportError(response, "Creation of temporary directory failed"); |
| 84 } else { |
| 85 _path = response; |
| 75 callback(); | 86 callback(); |
| 76 } else if (_onError != null) { | |
| 77 _onError("Could not create temporary directory [$_path]: ${result[1]}"); | |
| 78 } | 87 } |
| 79 }); | 88 }); |
| 80 } | 89 } |
| 81 | 90 |
| 82 void createTempSync() { | 91 void createTempSync() { |
| 83 if (_path is !String) { | 92 if (_path is !String) { |
| 84 throw new IllegalArgumentException(); | 93 throw new IllegalArgumentException(); |
| 85 } | 94 } |
| 86 var result = _createTemp(path); | 95 var result = _createTemp(path); |
| 87 if (result is OSError) { | 96 if (result is OSError) { |
| 88 throw new DirectoryIOException("Could not create temporary directory", | 97 throw new DirectoryIOException("Creation of temporary directory failed", |
| 98 _path, |
| 89 result); | 99 result); |
| 90 } | 100 } |
| 91 _path = result; | 101 _path = result; |
| 92 } | 102 } |
| 93 | 103 |
| 94 void _deleteHelper(bool recursive, String errorMsg, void callback()) { | 104 void _deleteHelper(bool recursive, String errorMsg, void callback()) { |
| 95 _ensureDirectoryService(); | 105 _ensureDirectoryService(); |
| 96 List request = new List(3); | 106 List request = new List(3); |
| 97 request[0] = kDeleteRequest; | 107 request[0] = kDeleteRequest; |
| 98 request[1] = _path; | 108 request[1] = _path; |
| 99 request[2] = recursive; | 109 request[2] = recursive; |
| 100 _directoryService.call(request).then((result) { | 110 _directoryService.call(request).then((response) { |
| 101 if (result) { | 111 if (_isErrorResponse(response)) { |
| 112 _reportError(response, errorMsg); |
| 113 } else { |
| 102 callback(); | 114 callback(); |
| 103 } else if (_onError != null) { | |
| 104 _onError("${errorMsg}: $_path"); | |
| 105 } | 115 } |
| 106 }); | 116 }); |
| 107 } | 117 } |
| 108 | 118 |
| 109 void delete(void callback()) { | 119 void delete(void callback()) { |
| 110 _deleteHelper(false, "Directory deletion failed", callback); | 120 _deleteHelper(false, "Deletion failed", callback); |
| 111 } | 121 } |
| 112 | 122 |
| 113 void deleteRecursively(void callback()) { | 123 void deleteRecursively(void callback()) { |
| 114 _deleteHelper(true, "Recursive directory deletion failed", callback); | 124 _deleteHelper(true, "Deletion failed", callback); |
| 115 } | 125 } |
| 116 | 126 |
| 117 void deleteSync() { | 127 void deleteSync() { |
| 118 bool recursive = false; | 128 if (_path is !String) { |
| 119 if (!_delete(_path, recursive)) { | 129 throw new IllegalArgumentException(); |
| 120 throw new DirectoryIOException("Directory deletion failed: $_path"); | 130 } |
| 131 var result = _delete(_path, false); |
| 132 if (result is OSError) { |
| 133 throw new DirectoryIOException("Deletion failed", _path, result); |
| 121 } | 134 } |
| 122 } | 135 } |
| 123 | 136 |
| 124 void deleteRecursivelySync() { | 137 void deleteRecursivelySync() { |
| 125 bool recursive = true; | 138 if (_path is !String) { |
| 126 if (!_delete(_path, recursive)) { | 139 throw new IllegalArgumentException(); |
| 127 throw new DirectoryIOException( | 140 } |
| 128 "Recursive directory deletion failed: $_path"); | 141 var result = _delete(_path, true); |
| 142 if (result is OSError) { |
| 143 throw new DirectoryIOException("Deletion failed", _path, result); |
| 129 } | 144 } |
| 130 } | 145 } |
| 131 | 146 |
| 132 void list([bool recursive = false]) { | 147 void list([bool recursive = false]) { |
| 133 final int kListDirectory = 0; | 148 final int kListDirectory = 0; |
| 134 final int kListFile = 1; | 149 final int kListFile = 1; |
| 135 final int kListError = 2; | 150 final int kListError = 2; |
| 136 final int kListDone = 3; | 151 final int kListDone = 3; |
| 137 | 152 |
| 153 final int kResponseType = 0; |
| 154 final int kResponsePath = 1; |
| 155 final int kResponseComplete = 1; |
| 156 final int kResponseError = 2; |
| 157 |
| 138 List request = new List(3); | 158 List request = new List(3); |
| 139 request[0] = kListRequest; | 159 request[0] = kListRequest; |
| 140 request[1] = _path; | 160 request[1] = _path; |
| 141 request[2] = recursive; | 161 request[2] = recursive; |
| 142 ReceivePort responsePort = new ReceivePort(); | 162 ReceivePort responsePort = new ReceivePort(); |
| 143 // Use a separate directory service port for each listing as | 163 // Use a separate directory service port for each listing as |
| 144 // listing operations on the same directory can run in parallel. | 164 // listing operations on the same directory can run in parallel. |
| 145 _newServicePort().send(request, responsePort.toSendPort()); | 165 _newServicePort().send(request, responsePort.toSendPort()); |
| 146 responsePort.receive((message, replyTo) { | 166 responsePort.receive((message, replyTo) { |
| 147 if (message is !List || message[0] is !int) { | 167 if (message is !List || message[kResponseType] is !int) { |
| 148 responsePort.close(); | 168 responsePort.close(); |
| 149 if (_onError != null) _onError("Internal error"); | 169 if (_onError != null) { |
| 170 _onError(new DirectoryIOException("Internal error")); |
| 171 } |
| 150 return; | 172 return; |
| 151 } | 173 } |
| 152 switch (message[0]) { | 174 switch (message[kResponseType]) { |
| 153 case kListDirectory: | 175 case kListDirectory: |
| 154 if (_onDir != null) _onDir(message[1]); | 176 if (_onDir != null) _onDir(message[kResponsePath]); |
| 155 break; | 177 break; |
| 156 case kListFile: | 178 case kListFile: |
| 157 if (_onFile != null) _onFile(message[1]); | 179 if (_onFile != null) _onFile(message[kResponsePath]); |
| 158 break; | 180 break; |
| 159 case kListError: | 181 case kListError: |
| 160 if (_onError != null) _onError(message[1]); | 182 if (_onError != null) { |
| 183 var errorType = |
| 184 message[kResponseError][_FileUtils.kErrorResponseErrorType]; |
| 185 if (errorType == _FileUtils.kIllegalArgumentResponse) { |
| 186 _onError(new IllegalArgumentException()); |
| 187 } else if (errorType == _FileUtils.kOSErrorResponse) { |
| 188 var err = new OSError( |
| 189 message[kResponseError][_FileUtils.kOSErrorResponseErrorCode], |
| 190 message[kResponseError][_FileUtils.kOSErrorResponseMessage]); |
| 191 _onError(new DirectoryIOException("Directory listing failed", |
| 192 message[kResponsePath], |
| 193 err)); |
| 194 } else { |
| 195 _onError(new DirectoryIOException("Internal error")); |
| 196 } |
| 197 } |
| 161 break; | 198 break; |
| 162 case kListDone: | 199 case kListDone: |
| 163 responsePort.close(); | 200 responsePort.close(); |
| 164 if (_onDone != null) _onDone(message[1]); | 201 if (_onDone != null) _onDone(message[kResponseComplete]); |
| 165 break; | 202 break; |
| 166 } | 203 } |
| 167 }); | 204 }); |
| 168 } | 205 } |
| 169 | 206 |
| 170 void set onDir(void onDir(String dir)) { | 207 void set onDir(void onDir(String dir)) { |
| 171 _onDir = onDir; | 208 _onDir = onDir; |
| 172 } | 209 } |
| 173 | 210 |
| 174 void set onFile(void onFile(String file)) { | 211 void set onFile(void onFile(String file)) { |
| 175 _onFile = onFile; | 212 _onFile = onFile; |
| 176 } | 213 } |
| 177 | 214 |
| 178 void set onDone(void onDone(bool completed)) { | 215 void set onDone(void onDone(bool completed)) { |
| 179 _onDone = onDone; | 216 _onDone = onDone; |
| 180 } | 217 } |
| 181 | 218 |
| 182 void set onError(void onError(String error)) { | 219 void set onError(void onError(Exception e)) { |
| 183 _onError = onError; | 220 _onError = onError; |
| 184 } | 221 } |
| 185 | 222 |
| 186 String get path() { return _path; } | 223 String get path() { return _path; } |
| 187 | 224 |
| 188 void _ensureDirectoryService() { | 225 void _ensureDirectoryService() { |
| 189 if (_directoryService == null) { | 226 if (_directoryService == null) { |
| 190 _directoryService = _newServicePort(); | 227 _directoryService = _newServicePort(); |
| 191 } | 228 } |
| 192 } | 229 } |
| 193 | 230 |
| 194 var _onDir; | 231 bool _isErrorResponse(response) { |
| 195 var _onFile; | 232 return response is List && response[0] != _FileUtils.kSuccessResponse; |
| 196 var _onDone; | 233 } |
| 197 var _onError; | 234 |
| 235 bool _reportError(response, String message) { |
| 236 assert(_isErrorResponse(response)); |
| 237 if (_onError != null) { |
| 238 switch (response[_FileUtils.kErrorResponseErrorType]) { |
| 239 case _FileUtils.kIllegalArgumentResponse: |
| 240 _onError(new IllegalArgumentException()); |
| 241 break; |
| 242 case _FileUtils.kOSErrorResponse: |
| 243 var err = new OSError(response[_FileUtils.kOSErrorResponseErrorCode], |
| 244 response[_FileUtils.kOSErrorResponseMessage]); |
| 245 _onError(new DirectoryIOException(message, _path, err)); |
| 246 break; |
| 247 default: |
| 248 _onError(new Exception("Unknown error")); |
| 249 break; |
| 250 } |
| 251 } |
| 252 } |
| 253 |
| 254 Function _onDir; |
| 255 Function _onFile; |
| 256 Function _onDone; |
| 257 Function _onError; |
| 198 | 258 |
| 199 String _path; | 259 String _path; |
| 200 SendPort _directoryService; | 260 SendPort _directoryService; |
| 201 } | 261 } |
| OLD | NEW |