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( |
| 311 _Namespace namespace, String oldPath, String newPath); |
298 | 312 |
299 external static _renameLink(String oldPath, String newPath); | 313 external static _renameLink( |
| 314 _Namespace namespace, String oldPath, String newPath); |
300 | 315 |
301 File renameSync(String newPath) { | 316 File renameSync(String newPath) { |
302 var result = _rename(path, newPath); | 317 var result = _rename(_Namespace._namespace, path, newPath); |
303 throwIfError(result, "Cannot rename file to '$newPath'", path); | 318 throwIfError(result, "Cannot rename file to '$newPath'", path); |
304 return new File(newPath); | 319 return new File(newPath); |
305 } | 320 } |
306 | 321 |
307 Future<File> copy(String newPath) { | 322 Future<File> copy(String newPath) { |
308 return _IOService._dispatch(_FILE_COPY, [path, newPath]).then((response) { | 323 return _dispatchWithNamespace(_FILE_COPY, [null, path, newPath]) |
| 324 .then((response) { |
309 if (_isErrorResponse(response)) { | 325 if (_isErrorResponse(response)) { |
310 throw _exceptionFromResponse( | 326 throw _exceptionFromResponse( |
311 response, "Cannot copy file to '$newPath'", path); | 327 response, "Cannot copy file to '$newPath'", path); |
312 } | 328 } |
313 return new File(newPath); | 329 return new File(newPath); |
314 }); | 330 }); |
315 } | 331 } |
316 | 332 |
317 external static _copy(String oldPath, String newPath); | 333 external static _copy(_Namespace namespace, String oldPath, String newPath); |
318 | 334 |
319 File copySync(String newPath) { | 335 File copySync(String newPath) { |
320 var result = _copy(path, newPath); | 336 var result = _copy(_Namespace._namespace, path, newPath); |
321 throwIfError(result, "Cannot copy file to '$newPath'", path); | 337 throwIfError(result, "Cannot copy file to '$newPath'", path); |
322 return new File(newPath); | 338 return new File(newPath); |
323 } | 339 } |
324 | 340 |
325 Future<RandomAccessFile> open({FileMode mode: FileMode.READ}) { | 341 Future<RandomAccessFile> open({FileMode mode: FileMode.READ}) { |
326 if (mode != FileMode.READ && | 342 if (mode != FileMode.READ && |
327 mode != FileMode.WRITE && | 343 mode != FileMode.WRITE && |
328 mode != FileMode.APPEND && | 344 mode != FileMode.APPEND && |
329 mode != FileMode.WRITE_ONLY && | 345 mode != FileMode.WRITE_ONLY && |
330 mode != FileMode.WRITE_ONLY_APPEND) { | 346 mode != FileMode.WRITE_ONLY_APPEND) { |
331 return new Future.error( | 347 return new Future.error( |
332 new ArgumentError('Invalid file mode for this operation')); | 348 new ArgumentError('Invalid file mode for this operation')); |
333 } | 349 } |
334 return _IOService | 350 return _dispatchWithNamespace(_FILE_OPEN, [null, path, mode._mode]) |
335 ._dispatch(_FILE_OPEN, [path, mode._mode]).then((response) { | 351 .then((response) { |
336 if (_isErrorResponse(response)) { | 352 if (_isErrorResponse(response)) { |
337 throw _exceptionFromResponse(response, "Cannot open file", path); | 353 throw _exceptionFromResponse(response, "Cannot open file", path); |
338 } | 354 } |
339 return new _RandomAccessFile(response, path); | 355 return new _RandomAccessFile(response, path); |
340 }); | 356 }); |
341 } | 357 } |
342 | 358 |
343 Future<int> length() { | 359 Future<int> length() { |
344 return _IOService | 360 return _dispatchWithNamespace(_FILE_LENGTH_FROM_PATH, [null, path]) |
345 ._dispatch(_FILE_LENGTH_FROM_PATH, [path]).then((response) { | 361 .then((response) { |
346 if (_isErrorResponse(response)) { | 362 if (_isErrorResponse(response)) { |
347 throw _exceptionFromResponse( | 363 throw _exceptionFromResponse( |
348 response, "Cannot retrieve length of file", path); | 364 response, "Cannot retrieve length of file", path); |
349 } | 365 } |
350 return response; | 366 return response; |
351 }); | 367 }); |
352 } | 368 } |
353 | 369 |
354 external static _lengthFromPath(String path); | 370 external static _lengthFromPath(_Namespace namespace, String path); |
355 | 371 |
356 int lengthSync() { | 372 int lengthSync() { |
357 var result = _lengthFromPath(path); | 373 var result = _lengthFromPath(_Namespace._namespace, path); |
358 throwIfError(result, "Cannot retrieve length of file", path); | 374 throwIfError(result, "Cannot retrieve length of file", path); |
359 return result; | 375 return result; |
360 } | 376 } |
361 | 377 |
362 Future<DateTime> lastAccessed() { | 378 Future<DateTime> lastAccessed() { |
363 return _IOService._dispatch(_FILE_LAST_ACCESSED, [path]).then((response) { | 379 return _dispatchWithNamespace(_FILE_LAST_ACCESSED, [null, path]) |
| 380 .then((response) { |
364 if (_isErrorResponse(response)) { | 381 if (_isErrorResponse(response)) { |
365 throw _exceptionFromResponse( | 382 throw _exceptionFromResponse( |
366 response, "Cannot retrieve access time", path); | 383 response, "Cannot retrieve access time", path); |
367 } | 384 } |
368 return new DateTime.fromMillisecondsSinceEpoch(response); | 385 return new DateTime.fromMillisecondsSinceEpoch(response); |
369 }); | 386 }); |
370 } | 387 } |
371 | 388 |
372 external static _lastAccessed(String path); | 389 external static _lastAccessed(_Namespace namespace, String path); |
373 | 390 |
374 DateTime lastAccessedSync() { | 391 DateTime lastAccessedSync() { |
375 var ms = _lastAccessed(path); | 392 var ms = _lastAccessed(_Namespace._namespace, path); |
376 throwIfError(ms, "Cannot retrieve access time", path); | 393 throwIfError(ms, "Cannot retrieve access time", path); |
377 return new DateTime.fromMillisecondsSinceEpoch(ms); | 394 return new DateTime.fromMillisecondsSinceEpoch(ms); |
378 } | 395 } |
379 | 396 |
380 Future setLastAccessed(DateTime time) { | 397 Future setLastAccessed(DateTime time) { |
381 int millis = time.millisecondsSinceEpoch; | 398 int millis = time.millisecondsSinceEpoch; |
382 return _IOService | 399 return _dispatchWithNamespace(_FILE_SET_LAST_ACCESSED, [null, path, millis]) |
383 ._dispatch(_FILE_SET_LAST_ACCESSED, [path, millis]).then((response) { | 400 .then((response) { |
384 if (_isErrorResponse(response)) { | 401 if (_isErrorResponse(response)) { |
385 throw _exceptionFromResponse(response, "Cannot set access time", path); | 402 throw _exceptionFromResponse(response, "Cannot set access time", path); |
386 } | 403 } |
387 return null; | 404 return null; |
388 }); | 405 }); |
389 } | 406 } |
390 | 407 |
391 external static _setLastAccessed(String path, int millis); | 408 external static _setLastAccessed( |
| 409 _Namespace namespace, String path, int millis); |
392 | 410 |
393 void setLastAccessedSync(DateTime time) { | 411 void setLastAccessedSync(DateTime time) { |
394 int millis = time.millisecondsSinceEpoch; | 412 int millis = time.millisecondsSinceEpoch; |
395 var result = _setLastAccessed(path, millis); | 413 var result = _setLastAccessed(_Namespace._namespace, path, millis); |
396 if (result is OSError) { | 414 if (result is OSError) { |
397 throw new FileSystemException( | 415 throw new FileSystemException( |
398 "Failed to set file access time", path, result); | 416 "Failed to set file access time", path, result); |
399 } | 417 } |
400 } | 418 } |
401 | 419 |
402 Future<DateTime> lastModified() { | 420 Future<DateTime> lastModified() { |
403 return _IOService._dispatch(_FILE_LAST_MODIFIED, [path]).then((response) { | 421 return _dispatchWithNamespace(_FILE_LAST_MODIFIED, [null, path]) |
| 422 .then((response) { |
404 if (_isErrorResponse(response)) { | 423 if (_isErrorResponse(response)) { |
405 throw _exceptionFromResponse( | 424 throw _exceptionFromResponse( |
406 response, "Cannot retrieve modification time", path); | 425 response, "Cannot retrieve modification time", path); |
407 } | 426 } |
408 return new DateTime.fromMillisecondsSinceEpoch(response); | 427 return new DateTime.fromMillisecondsSinceEpoch(response); |
409 }); | 428 }); |
410 } | 429 } |
411 | 430 |
412 external static _lastModified(String path); | 431 external static _lastModified(_Namespace namespace, String path); |
413 | 432 |
414 DateTime lastModifiedSync() { | 433 DateTime lastModifiedSync() { |
415 var ms = _lastModified(path); | 434 var ms = _lastModified(_Namespace._namespace, path); |
416 throwIfError(ms, "Cannot retrieve modification time", path); | 435 throwIfError(ms, "Cannot retrieve modification time", path); |
417 return new DateTime.fromMillisecondsSinceEpoch(ms); | 436 return new DateTime.fromMillisecondsSinceEpoch(ms); |
418 } | 437 } |
419 | 438 |
420 Future setLastModified(DateTime time) { | 439 Future setLastModified(DateTime time) { |
421 int millis = time.millisecondsSinceEpoch; | 440 int millis = time.millisecondsSinceEpoch; |
422 return _IOService | 441 return _dispatchWithNamespace(_FILE_SET_LAST_MODIFIED, [null, path, millis]) |
423 ._dispatch(_FILE_SET_LAST_MODIFIED, [path, millis]).then((response) { | 442 .then((response) { |
424 if (_isErrorResponse(response)) { | 443 if (_isErrorResponse(response)) { |
425 throw _exceptionFromResponse( | 444 throw _exceptionFromResponse( |
426 response, "Cannot set modification time", path); | 445 response, "Cannot set modification time", path); |
427 } | 446 } |
428 return null; | 447 return null; |
429 }); | 448 }); |
430 } | 449 } |
431 | 450 |
432 external static _setLastModified(String path, int millis); | 451 external static _setLastModified( |
| 452 _Namespace namespace, String path, int millis); |
433 | 453 |
434 void setLastModifiedSync(DateTime time) { | 454 void setLastModifiedSync(DateTime time) { |
435 int millis = time.millisecondsSinceEpoch; | 455 int millis = time.millisecondsSinceEpoch; |
436 var result = _setLastModified(path, millis); | 456 var result = _setLastModified(_Namespace._namespace, path, millis); |
437 if (result is OSError) { | 457 if (result is OSError) { |
438 throw new FileSystemException( | 458 throw new FileSystemException( |
439 "Failed to set file modification time", path, result); | 459 "Failed to set file modification time", path, result); |
440 } | 460 } |
441 } | 461 } |
442 | 462 |
443 external static _open(String path, int mode); | 463 external static _open(_Namespace namespace, String path, int mode); |
444 | 464 |
445 RandomAccessFile openSync({FileMode mode: FileMode.READ}) { | 465 RandomAccessFile openSync({FileMode mode: FileMode.READ}) { |
446 if (mode != FileMode.READ && | 466 if (mode != FileMode.READ && |
447 mode != FileMode.WRITE && | 467 mode != FileMode.WRITE && |
448 mode != FileMode.APPEND && | 468 mode != FileMode.APPEND && |
449 mode != FileMode.WRITE_ONLY && | 469 mode != FileMode.WRITE_ONLY && |
450 mode != FileMode.WRITE_ONLY_APPEND) { | 470 mode != FileMode.WRITE_ONLY_APPEND) { |
451 throw new ArgumentError('Invalid file mode for this operation'); | 471 throw new ArgumentError('Invalid file mode for this operation'); |
452 } | 472 } |
453 var id = _open(path, mode._mode); | 473 var id = _open(_Namespace._namespace, path, mode._mode); |
454 throwIfError(id, "Cannot open file", path); | 474 throwIfError(id, "Cannot open file", path); |
455 return new _RandomAccessFile(id, path); | 475 return new _RandomAccessFile(id, path); |
456 } | 476 } |
457 | 477 |
458 external static int _openStdio(int fd); | 478 external static int _openStdio(int fd); |
459 | 479 |
460 static RandomAccessFile _openStdioSync(int fd) { | 480 static RandomAccessFile _openStdioSync(int fd) { |
461 var id = _openStdio(fd); | 481 var id = _openStdio(fd); |
462 if (id == 0) { | 482 if (id == 0) { |
463 throw new FileSystemException("Cannot open stdio file for: $fd"); | 483 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(); | 1048 throw new ArgumentError(); |
1029 } | 1049 } |
1030 var result = _ops.lock(LOCK_UNLOCK, start, end); | 1050 var result = _ops.lock(LOCK_UNLOCK, start, end); |
1031 if (result is OSError) { | 1051 if (result is OSError) { |
1032 throw new FileSystemException('unlock failed', path, result); | 1052 throw new FileSystemException('unlock failed', path, result); |
1033 } | 1053 } |
1034 } | 1054 } |
1035 | 1055 |
1036 bool closed = false; | 1056 bool closed = false; |
1037 | 1057 |
| 1058 // WARNING: |
1038 // Calling this function will increase the reference count on the native | 1059 // Calling this function will increase the reference count on the native |
1039 // object that implements the file operations. It should only be called to | 1060 // 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 | 1061 // pass the pointer to the IO Service, which will decrement the reference |
1041 // count when it is finished with it. | 1062 // count when it is finished with it. |
1042 int _pointer() => _ops.getPointer(); | 1063 int _pointer() => _ops.getPointer(); |
1043 | 1064 |
1044 Future _dispatch(int request, List data, {bool markClosed: false}) { | 1065 Future _dispatch(int request, List data, {bool markClosed: false}) { |
1045 if (closed) { | 1066 if (closed) { |
1046 return new Future.error(new FileSystemException("File closed", path)); | 1067 return new Future.error(new FileSystemException("File closed", path)); |
1047 } | 1068 } |
(...skipping 16 matching lines...) Expand all Loading... |
1064 void _checkAvailable() { | 1085 void _checkAvailable() { |
1065 if (_asyncDispatched) { | 1086 if (_asyncDispatched) { |
1066 throw new FileSystemException( | 1087 throw new FileSystemException( |
1067 "An async operation is currently pending", path); | 1088 "An async operation is currently pending", path); |
1068 } | 1089 } |
1069 if (closed) { | 1090 if (closed) { |
1070 throw new FileSystemException("File closed", path); | 1091 throw new FileSystemException("File closed", path); |
1071 } | 1092 } |
1072 } | 1093 } |
1073 } | 1094 } |
OLD | NEW |