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 class _FileInputStream extends _BaseDataInputStream implements InputStream { | 5 class _FileInputStream extends _BaseDataInputStream implements InputStream { |
6 _FileInputStream(String name) { | 6 _FileInputStream(String name) { |
7 _file = new File(name); | 7 _file = new File(name); |
8 _data = []; | 8 _data = []; |
9 _position = 0; | 9 _position = 0; |
10 _file.errorHandler = (String s) { | 10 _file.onError = (String s) { |
11 if (_clientErrorHandler != null) { | 11 if (_clientErrorHandler != null) { |
12 _clientErrorHandler(); | 12 _clientErrorHandler(); |
13 } | 13 } |
14 }; | 14 }; |
15 _file.open(); | 15 _file.open(FileMode.READ, (openedFile) { |
16 _file.openHandler = (openedFile) { | |
17 _readDataFromFile(openedFile); | 16 _readDataFromFile(openedFile); |
18 }; | 17 }); |
19 } | 18 } |
20 | 19 |
21 _FileInputStream.fromStdio(int fd) { | 20 _FileInputStream.fromStdio(int fd) { |
22 assert(fd == 0); | 21 assert(fd == 0); |
23 _file = _File._openStdioSync(fd); | 22 _file = _File._openStdioSync(fd); |
24 _data = []; | 23 _data = []; |
25 _position = 0; | 24 _position = 0; |
26 _readDataFromFile(_file); | 25 _readDataFromFile(_file); |
27 } | 26 } |
28 | 27 |
29 void _readDataFromFile(RandomAccessFile openedFile) { | 28 void _readDataFromFile(RandomAccessFile openedFile) { |
30 openedFile.errorHandler = (String s) { | 29 openedFile.onError = (String s) { |
31 if (_clientErrorHandler != null) { | 30 if (_clientErrorHandler != null) { |
32 _clientErrorHandler(); | 31 _clientErrorHandler(); |
33 } | 32 } |
34 }; | 33 }; |
35 openedFile.length(); | 34 openedFile.length((length) { |
36 openedFile.lengthHandler = (length) { | |
37 var contents = new ByteArray(length); | 35 var contents = new ByteArray(length); |
38 if (length != 0) { | 36 if (length != 0) { |
39 openedFile.readList(contents, 0, length); | 37 openedFile.readList(contents, 0, length, (read) { |
40 openedFile.readListHandler = (read) { | |
41 if (read != length) { | 38 if (read != length) { |
42 if (_clientErrorHandler != null) { | 39 if (_clientErrorHandler != null) { |
43 _clientErrorHandler(); | 40 _clientErrorHandler(); |
44 } | 41 } |
45 _streamMarkedClosed = true; | 42 _streamMarkedClosed = true; |
46 _checkScheduleCallbacks(); | 43 _checkScheduleCallbacks(); |
47 } else { | 44 } else { |
48 _data = contents; | 45 _data = contents; |
49 _streamMarkedClosed = true; | 46 _streamMarkedClosed = true; |
50 _checkScheduleCallbacks(); | 47 _checkScheduleCallbacks(); |
51 } | 48 } |
52 openedFile.close(); | 49 openedFile.close(() => null); |
53 }; | 50 }); |
54 } else { | 51 } else { |
55 _streamMarkedClosed = true; | 52 _streamMarkedClosed = true; |
56 _checkScheduleCallbacks(); | 53 _checkScheduleCallbacks(); |
57 openedFile.close(); | 54 openedFile.close(() => null); |
58 } | 55 } |
59 }; | 56 }); |
60 } | 57 } |
61 | 58 |
62 int available() { | 59 int available() { |
63 return _closed ? 0 : _data.length - _position; | 60 return _closed ? 0 : _data.length - _position; |
64 } | 61 } |
65 | 62 |
66 void pipe(OutputStream output, [bool close = true]) { | 63 void pipe(OutputStream output, [bool close = true]) { |
67 _pipe(this, output, close: close); | 64 _pipe(this, output, close: close); |
68 } | 65 } |
69 | 66 |
(...skipping 21 matching lines...) Expand all Loading... |
91 List<int> _data; | 88 List<int> _data; |
92 int _position; | 89 int _position; |
93 bool _closed = false; | 90 bool _closed = false; |
94 } | 91 } |
95 | 92 |
96 | 93 |
97 class _FileOutputStream implements OutputStream { | 94 class _FileOutputStream implements OutputStream { |
98 _FileOutputStream(String name, FileMode mode) { | 95 _FileOutputStream(String name, FileMode mode) { |
99 _pendingOperations = new List<List<int>>(); | 96 _pendingOperations = new List<List<int>>(); |
100 var f = new File(name); | 97 var f = new File(name); |
101 f.open(mode); | 98 f.open(mode, (openedFile) { |
102 f.openHandler = (openedFile) { | |
103 _file = openedFile; | 99 _file = openedFile; |
104 _setupFileHandlers(); | 100 _setupFileHandlers(); |
105 _processPendingOperations(); | 101 _processPendingOperations(); |
106 }; | 102 }); |
107 f.errorHandler = (e) { | 103 f.onError = (e) { |
108 if (_errorHandler != null) _errorHandler(); | 104 if (_onError != null) _onError(); |
109 }; | 105 }; |
110 } | 106 } |
111 | 107 |
112 _FileOutputStream.fromStdio(int fd) { | 108 _FileOutputStream.fromStdio(int fd) { |
113 assert(1 <= fd && fd <= 2); | 109 assert(1 <= fd && fd <= 2); |
114 _file = _File._openStdioSync(fd); | 110 _file = _File._openStdioSync(fd); |
115 _setupFileHandlers(); | 111 _setupFileHandlers(); |
116 } | 112 } |
117 | 113 |
118 | 114 |
119 void _setupFileHandlers() { | 115 void _setupFileHandlers() { |
120 _file.errorHandler = (e) { | 116 _file.onError = (e) { |
121 if (_errorHandler != null) _errorHandler(); | 117 if (_onError != null) _onError(); |
122 }; | 118 }; |
123 _file.noPendingWriteHandler = () { | 119 _file.onNoPendingWrites = () { |
124 if (!_streamMarkedClosed && _noPendingWriteHandler != null) { | 120 if (!_streamMarkedClosed && _onNoPendingWrites != null) { |
125 _noPendingWriteHandler(); | 121 _onNoPendingWrites(); |
126 } | 122 } |
127 }; | 123 }; |
128 _file.closeHandler = () { | |
129 if (_closeHandler != null) _closeHandler(); | |
130 }; | |
131 } | 124 } |
132 | 125 |
133 bool write(List<int> buffer, [bool copyBuffer = false]) { | 126 bool write(List<int> buffer, [bool copyBuffer = false]) { |
134 var data = buffer; | 127 var data = buffer; |
135 if (copyBuffer) { | 128 if (copyBuffer) { |
136 var length = buffer.length; | 129 var length = buffer.length; |
137 data = new ByteArray(length); | 130 data = new ByteArray(length); |
138 data.setRange(0, length, buffer, 0); | 131 data.setRange(0, length, buffer, 0); |
139 } | 132 } |
140 if (_file == null) { | 133 if (_file == null) { |
(...skipping 13 matching lines...) Expand all Loading... |
154 } | 147 } |
155 var copy = new ByteArray(length); | 148 var copy = new ByteArray(length); |
156 copy.setRange(0, length, buffer, offset); | 149 copy.setRange(0, length, buffer, offset); |
157 return write(copy); | 150 return write(copy); |
158 } | 151 } |
159 | 152 |
160 void close() { | 153 void close() { |
161 if (_file == null) { | 154 if (_file == null) { |
162 _pendingOperations.add(null); | 155 _pendingOperations.add(null); |
163 } else if (!_streamMarkedClosed) { | 156 } else if (!_streamMarkedClosed) { |
164 _file.close(); | 157 _file.close(() { |
| 158 if (_onClosed != null) _onClosed(); |
| 159 }); |
165 _streamMarkedClosed = true; | 160 _streamMarkedClosed = true; |
166 } | 161 } |
167 } | 162 } |
168 | 163 |
169 void set noPendingWriteHandler(void callback()) { | 164 void set onNoPendingWrites(void callback()) { |
170 _noPendingWriteHandler = callback; | 165 _onNoPendingWrites = callback; |
171 } | 166 } |
172 | 167 |
173 void set closeHandler(void callback()) { | 168 void set onClosed(void callback()) { |
174 _closeHandler = callback; | 169 _onClosed = callback; |
175 } | 170 } |
176 | 171 |
177 void set errorHandler(void callback()) { | 172 void set onError(void callback()) { |
178 _errorHandler = callback; | 173 _onError = callback; |
179 } | 174 } |
180 | 175 |
181 void _processPendingOperations() { | 176 void _processPendingOperations() { |
182 _pendingOperations.forEach((buffer) { | 177 _pendingOperations.forEach((buffer) { |
183 (buffer != null) ? write(buffer) : close(); | 178 (buffer != null) ? write(buffer) : close(); |
184 }); | 179 }); |
185 _pendingOperations = null; | 180 _pendingOperations = null; |
186 } | 181 } |
187 | 182 |
188 void _write(List<int> buffer, int offset, int len) { | 183 void _write(List<int> buffer, int offset, int len) { |
189 _file.writeList(buffer, offset, len); | 184 _file.writeList(buffer, offset, len); |
190 } | 185 } |
191 | 186 |
192 RandomAccessFile _file; | 187 RandomAccessFile _file; |
193 | 188 |
194 // When this is set to true the stream is marked closed. When a | 189 // When this is set to true the stream is marked closed. When a |
195 // stream is marked closed no more data can be written. | 190 // stream is marked closed no more data can be written. |
196 bool _streamMarkedClosed = false; | 191 bool _streamMarkedClosed = false; |
197 | 192 |
198 // When this is set to true the close callback has been called and | 193 // When this is set to true the close callback has been called and |
199 // the stream is fully closed. | 194 // the stream is fully closed. |
200 bool _closeCallbackCalled = false; | 195 bool _closeCallbackCalled = false; |
201 | 196 |
202 // List of pending writes that were issued before the underlying | 197 // List of pending writes that were issued before the underlying |
203 // file was successfully opened. | 198 // file was successfully opened. |
204 List<List<int>> _pendingOperations; | 199 List<List<int>> _pendingOperations; |
205 | 200 |
206 Function _noPendingWriteHandler; | 201 Function _onNoPendingWrites; |
207 Function _closeHandler; | 202 Function _onClosed; |
208 Function _errorHandler; | 203 Function _onError; |
209 } | 204 } |
210 | 205 |
211 | 206 |
212 // Helper class containing static file helper methods. | 207 // Helper class containing static file helper methods. |
213 class _FileUtils { | 208 class _FileUtils { |
214 static final kExistsRequest = 0; | 209 static final kExistsRequest = 0; |
215 static final kCreateRequest = 1; | 210 static final kCreateRequest = 1; |
216 static final kDeleteRequest = 2; | 211 static final kDeleteRequest = 2; |
217 static final kOpenRequest = 3; | 212 static final kOpenRequest = 3; |
218 static final kFullPathRequest = 4; | 213 static final kFullPathRequest = 4; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 return writeString(id, string); | 311 return writeString(id, string); |
317 } | 312 } |
318 } | 313 } |
319 | 314 |
320 | 315 |
321 // Class for encapsulating the native implementation of files. | 316 // Class for encapsulating the native implementation of files. |
322 class _File implements File { | 317 class _File implements File { |
323 // Constructor for file. | 318 // Constructor for file. |
324 _File(String this._name) : _asyncUsed = false; | 319 _File(String this._name) : _asyncUsed = false; |
325 | 320 |
326 void exists() { | 321 void exists(void callback(bool exists)) { |
327 _ensureFileService(); | 322 _ensureFileService(); |
328 _asyncUsed = true; | 323 _asyncUsed = true; |
329 if (_name is !String) { | 324 if (_name is !String) { |
330 if (_errorHandler != null) { | 325 if (_onError != null) { |
331 _errorHandler('File name is not a string: $_name'); | 326 _onError('File name is not a string: $_name'); |
332 } | 327 } |
333 return; | 328 return; |
334 } | 329 } |
335 List request = new List(2); | 330 List request = new List(2); |
336 request[0] = _FileUtils.kExistsRequest; | 331 request[0] = _FileUtils.kExistsRequest; |
337 request[1] = _name; | 332 request[1] = _name; |
338 _fileService.call(request).receive((exists, replyTo) { | 333 _fileService.call(request).receive((exists, replyTo) { |
339 if (_existsHandler != null) _existsHandler(exists); | 334 callback(exists); |
340 }); | 335 }); |
341 } | 336 } |
342 | 337 |
343 bool existsSync() { | 338 bool existsSync() { |
344 if (_asyncUsed) { | 339 if (_asyncUsed) { |
345 throw new FileIOException( | 340 throw new FileIOException( |
346 "Mixed use of synchronous and asynchronous API"); | 341 "Mixed use of synchronous and asynchronous API"); |
347 } | 342 } |
348 if (_name is !String) { | 343 if (_name is !String) { |
349 throw new FileIOException('File name is not a string: $_name'); | 344 throw new FileIOException('File name is not a string: $_name'); |
350 } | 345 } |
351 return _FileUtils.exists(_name); | 346 return _FileUtils.exists(_name); |
352 } | 347 } |
353 | 348 |
354 void create() { | 349 void create(void callback()) { |
355 _ensureFileService(); | 350 _ensureFileService(); |
356 _asyncUsed = true; | 351 _asyncUsed = true; |
357 List request = new List(2); | 352 List request = new List(2); |
358 request[0] = _FileUtils.kCreateRequest; | 353 request[0] = _FileUtils.kCreateRequest; |
359 request[1] = _name; | 354 request[1] = _name; |
360 _fileService.call(request).receive((created, replyTo) { | 355 _fileService.call(request).receive((created, replyTo) { |
361 if (created) { | 356 if (created) { |
362 if (_createHandler != null) _createHandler(); | 357 callback(); |
363 } else if (_errorHandler != null) { | 358 } else if (_onError != null) { |
364 _errorHandler("Cannot create file: $_name"); | 359 _onError("Cannot create file: $_name"); |
365 } | 360 } |
366 }); | 361 }); |
367 } | 362 } |
368 | 363 |
369 void createSync() { | 364 void createSync() { |
370 if (_asyncUsed) { | 365 if (_asyncUsed) { |
371 throw new FileIOException( | 366 throw new FileIOException( |
372 "Mixed use of synchronous and asynchronous API"); | 367 "Mixed use of synchronous and asynchronous API"); |
373 } | 368 } |
374 bool created = _FileUtils.checkedCreate(_name); | 369 bool created = _FileUtils.checkedCreate(_name); |
375 if (!created) { | 370 if (!created) { |
376 throw new FileIOException("Cannot create file: $_name"); | 371 throw new FileIOException("Cannot create file: $_name"); |
377 } | 372 } |
378 } | 373 } |
379 | 374 |
380 void delete() { | 375 void delete(void callback()) { |
381 _ensureFileService(); | 376 _ensureFileService(); |
382 _asyncUsed = true; | 377 _asyncUsed = true; |
383 List request = new List(2); | 378 List request = new List(2); |
384 request[0] = _FileUtils.kDeleteRequest; | 379 request[0] = _FileUtils.kDeleteRequest; |
385 request[1] = _name; | 380 request[1] = _name; |
386 _fileService.call(request).receive((deleted, replyTo) { | 381 _fileService.call(request).receive((deleted, replyTo) { |
387 if (deleted) { | 382 if (deleted) { |
388 if (_deleteHandler != null) _deleteHandler(); | 383 callback(); |
389 } else if (_errorHandler != null) { | 384 } else if (_onError != null) { |
390 _errorHandler("Cannot delete file: $_name"); | 385 _onError("Cannot delete file: $_name"); |
391 } | 386 } |
392 }); | 387 }); |
393 } | 388 } |
394 | 389 |
395 void deleteSync() { | 390 void deleteSync() { |
396 if (_asyncUsed) { | 391 if (_asyncUsed) { |
397 throw new FileIOException( | 392 throw new FileIOException( |
398 "Mixed use of synchronous and asynchronous API"); | 393 "Mixed use of synchronous and asynchronous API"); |
399 } | 394 } |
400 bool deleted = _FileUtils.checkedDelete(_name); | 395 bool deleted = _FileUtils.checkedDelete(_name); |
401 if (!deleted) { | 396 if (!deleted) { |
402 throw new FileIOException("Cannot delete file: $_name"); | 397 throw new FileIOException("Cannot delete file: $_name"); |
403 } | 398 } |
404 } | 399 } |
405 | 400 |
406 void directory() { | 401 void directory(void callback(Directory dir)) { |
407 _ensureFileService(); | 402 _ensureFileService(); |
408 _asyncUsed = true; | 403 _asyncUsed = true; |
409 List request = new List(2); | 404 List request = new List(2); |
410 request[0] = _FileUtils.kDirectoryRequest; | 405 request[0] = _FileUtils.kDirectoryRequest; |
411 request[1] = _name; | 406 request[1] = _name; |
412 _fileService.call(request).receive((path, replyTo) { | 407 _fileService.call(request).receive((path, replyTo) { |
413 if (path != null) { | 408 if (path != null) { |
414 if (_directoryHandler != null) _directoryHandler(new Directory(path)); | 409 callback(new Directory(path)); |
415 } else if (_errorHandler != null) { | 410 } else if (_onError != null) { |
416 _errorHandler("Cannot get directory for: ${_name}"); | 411 _onError("Cannot get directory for: ${_name}"); |
417 } | 412 } |
418 }); | 413 }); |
419 } | 414 } |
420 | 415 |
421 Directory directorySync() { | 416 Directory directorySync() { |
422 if (_asyncUsed) { | 417 if (_asyncUsed) { |
423 throw new FileIOException( | 418 throw new FileIOException( |
424 "Mixed use of synchronous and asynchronous API"); | 419 "Mixed use of synchronous and asynchronous API"); |
425 } | 420 } |
426 if (!existsSync()) { | 421 if (!existsSync()) { |
427 throw new FileIOException("Cannot get directory for: $_name"); | 422 throw new FileIOException("Cannot get directory for: $_name"); |
428 } | 423 } |
429 return new Directory(_FileUtils.directory(_name)); | 424 return new Directory(_FileUtils.directory(_name)); |
430 } | 425 } |
431 | 426 |
432 void open([FileMode mode = FileMode.READ]) { | 427 void open(FileMode mode, void callback(RandomAccessFile file)) { |
433 _ensureFileService(); | 428 _ensureFileService(); |
434 _asyncUsed = true; | 429 _asyncUsed = true; |
435 if (mode != FileMode.READ && | 430 if (mode != FileMode.READ && |
436 mode != FileMode.WRITE && | 431 mode != FileMode.WRITE && |
437 mode != FileMode.APPEND) { | 432 mode != FileMode.APPEND) { |
438 if (_errorHandler != null) { | 433 if (_onError != null) { |
439 _errorHandler("Unknown file mode. Use FileMode.READ, FileMode.WRITE " + | 434 _onError("Unknown file mode. Use FileMode.READ, FileMode.WRITE " + |
440 "or FileMode.APPEND."); | 435 "or FileMode.APPEND."); |
441 return; | 436 return; |
442 } | 437 } |
443 } | 438 } |
444 List request = new List(3); | 439 List request = new List(3); |
445 request[0] = _FileUtils.kOpenRequest; | 440 request[0] = _FileUtils.kOpenRequest; |
446 request[1] = _name; | 441 request[1] = _name; |
447 request[2] = mode._mode; // Direct int value for serialization. | 442 request[2] = mode._mode; // Direct int value for serialization. |
448 _fileService.call(request).receive((id, replyTo) { | 443 _fileService.call(request).receive((id, replyTo) { |
449 var handler = _openHandler; | |
450 if (handler === null) { | |
451 // If no open handler is present, close the file immediately to | |
452 // avoid leaking an open file descriptor. | |
453 handler = (file) => file.close(); | |
454 } | |
455 if (id != 0) { | 444 if (id != 0) { |
456 var randomAccessFile = new _RandomAccessFile(id, _name); | 445 callback(new _RandomAccessFile(id, _name)); |
457 handler(randomAccessFile); | 446 } else if (_onError != null) { |
458 } else if (_errorHandler != null) { | 447 _onError("Cannot open file: $_name"); |
459 _errorHandler("Cannot open file: $_name"); | |
460 } | 448 } |
461 }); | 449 }); |
462 } | 450 } |
463 | 451 |
464 RandomAccessFile openSync([FileMode mode = FileMode.READ]) { | 452 RandomAccessFile openSync([FileMode mode = FileMode.READ]) { |
465 if (_asyncUsed) { | 453 if (_asyncUsed) { |
466 throw new FileIOException( | 454 throw new FileIOException( |
467 "Mixed use of synchronous and asynchronous API"); | 455 "Mixed use of synchronous and asynchronous API"); |
468 } | 456 } |
469 if (mode != FileMode.READ && | 457 if (mode != FileMode.READ && |
(...skipping 10 matching lines...) Expand all Loading... |
480 } | 468 } |
481 | 469 |
482 static RandomAccessFile _openStdioSync(int fd) { | 470 static RandomAccessFile _openStdioSync(int fd) { |
483 var id = _FileUtils.openStdio(fd); | 471 var id = _FileUtils.openStdio(fd); |
484 if (id == 0) { | 472 if (id == 0) { |
485 throw new FileIOException("Cannot open stdio file for: $fd"); | 473 throw new FileIOException("Cannot open stdio file for: $fd"); |
486 } | 474 } |
487 return new _RandomAccessFile(id, ""); | 475 return new _RandomAccessFile(id, ""); |
488 } | 476 } |
489 | 477 |
490 void fullPath() { | 478 void fullPath(void callback(String result)) { |
491 _ensureFileService(); | 479 _ensureFileService(); |
492 _asyncUsed = true; | 480 _asyncUsed = true; |
493 List request = new List(2); | 481 List request = new List(2); |
494 request[0] = _FileUtils.kFullPathRequest; | 482 request[0] = _FileUtils.kFullPathRequest; |
495 request[1] = _name; | 483 request[1] = _name; |
496 _fileService.call(request).receive((result, replyTo) { | 484 _fileService.call(request).receive((result, replyTo) { |
497 if (result != null) { | 485 if (result != null) { |
498 if (_fullPathHandler != null) _fullPathHandler(result); | 486 callback(result); |
499 } else if (_errorHandler != null) { | 487 } else if (_onError != null) { |
500 _errorHandler("fullPath failed"); | 488 _onError("fullPath failed"); |
501 } | 489 } |
502 }); | 490 }); |
503 } | 491 } |
504 | 492 |
505 String fullPathSync() { | 493 String fullPathSync() { |
506 if (_asyncUsed) { | 494 if (_asyncUsed) { |
507 throw new FileIOException( | 495 throw new FileIOException( |
508 "Mixed use of synchronous and asynchronous API"); | 496 "Mixed use of synchronous and asynchronous API"); |
509 } | 497 } |
510 String result = _FileUtils.checkedFullPath(_name); | 498 String result = _FileUtils.checkedFullPath(_name); |
511 if (result == null) { | 499 if (result == null) { |
512 throw new FileIOException("fullPath failed"); | 500 throw new FileIOException("fullPath failed"); |
513 } | 501 } |
514 return result; | 502 return result; |
515 } | 503 } |
516 | 504 |
517 InputStream openInputStream() { | 505 InputStream openInputStream() { |
518 return new _FileInputStream(_name); | 506 return new _FileInputStream(_name); |
519 } | 507 } |
520 | 508 |
521 OutputStream openOutputStream([FileMode mode = FileMode.WRITE]) { | 509 OutputStream openOutputStream([FileMode mode = FileMode.WRITE]) { |
522 if (mode != FileMode.WRITE && | 510 if (mode != FileMode.WRITE && |
523 mode != FileMode.APPEND) { | 511 mode != FileMode.APPEND) { |
524 throw new FileIOException( | 512 throw new FileIOException( |
525 "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND"); | 513 "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND"); |
526 } | 514 } |
527 return new _FileOutputStream(_name, mode); | 515 return new _FileOutputStream(_name, mode); |
528 } | 516 } |
529 | 517 |
530 void readAsBytes() { | 518 void readAsBytes(void callback(List<int> bytes)) { |
531 _asyncUsed = true; | 519 _asyncUsed = true; |
532 var chunks = new _BufferList(); | 520 var chunks = new _BufferList(); |
533 var stream = openInputStream(); | 521 var stream = openInputStream(); |
534 stream.closeHandler = () { | 522 stream.onClosed = () { |
535 if (_readAsBytesHandler != null) { | 523 callback(chunks.readBytes(chunks.length)); |
536 _readAsBytesHandler(chunks.readBytes(chunks.length)); | |
537 } | |
538 }; | 524 }; |
539 stream.dataHandler = () { | 525 stream.onData = () { |
540 var chunk = stream.read(); | 526 var chunk = stream.read(); |
541 chunks.add(chunk); | 527 chunks.add(chunk); |
542 }; | 528 }; |
543 stream.errorHandler = () { | 529 stream.onError = () { |
544 if (_errorHandler != null) { | 530 if (_onError != null) { |
545 _errorHandler("Failed to read file as bytes: $_name"); | 531 _onError("Failed to read file as bytes: $_name"); |
546 } | 532 } |
547 }; | 533 }; |
548 } | 534 } |
549 | 535 |
550 List<int> readAsBytesSync() { | 536 List<int> readAsBytesSync() { |
551 if (_asyncUsed) { | 537 if (_asyncUsed) { |
552 throw new FileIOException( | 538 throw new FileIOException( |
553 "Mixed use of synchronous and asynchronous API"); | 539 "Mixed use of synchronous and asynchronous API"); |
554 } | 540 } |
555 var opened = openSync(); | 541 var opened = openSync(); |
556 var length = opened.lengthSync(); | 542 var length = opened.lengthSync(); |
557 var result = new ByteArray(length); | 543 var result = new ByteArray(length); |
558 var read = opened.readListSync(result, 0, length); | 544 var read = opened.readListSync(result, 0, length); |
559 if (read != length) { | 545 if (read != length) { |
560 throw new FileIOException("Failed reading file as bytes: $_name"); | 546 throw new FileIOException("Failed reading file as bytes: $_name"); |
561 } | 547 } |
562 opened.close(); | 548 opened.closeSync(); |
563 return result; | 549 return result; |
564 } | 550 } |
565 | 551 |
566 _StringDecoder _getDecoder(encoding) { | 552 _StringDecoder _getDecoder(encoding) { |
567 if (encoding == "UTF-8") { | 553 if (encoding == "UTF-8") { |
568 return new _UTF8Decoder(); | 554 return new _UTF8Decoder(); |
569 } else if (encoding == "ISO-8859-1") { | 555 } else if (encoding == "ISO-8859-1") { |
570 return new _Latin1Decoder(); | 556 return new _Latin1Decoder(); |
571 } else if (encoding == "ASCII") { | 557 } else if (encoding == "ASCII") { |
572 return new _AsciiDecoder(); | 558 return new _AsciiDecoder(); |
573 } | 559 } |
574 throw new FileIOException("Unsupported encoding $_encoding"); | 560 throw new FileIOException("Unsupported encoding $_encoding"); |
575 } | 561 } |
576 | 562 |
577 void readAsText([String encoding = "UTF-8"]) { | 563 void readAsText(String encoding, void callback(String text)) { |
578 _asyncUsed = true; | 564 _asyncUsed = true; |
579 var decoder = _getDecoder(encoding); | 565 var decoder = _getDecoder(encoding); |
580 readAsBytes(); | 566 readAsBytes((bytes) { |
581 readAsBytesHandler = (bytes) { | 567 try { |
582 if (_readAsTextHandler != null) { | 568 decoder.write(bytes); |
583 try { | 569 } catch (var e) { |
584 decoder.write(bytes); | 570 if (_onError != null) { |
585 } catch (var e) { | 571 _onError(e.toString()); |
586 if (_errorHandler != null) { | 572 return; |
587 _errorHandler(e.toString()); | |
588 return; | |
589 } | |
590 } | 573 } |
591 _readAsTextHandler(decoder.decoded); | |
592 } | 574 } |
593 }; | 575 callback(decoder.decoded); |
| 576 }); |
594 } | 577 } |
595 | 578 |
596 String readAsTextSync([String encoding = "UTF-8"]) { | 579 String readAsTextSync([String encoding = 'UTF-8']) { |
597 if (_asyncUsed) { | 580 if (_asyncUsed) { |
598 throw new FileIOException( | 581 throw new FileIOException( |
599 "Mixed use of synchronous and asynchronous API"); | 582 "Mixed use of synchronous and asynchronous API"); |
600 } | 583 } |
601 var decoder = _getDecoder(encoding); | 584 var decoder = _getDecoder(encoding); |
602 List<int> bytes = readAsBytesSync(); | 585 List<int> bytes = readAsBytesSync(); |
603 decoder.write(bytes); | 586 decoder.write(bytes); |
604 return decoder.decoded; | 587 return decoder.decoded; |
605 } | 588 } |
606 | 589 |
607 List<String> _getDecodedLines(_StringDecoder decoder) { | 590 List<String> _getDecodedLines(_StringDecoder decoder) { |
608 List<String> result = []; | 591 List<String> result = []; |
609 var line = decoder.decodedLine; | 592 var line = decoder.decodedLine; |
610 while (line != null) { | 593 while (line != null) { |
611 result.add(line); | 594 result.add(line); |
612 line = decoder.decodedLine; | 595 line = decoder.decodedLine; |
613 } | 596 } |
614 // If there is more data with no terminating line break we treat | 597 // If there is more data with no terminating line break we treat |
615 // it as the last line. | 598 // it as the last line. |
616 var data = decoder.decoded; | 599 var data = decoder.decoded; |
617 if (data != null) { | 600 if (data != null) { |
618 result.add(data); | 601 result.add(data); |
619 } | 602 } |
620 return result; | 603 return result; |
621 } | 604 } |
622 | 605 |
623 void readAsLines([String encoding = "UTF-8"]) { | 606 void readAsLines(String encoding, void callback(List<String> lines)) { |
624 _asyncUsed = true; | 607 _asyncUsed = true; |
625 var decoder = _getDecoder(encoding); | 608 var decoder = _getDecoder(encoding); |
626 readAsBytes(); | 609 readAsBytes((bytes) { |
627 readAsBytesHandler = (bytes) { | 610 try { |
628 if (_readAsLinesHandler != null) { | 611 decoder.write(bytes); |
629 try { | 612 } catch (var e) { |
630 decoder.write(bytes); | 613 if (_onError != null) { |
631 } catch (var e) { | 614 _onError(e.toString()); |
632 if (_errorHandler != null) { | 615 return; |
633 _errorHandler(e.toString()); | |
634 return; | |
635 } | |
636 } | 616 } |
637 _readAsLinesHandler(_getDecodedLines(decoder)); | |
638 } | 617 } |
639 }; | 618 callback(_getDecodedLines(decoder)); |
| 619 }); |
640 } | 620 } |
641 | 621 |
642 List<String> readAsLinesSync([String encoding = "UTF-8"]) { | 622 List<String> readAsLinesSync([String encoding = "UTF-8"]) { |
643 if (_asyncUsed) { | 623 if (_asyncUsed) { |
644 throw new FileIOException( | 624 throw new FileIOException( |
645 "Mixed use of synchronous and asynchronous API"); | 625 "Mixed use of synchronous and asynchronous API"); |
646 } | 626 } |
647 var decoder = _getDecoder(encoding); | 627 var decoder = _getDecoder(encoding); |
648 List<int> bytes = readAsBytesSync(); | 628 List<int> bytes = readAsBytesSync(); |
649 decoder.write(bytes); | 629 decoder.write(bytes); |
650 return _getDecodedLines(decoder); | 630 return _getDecodedLines(decoder); |
651 } | 631 } |
652 | 632 |
653 String get name() => _name; | 633 String get name() => _name; |
654 | 634 |
655 void set existsHandler(void handler(bool exists)) { | 635 void set onError(void handler(String error)) { |
656 _existsHandler = handler; | 636 _onError = handler; |
657 } | |
658 | |
659 void set createHandler(void handler()) { | |
660 _createHandler = handler; | |
661 } | |
662 | |
663 void set deleteHandler(void handler()) { | |
664 _deleteHandler = handler; | |
665 } | |
666 | |
667 void set directoryHandler(void handler(Directory directory)) { | |
668 _directoryHandler = handler; | |
669 } | |
670 | |
671 void set openHandler(void handler(RandomAccessFile file)) { | |
672 _openHandler = handler; | |
673 } | |
674 | |
675 void set readAsBytesHandler(void handler(List<int> bytes)) { | |
676 _readAsBytesHandler = handler; | |
677 } | |
678 | |
679 void set readAsTextHandler(void handler(String text)) { | |
680 _readAsTextHandler = handler; | |
681 } | |
682 | |
683 void set readAsLinesHandler(void handler(List<String> lines)) { | |
684 _readAsLinesHandler = handler; | |
685 } | |
686 | |
687 void set fullPathHandler(void handler(String)) { | |
688 _fullPathHandler = handler; | |
689 } | |
690 | |
691 void set errorHandler(void handler(String error)) { | |
692 _errorHandler = handler; | |
693 } | 637 } |
694 | 638 |
695 void _ensureFileService() { | 639 void _ensureFileService() { |
696 if (_fileService == null) { | 640 if (_fileService == null) { |
697 _fileService = _FileUtils.newServicePort(); | 641 _fileService = _FileUtils.newServicePort(); |
698 } | 642 } |
699 } | 643 } |
700 | 644 |
701 String _name; | 645 String _name; |
702 bool _asyncUsed; | 646 bool _asyncUsed; |
703 | 647 |
704 SendPort _fileService; | 648 SendPort _fileService; |
705 | 649 |
706 Function _existsHandler; | 650 Function _onError; |
707 Function _createHandler; | |
708 Function _deleteHandler; | |
709 Function _directoryHandler; | |
710 Function _openHandler; | |
711 Function _readAsBytesHandler; | |
712 Function _readAsTextHandler; | |
713 Function _readAsLinesHandler; | |
714 Function _fullPathHandler; | |
715 Function _errorHandler; | |
716 } | 651 } |
717 | 652 |
718 | 653 |
719 class _RandomAccessFile implements RandomAccessFile { | 654 class _RandomAccessFile implements RandomAccessFile { |
720 _RandomAccessFile(int this._id, String this._name) : _asyncUsed = false; | 655 _RandomAccessFile(int this._id, String this._name) : _asyncUsed = false; |
721 | 656 |
722 void close() { | 657 void close(void callback()) { |
723 if (_id == 0) return; | 658 if (_id == 0) return; |
724 _ensureFileService(); | 659 _ensureFileService(); |
725 _asyncUsed = true; | 660 _asyncUsed = true; |
726 List request = new List(2); | 661 List request = new List(2); |
727 request[0] = _FileUtils.kCloseRequest; | 662 request[0] = _FileUtils.kCloseRequest; |
728 request[1] = _id; | 663 request[1] = _id; |
729 // Set the id_ to 0 (NULL) to ensure the no more async requests | 664 // Set the id_ to 0 (NULL) to ensure the no more async requests |
730 // can be issues for this file. | 665 // can be issues for this file. |
731 _id = 0; | 666 _id = 0; |
732 _fileService.call(request).receive((result, replyTo) { | 667 _fileService.call(request).receive((result, replyTo) { |
733 if (result != -1) { | 668 if (result != -1) { |
734 _id = result; | 669 _id = result; |
735 if (_closeHandler != null) _closeHandler(); | 670 callback(); |
736 } else if (_errorHandler != null) { | 671 } else if (_onError != null) { |
737 _errorHandler("Cannot close file: $_name"); | 672 _onError("Cannot close file: $_name"); |
738 } | 673 } |
739 }); | 674 }); |
740 } | 675 } |
741 | 676 |
742 void closeSync() { | 677 void closeSync() { |
743 if (_asyncUsed) { | 678 if (_asyncUsed) { |
744 throw new FileIOException( | 679 throw new FileIOException( |
745 "Mixed use of synchronous and asynchronous API"); | 680 "Mixed use of synchronous and asynchronous API"); |
746 } | 681 } |
747 var id = _FileUtils.close(_id); | 682 var id = _FileUtils.close(_id); |
748 if (id == -1) { | 683 if (id == -1) { |
749 throw new FileIOException("Cannot close file: $_name"); | 684 throw new FileIOException("Cannot close file: $_name"); |
750 } | 685 } |
751 _id = id; | 686 _id = id; |
752 } | 687 } |
753 | 688 |
754 void readByte() { | 689 void readByte(void callback(int byte)) { |
755 _ensureFileService(); | 690 _ensureFileService(); |
756 _asyncUsed = true; | 691 _asyncUsed = true; |
757 List request = new List(2); | 692 List request = new List(2); |
758 request[0] = _FileUtils.kReadByteRequest; | 693 request[0] = _FileUtils.kReadByteRequest; |
759 request[1] = _id; | 694 request[1] = _id; |
760 _fileService.call(request).receive((result, replyTo) { | 695 _fileService.call(request).receive((result, replyTo) { |
761 if (result != -1) { | 696 if (result != -1) { |
762 if (_readByteHandler != null) _readByteHandler(result); | 697 callback(result); |
763 } else if (_errorHandler != null) { | 698 } else if (_onError != null) { |
764 _errorHandler("readByte failed"); | 699 _onError("readByte failed"); |
765 } | 700 } |
766 }); | 701 }); |
767 } | 702 } |
768 | 703 |
769 int readByteSync() { | 704 int readByteSync() { |
770 if (_asyncUsed) { | 705 if (_asyncUsed) { |
771 throw new FileIOException( | 706 throw new FileIOException( |
772 "Mixed use of synchronous and asynchronous API"); | 707 "Mixed use of synchronous and asynchronous API"); |
773 } | 708 } |
774 int result = _FileUtils.readByte(_id); | 709 int result = _FileUtils.readByte(_id); |
775 if (result == -1) { | 710 if (result == -1) { |
776 throw new FileIOException("readByte failed"); | 711 throw new FileIOException("readByte failed"); |
777 } | 712 } |
778 return result; | 713 return result; |
779 } | 714 } |
780 | 715 |
781 void readList(List<int> buffer, int offset, int bytes) { | 716 void readList(List<int> buffer, int offset, int bytes, |
| 717 void callback(int read)) { |
782 _ensureFileService(); | 718 _ensureFileService(); |
783 _asyncUsed = true; | 719 _asyncUsed = true; |
784 if (buffer is !List || offset is !int || bytes is !int) { | 720 if (buffer is !List || offset is !int || bytes is !int) { |
785 if (_errorHandler != null) { | 721 if (_onError != null) { |
786 _errorHandler("Invalid arguments to readList"); | 722 _onError("Invalid arguments to readList"); |
787 } | 723 } |
788 return; | 724 return; |
789 }; | 725 }; |
790 List request = new List(3); | 726 List request = new List(3); |
791 request[0] = _FileUtils.kReadListRequest; | 727 request[0] = _FileUtils.kReadListRequest; |
792 request[1] = _id; | 728 request[1] = _id; |
793 request[2] = bytes; | 729 request[2] = bytes; |
794 _fileService.call(request).receive((result, replyTo) { | 730 _fileService.call(request).receive((result, replyTo) { |
795 if (result is List && result.length == 2 && result[0] != -1) { | 731 if (result is List && result.length == 2 && result[0] != -1) { |
796 var read = result[0]; | 732 var read = result[0]; |
797 var data = result[1]; | 733 var data = result[1]; |
798 buffer.setRange(offset, read, data); | 734 buffer.setRange(offset, read, data); |
799 if (_readListHandler != null) _readListHandler(read); | 735 callback(read); |
800 return; | 736 return; |
801 } else if (_errorHandler != null) { | 737 } else if (_onError != null) { |
802 _errorHandler(result is String ? result : "readList failed"); | 738 _onError(result is String ? result : "readList failed"); |
803 } | 739 } |
804 }); | 740 }); |
805 } | 741 } |
806 | 742 |
807 int readListSync(List<int> buffer, int offset, int bytes) { | 743 int readListSync(List<int> buffer, int offset, int bytes) { |
808 if (_asyncUsed) { | 744 if (_asyncUsed) { |
809 throw new FileIOException( | 745 throw new FileIOException( |
810 "Mixed use of synchronous and asynchronous API"); | 746 "Mixed use of synchronous and asynchronous API"); |
811 } | 747 } |
812 if (buffer is !List || offset is !int || bytes is !int) { | 748 if (buffer is !List || offset is !int || bytes is !int) { |
813 throw new FileIOException("Invalid arguments to readList"); | 749 throw new FileIOException("Invalid arguments to readList"); |
814 } | 750 } |
815 if (bytes == 0) return 0; | 751 if (bytes == 0) return 0; |
816 int index = | 752 int index = |
817 _FileUtils.checkReadWriteListArguments(buffer.length, offset, bytes); | 753 _FileUtils.checkReadWriteListArguments(buffer.length, offset, bytes); |
818 if (index != 0) { | 754 if (index != 0) { |
819 throw new IndexOutOfRangeException(index); | 755 throw new IndexOutOfRangeException(index); |
820 } | 756 } |
821 int result = _FileUtils.readList(_id, buffer, offset, bytes); | 757 int result = _FileUtils.readList(_id, buffer, offset, bytes); |
822 if (result == -1) { | 758 if (result == -1) { |
823 throw new FileIOException("readList failed"); | 759 throw new FileIOException("readList failed"); |
824 } | 760 } |
825 return result; | 761 return result; |
826 } | 762 } |
827 | 763 |
828 void writeByte(int value) { | 764 void writeByte(int value) { |
829 _ensureFileService(); | 765 _ensureFileService(); |
830 _asyncUsed = true; | 766 _asyncUsed = true; |
831 if (value is !int) { | 767 if (value is !int) { |
832 if (_errorHandler != null) { | 768 if (_onError != null) { |
833 _errorHandler("Invalid argument to writeByte"); | 769 _onError("Invalid argument to writeByte"); |
834 } | 770 } |
835 return; | 771 return; |
836 } | 772 } |
837 List request = new List(3); | 773 List request = new List(3); |
838 request[0] = _FileUtils.kWriteByteRequest; | 774 request[0] = _FileUtils.kWriteByteRequest; |
839 request[1] = _id; | 775 request[1] = _id; |
840 request[2] = value; | 776 request[2] = value; |
841 _writeEnqueued(); | 777 _writeEnqueued(); |
842 _fileService.call(request).receive((result, replyTo) { | 778 _fileService.call(request).receive((result, replyTo) { |
843 _writeCompleted(); | 779 _writeCompleted(); |
844 if (result == -1 && _errorHandler !== null) { | 780 if (result == -1 && _onError !== null) { |
845 _errorHandler("writeByte failed"); | 781 _onError("writeByte failed"); |
846 } | 782 } |
847 }); | 783 }); |
848 } | 784 } |
849 | 785 |
850 int writeByteSync(int value) { | 786 int writeByteSync(int value) { |
851 if (_asyncUsed) { | 787 if (_asyncUsed) { |
852 throw new FileIOException( | 788 throw new FileIOException( |
853 "Mixed use of synchronous and asynchronous API"); | 789 "Mixed use of synchronous and asynchronous API"); |
854 } | 790 } |
855 if (value is !int) { | 791 if (value is !int) { |
856 throw new FileIOException("Invalid argument to writeByte"); | 792 throw new FileIOException("Invalid argument to writeByte"); |
857 } | 793 } |
858 int result = _FileUtils.writeByte(_id, value); | 794 int result = _FileUtils.writeByte(_id, value); |
859 if (result == -1) { | 795 if (result == -1) { |
860 throw new FileIOException("writeByte failed"); | 796 throw new FileIOException("writeByte failed"); |
861 } | 797 } |
862 return result; | 798 return result; |
863 } | 799 } |
864 | 800 |
865 void writeList(List<int> buffer, int offset, int bytes) { | 801 void writeList(List<int> buffer, int offset, int bytes) { |
866 _ensureFileService(); | 802 _ensureFileService(); |
867 _asyncUsed = true; | 803 _asyncUsed = true; |
868 if (buffer is !List || offset is !int || bytes is !int) { | 804 if (buffer is !List || offset is !int || bytes is !int) { |
869 if (_errorHandler != null) { | 805 if (_onError != null) { |
870 _errorHandler("Invalid arguments to writeList"); | 806 _onError("Invalid arguments to writeList"); |
871 } | 807 } |
872 return; | 808 return; |
873 } | 809 } |
874 | 810 |
875 List result = | 811 List result = |
876 _FileUtils.ensureFastAndSerializableBuffer(buffer, offset, bytes); | 812 _FileUtils.ensureFastAndSerializableBuffer(buffer, offset, bytes); |
877 List outBuffer = result[0]; | 813 List outBuffer = result[0]; |
878 int outOffset = result[1]; | 814 int outOffset = result[1]; |
879 | 815 |
880 List request = new List(5); | 816 List request = new List(5); |
881 request[0] = _FileUtils.kWriteListRequest; | 817 request[0] = _FileUtils.kWriteListRequest; |
882 request[1] = _id; | 818 request[1] = _id; |
883 request[2] = outBuffer; | 819 request[2] = outBuffer; |
884 request[3] = outOffset; | 820 request[3] = outOffset; |
885 request[4] = bytes; | 821 request[4] = bytes; |
886 _writeEnqueued(); | 822 _writeEnqueued(); |
887 _fileService.call(request).receive((result, replyTo) { | 823 _fileService.call(request).receive((result, replyTo) { |
888 _writeCompleted(); | 824 _writeCompleted(); |
889 if (result == -1 && _errorHandler !== null) { | 825 if (result == -1 && _onError !== null) { |
890 _errorHandler("writeList failed"); | 826 _onError("writeList failed"); |
891 } | 827 } |
892 }); | 828 }); |
893 } | 829 } |
894 | 830 |
895 int writeListSync(List<int> buffer, int offset, int bytes) { | 831 int writeListSync(List<int> buffer, int offset, int bytes) { |
896 if (_asyncUsed) { | 832 if (_asyncUsed) { |
897 throw new FileIOException( | 833 throw new FileIOException( |
898 "Mixed use of synchronous and asynchronous API"); | 834 "Mixed use of synchronous and asynchronous API"); |
899 } | 835 } |
900 if (buffer is !List || offset is !int || bytes is !int) { | 836 if (buffer is !List || offset is !int || bytes is !int) { |
(...skipping 15 matching lines...) Expand all Loading... |
916 void writeString(String string) { | 852 void writeString(String string) { |
917 _ensureFileService(); | 853 _ensureFileService(); |
918 _asyncUsed = true; | 854 _asyncUsed = true; |
919 List request = new List(3); | 855 List request = new List(3); |
920 request[0] = _FileUtils.kWriteStringRequest; | 856 request[0] = _FileUtils.kWriteStringRequest; |
921 request[1] = _id; | 857 request[1] = _id; |
922 request[2] = string; | 858 request[2] = string; |
923 _writeEnqueued(); | 859 _writeEnqueued(); |
924 _fileService.call(request).receive((result, replyTo) { | 860 _fileService.call(request).receive((result, replyTo) { |
925 _writeCompleted(); | 861 _writeCompleted(); |
926 if (result == -1 && _errorHandler !== null) { | 862 if (result == -1 && _onError !== null) { |
927 _errorHandler("writeString failed"); | 863 _onError("writeString failed"); |
928 } | 864 } |
929 }); | 865 }); |
930 } | 866 } |
931 | 867 |
932 int writeStringSync(String string) { | 868 int writeStringSync(String string) { |
933 if (_asyncUsed) { | 869 if (_asyncUsed) { |
934 throw new FileIOException( | 870 throw new FileIOException( |
935 "Mixed use of synchronous and asynchronous API"); | 871 "Mixed use of synchronous and asynchronous API"); |
936 } | 872 } |
937 int result = _FileUtils.checkedWriteString(_id, string); | 873 int result = _FileUtils.checkedWriteString(_id, string); |
938 if (result == -1) { | 874 if (result == -1) { |
939 throw new FileIOException("writeString failed"); | 875 throw new FileIOException("writeString failed"); |
940 } | 876 } |
941 return result; | 877 return result; |
942 } | 878 } |
943 | 879 |
944 void position() { | 880 void position(void callback(int position)) { |
945 _ensureFileService(); | 881 _ensureFileService(); |
946 _asyncUsed = true; | 882 _asyncUsed = true; |
947 List request = new List(2); | 883 List request = new List(2); |
948 request[0] = _FileUtils.kPositionRequest; | 884 request[0] = _FileUtils.kPositionRequest; |
949 request[1] = _id; | 885 request[1] = _id; |
950 _fileService.call(request).receive((result, replyTo) { | 886 _fileService.call(request).receive((result, replyTo) { |
951 if (result != -1) { | 887 if (result != -1) { |
952 if (_positionHandler != null) _positionHandler(result); | 888 callback(result); |
953 } else if (_errorHandler != null) { | 889 } else if (_onError != null) { |
954 _errorHandler("position failed"); | 890 _onError("position failed"); |
955 } | 891 } |
956 }); | 892 }); |
957 } | 893 } |
958 | 894 |
959 int positionSync() { | 895 int positionSync() { |
960 if (_asyncUsed) { | 896 if (_asyncUsed) { |
961 throw new FileIOException( | 897 throw new FileIOException( |
962 "Mixed use of synchronous and asynchronous API"); | 898 "Mixed use of synchronous and asynchronous API"); |
963 } | 899 } |
964 int result = _FileUtils.position(_id); | 900 int result = _FileUtils.position(_id); |
965 if (result == -1) { | 901 if (result == -1) { |
966 throw new FileIOException("position failed"); | 902 throw new FileIOException("position failed"); |
967 } | 903 } |
968 return result; | 904 return result; |
969 } | 905 } |
970 | 906 |
971 void setPosition(int position) { | 907 void setPosition(int position, void callback()) { |
972 _ensureFileService(); | 908 _ensureFileService(); |
973 _asyncUsed = true; | 909 _asyncUsed = true; |
974 List request = new List(3); | 910 List request = new List(3); |
975 request[0] = _FileUtils.kSetPositionRequest; | 911 request[0] = _FileUtils.kSetPositionRequest; |
976 request[1] = _id; | 912 request[1] = _id; |
977 request[2] = position; | 913 request[2] = position; |
978 _fileService.call(request).receive((result, replyTo) { | 914 _fileService.call(request).receive((result, replyTo) { |
979 if (result) { | 915 if (result) { |
980 if (_setPositionHandler != null) _setPositionHandler(); | 916 callback(); |
981 } else if (_errorHandler != null) { | 917 } else if (_onError != null) { |
982 _errorHandler("setPosition failed"); | 918 _onError("setPosition failed"); |
983 } | 919 } |
984 }); | 920 }); |
985 } | 921 } |
986 | 922 |
987 void setPositionSync(int position) { | 923 void setPositionSync(int position) { |
988 _ensureFileService(); | 924 _ensureFileService(); |
989 if (_asyncUsed) { | 925 if (_asyncUsed) { |
990 throw new FileIOException( | 926 throw new FileIOException( |
991 "Mixed use of synchronous and asynchronous API"); | 927 "Mixed use of synchronous and asynchronous API"); |
992 } | 928 } |
993 bool result = _FileUtils.setPosition(_id, position); | 929 bool result = _FileUtils.setPosition(_id, position); |
994 if (result == false) { | 930 if (result == false) { |
995 throw new FileIOException("setPosition failed"); | 931 throw new FileIOException("setPosition failed"); |
996 } | 932 } |
997 } | 933 } |
998 | 934 |
999 void truncate(int length) { | 935 void truncate(int length, void callback()) { |
1000 _ensureFileService(); | 936 _ensureFileService(); |
1001 _asyncUsed = true; | 937 _asyncUsed = true; |
1002 List request = new List(3); | 938 List request = new List(3); |
1003 request[0] = _FileUtils.kTruncateRequest; | 939 request[0] = _FileUtils.kTruncateRequest; |
1004 request[1] = _id; | 940 request[1] = _id; |
1005 request[2] = length; | 941 request[2] = length; |
1006 _fileService.call(request).receive((result, replyTo) { | 942 _fileService.call(request).receive((result, replyTo) { |
1007 if (result) { | 943 if (result) { |
1008 if (_truncateHandler != null) _truncateHandler(); | 944 callback(); |
1009 } else if (_errorHandler != null) { | 945 } else if (_onError != null) { |
1010 _errorHandler("truncate failed"); | 946 _onError("truncate failed"); |
1011 } | 947 } |
1012 }); | 948 }); |
1013 } | 949 } |
1014 | 950 |
1015 void truncateSync(int length) { | 951 void truncateSync(int length) { |
1016 if (_asyncUsed) { | 952 if (_asyncUsed) { |
1017 throw new FileIOException( | 953 throw new FileIOException( |
1018 "Mixed use of synchronous and asynchronous API"); | 954 "Mixed use of synchronous and asynchronous API"); |
1019 } | 955 } |
1020 bool result = _FileUtils.truncate(_id, length); | 956 bool result = _FileUtils.truncate(_id, length); |
1021 if (result == false) { | 957 if (result == false) { |
1022 throw new FileIOException("truncate failed"); | 958 throw new FileIOException("truncate failed"); |
1023 } | 959 } |
1024 } | 960 } |
1025 | 961 |
1026 void length() { | 962 void length(void callback(int length)) { |
1027 _ensureFileService(); | 963 _ensureFileService(); |
1028 _asyncUsed = true; | 964 _asyncUsed = true; |
1029 List request = new List(2); | 965 List request = new List(2); |
1030 request[0] = _FileUtils.kLengthRequest; | 966 request[0] = _FileUtils.kLengthRequest; |
1031 request[1] = _id; | 967 request[1] = _id; |
1032 _fileService.call(request).receive((result, replyTo) { | 968 _fileService.call(request).receive((result, replyTo) { |
1033 if (result != -1) { | 969 if (result != -1) { |
1034 if (_lengthHandler != null) _lengthHandler(result); | 970 callback(result); |
1035 } else if (_errorHandler != null) { | 971 } else if (_onError != null) { |
1036 _errorHandler("length failed"); | 972 _onError("length failed"); |
1037 } | 973 } |
1038 }); | 974 }); |
1039 } | 975 } |
1040 | 976 |
1041 int lengthSync() { | 977 int lengthSync() { |
1042 if (_asyncUsed) { | 978 if (_asyncUsed) { |
1043 throw new FileIOException( | 979 throw new FileIOException( |
1044 "Mixed use of synchronous and asynchronous API"); | 980 "Mixed use of synchronous and asynchronous API"); |
1045 } | 981 } |
1046 int result = _FileUtils.length(_id); | 982 int result = _FileUtils.length(_id); |
1047 if (result == -1) { | 983 if (result == -1) { |
1048 throw new FileIOException("length failed"); | 984 throw new FileIOException("length failed"); |
1049 } | 985 } |
1050 return result; | 986 return result; |
1051 } | 987 } |
1052 | 988 |
1053 void flush() { | 989 void flush(void callback()) { |
1054 _ensureFileService(); | 990 _ensureFileService(); |
1055 _asyncUsed = true; | 991 _asyncUsed = true; |
1056 List request = new List(2); | 992 List request = new List(2); |
1057 request[0] = _FileUtils.kFlushRequest; | 993 request[0] = _FileUtils.kFlushRequest; |
1058 request[1] = _id; | 994 request[1] = _id; |
1059 _fileService.call(request).receive((result, replyTo) { | 995 _fileService.call(request).receive((result, replyTo) { |
1060 if (result != -1) { | 996 if (result != -1) { |
1061 if (_flushHandler != null) _flushHandler(); | 997 callback(); |
1062 } else if (_errorHandler != null) { | 998 } else if (_onError != null) { |
1063 _errorHandler("flush failed"); | 999 _onError("flush failed"); |
1064 } | 1000 } |
1065 }); | 1001 }); |
1066 } | 1002 } |
1067 | 1003 |
1068 void flushSync() { | 1004 void flushSync() { |
1069 if (_asyncUsed) { | 1005 if (_asyncUsed) { |
1070 throw new FileIOException( | 1006 throw new FileIOException( |
1071 "Mixed use of synchronous and asynchronous API"); | 1007 "Mixed use of synchronous and asynchronous API"); |
1072 } | 1008 } |
1073 int result = _FileUtils.flush(_id); | 1009 int result = _FileUtils.flush(_id); |
1074 if (result == -1) { | 1010 if (result == -1) { |
1075 throw new FileIOException("flush failed"); | 1011 throw new FileIOException("flush failed"); |
1076 } | 1012 } |
1077 } | 1013 } |
1078 | 1014 |
1079 String get name() => _name; | 1015 String get name() => _name; |
1080 | 1016 |
1081 void set errorHandler(void handler(String error)) { | 1017 void set onError(void handler(String error)) { |
1082 _errorHandler = handler; | 1018 _onError = handler; |
1083 } | 1019 } |
1084 | 1020 |
1085 void set closeHandler(void handler()) { | 1021 void set onNoPendingWrites(void handler()) { |
1086 _closeHandler = handler; | 1022 _onNoPendingWrites = handler; |
1087 } | |
1088 | |
1089 void set readByteHandler(void handler(int byte)) { | |
1090 _readByteHandler = handler; | |
1091 } | |
1092 | |
1093 void set readListHandler(void handler(int read)) { | |
1094 _readListHandler = handler; | |
1095 } | |
1096 | |
1097 void set noPendingWriteHandler(void handler()) { | |
1098 _noPendingWriteHandler = handler; | |
1099 if (_pendingWrites == 0) { | 1023 if (_pendingWrites == 0) { |
1100 _noPendingWriteTimer = new Timer((t) { | 1024 _noPendingWriteTimer = new Timer((t) { |
1101 if (_noPendingWriteHandler != null) _noPendingWriteHandler(); | 1025 if (_onNoPendingWrites != null) _onNoPendingWrites(); |
1102 }, 0); | 1026 }, 0); |
1103 } | 1027 } |
1104 } | 1028 } |
1105 | 1029 |
1106 void set positionHandler(void handler(int pos)) { | |
1107 _positionHandler = handler; | |
1108 } | |
1109 | |
1110 void set setPositionHandler(void handler()) { | |
1111 _setPositionHandler = handler; | |
1112 } | |
1113 | |
1114 void set truncateHandler(void handler()) { | |
1115 _truncateHandler = handler; | |
1116 } | |
1117 | |
1118 void set lengthHandler(void handler(int length)) { | |
1119 _lengthHandler = handler; | |
1120 } | |
1121 | |
1122 void set flushHandler(void handler()) { | |
1123 _flushHandler = handler; | |
1124 } | |
1125 | |
1126 void _ensureFileService() { | 1030 void _ensureFileService() { |
1127 if (_fileService == null) { | 1031 if (_fileService == null) { |
1128 _fileService = _FileUtils.newServicePort(); | 1032 _fileService = _FileUtils.newServicePort(); |
1129 } | 1033 } |
1130 } | 1034 } |
1131 | 1035 |
1132 void _writeEnqueued() { | 1036 void _writeEnqueued() { |
1133 _pendingWrites++; | 1037 _pendingWrites++; |
1134 if (_noPendingWriteTimer != null) { | 1038 if (_noPendingWriteTimer != null) { |
1135 _noPendingWriteTimer.cancel(); | 1039 _noPendingWriteTimer.cancel(); |
1136 _noPendingWriteTimer = null; | 1040 _noPendingWriteTimer = null; |
1137 } | 1041 } |
1138 } | 1042 } |
1139 | 1043 |
1140 void _writeCompleted() { | 1044 void _writeCompleted() { |
1141 _pendingWrites--; | 1045 _pendingWrites--; |
1142 if (_pendingWrites == 0 && _noPendingWriteHandler != null) { | 1046 if (_pendingWrites == 0 && _onNoPendingWrites != null) { |
1143 _noPendingWriteHandler(); | 1047 _onNoPendingWrites(); |
1144 } | 1048 } |
1145 } | 1049 } |
1146 | 1050 |
1147 | 1051 |
1148 String _name; | 1052 String _name; |
1149 int _id; | 1053 int _id; |
1150 bool _asyncUsed; | 1054 bool _asyncUsed; |
1151 int _pendingWrites = 0; | 1055 int _pendingWrites = 0; |
1152 | 1056 |
1153 SendPort _fileService; | 1057 SendPort _fileService; |
1154 | 1058 |
1155 Timer _noPendingWriteTimer; | 1059 Timer _noPendingWriteTimer; |
1156 | 1060 |
1157 Function _closeHandler; | 1061 Function _onNoPendingWrites; |
1158 Function _readByteHandler; | 1062 Function _onError; |
1159 Function _readListHandler; | |
1160 Function _noPendingWriteHandler; | |
1161 Function _positionHandler; | |
1162 Function _setPositionHandler; | |
1163 Function _truncateHandler; | |
1164 Function _lengthHandler; | |
1165 Function _flushHandler; | |
1166 Function _errorHandler; | |
1167 } | 1063 } |
OLD | NEW |