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 | 7 |
8 class _FileStream extends Stream<List<int>> { | 8 class _FileStream extends Stream<List<int>> { |
9 // Stream controller. | 9 // Stream controller. |
10 StreamController<List<int>> _controller; | 10 StreamController<List<int>> _controller; |
11 | 11 |
12 // Read the file in blocks of size 64k. | 12 // Read the file in blocks of size 64k. |
13 final int _blockSize = 64 * 1024; | 13 final int _blockSize = 64 * 1024; |
14 | 14 |
15 // Information about the underlying file. | 15 // Information about the underlying file. |
16 String _name; | 16 String _path; |
17 RandomAccessFile _openedFile; | 17 RandomAccessFile _openedFile; |
18 int _position; | 18 int _position; |
19 | 19 |
20 // Has the stream been paused or unsubscribed? | 20 // Has the stream been paused or unsubscribed? |
21 bool _paused = false; | 21 bool _paused = false; |
22 bool _unsubscribed = false; | 22 bool _unsubscribed = false; |
23 | 23 |
24 // Is there a read currently in progress? | 24 // Is there a read currently in progress? |
25 bool _readInProgress = false; | 25 bool _readInProgress = false; |
26 | 26 |
27 // Block read but not yet send because stream is paused. | 27 // Block read but not yet send because stream is paused. |
28 List<int> _currentBlock; | 28 List<int> _currentBlock; |
29 | 29 |
30 _FileStream(String this._name) : _position = 0 { | 30 _FileStream(String this._path) : _position = 0 { |
31 _setupController(); | 31 _setupController(); |
32 } | 32 } |
33 | 33 |
34 _FileStream.forStdin() : _position = 0 { | 34 _FileStream.forStdin() : _position = 0 { |
35 _setupController(); | 35 _setupController(); |
36 } | 36 } |
37 | 37 |
38 StreamSubscription<List<int>> listen(void onData(List<int> event), | 38 StreamSubscription<List<int>> listen(void onData(List<int> event), |
39 {void onError(AsyncError error), | 39 {void onError(AsyncError error), |
40 void onDone(), | 40 void onDone(), |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 if (!_unsubscribed) { | 96 if (!_unsubscribed) { |
97 _controller.signalError(e); | 97 _controller.signalError(e); |
98 _closeFile().then((_) { _controller.close(); }); | 98 _closeFile().then((_) { _controller.close(); }); |
99 _unsubscribed = true; | 99 _unsubscribed = true; |
100 } | 100 } |
101 }); | 101 }); |
102 } | 102 } |
103 | 103 |
104 void _start() { | 104 void _start() { |
105 Future<RandomAccessFile> openFuture; | 105 Future<RandomAccessFile> openFuture; |
106 if (_name != null) { | 106 if (_path != null) { |
107 openFuture = new File(_name).open(FileMode.READ); | 107 openFuture = new File(_path).open(FileMode.READ); |
108 } else { | 108 } else { |
109 openFuture = new Future.immediate(_File._openStdioSync(0)); | 109 openFuture = new Future.immediate(_File._openStdioSync(0)); |
110 } | 110 } |
111 openFuture | 111 openFuture |
112 .then((RandomAccessFile opened) { | 112 .then((RandomAccessFile opened) { |
113 _openedFile = opened; | 113 _openedFile = opened; |
114 _readBlock(); | 114 _readBlock(); |
115 }) | 115 }) |
116 .catchError((e) { | 116 .catchError((e) { |
117 _controller.signalError(e); | 117 _controller.signalError(e); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 const int _CREATE_REQUEST = 1; | 204 const int _CREATE_REQUEST = 1; |
205 const int _DELETE_REQUEST = 2; | 205 const int _DELETE_REQUEST = 2; |
206 const int _OPEN_REQUEST = 3; | 206 const int _OPEN_REQUEST = 3; |
207 const int _FULL_PATH_REQUEST = 4; | 207 const int _FULL_PATH_REQUEST = 4; |
208 const int _DIRECTORY_REQUEST = 5; | 208 const int _DIRECTORY_REQUEST = 5; |
209 const int _CLOSE_REQUEST = 6; | 209 const int _CLOSE_REQUEST = 6; |
210 const int _POSITION_REQUEST = 7; | 210 const int _POSITION_REQUEST = 7; |
211 const int _SET_POSITION_REQUEST = 8; | 211 const int _SET_POSITION_REQUEST = 8; |
212 const int _TRUNCATE_REQUEST = 9; | 212 const int _TRUNCATE_REQUEST = 9; |
213 const int _LENGTH_REQUEST = 10; | 213 const int _LENGTH_REQUEST = 10; |
214 const int _LENGTH_FROM_NAME_REQUEST = 11; | 214 const int _LENGTH_FROM_PATH_REQUEST = 11; |
215 const int _LAST_MODIFIED_REQUEST = 12; | 215 const int _LAST_MODIFIED_REQUEST = 12; |
216 const int _FLUSH_REQUEST = 13; | 216 const int _FLUSH_REQUEST = 13; |
217 const int _READ_BYTE_REQUEST = 14; | 217 const int _READ_BYTE_REQUEST = 14; |
218 const int _WRITE_BYTE_REQUEST = 15; | 218 const int _WRITE_BYTE_REQUEST = 15; |
219 const int _READ_REQUEST = 16; | 219 const int _READ_REQUEST = 16; |
220 const int _READ_LIST_REQUEST = 17; | 220 const int _READ_LIST_REQUEST = 17; |
221 const int _WRITE_LIST_REQUEST = 18; | 221 const int _WRITE_LIST_REQUEST = 18; |
222 | 222 |
223 // Base class for _File and _RandomAccessFile with shared functions. | 223 // Base class for _File and _RandomAccessFile with shared functions. |
224 class _FileBase { | 224 class _FileBase { |
(...skipping 21 matching lines...) Expand all Loading... |
246 // TODO(ager): The only reason for this class is that the patching | 246 // TODO(ager): The only reason for this class is that the patching |
247 // mechanism doesn't seem to like patching a private top level | 247 // mechanism doesn't seem to like patching a private top level |
248 // function. | 248 // function. |
249 class _FileUtils { | 249 class _FileUtils { |
250 external static SendPort _newServicePort(); | 250 external static SendPort _newServicePort(); |
251 } | 251 } |
252 | 252 |
253 // Class for encapsulating the native implementation of files. | 253 // Class for encapsulating the native implementation of files. |
254 class _File extends _FileBase implements File { | 254 class _File extends _FileBase implements File { |
255 // Constructor for file. | 255 // Constructor for file. |
256 _File(String this._name) { | 256 _File(String this._path) { |
257 if (_name is! String) { | 257 if (_path is! String) { |
258 throw new ArgumentError('${Error.safeToString(_name)} ' | 258 throw new ArgumentError('${Error.safeToString(_path)} ' |
259 'is not a String'); | 259 'is not a String'); |
260 } | 260 } |
261 } | 261 } |
262 | 262 |
263 // Constructor from Path for file. | 263 // Constructor from Path for file. |
264 _File.fromPath(Path path) : this(path.toNativePath()); | 264 _File.fromPath(Path path) : this(path.toNativePath()); |
265 | 265 |
266 Future<bool> exists() { | 266 Future<bool> exists() { |
267 _ensureFileService(); | 267 _ensureFileService(); |
268 List request = new List(2); | 268 List request = new List(2); |
269 request[0] = _EXISTS_REQUEST; | 269 request[0] = _EXISTS_REQUEST; |
270 request[1] = _name; | 270 request[1] = _path; |
271 return _fileService.call(request).then((response) { | 271 return _fileService.call(request).then((response) { |
272 if (_isErrorResponse(response)) { | 272 if (_isErrorResponse(response)) { |
273 throw _exceptionFromResponse(response, "Cannot open file '$_name'"); | 273 throw _exceptionFromResponse(response, "Cannot open file '$_path'"); |
274 } | 274 } |
275 return response; | 275 return response; |
276 }); | 276 }); |
277 } | 277 } |
278 | 278 |
279 external static _exists(String name); | 279 external static _exists(String path); |
280 | 280 |
281 bool existsSync() { | 281 bool existsSync() { |
282 var result = _exists(_name); | 282 var result = _exists(_path); |
283 throwIfError(result, "Cannot check existence of file '$_name'"); | 283 throwIfError(result, "Cannot check existence of file '$_path'"); |
284 return result; | 284 return result; |
285 } | 285 } |
286 | 286 |
287 Future<File> create() { | 287 Future<File> create() { |
288 _ensureFileService(); | 288 _ensureFileService(); |
289 List request = new List(2); | 289 List request = new List(2); |
290 request[0] = _CREATE_REQUEST; | 290 request[0] = _CREATE_REQUEST; |
291 request[1] = _name; | 291 request[1] = _path; |
292 return _fileService.call(request).then((response) { | 292 return _fileService.call(request).then((response) { |
293 if (_isErrorResponse(response)) { | 293 if (_isErrorResponse(response)) { |
294 throw _exceptionFromResponse(response, "Cannot create file '$_name'"); | 294 throw _exceptionFromResponse(response, "Cannot create file '$_path'"); |
295 } | 295 } |
296 return this; | 296 return this; |
297 }); | 297 }); |
298 } | 298 } |
299 | 299 |
300 external static _create(String name); | 300 external static _create(String path); |
301 | 301 |
302 void createSync() { | 302 void createSync() { |
303 var result = _create(_name); | 303 var result = _create(_path); |
304 throwIfError(result, "Cannot create file '$_name'"); | 304 throwIfError(result, "Cannot create file '$_path'"); |
305 } | 305 } |
306 | 306 |
307 Future<File> delete() { | 307 Future<File> delete() { |
308 _ensureFileService(); | 308 _ensureFileService(); |
309 List request = new List(2); | 309 List request = new List(2); |
310 request[0] = _DELETE_REQUEST; | 310 request[0] = _DELETE_REQUEST; |
311 request[1] = _name; | 311 request[1] = _path; |
312 return _fileService.call(request).then((response) { | 312 return _fileService.call(request).then((response) { |
313 if (_isErrorResponse(response)) { | 313 if (_isErrorResponse(response)) { |
314 throw _exceptionFromResponse(response, "Cannot delete file '$_name'"); | 314 throw _exceptionFromResponse(response, "Cannot delete file '$_path'"); |
315 } | 315 } |
316 return this; | 316 return this; |
317 }); | 317 }); |
318 } | 318 } |
319 | 319 |
320 external static _delete(String name); | 320 external static _delete(String path); |
321 | 321 |
322 void deleteSync() { | 322 void deleteSync() { |
323 var result = _delete(_name); | 323 var result = _delete(_path); |
324 throwIfError(result, "Cannot delete file '$_name'"); | 324 throwIfError(result, "Cannot delete file '$_path'"); |
325 } | 325 } |
326 | 326 |
327 Future<Directory> directory() { | 327 Future<Directory> directory() { |
328 _ensureFileService(); | 328 _ensureFileService(); |
329 List request = new List(2); | 329 List request = new List(2); |
330 request[0] = _DIRECTORY_REQUEST; | 330 request[0] = _DIRECTORY_REQUEST; |
331 request[1] = _name; | 331 request[1] = _path; |
332 return _fileService.call(request).then((response) { | 332 return _fileService.call(request).then((response) { |
333 if (_isErrorResponse(response)) { | 333 if (_isErrorResponse(response)) { |
334 throw _exceptionFromResponse(response, | 334 throw _exceptionFromResponse(response, |
335 "Cannot retrieve directory for " | 335 "Cannot retrieve directory for " |
336 "file '$_name'"); | 336 "file '$_path'"); |
337 } | 337 } |
338 return new Directory(response); | 338 return new Directory(response); |
339 }); | 339 }); |
340 } | 340 } |
341 | 341 |
342 external static _directory(String name); | 342 external static _directory(String path); |
343 | 343 |
344 Directory directorySync() { | 344 Directory directorySync() { |
345 var result = _directory(name); | 345 var result = _directory(path); |
346 throwIfError(result, "Cannot retrieve directory for file '$_name'"); | 346 throwIfError(result, "Cannot retrieve directory for file '$_path'"); |
347 return new Directory(result); | 347 return new Directory(result); |
348 } | 348 } |
349 | 349 |
350 Future<RandomAccessFile> open([FileMode mode = FileMode.READ]) { | 350 Future<RandomAccessFile> open([FileMode mode = FileMode.READ]) { |
351 _ensureFileService(); | 351 _ensureFileService(); |
352 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 352 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
353 if (mode != FileMode.READ && | 353 if (mode != FileMode.READ && |
354 mode != FileMode.WRITE && | 354 mode != FileMode.WRITE && |
355 mode != FileMode.APPEND) { | 355 mode != FileMode.APPEND) { |
356 Timer.run(() { | 356 Timer.run(() { |
357 completer.completeError(new ArgumentError()); | 357 completer.completeError(new ArgumentError()); |
358 }); | 358 }); |
359 return completer.future; | 359 return completer.future; |
360 } | 360 } |
361 List request = new List(3); | 361 List request = new List(3); |
362 request[0] = _OPEN_REQUEST; | 362 request[0] = _OPEN_REQUEST; |
363 request[1] = _name; | 363 request[1] = _path; |
364 request[2] = mode._mode; // Direct int value for serialization. | 364 request[2] = mode._mode; // Direct int value for serialization. |
365 return _fileService.call(request).then((response) { | 365 return _fileService.call(request).then((response) { |
366 if (_isErrorResponse(response)) { | 366 if (_isErrorResponse(response)) { |
367 throw _exceptionFromResponse(response, "Cannot open file '$_name'"); | 367 throw _exceptionFromResponse(response, "Cannot open file '$_path'"); |
368 } | 368 } |
369 return new _RandomAccessFile(response, _name); | 369 return new _RandomAccessFile(response, _path); |
370 }); | 370 }); |
371 } | 371 } |
372 | 372 |
373 Future<int> length() { | 373 Future<int> length() { |
374 _ensureFileService(); | 374 _ensureFileService(); |
375 List request = new List(2); | 375 List request = new List(2); |
376 request[0] = _LENGTH_FROM_NAME_REQUEST; | 376 request[0] = _LENGTH_FROM_PATH_REQUEST; |
377 request[1] = _name; | 377 request[1] = _path; |
378 return _fileService.call(request).then((response) { | 378 return _fileService.call(request).then((response) { |
379 if (_isErrorResponse(response)) { | 379 if (_isErrorResponse(response)) { |
380 throw _exceptionFromResponse(response, | 380 throw _exceptionFromResponse(response, |
381 "Cannot retrieve length of " | 381 "Cannot retrieve length of " |
382 "file '$_name'"); | 382 "file '$_path'"); |
383 } | 383 } |
384 return response; | 384 return response; |
385 }); | 385 }); |
386 } | 386 } |
387 | 387 |
388 | 388 |
389 external static _lengthFromName(String name); | 389 external static _lengthFromPath(String path); |
390 | 390 |
391 int lengthSync() { | 391 int lengthSync() { |
392 var result = _lengthFromName(_name); | 392 var result = _lengthFromPath(_path); |
393 throwIfError(result, "Cannot retrieve length of file '$_name'"); | 393 throwIfError(result, "Cannot retrieve length of file '$_path'"); |
394 return result; | 394 return result; |
395 } | 395 } |
396 | 396 |
397 Future<DateTime> lastModified() { | 397 Future<DateTime> lastModified() { |
398 _ensureFileService(); | 398 _ensureFileService(); |
399 List request = new List(2); | 399 List request = new List(2); |
400 request[0] = _LAST_MODIFIED_REQUEST; | 400 request[0] = _LAST_MODIFIED_REQUEST; |
401 request[1] = _name; | 401 request[1] = _path; |
402 return _fileService.call(request).then((response) { | 402 return _fileService.call(request).then((response) { |
403 if (_isErrorResponse(response)) { | 403 if (_isErrorResponse(response)) { |
404 throw _exceptionFromResponse(response, | 404 throw _exceptionFromResponse(response, |
405 "Cannot retrieve modification time " | 405 "Cannot retrieve modification time " |
406 "for file '$_name'"); | 406 "for file '$_path'"); |
407 } | 407 } |
408 return new DateTime.fromMillisecondsSinceEpoch(response); | 408 return new DateTime.fromMillisecondsSinceEpoch(response); |
409 }); | 409 }); |
410 } | 410 } |
411 | 411 |
412 external static _lastModified(String name); | 412 external static _lastModified(String path); |
413 | 413 |
414 DateTime lastModifiedSync() { | 414 DateTime lastModifiedSync() { |
415 var ms = _lastModified(name); | 415 var ms = _lastModified(path); |
416 throwIfError(ms, "Cannot retrieve modification time for file '$_name'"); | 416 throwIfError(ms, "Cannot retrieve modification time for file '$_path'"); |
417 return new DateTime.fromMillisecondsSinceEpoch(ms); | 417 return new DateTime.fromMillisecondsSinceEpoch(ms); |
418 } | 418 } |
419 | 419 |
420 external static _open(String name, int mode); | 420 external static _open(String path, int mode); |
421 | 421 |
422 RandomAccessFile openSync([FileMode mode = FileMode.READ]) { | 422 RandomAccessFile openSync([FileMode mode = FileMode.READ]) { |
423 if (mode != FileMode.READ && | 423 if (mode != FileMode.READ && |
424 mode != FileMode.WRITE && | 424 mode != FileMode.WRITE && |
425 mode != FileMode.APPEND) { | 425 mode != FileMode.APPEND) { |
426 throw new FileIOException("Unknown file mode. Use FileMode.READ, " | 426 throw new FileIOException("Unknown file mode. Use FileMode.READ, " |
427 "FileMode.WRITE or FileMode.APPEND."); | 427 "FileMode.WRITE or FileMode.APPEND."); |
428 } | 428 } |
429 var id = _open(_name, mode._mode); | 429 var id = _open(_path, mode._mode); |
430 throwIfError(id, "Cannot open file '$_name'"); | 430 throwIfError(id, "Cannot open file '$_path'"); |
431 return new _RandomAccessFile(id, _name); | 431 return new _RandomAccessFile(id, _path); |
432 } | 432 } |
433 | 433 |
434 external static int _openStdio(int fd); | 434 external static int _openStdio(int fd); |
435 | 435 |
436 static RandomAccessFile _openStdioSync(int fd) { | 436 static RandomAccessFile _openStdioSync(int fd) { |
437 var id = _openStdio(fd); | 437 var id = _openStdio(fd); |
438 if (id == 0) { | 438 if (id == 0) { |
439 throw new FileIOException("Cannot open stdio file for: $fd"); | 439 throw new FileIOException("Cannot open stdio file for: $fd"); |
440 } | 440 } |
441 return new _RandomAccessFile(id, ""); | 441 return new _RandomAccessFile(id, ""); |
442 } | 442 } |
443 | 443 |
444 Future<String> fullPath() { | 444 Future<String> fullPath() { |
445 _ensureFileService(); | 445 _ensureFileService(); |
446 List request = new List(2); | 446 List request = new List(2); |
447 request[0] = _FULL_PATH_REQUEST; | 447 request[0] = _FULL_PATH_REQUEST; |
448 request[1] = _name; | 448 request[1] = _path; |
449 return _fileService.call(request).then((response) { | 449 return _fileService.call(request).then((response) { |
450 if (_isErrorResponse(response)) { | 450 if (_isErrorResponse(response)) { |
451 throw _exceptionFromResponse(response, | 451 throw _exceptionFromResponse(response, |
452 "Cannot retrieve full path" | 452 "Cannot retrieve full path" |
453 " for '$_name'"); | 453 " for '$_path'"); |
454 } | 454 } |
455 return response; | 455 return response; |
456 }); | 456 }); |
457 } | 457 } |
458 | 458 |
459 external static _fullPath(String name); | 459 external static _fullPath(String path); |
460 | 460 |
461 String fullPathSync() { | 461 String fullPathSync() { |
462 var result = _fullPath(_name); | 462 var result = _fullPath(_path); |
463 throwIfError(result, "Cannot retrieve full path for file '$_name'"); | 463 throwIfError(result, "Cannot retrieve full path for file '$_path'"); |
464 return result; | 464 return result; |
465 } | 465 } |
466 | 466 |
467 Stream<List<int>> openRead() { | 467 Stream<List<int>> openRead() { |
468 return new _FileStream(_name); | 468 return new _FileStream(_path); |
469 } | 469 } |
470 | 470 |
471 IOSink<File> openWrite([FileMode mode = FileMode.WRITE]) { | 471 IOSink<File> openWrite([FileMode mode = FileMode.WRITE]) { |
472 if (mode != FileMode.WRITE && | 472 if (mode != FileMode.WRITE && |
473 mode != FileMode.APPEND) { | 473 mode != FileMode.APPEND) { |
474 throw new FileIOException( | 474 throw new FileIOException( |
475 "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND"); | 475 "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND"); |
476 } | 476 } |
477 var consumer = new _FileStreamConsumer(this, mode); | 477 var consumer = new _FileStreamConsumer(this, mode); |
478 return new IOSink<File>(consumer); | 478 return new IOSink<File>(consumer); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
583 return completer.future; | 583 return completer.future; |
584 } | 584 } |
585 } | 585 } |
586 | 586 |
587 void writeAsStringSync(String contents, | 587 void writeAsStringSync(String contents, |
588 {FileMode mode: FileMode.WRITE, | 588 {FileMode mode: FileMode.WRITE, |
589 Encoding encoding: Encoding.UTF_8}) { | 589 Encoding encoding: Encoding.UTF_8}) { |
590 writeAsBytesSync(_encodeString(contents, encoding), mode); | 590 writeAsBytesSync(_encodeString(contents, encoding), mode); |
591 } | 591 } |
592 | 592 |
593 String get name => _name; | 593 String get path => _path; |
594 | 594 |
595 String toString() => "File: '$name'"; | 595 String toString() => "File: '$path'"; |
596 | 596 |
597 void _ensureFileService() { | 597 void _ensureFileService() { |
598 if (_fileService == null) { | 598 if (_fileService == null) { |
599 _fileService = _FileUtils._newServicePort(); | 599 _fileService = _FileUtils._newServicePort(); |
600 } | 600 } |
601 } | 601 } |
602 | 602 |
603 static throwIfError(Object result, String msg) { | 603 static throwIfError(Object result, String msg) { |
604 if (result is OSError) { | 604 if (result is OSError) { |
605 throw new FileIOException(msg, result); | 605 throw new FileIOException(msg, result); |
606 } | 606 } |
607 } | 607 } |
608 | 608 |
609 final String _name; | 609 final String _path; |
610 | 610 |
611 SendPort _fileService; | 611 SendPort _fileService; |
612 } | 612 } |
613 | 613 |
614 | 614 |
615 class _RandomAccessFile extends _FileBase implements RandomAccessFile { | 615 class _RandomAccessFile extends _FileBase implements RandomAccessFile { |
616 _RandomAccessFile(int this._id, String this._name); | 616 _RandomAccessFile(int this._id, String this._path); |
617 | 617 |
618 Future<RandomAccessFile> close() { | 618 Future<RandomAccessFile> close() { |
619 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 619 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
620 if (closed) return _completeWithClosedException(completer); | 620 if (closed) return _completeWithClosedException(completer); |
621 _ensureFileService(); | 621 _ensureFileService(); |
622 List request = new List(2); | 622 List request = new List(2); |
623 request[0] = _CLOSE_REQUEST; | 623 request[0] = _CLOSE_REQUEST; |
624 request[1] = _id; | 624 request[1] = _id; |
625 // Set the id_ to 0 (NULL) to ensure the no more async requests | 625 // Set the id_ to 0 (NULL) to ensure the no more async requests |
626 // can be issued for this file. | 626 // can be issued for this file. |
627 _id = 0; | 627 _id = 0; |
628 return _fileService.call(request).then((result) { | 628 return _fileService.call(request).then((result) { |
629 if (result != -1) { | 629 if (result != -1) { |
630 _id = result; | 630 _id = result; |
631 return this; | 631 return this; |
632 } else { | 632 } else { |
633 throw new FileIOException("Cannot close file '$_name'"); | 633 throw new FileIOException("Cannot close file '$_path'"); |
634 } | 634 } |
635 }); | 635 }); |
636 } | 636 } |
637 | 637 |
638 external static int _close(int id); | 638 external static int _close(int id); |
639 | 639 |
640 void closeSync() { | 640 void closeSync() { |
641 _checkNotClosed(); | 641 _checkNotClosed(); |
642 var id = _close(_id); | 642 var id = _close(_id); |
643 if (id == -1) { | 643 if (id == -1) { |
644 throw new FileIOException("Cannot close file '$_name'"); | 644 throw new FileIOException("Cannot close file '$_path'"); |
645 } | 645 } |
646 _id = id; | 646 _id = id; |
647 } | 647 } |
648 | 648 |
649 Future<int> readByte() { | 649 Future<int> readByte() { |
650 _ensureFileService(); | 650 _ensureFileService(); |
651 Completer<int> completer = new Completer<int>(); | 651 Completer<int> completer = new Completer<int>(); |
652 if (closed) return _completeWithClosedException(completer); | 652 if (closed) return _completeWithClosedException(completer); |
653 List request = new List(2); | 653 List request = new List(2); |
654 request[0] = _READ_BYTE_REQUEST; | 654 request[0] = _READ_BYTE_REQUEST; |
655 request[1] = _id; | 655 request[1] = _id; |
656 return _fileService.call(request).then((response) { | 656 return _fileService.call(request).then((response) { |
657 if (_isErrorResponse(response)) { | 657 if (_isErrorResponse(response)) { |
658 throw _exceptionFromResponse(response, | 658 throw _exceptionFromResponse(response, |
659 "readByte failed for file '$_name'"); | 659 "readByte failed for file '$_path'"); |
660 } | 660 } |
661 return response; | 661 return response; |
662 }); | 662 }); |
663 } | 663 } |
664 | 664 |
665 external static _readByte(int id); | 665 external static _readByte(int id); |
666 | 666 |
667 int readByteSync() { | 667 int readByteSync() { |
668 _checkNotClosed(); | 668 _checkNotClosed(); |
669 var result = _readByte(_id); | 669 var result = _readByte(_id); |
670 if (result is OSError) { | 670 if (result is OSError) { |
671 throw new FileIOException("readByte failed for file '$_name'", result); | 671 throw new FileIOException("readByte failed for file '$_path'", result); |
672 } | 672 } |
673 return result; | 673 return result; |
674 } | 674 } |
675 | 675 |
676 Future<List<int>> read(int bytes) { | 676 Future<List<int>> read(int bytes) { |
677 _ensureFileService(); | 677 _ensureFileService(); |
678 Completer<List<int>> completer = new Completer<List<int>>(); | 678 Completer<List<int>> completer = new Completer<List<int>>(); |
679 if (bytes is !int) { | 679 if (bytes is !int) { |
680 // Complete asynchronously so the user has a chance to setup | 680 // Complete asynchronously so the user has a chance to setup |
681 // handlers without getting exceptions when registering the | 681 // handlers without getting exceptions when registering the |
682 // then handler. | 682 // then handler. |
683 Timer.run(() { | 683 Timer.run(() { |
684 completer.completeError(new FileIOException( | 684 completer.completeError(new FileIOException( |
685 "Invalid arguments to read for file '$_name'")); | 685 "Invalid arguments to read for file '$_path'")); |
686 }); | 686 }); |
687 return completer.future; | 687 return completer.future; |
688 }; | 688 }; |
689 if (closed) return _completeWithClosedException(completer); | 689 if (closed) return _completeWithClosedException(completer); |
690 List request = new List(3); | 690 List request = new List(3); |
691 request[0] = _READ_REQUEST; | 691 request[0] = _READ_REQUEST; |
692 request[1] = _id; | 692 request[1] = _id; |
693 request[2] = bytes; | 693 request[2] = bytes; |
694 return _fileService.call(request).then((response) { | 694 return _fileService.call(request).then((response) { |
695 if (_isErrorResponse(response)) { | 695 if (_isErrorResponse(response)) { |
696 throw _exceptionFromResponse(response, | 696 throw _exceptionFromResponse(response, |
697 "read failed for file '$_name'"); | 697 "read failed for file '$_path'"); |
698 } | 698 } |
699 return response[1]; | 699 return response[1]; |
700 }); | 700 }); |
701 } | 701 } |
702 | 702 |
703 external static _read(int id, int bytes); | 703 external static _read(int id, int bytes); |
704 | 704 |
705 List<int> readSync(int bytes) { | 705 List<int> readSync(int bytes) { |
706 if (bytes is !int) { | 706 if (bytes is !int) { |
707 throw new FileIOException( | 707 throw new FileIOException( |
708 "Invalid arguments to readSync for file '$_name'"); | 708 "Invalid arguments to readSync for file '$_path'"); |
709 } | 709 } |
710 return _read(_id, bytes); | 710 return _read(_id, bytes); |
711 } | 711 } |
712 | 712 |
713 Future<int> readList(List<int> buffer, int offset, int bytes) { | 713 Future<int> readList(List<int> buffer, int offset, int bytes) { |
714 _ensureFileService(); | 714 _ensureFileService(); |
715 Completer<int> completer = new Completer<int>(); | 715 Completer<int> completer = new Completer<int>(); |
716 if (buffer is !List || offset is !int || bytes is !int) { | 716 if (buffer is !List || offset is !int || bytes is !int) { |
717 // Complete asynchronously so the user has a chance to setup | 717 // Complete asynchronously so the user has a chance to setup |
718 // handlers without getting exceptions when registering the | 718 // handlers without getting exceptions when registering the |
719 // then handler. | 719 // then handler. |
720 Timer.run(() { | 720 Timer.run(() { |
721 completer.completeError(new FileIOException( | 721 completer.completeError(new FileIOException( |
722 "Invalid arguments to readList for file '$_name'")); | 722 "Invalid arguments to readList for file '$_path'")); |
723 }); | 723 }); |
724 return completer.future; | 724 return completer.future; |
725 }; | 725 }; |
726 if (closed) return _completeWithClosedException(completer); | 726 if (closed) return _completeWithClosedException(completer); |
727 List request = new List(3); | 727 List request = new List(3); |
728 request[0] = _READ_LIST_REQUEST; | 728 request[0] = _READ_LIST_REQUEST; |
729 request[1] = _id; | 729 request[1] = _id; |
730 request[2] = bytes; | 730 request[2] = bytes; |
731 return _fileService.call(request).then((response) { | 731 return _fileService.call(request).then((response) { |
732 if (_isErrorResponse(response)) { | 732 if (_isErrorResponse(response)) { |
733 throw _exceptionFromResponse(response, | 733 throw _exceptionFromResponse(response, |
734 "readList failed for file '$_name'"); | 734 "readList failed for file '$_path'"); |
735 } | 735 } |
736 var read = response[1]; | 736 var read = response[1]; |
737 var data = response[2]; | 737 var data = response[2]; |
738 buffer.setRange(offset, read, data); | 738 buffer.setRange(offset, read, data); |
739 return read; | 739 return read; |
740 }); | 740 }); |
741 } | 741 } |
742 | 742 |
743 static void _checkReadWriteListArguments(int length, int offset, int bytes) { | 743 static void _checkReadWriteListArguments(int length, int offset, int bytes) { |
744 if (offset < 0) throw new RangeError.value(offset); | 744 if (offset < 0) throw new RangeError.value(offset); |
745 if (bytes < 0) throw new RangeError.value(bytes); | 745 if (bytes < 0) throw new RangeError.value(bytes); |
746 if ((offset + bytes) > length) { | 746 if ((offset + bytes) > length) { |
747 throw new RangeError.value(offset + bytes); | 747 throw new RangeError.value(offset + bytes); |
748 } | 748 } |
749 } | 749 } |
750 | 750 |
751 external static _readList(int id, List<int> buffer, int offset, int bytes); | 751 external static _readList(int id, List<int> buffer, int offset, int bytes); |
752 | 752 |
753 int readListSync(List<int> buffer, int offset, int bytes) { | 753 int readListSync(List<int> buffer, int offset, int bytes) { |
754 _checkNotClosed(); | 754 _checkNotClosed(); |
755 if (buffer is !List || offset is !int || bytes is !int) { | 755 if (buffer is !List || offset is !int || bytes is !int) { |
756 throw new FileIOException( | 756 throw new FileIOException( |
757 "Invalid arguments to readList for file '$_name'"); | 757 "Invalid arguments to readList for file '$_path'"); |
758 } | 758 } |
759 if (bytes == 0) return 0; | 759 if (bytes == 0) return 0; |
760 _checkReadWriteListArguments(buffer.length, offset, bytes); | 760 _checkReadWriteListArguments(buffer.length, offset, bytes); |
761 var result = _readList(_id, buffer, offset, bytes); | 761 var result = _readList(_id, buffer, offset, bytes); |
762 if (result is OSError) { | 762 if (result is OSError) { |
763 throw new FileIOException("readList failed for file '$_name'", | 763 throw new FileIOException("readList failed for file '$_path'", |
764 result); | 764 result); |
765 } | 765 } |
766 return result; | 766 return result; |
767 } | 767 } |
768 | 768 |
769 Future<RandomAccessFile> writeByte(int value) { | 769 Future<RandomAccessFile> writeByte(int value) { |
770 _ensureFileService(); | 770 _ensureFileService(); |
771 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 771 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
772 if (value is !int) { | 772 if (value is !int) { |
773 // Complete asynchronously so the user has a chance to setup | 773 // Complete asynchronously so the user has a chance to setup |
774 // handlers without getting exceptions when registering the | 774 // handlers without getting exceptions when registering the |
775 // then handler. | 775 // then handler. |
776 Timer.run(() { | 776 Timer.run(() { |
777 completer.completeError(new FileIOException( | 777 completer.completeError(new FileIOException( |
778 "Invalid argument to writeByte for file '$_name'")); | 778 "Invalid argument to writeByte for file '$_path'")); |
779 }); | 779 }); |
780 return completer.future; | 780 return completer.future; |
781 } | 781 } |
782 if (closed) return _completeWithClosedException(completer); | 782 if (closed) return _completeWithClosedException(completer); |
783 List request = new List(3); | 783 List request = new List(3); |
784 request[0] = _WRITE_BYTE_REQUEST; | 784 request[0] = _WRITE_BYTE_REQUEST; |
785 request[1] = _id; | 785 request[1] = _id; |
786 request[2] = value; | 786 request[2] = value; |
787 return _fileService.call(request).then((response) { | 787 return _fileService.call(request).then((response) { |
788 if (_isErrorResponse(response)) { | 788 if (_isErrorResponse(response)) { |
789 throw _exceptionFromResponse(response, | 789 throw _exceptionFromResponse(response, |
790 "writeByte failed for file '$_name'"); | 790 "writeByte failed for file '$_path'"); |
791 } | 791 } |
792 return this; | 792 return this; |
793 }); | 793 }); |
794 } | 794 } |
795 | 795 |
796 external static _writeByte(int id, int value); | 796 external static _writeByte(int id, int value); |
797 | 797 |
798 int writeByteSync(int value) { | 798 int writeByteSync(int value) { |
799 _checkNotClosed(); | 799 _checkNotClosed(); |
800 if (value is !int) { | 800 if (value is !int) { |
801 throw new FileIOException( | 801 throw new FileIOException( |
802 "Invalid argument to writeByte for file '$_name'"); | 802 "Invalid argument to writeByte for file '$_path'"); |
803 } | 803 } |
804 var result = _writeByte(_id, value); | 804 var result = _writeByte(_id, value); |
805 if (result is OSError) { | 805 if (result is OSError) { |
806 throw new FileIOException("writeByte failed for file '$_name'", | 806 throw new FileIOException("writeByte failed for file '$_path'", |
807 result); | 807 result); |
808 } | 808 } |
809 return result; | 809 return result; |
810 } | 810 } |
811 | 811 |
812 Future<RandomAccessFile> writeList(List<int> buffer, int offset, int bytes) { | 812 Future<RandomAccessFile> writeList(List<int> buffer, int offset, int bytes) { |
813 _ensureFileService(); | 813 _ensureFileService(); |
814 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 814 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
815 if (buffer is !List || offset is !int || bytes is !int) { | 815 if (buffer is !List || offset is !int || bytes is !int) { |
816 // Complete asynchronously so the user has a chance to setup | 816 // Complete asynchronously so the user has a chance to setup |
817 // handlers without getting exceptions when registering the | 817 // handlers without getting exceptions when registering the |
818 // then handler. | 818 // then handler. |
819 Timer.run(() { | 819 Timer.run(() { |
820 completer.completeError(new FileIOException( | 820 completer.completeError(new FileIOException( |
821 "Invalid arguments to writeList for file '$_name'")); | 821 "Invalid arguments to writeList for file '$_path'")); |
822 }); | 822 }); |
823 return completer.future; | 823 return completer.future; |
824 } | 824 } |
825 if (closed) return _completeWithClosedException(completer); | 825 if (closed) return _completeWithClosedException(completer); |
826 | 826 |
827 _BufferAndOffset result; | 827 _BufferAndOffset result; |
828 try { | 828 try { |
829 result = _ensureFastAndSerializableBuffer(buffer, offset, bytes); | 829 result = _ensureFastAndSerializableBuffer(buffer, offset, bytes); |
830 } catch (e) { | 830 } catch (e) { |
831 // Complete asynchronously so the user has a chance to setup | 831 // Complete asynchronously so the user has a chance to setup |
832 // handlers without getting exceptions when registering the | 832 // handlers without getting exceptions when registering the |
833 // then handler. | 833 // then handler. |
834 Timer.run(() => completer.completeError(e)); | 834 Timer.run(() => completer.completeError(e)); |
835 return completer.future; | 835 return completer.future; |
836 } | 836 } |
837 | 837 |
838 List request = new List(5); | 838 List request = new List(5); |
839 request[0] = _WRITE_LIST_REQUEST; | 839 request[0] = _WRITE_LIST_REQUEST; |
840 request[1] = _id; | 840 request[1] = _id; |
841 request[2] = result.buffer; | 841 request[2] = result.buffer; |
842 request[3] = result.offset; | 842 request[3] = result.offset; |
843 request[4] = bytes; | 843 request[4] = bytes; |
844 return _fileService.call(request).then((response) { | 844 return _fileService.call(request).then((response) { |
845 if (_isErrorResponse(response)) { | 845 if (_isErrorResponse(response)) { |
846 throw _exceptionFromResponse(response, | 846 throw _exceptionFromResponse(response, |
847 "writeList failed for file '$_name'"); | 847 "writeList failed for file '$_path'"); |
848 } | 848 } |
849 return this; | 849 return this; |
850 }); | 850 }); |
851 } | 851 } |
852 | 852 |
853 external static _writeList(int id, List<int> buffer, int offset, int bytes); | 853 external static _writeList(int id, List<int> buffer, int offset, int bytes); |
854 | 854 |
855 int writeListSync(List<int> buffer, int offset, int bytes) { | 855 int writeListSync(List<int> buffer, int offset, int bytes) { |
856 _checkNotClosed(); | 856 _checkNotClosed(); |
857 if (buffer is !List || offset is !int || bytes is !int) { | 857 if (buffer is !List || offset is !int || bytes is !int) { |
858 throw new FileIOException( | 858 throw new FileIOException( |
859 "Invalid arguments to writeList for file '$_name'"); | 859 "Invalid arguments to writeList for file '$_path'"); |
860 } | 860 } |
861 if (bytes == 0) return 0; | 861 if (bytes == 0) return 0; |
862 _checkReadWriteListArguments(buffer.length, offset, bytes); | 862 _checkReadWriteListArguments(buffer.length, offset, bytes); |
863 _BufferAndOffset bufferAndOffset = | 863 _BufferAndOffset bufferAndOffset = |
864 _ensureFastAndSerializableBuffer(buffer, offset, bytes); | 864 _ensureFastAndSerializableBuffer(buffer, offset, bytes); |
865 var result = | 865 var result = |
866 _writeList(_id, bufferAndOffset.buffer, bufferAndOffset.offset, bytes); | 866 _writeList(_id, bufferAndOffset.buffer, bufferAndOffset.offset, bytes); |
867 if (result is OSError) { | 867 if (result is OSError) { |
868 throw new FileIOException("writeList failed for file '$_name'", result); | 868 throw new FileIOException("writeList failed for file '$_path'", result); |
869 } | 869 } |
870 return result; | 870 return result; |
871 } | 871 } |
872 | 872 |
873 Future<RandomAccessFile> writeString(String string, | 873 Future<RandomAccessFile> writeString(String string, |
874 [Encoding encoding = Encoding.UTF_8]) { | 874 [Encoding encoding = Encoding.UTF_8]) { |
875 if (encoding is! Encoding) { | 875 if (encoding is! Encoding) { |
876 var completer = new Completer(); | 876 var completer = new Completer(); |
877 Timer.run(() { | 877 Timer.run(() { |
878 completer.completeError(new FileIOException( | 878 completer.completeError(new FileIOException( |
(...skipping 17 matching lines...) Expand all Loading... |
896 Future<int> position() { | 896 Future<int> position() { |
897 _ensureFileService(); | 897 _ensureFileService(); |
898 Completer<int> completer = new Completer<int>(); | 898 Completer<int> completer = new Completer<int>(); |
899 if (closed) return _completeWithClosedException(completer); | 899 if (closed) return _completeWithClosedException(completer); |
900 List request = new List(2); | 900 List request = new List(2); |
901 request[0] = _POSITION_REQUEST; | 901 request[0] = _POSITION_REQUEST; |
902 request[1] = _id; | 902 request[1] = _id; |
903 return _fileService.call(request).then((response) { | 903 return _fileService.call(request).then((response) { |
904 if (_isErrorResponse(response)) { | 904 if (_isErrorResponse(response)) { |
905 throw _exceptionFromResponse(response, | 905 throw _exceptionFromResponse(response, |
906 "position failed for file '$_name'"); | 906 "position failed for file '$_path'"); |
907 } | 907 } |
908 return response; | 908 return response; |
909 }); | 909 }); |
910 } | 910 } |
911 | 911 |
912 external static _position(int id); | 912 external static _position(int id); |
913 | 913 |
914 int positionSync() { | 914 int positionSync() { |
915 _checkNotClosed(); | 915 _checkNotClosed(); |
916 var result = _position(_id); | 916 var result = _position(_id); |
917 if (result is OSError) { | 917 if (result is OSError) { |
918 throw new FileIOException("position failed for file '$_name'", result); | 918 throw new FileIOException("position failed for file '$_path'", result); |
919 } | 919 } |
920 return result; | 920 return result; |
921 } | 921 } |
922 | 922 |
923 Future<RandomAccessFile> setPosition(int position) { | 923 Future<RandomAccessFile> setPosition(int position) { |
924 _ensureFileService(); | 924 _ensureFileService(); |
925 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 925 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
926 if (closed) return _completeWithClosedException(completer); | 926 if (closed) return _completeWithClosedException(completer); |
927 List request = new List(3); | 927 List request = new List(3); |
928 request[0] = _SET_POSITION_REQUEST; | 928 request[0] = _SET_POSITION_REQUEST; |
929 request[1] = _id; | 929 request[1] = _id; |
930 request[2] = position; | 930 request[2] = position; |
931 return _fileService.call(request).then((response) { | 931 return _fileService.call(request).then((response) { |
932 if (_isErrorResponse(response)) { | 932 if (_isErrorResponse(response)) { |
933 throw _exceptionFromResponse(response, | 933 throw _exceptionFromResponse(response, |
934 "setPosition failed for file '$_name'"); | 934 "setPosition failed for file '$_path'"); |
935 } | 935 } |
936 return this; | 936 return this; |
937 }); | 937 }); |
938 } | 938 } |
939 | 939 |
940 external static _setPosition(int id, int position); | 940 external static _setPosition(int id, int position); |
941 | 941 |
942 void setPositionSync(int position) { | 942 void setPositionSync(int position) { |
943 _checkNotClosed(); | 943 _checkNotClosed(); |
944 var result = _setPosition(_id, position); | 944 var result = _setPosition(_id, position); |
945 if (result is OSError) { | 945 if (result is OSError) { |
946 throw new FileIOException("setPosition failed for file '$_name'", result); | 946 throw new FileIOException("setPosition failed for file '$_path'", result); |
947 } | 947 } |
948 } | 948 } |
949 | 949 |
950 Future<RandomAccessFile> truncate(int length) { | 950 Future<RandomAccessFile> truncate(int length) { |
951 _ensureFileService(); | 951 _ensureFileService(); |
952 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 952 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
953 if (closed) return _completeWithClosedException(completer); | 953 if (closed) return _completeWithClosedException(completer); |
954 List request = new List(3); | 954 List request = new List(3); |
955 request[0] = _TRUNCATE_REQUEST; | 955 request[0] = _TRUNCATE_REQUEST; |
956 request[1] = _id; | 956 request[1] = _id; |
957 request[2] = length; | 957 request[2] = length; |
958 return _fileService.call(request).then((response) { | 958 return _fileService.call(request).then((response) { |
959 if (_isErrorResponse(response)) { | 959 if (_isErrorResponse(response)) { |
960 throw _exceptionFromResponse(response, | 960 throw _exceptionFromResponse(response, |
961 "truncate failed for file '$_name'"); | 961 "truncate failed for file '$_path'"); |
962 } | 962 } |
963 return this; | 963 return this; |
964 }); | 964 }); |
965 } | 965 } |
966 | 966 |
967 external static _truncate(int id, int length); | 967 external static _truncate(int id, int length); |
968 | 968 |
969 void truncateSync(int length) { | 969 void truncateSync(int length) { |
970 _checkNotClosed(); | 970 _checkNotClosed(); |
971 var result = _truncate(_id, length); | 971 var result = _truncate(_id, length); |
972 if (result is OSError) { | 972 if (result is OSError) { |
973 throw new FileIOException("truncate failed for file '$_name'", result); | 973 throw new FileIOException("truncate failed for file '$_path'", result); |
974 } | 974 } |
975 } | 975 } |
976 | 976 |
977 Future<int> length() { | 977 Future<int> length() { |
978 _ensureFileService(); | 978 _ensureFileService(); |
979 Completer<int> completer = new Completer<int>(); | 979 Completer<int> completer = new Completer<int>(); |
980 if (closed) return _completeWithClosedException(completer); | 980 if (closed) return _completeWithClosedException(completer); |
981 List request = new List(2); | 981 List request = new List(2); |
982 request[0] = _LENGTH_REQUEST; | 982 request[0] = _LENGTH_REQUEST; |
983 request[1] = _id; | 983 request[1] = _id; |
984 return _fileService.call(request).then((response) { | 984 return _fileService.call(request).then((response) { |
985 if (_isErrorResponse(response)) { | 985 if (_isErrorResponse(response)) { |
986 throw _exceptionFromResponse(response, | 986 throw _exceptionFromResponse(response, |
987 "length failed for file '$_name'"); | 987 "length failed for file '$_path'"); |
988 } | 988 } |
989 return response; | 989 return response; |
990 }); | 990 }); |
991 } | 991 } |
992 | 992 |
993 external static _length(int id); | 993 external static _length(int id); |
994 | 994 |
995 int lengthSync() { | 995 int lengthSync() { |
996 _checkNotClosed(); | 996 _checkNotClosed(); |
997 var result = _length(_id); | 997 var result = _length(_id); |
998 if (result is OSError) { | 998 if (result is OSError) { |
999 throw new FileIOException("length failed for file '$_name'", result); | 999 throw new FileIOException("length failed for file '$_path'", result); |
1000 } | 1000 } |
1001 return result; | 1001 return result; |
1002 } | 1002 } |
1003 | 1003 |
1004 Future<RandomAccessFile> flush() { | 1004 Future<RandomAccessFile> flush() { |
1005 _ensureFileService(); | 1005 _ensureFileService(); |
1006 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); | 1006 Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>(); |
1007 if (closed) return _completeWithClosedException(completer); | 1007 if (closed) return _completeWithClosedException(completer); |
1008 List request = new List(2); | 1008 List request = new List(2); |
1009 request[0] = _FLUSH_REQUEST; | 1009 request[0] = _FLUSH_REQUEST; |
1010 request[1] = _id; | 1010 request[1] = _id; |
1011 return _fileService.call(request).then((response) { | 1011 return _fileService.call(request).then((response) { |
1012 if (_isErrorResponse(response)) { | 1012 if (_isErrorResponse(response)) { |
1013 throw _exceptionFromResponse(response, | 1013 throw _exceptionFromResponse(response, |
1014 "flush failed for file '$_name'"); | 1014 "flush failed for file '$_path'"); |
1015 } | 1015 } |
1016 return this; | 1016 return this; |
1017 }); | 1017 }); |
1018 } | 1018 } |
1019 | 1019 |
1020 external static _flush(int id); | 1020 external static _flush(int id); |
1021 | 1021 |
1022 void flushSync() { | 1022 void flushSync() { |
1023 _checkNotClosed(); | 1023 _checkNotClosed(); |
1024 var result = _flush(_id); | 1024 var result = _flush(_id); |
1025 if (result is OSError) { | 1025 if (result is OSError) { |
1026 throw new FileIOException("flush failed for file '$_name'", result); | 1026 throw new FileIOException("flush failed for file '$_path'", result); |
1027 } | 1027 } |
1028 } | 1028 } |
1029 | 1029 |
1030 String get name => _name; | 1030 String get path => _path; |
1031 | 1031 |
1032 void _ensureFileService() { | 1032 void _ensureFileService() { |
1033 if (_fileService == null) { | 1033 if (_fileService == null) { |
1034 _fileService = _FileUtils._newServicePort(); | 1034 _fileService = _FileUtils._newServicePort(); |
1035 } | 1035 } |
1036 } | 1036 } |
1037 | 1037 |
1038 bool get closed => _id == 0; | 1038 bool get closed => _id == 0; |
1039 | 1039 |
1040 void _checkNotClosed() { | 1040 void _checkNotClosed() { |
1041 if (closed) { | 1041 if (closed) { |
1042 throw new FileIOException("File closed '$_name'"); | 1042 throw new FileIOException("File closed '$_path'"); |
1043 } | 1043 } |
1044 } | 1044 } |
1045 | 1045 |
1046 Future _completeWithClosedException(Completer completer) { | 1046 Future _completeWithClosedException(Completer completer) { |
1047 Timer.run(() { | 1047 Timer.run(() { |
1048 completer.completeError( | 1048 completer.completeError( |
1049 new FileIOException("File closed '$_name'")); | 1049 new FileIOException("File closed '$_path'")); |
1050 }); | 1050 }); |
1051 return completer.future; | 1051 return completer.future; |
1052 } | 1052 } |
1053 | 1053 |
1054 final String _name; | 1054 final String _path; |
1055 int _id; | 1055 int _id; |
1056 | 1056 |
1057 SendPort _fileService; | 1057 SendPort _fileService; |
1058 } | 1058 } |
OLD | NEW |