| 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 part of dart.io; | 5 part of dart.io; |
| 6 | 6 |
| 7 // Read the file in blocks of size 64k. | 7 // Read the file in blocks of size 64k. |
| 8 const int _BLOCK_SIZE = 64 * 1024; | 8 const int _BLOCK_SIZE = 64 * 1024; |
| 9 | 9 |
| 10 class _FileStream extends Stream<List<int>> { | 10 class _FileStream extends Stream<List<int>> { |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 final String path; | 207 final String path; |
| 208 | 208 |
| 209 // Constructor for file. | 209 // Constructor for file. |
| 210 _File(this.path) { | 210 _File(this.path) { |
| 211 if (path is! String) { | 211 if (path is! String) { |
| 212 throw new ArgumentError('${Error.safeToString(path)} ' | 212 throw new ArgumentError('${Error.safeToString(path)} ' |
| 213 'is not a String'); | 213 'is not a String'); |
| 214 } | 214 } |
| 215 } | 215 } |
| 216 | 216 |
| 217 // WARNING: |
| 218 // Calling this function will increase the reference count on the native |
| 219 // namespace object. It should only be called to pass the pointer to the |
| 220 // IOService, which will decrement the reference count when it is finished |
| 221 // with it. |
| 222 static int _namespacePointer() => _Namespace._namespacePointer; |
| 223 |
| 224 static Future _dispatchWithNamespace(int request, List data) { |
| 225 data[0] = _namespacePointer(); |
| 226 return _IOService._dispatch(request, data); |
| 227 } |
| 228 |
| 217 Future<bool> exists() { | 229 Future<bool> exists() { |
| 218 return _IOService._dispatch(_FILE_EXISTS, [path]).then((response) { | 230 return _dispatchWithNamespace(_FILE_EXISTS, [null, path]).then((response) { |
| 219 if (_isErrorResponse(response)) { | 231 if (_isErrorResponse(response)) { |
| 220 throw _exceptionFromResponse(response, "Cannot check existence", path); | 232 throw _exceptionFromResponse(response, "Cannot check existence", path); |
| 221 } | 233 } |
| 222 return response; | 234 return response; |
| 223 }); | 235 }); |
| 224 } | 236 } |
| 225 | 237 |
| 226 external static _exists(String path); | 238 external static _exists(_Namespace namespace, String path); |
| 227 | 239 |
| 228 bool existsSync() { | 240 bool existsSync() { |
| 229 var result = _exists(path); | 241 var result = _exists(_Namespace._namespace, path); |
| 230 throwIfError(result, "Cannot check existence of file", path); | 242 throwIfError(result, "Cannot check existence of file", path); |
| 231 return result; | 243 return result; |
| 232 } | 244 } |
| 233 | 245 |
| 234 File get absolute => new File(_absolutePath); | 246 File get absolute => new File(_absolutePath); |
| 235 | 247 |
| 236 Future<File> create({bool recursive: false}) { | 248 Future<File> create({bool recursive: false}) { |
| 237 var result = | 249 var result = |
| 238 recursive ? parent.create(recursive: true) : new Future.value(null); | 250 recursive ? parent.create(recursive: true) : new Future.value(null); |
| 239 return result | 251 return result |
| 240 .then((_) => _IOService._dispatch(_FILE_CREATE, [path])) | 252 .then((_) => _dispatchWithNamespace(_FILE_CREATE, [null, path])) |
| 241 .then((response) { | 253 .then((response) { |
| 242 if (_isErrorResponse(response)) { | 254 if (_isErrorResponse(response)) { |
| 243 throw _exceptionFromResponse(response, "Cannot create file", path); | 255 throw _exceptionFromResponse(response, "Cannot create file", path); |
| 244 } | 256 } |
| 245 return this; | 257 return this; |
| 246 }); | 258 }); |
| 247 } | 259 } |
| 248 | 260 |
| 249 external static _create(String path); | 261 external static _create(_Namespace namespace, String path); |
| 250 | 262 |
| 251 external static _createLink(String path, String target); | 263 external static _createLink(_Namespace namespace, String path, String target); |
| 252 | 264 |
| 253 external static _linkTarget(String path); | 265 external static _linkTarget(_Namespace namespace, String path); |
| 254 | 266 |
| 255 void createSync({bool recursive: false}) { | 267 void createSync({bool recursive: false}) { |
| 256 if (recursive) { | 268 if (recursive) { |
| 257 parent.createSync(recursive: true); | 269 parent.createSync(recursive: true); |
| 258 } | 270 } |
| 259 var result = _create(path); | 271 var result = _create(_Namespace._namespace, path); |
| 260 throwIfError(result, "Cannot create file", path); | 272 throwIfError(result, "Cannot create file", path); |
| 261 } | 273 } |
| 262 | 274 |
| 263 Future<File> _delete({bool recursive: false}) { | 275 Future<File> _delete({bool recursive: false}) { |
| 264 if (recursive) { | 276 if (recursive) { |
| 265 return new Directory(path).delete(recursive: true).then((_) => this); | 277 return new Directory(path).delete(recursive: true).then((_) => this); |
| 266 } | 278 } |
| 267 return _IOService._dispatch(_FILE_DELETE, [path]).then((response) { | 279 return _dispatchWithNamespace(_FILE_DELETE, [null, path]).then((response) { |
| 268 if (_isErrorResponse(response)) { | 280 if (_isErrorResponse(response)) { |
| 269 throw _exceptionFromResponse(response, "Cannot delete file", path); | 281 throw _exceptionFromResponse(response, "Cannot delete file", path); |
| 270 } | 282 } |
| 271 return this; | 283 return this; |
| 272 }); | 284 }); |
| 273 } | 285 } |
| 274 | 286 |
| 275 external static _deleteNative(String path); | 287 external static _deleteNative(_Namespace namespace, String path); |
| 276 | 288 |
| 277 external static _deleteLinkNative(String path); | 289 external static _deleteLinkNative(_Namespace namespace, String path); |
| 278 | 290 |
| 279 void _deleteSync({bool recursive: false}) { | 291 void _deleteSync({bool recursive: false}) { |
| 280 if (recursive) { | 292 if (recursive) { |
| 281 return new Directory(path).deleteSync(recursive: true); | 293 return new Directory(path).deleteSync(recursive: true); |
| 282 } | 294 } |
| 283 var result = _deleteNative(path); | 295 var result = _deleteNative(_Namespace._namespace, path); |
| 284 throwIfError(result, "Cannot delete file", path); | 296 throwIfError(result, "Cannot delete file", path); |
| 285 } | 297 } |
| 286 | 298 |
| 287 Future<File> rename(String newPath) { | 299 Future<File> rename(String newPath) { |
| 288 return _IOService._dispatch(_FILE_RENAME, [path, newPath]).then((response) { | 300 return _dispatchWithNamespace(_FILE_RENAME, [null, path, newPath]) |
| 301 .then((response) { |
| 289 if (_isErrorResponse(response)) { | 302 if (_isErrorResponse(response)) { |
| 290 throw _exceptionFromResponse( | 303 throw _exceptionFromResponse( |
| 291 response, "Cannot rename file to '$newPath'", path); | 304 response, "Cannot rename file to '$newPath'", path); |
| 292 } | 305 } |
| 293 return new File(newPath); | 306 return new File(newPath); |
| 294 }); | 307 }); |
| 295 } | 308 } |
| 296 | 309 |
| 297 external static _rename(String oldPath, String newPath); | 310 external static _rename(_Namespace namespace, String oldPath, String newPath); |
| 298 | 311 |
| 299 external static _renameLink(String oldPath, String newPath); | 312 external static _renameLink( |
| 313 _Namespace namespace, String oldPath, String newPath); |
| 300 | 314 |
| 301 File renameSync(String newPath) { | 315 File renameSync(String newPath) { |
| 302 var result = _rename(path, newPath); | 316 var result = _rename(_Namespace._namespace, path, newPath); |
| 303 throwIfError(result, "Cannot rename file to '$newPath'", path); | 317 throwIfError(result, "Cannot rename file to '$newPath'", path); |
| 304 return new File(newPath); | 318 return new File(newPath); |
| 305 } | 319 } |
| 306 | 320 |
| 307 Future<File> copy(String newPath) { | 321 Future<File> copy(String newPath) { |
| 308 return _IOService._dispatch(_FILE_COPY, [path, newPath]).then((response) { | 322 return _dispatchWithNamespace(_FILE_COPY, [null, path, newPath]) |
| 323 .then((response) { |
| 309 if (_isErrorResponse(response)) { | 324 if (_isErrorResponse(response)) { |
| 310 throw _exceptionFromResponse( | 325 throw _exceptionFromResponse( |
| 311 response, "Cannot copy file to '$newPath'", path); | 326 response, "Cannot copy file to '$newPath'", path); |
| 312 } | 327 } |
| 313 return new File(newPath); | 328 return new File(newPath); |
| 314 }); | 329 }); |
| 315 } | 330 } |
| 316 | 331 |
| 317 external static _copy(String oldPath, String newPath); | 332 external static _copy(_Namespace namespace, String oldPath, String newPath); |
| 318 | 333 |
| 319 File copySync(String newPath) { | 334 File copySync(String newPath) { |
| 320 var result = _copy(path, newPath); | 335 var result = _copy(_Namespace._namespace, path, newPath); |
| 321 throwIfError(result, "Cannot copy file to '$newPath'", path); | 336 throwIfError(result, "Cannot copy file to '$newPath'", path); |
| 322 return new File(newPath); | 337 return new File(newPath); |
| 323 } | 338 } |
| 324 | 339 |
| 325 Future<RandomAccessFile> open({FileMode mode: FileMode.READ}) { | 340 Future<RandomAccessFile> open({FileMode mode: FileMode.READ}) { |
| 326 if (mode != FileMode.READ && | 341 if (mode != FileMode.READ && |
| 327 mode != FileMode.WRITE && | 342 mode != FileMode.WRITE && |
| 328 mode != FileMode.APPEND && | 343 mode != FileMode.APPEND && |
| 329 mode != FileMode.WRITE_ONLY && | 344 mode != FileMode.WRITE_ONLY && |
| 330 mode != FileMode.WRITE_ONLY_APPEND) { | 345 mode != FileMode.WRITE_ONLY_APPEND) { |
| 331 return new Future.error( | 346 return new Future.error( |
| 332 new ArgumentError('Invalid file mode for this operation')); | 347 new ArgumentError('Invalid file mode for this operation')); |
| 333 } | 348 } |
| 334 return _IOService | 349 return _dispatchWithNamespace(_FILE_OPEN, [null, path, mode._mode]) |
| 335 ._dispatch(_FILE_OPEN, [path, mode._mode]).then((response) { | 350 .then((response) { |
| 336 if (_isErrorResponse(response)) { | 351 if (_isErrorResponse(response)) { |
| 337 throw _exceptionFromResponse(response, "Cannot open file", path); | 352 throw _exceptionFromResponse(response, "Cannot open file", path); |
| 338 } | 353 } |
| 339 return new _RandomAccessFile(response, path); | 354 return new _RandomAccessFile(response, path); |
| 340 }); | 355 }); |
| 341 } | 356 } |
| 342 | 357 |
| 343 Future<int> length() { | 358 Future<int> length() { |
| 344 return _IOService | 359 return _dispatchWithNamespace(_FILE_LENGTH_FROM_PATH, [null, path]) |
| 345 ._dispatch(_FILE_LENGTH_FROM_PATH, [path]).then((response) { | 360 .then((response) { |
| 346 if (_isErrorResponse(response)) { | 361 if (_isErrorResponse(response)) { |
| 347 throw _exceptionFromResponse( | 362 throw _exceptionFromResponse( |
| 348 response, "Cannot retrieve length of file", path); | 363 response, "Cannot retrieve length of file", path); |
| 349 } | 364 } |
| 350 return response; | 365 return response; |
| 351 }); | 366 }); |
| 352 } | 367 } |
| 353 | 368 |
| 354 external static _lengthFromPath(String path); | 369 external static _lengthFromPath(_Namespace namespace, String path); |
| 355 | 370 |
| 356 int lengthSync() { | 371 int lengthSync() { |
| 357 var result = _lengthFromPath(path); | 372 var result = _lengthFromPath(_Namespace._namespace, path); |
| 358 throwIfError(result, "Cannot retrieve length of file", path); | 373 throwIfError(result, "Cannot retrieve length of file", path); |
| 359 return result; | 374 return result; |
| 360 } | 375 } |
| 361 | 376 |
| 362 Future<DateTime> lastAccessed() { | 377 Future<DateTime> lastAccessed() { |
| 363 return _IOService._dispatch(_FILE_LAST_ACCESSED, [path]).then((response) { | 378 return _dispatchWithNamespace(_FILE_LAST_ACCESSED, [null, path]) |
| 379 .then((response) { |
| 364 if (_isErrorResponse(response)) { | 380 if (_isErrorResponse(response)) { |
| 365 throw _exceptionFromResponse( | 381 throw _exceptionFromResponse( |
| 366 response, "Cannot retrieve access time", path); | 382 response, "Cannot retrieve access time", path); |
| 367 } | 383 } |
| 368 return new DateTime.fromMillisecondsSinceEpoch(response); | 384 return new DateTime.fromMillisecondsSinceEpoch(response); |
| 369 }); | 385 }); |
| 370 } | 386 } |
| 371 | 387 |
| 372 external static _lastAccessed(String path); | 388 external static _lastAccessed(_Namespace namespace, String path); |
| 373 | 389 |
| 374 DateTime lastAccessedSync() { | 390 DateTime lastAccessedSync() { |
| 375 var ms = _lastAccessed(path); | 391 var ms = _lastAccessed(_Namespace._namespace, path); |
| 376 throwIfError(ms, "Cannot retrieve access time", path); | 392 throwIfError(ms, "Cannot retrieve access time", path); |
| 377 return new DateTime.fromMillisecondsSinceEpoch(ms); | 393 return new DateTime.fromMillisecondsSinceEpoch(ms); |
| 378 } | 394 } |
| 379 | 395 |
| 380 Future setLastAccessed(DateTime time) { | 396 Future setLastAccessed(DateTime time) { |
| 381 int millis = time.millisecondsSinceEpoch; | 397 int millis = time.millisecondsSinceEpoch; |
| 382 return _IOService | 398 return _dispatchWithNamespace(_FILE_SET_LAST_ACCESSED, [null, path, millis]) |
| 383 ._dispatch(_FILE_SET_LAST_ACCESSED, [path, millis]).then((response) { | 399 .then((response) { |
| 384 if (_isErrorResponse(response)) { | 400 if (_isErrorResponse(response)) { |
| 385 throw _exceptionFromResponse(response, "Cannot set access time", path); | 401 throw _exceptionFromResponse(response, "Cannot set access time", path); |
| 386 } | 402 } |
| 387 return null; | 403 return null; |
| 388 }); | 404 }); |
| 389 } | 405 } |
| 390 | 406 |
| 391 external static _setLastAccessed(String path, int millis); | 407 external static _setLastAccessed( |
| 408 _Namespace namespace, String path, int millis); |
| 392 | 409 |
| 393 void setLastAccessedSync(DateTime time) { | 410 void setLastAccessedSync(DateTime time) { |
| 394 int millis = time.millisecondsSinceEpoch; | 411 int millis = time.millisecondsSinceEpoch; |
| 395 var result = _setLastAccessed(path, millis); | 412 var result = _setLastAccessed(_Namespace._namespace, path, millis); |
| 396 if (result is OSError) { | 413 if (result is OSError) { |
| 397 throw new FileSystemException( | 414 throw new FileSystemException( |
| 398 "Failed to set file access time", path, result); | 415 "Failed to set file access time", path, result); |
| 399 } | 416 } |
| 400 } | 417 } |
| 401 | 418 |
| 402 Future<DateTime> lastModified() { | 419 Future<DateTime> lastModified() { |
| 403 return _IOService._dispatch(_FILE_LAST_MODIFIED, [path]).then((response) { | 420 return _dispatchWithNamespace(_FILE_LAST_MODIFIED, [null, path]) |
| 421 .then((response) { |
| 404 if (_isErrorResponse(response)) { | 422 if (_isErrorResponse(response)) { |
| 405 throw _exceptionFromResponse( | 423 throw _exceptionFromResponse( |
| 406 response, "Cannot retrieve modification time", path); | 424 response, "Cannot retrieve modification time", path); |
| 407 } | 425 } |
| 408 return new DateTime.fromMillisecondsSinceEpoch(response); | 426 return new DateTime.fromMillisecondsSinceEpoch(response); |
| 409 }); | 427 }); |
| 410 } | 428 } |
| 411 | 429 |
| 412 external static _lastModified(String path); | 430 external static _lastModified(_Namespace namespace, String path); |
| 413 | 431 |
| 414 DateTime lastModifiedSync() { | 432 DateTime lastModifiedSync() { |
| 415 var ms = _lastModified(path); | 433 var ms = _lastModified(_Namespace._namespace, path); |
| 416 throwIfError(ms, "Cannot retrieve modification time", path); | 434 throwIfError(ms, "Cannot retrieve modification time", path); |
| 417 return new DateTime.fromMillisecondsSinceEpoch(ms); | 435 return new DateTime.fromMillisecondsSinceEpoch(ms); |
| 418 } | 436 } |
| 419 | 437 |
| 420 Future setLastModified(DateTime time) { | 438 Future setLastModified(DateTime time) { |
| 421 int millis = time.millisecondsSinceEpoch; | 439 int millis = time.millisecondsSinceEpoch; |
| 422 return _IOService | 440 return _dispatchWithNamespace(_FILE_SET_LAST_MODIFIED, [null, path, millis]) |
| 423 ._dispatch(_FILE_SET_LAST_MODIFIED, [path, millis]).then((response) { | 441 .then((response) { |
| 424 if (_isErrorResponse(response)) { | 442 if (_isErrorResponse(response)) { |
| 425 throw _exceptionFromResponse( | 443 throw _exceptionFromResponse( |
| 426 response, "Cannot set modification time", path); | 444 response, "Cannot set modification time", path); |
| 427 } | 445 } |
| 428 return null; | 446 return null; |
| 429 }); | 447 }); |
| 430 } | 448 } |
| 431 | 449 |
| 432 external static _setLastModified(String path, int millis); | 450 external static _setLastModified( |
| 451 _Namespace namespace, String path, int millis); |
| 433 | 452 |
| 434 void setLastModifiedSync(DateTime time) { | 453 void setLastModifiedSync(DateTime time) { |
| 435 int millis = time.millisecondsSinceEpoch; | 454 int millis = time.millisecondsSinceEpoch; |
| 436 var result = _setLastModified(path, millis); | 455 var result = _setLastModified(_Namespace._namespace, path, millis); |
| 437 if (result is OSError) { | 456 if (result is OSError) { |
| 438 throw new FileSystemException( | 457 throw new FileSystemException( |
| 439 "Failed to set file modification time", path, result); | 458 "Failed to set file modification time", path, result); |
| 440 } | 459 } |
| 441 } | 460 } |
| 442 | 461 |
| 443 external static _open(String path, int mode); | 462 external static _open(_Namespace namespace, String path, int mode); |
| 444 | 463 |
| 445 RandomAccessFile openSync({FileMode mode: FileMode.READ}) { | 464 RandomAccessFile openSync({FileMode mode: FileMode.READ}) { |
| 446 if (mode != FileMode.READ && | 465 if (mode != FileMode.READ && |
| 447 mode != FileMode.WRITE && | 466 mode != FileMode.WRITE && |
| 448 mode != FileMode.APPEND && | 467 mode != FileMode.APPEND && |
| 449 mode != FileMode.WRITE_ONLY && | 468 mode != FileMode.WRITE_ONLY && |
| 450 mode != FileMode.WRITE_ONLY_APPEND) { | 469 mode != FileMode.WRITE_ONLY_APPEND) { |
| 451 throw new ArgumentError('Invalid file mode for this operation'); | 470 throw new ArgumentError('Invalid file mode for this operation'); |
| 452 } | 471 } |
| 453 var id = _open(path, mode._mode); | 472 var id = _open(_Namespace._namespace, path, mode._mode); |
| 454 throwIfError(id, "Cannot open file", path); | 473 throwIfError(id, "Cannot open file", path); |
| 455 return new _RandomAccessFile(id, path); | 474 return new _RandomAccessFile(id, path); |
| 456 } | 475 } |
| 457 | 476 |
| 458 external static int _openStdio(int fd); | 477 external static int _openStdio(int fd); |
| 459 | 478 |
| 460 static RandomAccessFile _openStdioSync(int fd) { | 479 static RandomAccessFile _openStdioSync(int fd) { |
| 461 var id = _openStdio(fd); | 480 var id = _openStdio(fd); |
| 462 if (id == 0) { | 481 if (id == 0) { |
| 463 throw new FileSystemException("Cannot open stdio file for: $fd"); | 482 throw new FileSystemException("Cannot open stdio file for: $fd"); |
| (...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1028 throw new ArgumentError(); | 1047 throw new ArgumentError(); |
| 1029 } | 1048 } |
| 1030 var result = _ops.lock(LOCK_UNLOCK, start, end); | 1049 var result = _ops.lock(LOCK_UNLOCK, start, end); |
| 1031 if (result is OSError) { | 1050 if (result is OSError) { |
| 1032 throw new FileSystemException('unlock failed', path, result); | 1051 throw new FileSystemException('unlock failed', path, result); |
| 1033 } | 1052 } |
| 1034 } | 1053 } |
| 1035 | 1054 |
| 1036 bool closed = false; | 1055 bool closed = false; |
| 1037 | 1056 |
| 1057 // WARNING: |
| 1038 // Calling this function will increase the reference count on the native | 1058 // Calling this function will increase the reference count on the native |
| 1039 // object that implements the file operations. It should only be called to | 1059 // object that implements the file operations. It should only be called to |
| 1040 // pass the pointer to the IO Service, which will decrement the reference | 1060 // pass the pointer to the IO Service, which will decrement the reference |
| 1041 // count when it is finished with it. | 1061 // count when it is finished with it. |
| 1042 int _pointer() => _ops.getPointer(); | 1062 int _pointer() => _ops.getPointer(); |
| 1043 | 1063 |
| 1044 Future _dispatch(int request, List data, {bool markClosed: false}) { | 1064 Future _dispatch(int request, List data, {bool markClosed: false}) { |
| 1045 if (closed) { | 1065 if (closed) { |
| 1046 return new Future.error(new FileSystemException("File closed", path)); | 1066 return new Future.error(new FileSystemException("File closed", path)); |
| 1047 } | 1067 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1064 void _checkAvailable() { | 1084 void _checkAvailable() { |
| 1065 if (_asyncDispatched) { | 1085 if (_asyncDispatched) { |
| 1066 throw new FileSystemException( | 1086 throw new FileSystemException( |
| 1067 "An async operation is currently pending", path); | 1087 "An async operation is currently pending", path); |
| 1068 } | 1088 } |
| 1069 if (closed) { | 1089 if (closed) { |
| 1070 throw new FileSystemException("File closed", path); | 1090 throw new FileSystemException("File closed", path); |
| 1071 } | 1091 } |
| 1072 } | 1092 } |
| 1073 } | 1093 } |
| OLD | NEW |