OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 implements FileInputStream { | 5 class _FileInputStream implements FileInputStream { |
6 _FileInputStream(File file) { | 6 _FileInputStream(File file) { |
7 _file = new File(file.name); | 7 _file = new File(file.name); |
8 _file.openSync(); | 8 _file.openSync(); |
9 } | 9 } |
10 | 10 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 return true; | 107 return true; |
108 } else { | 108 } else { |
109 throw "FileOutputStream: write error"; | 109 throw "FileOutputStream: write error"; |
110 } | 110 } |
111 } | 111 } |
112 | 112 |
113 File _file; | 113 File _file; |
114 } | 114 } |
115 | 115 |
116 | 116 |
| 117 class _FileOperationIsolate extends Isolate { |
| 118 static int EXISTS = 0; |
| 119 static int OPEN = 1; |
| 120 static int CLOSE = 2; |
| 121 static int READ_BYTE = 3; |
| 122 static int READ_LIST = 4; |
| 123 static int WRITE_BYTE = 5; |
| 124 static int WRITE_LIST = 6; |
| 125 static int WRITE_STRING = 7; |
| 126 static int POSITION = 8; |
| 127 static int LENGTH = 9; |
| 128 static int FLUSH = 10; |
| 129 static int EXIT = 11; |
| 130 |
| 131 _FileOperationIsolate() : super.heavy(); |
| 132 |
| 133 void handleOperation(Map message, SendPort ignored) { |
| 134 switch (message["type"]) { |
| 135 case EXISTS: |
| 136 message["reply"].send(_File._exists(message["name"]), |
| 137 port.toSendPort()); |
| 138 break; |
| 139 case OPEN: |
| 140 var name = message["name"]; |
| 141 var writable = message["writable"]; |
| 142 message["reply"].send(_File._open(name, writable), |
| 143 port.toSendPort()); |
| 144 break; |
| 145 case CLOSE: |
| 146 message["reply"].send(_File._close(message["id"]), |
| 147 port.toSendPort()); |
| 148 break; |
| 149 case READ_BYTE: |
| 150 message["reply"].send(_File._readByte(message["id"]), |
| 151 port.toSendPort()); |
| 152 break; |
| 153 case READ_LIST: |
| 154 var replyPort = message["reply"]; |
| 155 var bytes = message["bytes"]; |
| 156 var offset = message["offset"]; |
| 157 var length = message["length"]; |
| 158 var id = message["id"]; |
| 159 if (bytes == 0) { |
| 160 replyPort.send(0, port.toSendPort()); |
| 161 return; |
| 162 } |
| 163 int index = _File._checkReadWriteListArguments(length, offset, bytes); |
| 164 if (index != 0) { |
| 165 replyPort.send("index out of range in readList: $index", |
| 166 port.toSendPort()); |
| 167 return; |
| 168 } |
| 169 var buffer = new List(bytes); |
| 170 var result = { "read": _File._readList(id, buffer, 0, bytes), |
| 171 "buffer": buffer }; |
| 172 replyPort.send(result, port.toSendPort()); |
| 173 break; |
| 174 case WRITE_BYTE: |
| 175 message["reply"].send(_File._writeByte(message["id"], message["value"]), |
| 176 port.toSendPort()); |
| 177 break; |
| 178 case WRITE_LIST: |
| 179 var replyPort = message["reply"]; |
| 180 var buffer = message["buffer"]; |
| 181 var bytes = message["bytes"]; |
| 182 var offset = message["offset"]; |
| 183 var id = message["id"]; |
| 184 if (bytes == 0) { |
| 185 replyPort.send(0, port.toSendPort()); |
| 186 return; |
| 187 } |
| 188 int index = |
| 189 _File._checkReadWriteListArguments(buffer.length, offset, bytes); |
| 190 if (index != 0) { |
| 191 replyPort.send("index out of range in writeList: $index", |
| 192 port.toSendPort()); |
| 193 return; |
| 194 } |
| 195 var result = _File._writeList(id, buffer, offset, bytes); |
| 196 replyPort.send(result, port.toSendPort()); |
| 197 break; |
| 198 case WRITE_STRING: |
| 199 var id = message["id"]; |
| 200 var string = message["string"]; |
| 201 message["reply"].send(_File._writeString(id, string), |
| 202 port.toSendPort()); |
| 203 break; |
| 204 case POSITION: |
| 205 message["reply"].send(_File._position(message["id"]), |
| 206 port.toSendPort()); |
| 207 break; |
| 208 case LENGTH: |
| 209 message["reply"].send(_File._length(message["id"]), |
| 210 port.toSendPort()); |
| 211 break; |
| 212 case FLUSH: |
| 213 message["reply"].send(_File._flush(message["id"]), |
| 214 port.toSendPort()); |
| 215 break; |
| 216 case EXIT: |
| 217 port.close(); |
| 218 return; |
| 219 } |
| 220 port.receive(handleOperation); |
| 221 } |
| 222 |
| 223 void main() { |
| 224 port.receive(handleOperation); |
| 225 } |
| 226 } |
| 227 |
| 228 |
| 229 class _FileOperationScheduler { |
| 230 _FileOperationScheduler() : _queue = new Queue(); |
| 231 |
| 232 void schedule(SendPort port) { |
| 233 assert(_isolate != null); |
| 234 if (_queue.isEmpty()) { |
| 235 port.send({ "type": _FileOperationIsolate.EXIT }); |
| 236 _isolate = null; |
| 237 } else { |
| 238 port.send(_queue.removeFirst()); |
| 239 } |
| 240 } |
| 241 |
| 242 void scheduleWrap(void callback(result, ignored)) { |
| 243 return (result, replyTo) { |
| 244 callback(result, replyTo); |
| 245 schedule(replyTo); |
| 246 }; |
| 247 } |
| 248 |
| 249 void enqueue(Map params, void callback(result, ignored)) { |
| 250 ReceivePort replyPort = new ReceivePort.singleShot(); |
| 251 replyPort.receive(scheduleWrap(callback)); |
| 252 params["reply"] = replyPort.toSendPort(); |
| 253 _queue.addLast(params); |
| 254 if (_isolate == null) { |
| 255 _isolate = new _FileOperationIsolate(); |
| 256 _isolate.spawn().then((port) { |
| 257 schedule(port); |
| 258 }); |
| 259 } |
| 260 } |
| 261 |
| 262 bool noPendingWrite() { |
| 263 int queuedWrites = 0; |
| 264 _queue.forEach((map) { |
| 265 if (_isWriteOperation(map["type"])) { |
| 266 queuedWrites++; |
| 267 } |
| 268 }); |
| 269 return queuedWrites == 0; |
| 270 } |
| 271 |
| 272 bool _isWriteOperation(int type) { |
| 273 return (type == _FileOperationIsolate.WRITE_BYTE) || |
| 274 (type == _FileOperationIsolate.WRITE_LIST) || |
| 275 (type == _FileOperationIsolate.WRITE_STRING); |
| 276 } |
| 277 |
| 278 Queue<Map> _queue; |
| 279 _FileOperationIsolate _isolate; |
| 280 } |
| 281 |
| 282 |
117 // Class for encapsulating the native implementation of files. | 283 // Class for encapsulating the native implementation of files. |
118 class _File implements File { | 284 class _File implements File { |
119 // Constructor for file. | 285 // Constructor for file. |
120 _File(String this._name); | 286 _File(String this._name) |
| 287 : _scheduler = new _FileOperationScheduler(), |
| 288 _asyncUsed = false; |
| 289 |
| 290 static bool _exists(String name) native "File_Exists"; |
| 291 static int _open(String name, bool writable) native "File_Open"; |
| 292 static int _close(int id) native "File_Close"; |
| 293 static int _readByte(int id) native "File_ReadByte"; |
| 294 static int _readList(int id, List<int> buffer, int offset, int bytes) |
| 295 native "File_ReadList"; |
| 296 static int _writeByte(int id, int value) native "File_WriteByte"; |
| 297 static int _writeList(int id, List<int> buffer, int offset, int bytes) |
| 298 native "File_WriteList"; |
| 299 static int _writeString(int id, String string) native "File_WriteString"; |
| 300 static int _position(int id) native "File_Position"; |
| 301 static int _length(int id) native "File_Length"; |
| 302 static int _flush(int id) native "File_Flush"; |
| 303 |
| 304 static int _checkReadWriteListArguments(int length, int offset, int bytes) { |
| 305 if (offset < 0) return offset; |
| 306 if (bytes < 0) return bytes; |
| 307 if ((offset + bytes) > length) return offset + bytes; |
| 308 return 0; |
| 309 } |
121 | 310 |
122 void exists() { | 311 void exists() { |
| 312 _asyncUsed = true; |
| 313 var handler = |
| 314 (_existsHandler != null) ? _existsHandler : (result) => null; |
| 315 Map params = { |
| 316 "type": _FileOperationIsolate.EXISTS, |
| 317 "name": _name |
| 318 }; |
| 319 _scheduler.enqueue(params, (result, ignored) { _existsHandler(result); }); |
| 320 } |
| 321 |
| 322 bool existsSync() { |
| 323 if (_asyncUsed) { |
| 324 throw new FileIOException( |
| 325 "Mixed use of synchronous and asynchronous API"); |
| 326 } |
| 327 return _exists(_name); |
| 328 } |
| 329 |
| 330 void create() { |
| 331 _asyncUsed = true; |
123 throw "Unimplemented"; | 332 throw "Unimplemented"; |
124 } | 333 } |
125 | 334 |
126 bool existsSync() { | 335 void createSync() { |
127 return _fileExists(_name); | 336 if (_asyncUsed) { |
128 } | 337 throw new FileIOException( |
129 | 338 "Mixed use of synchronous and asynchronous API"); |
130 bool _fileExists(String name) native "File_Exists"; | 339 } |
131 | |
132 void create() { | |
133 throw "Unimplemented"; | 340 throw "Unimplemented"; |
134 } | 341 } |
135 | 342 |
136 void createSync() { | |
137 throw "Unimplemented"; | |
138 } | |
139 | |
140 void open([bool writable = false]) { | 343 void open([bool writable = false]) { |
141 throw "Unimplemented"; | 344 _asyncUsed = true; |
| 345 var handler = (_openHandler != null) ? _openHandler : () => null; |
| 346 var handleOpenResult = (result, ignored) { |
| 347 if (result != 0) { |
| 348 _id = result; |
| 349 handler(); |
| 350 } else if (_errorHandler != null) { |
| 351 _errorHandler("Cannot open file: $_name"); |
| 352 } |
| 353 }; |
| 354 Map params = { |
| 355 "type": _FileOperationIsolate.OPEN, |
| 356 "name": _name, |
| 357 "writable": writable |
| 358 }; |
| 359 _scheduler.enqueue(params, handleOpenResult); |
142 } | 360 } |
143 | 361 |
144 void openSync([bool writable = false]) { | 362 void openSync([bool writable = false]) { |
145 if (!_openFile(_name, writable)) { | 363 if (_asyncUsed) { |
| 364 throw new FileIOException( |
| 365 "Mixed use of synchronous and asynchronous API"); |
| 366 } |
| 367 _id = _open(_name, writable); |
| 368 if (_id == 0) { |
146 throw new FileIOException("Cannot open file: $_name"); | 369 throw new FileIOException("Cannot open file: $_name"); |
147 } | 370 } |
148 } | 371 } |
149 | 372 |
150 bool _openFile(String name, bool writable) native "File_OpenFile"; | |
151 | |
152 void close() { | 373 void close() { |
153 throw "Unimplemented"; | 374 _asyncUsed = true; |
| 375 var handler = (_closeHandler != null) ? _closeHandler : () => null; |
| 376 var handleOpenResult = (result, ignored) { |
| 377 if (result != -1) { |
| 378 _id = result; |
| 379 handler(); |
| 380 } else if (_errorHandler != null) { |
| 381 _errorHandler("Cannot open file: $_name"); |
| 382 } |
| 383 }; |
| 384 Map params = { |
| 385 "type": _FileOperationIsolate.CLOSE, |
| 386 "id": _id |
| 387 }; |
| 388 _scheduler.enqueue(params, handleOpenResult); |
154 } | 389 } |
155 | 390 |
156 void closeSync() { | 391 void closeSync() { |
157 _close(); | 392 if (_asyncUsed) { |
158 } | 393 throw new FileIOException( |
159 | 394 "Mixed use of synchronous and asynchronous API"); |
160 int _close() native "File_Close"; | 395 } |
| 396 _id = _close(_id); |
| 397 if (_id == -1) { |
| 398 throw new FileIOException("Cannot close file: $_name"); |
| 399 } |
| 400 } |
161 | 401 |
162 void readByte() { | 402 void readByte() { |
163 throw "Unimplemented"; | 403 _asyncUsed = true; |
| 404 var handler = |
| 405 (_readByteHandler != null) ? _readByteHandler : (byte) => null; |
| 406 var handleReadByteResult = (result, ignored) { |
| 407 if (result != -1) { |
| 408 handler(result); |
| 409 } else if (_errorHandler != null) { |
| 410 _errorHandler("readByte failed"); |
| 411 } |
| 412 }; |
| 413 Map params = { |
| 414 "type": _FileOperationIsolate.READ_BYTE, |
| 415 "id": _id |
| 416 }; |
| 417 _scheduler.enqueue(params, handleReadByteResult); |
164 } | 418 } |
165 | 419 |
166 int readByteSync() { | 420 int readByteSync() { |
167 int result = _readByte(); | 421 if (_asyncUsed) { |
168 if (result == -1) { | 422 throw new FileIOException( |
169 throw new FileIOException("Error: readByte failed"); | 423 "Mixed use of synchronous and asynchronous API"); |
170 } | 424 } |
171 return result; | 425 int result = _readByte(_id); |
172 } | 426 if (result == -1) { |
173 | 427 throw new FileIOException("readByte failed"); |
174 int _readByte() native "File_ReadByte"; | 428 } |
| 429 return result; |
| 430 } |
175 | 431 |
176 void readList(List<int> buffer, int offset, int bytes) { | 432 void readList(List<int> buffer, int offset, int bytes) { |
177 throw "Unimplemented"; | 433 _asyncUsed = true; |
| 434 var handler = |
| 435 (_readListHandler != null) ? _readListHandler : (result) => null; |
| 436 var handleReadListResult = (result, ignored) { |
| 437 if (result is Map && result["read"] != -1) { |
| 438 var read = result["read"]; |
| 439 buffer.setRange(offset, read, result["buffer"]); |
| 440 handler(read); |
| 441 return; |
| 442 } |
| 443 if (_errorHandler != null) { |
| 444 _errorHandler(result is String ? result : "readList failed"); |
| 445 } |
| 446 }; |
| 447 Map params = { |
| 448 "type": _FileOperationIsolate.READ_LIST, |
| 449 "length": buffer.length, |
| 450 "offset": offset, |
| 451 "bytes": bytes, |
| 452 "id": _id |
| 453 }; |
| 454 _scheduler.enqueue(params, handleReadListResult); |
178 } | 455 } |
179 | 456 |
180 int readListSync(List<int> buffer, int offset, int bytes) { | 457 int readListSync(List<int> buffer, int offset, int bytes) { |
181 if (bytes == 0) { | 458 if (_asyncUsed) { |
182 return 0; | 459 throw new FileIOException( |
183 } | 460 "Mixed use of synchronous and asynchronous API"); |
184 if (offset < 0) { | 461 } |
185 throw new IndexOutOfRangeException(offset); | 462 if (bytes == 0) return 0; |
186 } | 463 int index = _checkReadWriteListArguments(buffer.length, offset, bytes); |
187 if (bytes < 0) { | 464 if (index != 0) { |
188 throw new IndexOutOfRangeException(bytes); | 465 throw new IndexOutOfRangeException(index); |
189 } | 466 } |
190 if ((offset + bytes) > buffer.length) { | 467 int result = _readList(_id, buffer, offset, bytes); |
191 throw new IndexOutOfRangeException(offset + bytes); | 468 if (result == -1) { |
192 } | 469 throw new FileIOException("readList failed"); |
193 int result = _readList(buffer, offset, bytes); | 470 } |
194 if (result == -1) { | 471 return result; |
195 throw new FileIOException("Error: readList failed"); | 472 } |
196 } | 473 |
197 return result; | 474 void _checkPendingWrites() { |
198 } | 475 if (_scheduler.noPendingWrite() && _noPendingWriteHandler != null) { |
199 | 476 _noPendingWriteHandler(); |
200 int _readList(List<int> buffer, int offset, int bytes) native "File_ReadList"; | 477 } |
| 478 } |
201 | 479 |
202 void writeByte(int value) { | 480 void writeByte(int value) { |
203 throw "Unimplemented"; | 481 _asyncUsed = true; |
| 482 var handleReadByteResult = (result, ignored) { |
| 483 if (result == -1 &&_errorHandler != null) { |
| 484 _errorHandler("writeByte failed"); |
| 485 return; |
| 486 } |
| 487 _checkPendingWrites(); |
| 488 }; |
| 489 Map params = { |
| 490 "type": _FileOperationIsolate.WRITE_BYTE, |
| 491 "value": value, |
| 492 "id": _id |
| 493 }; |
| 494 _scheduler.enqueue(params, handleReadByteResult); |
204 } | 495 } |
205 | 496 |
206 int writeByteSync(int value) { | 497 int writeByteSync(int value) { |
207 int result = _writeByte(value); | 498 if (_asyncUsed) { |
208 if (result == -1) { | 499 throw new FileIOException( |
209 throw new FileIOException("Error: writeByte failed"); | 500 "Mixed use of synchronous and asynchronous API"); |
210 } | 501 } |
211 return result; | 502 int result = _writeByte(_id, value); |
212 } | 503 if (result == -1) { |
213 | 504 throw new FileIOException("writeByte failed"); |
214 int _writeByte(int value) native "File_WriteByte"; | 505 } |
215 | 506 return result; |
216 int writeList(List<int> buffer, int offset, int bytes) { | 507 } |
217 throw "Unimplemented"; | 508 |
| 509 void writeList(List<int> buffer, int offset, int bytes) { |
| 510 _asyncUsed = true; |
| 511 var handleWriteListResult = (result, ignored) { |
| 512 if (result is !String && result != -1) { |
| 513 if (result < bytes) { |
| 514 writeList(buffer, offset + result, bytes - result); |
| 515 } else { |
| 516 _checkPendingWrites(); |
| 517 } |
| 518 return; |
| 519 } |
| 520 if (_errorHandler != null) { |
| 521 _errorHandler(result is String ? result : "writeList failed"); |
| 522 } |
| 523 }; |
| 524 Map params = { |
| 525 "type": _FileOperationIsolate.WRITE_LIST, |
| 526 "buffer": buffer, |
| 527 "offset": offset, |
| 528 "bytes": bytes, |
| 529 "id": _id |
| 530 }; |
| 531 _scheduler.enqueue(params, handleWriteListResult); |
218 } | 532 } |
219 | 533 |
220 int writeListSync(List<int> buffer, int offset, int bytes) { | 534 int writeListSync(List<int> buffer, int offset, int bytes) { |
221 if (bytes == 0) { | 535 if (_asyncUsed) { |
222 return 0; | 536 throw new FileIOException( |
223 } | 537 "Mixed use of synchronous and asynchronous API"); |
224 if (offset < 0) { | 538 } |
225 throw new IndexOutOfRangeException(offset); | 539 if (bytes == 0) return 0; |
226 } | 540 int index = _checkReadWriteListArguments(buffer.length, offset, bytes); |
227 if (bytes < 0) { | 541 if (index != 0) { |
228 throw new IndexOutOfRangeException(bytes); | 542 throw new IndexOutOfRangeException(index); |
229 } | 543 } |
230 if ((offset + bytes) > buffer.length) { | 544 int result = _writeList(_id, buffer, offset, bytes); |
231 throw new IndexOutOfRangeException(offset + bytes); | 545 if (result == -1) { |
232 } | 546 throw new FileIOException("writeList failed"); |
233 int result = _writeList(buffer, offset, bytes); | 547 } |
234 if (result == -1) { | 548 return result; |
235 throw new FileIOException("Error: writeList failed"); | 549 } |
236 } | 550 |
237 return result; | 551 void writeString(String string) { |
238 } | 552 _asyncUsed = true; |
239 | 553 var handleWriteStringResult = (result, ignored) { |
240 int _writeList(List<int> buffer, int offset, int bytes) | 554 if (result == -1 &&_errorHandler != null) { |
241 native "File_WriteList"; | 555 _errorHandler("writeString failed"); |
242 | 556 return; |
243 int writeString(String string) { | 557 } |
244 throw "Unimplemented"; | 558 if (result < string.length) { |
| 559 writeString(string.substring(result)); |
| 560 } else { |
| 561 _checkPendingWrites(); |
| 562 } |
| 563 }; |
| 564 Map params = { |
| 565 "type": _FileOperationIsolate.WRITE_STRING, |
| 566 "string": string, |
| 567 "id": _id |
| 568 }; |
| 569 _scheduler.enqueue(params, handleWriteStringResult); |
245 } | 570 } |
246 | 571 |
247 int writeStringSync(String string) { | 572 int writeStringSync(String string) { |
248 int result = _writeString(string); | 573 if (_asyncUsed) { |
| 574 throw new FileIOException( |
| 575 "Mixed use of synchronous and asynchronous API"); |
| 576 } |
| 577 int result = _writeString(_id, string); |
249 if (result == -1) { | 578 if (result == -1) { |
250 throw new FileIOException("Error: writeString failed"); | 579 throw new FileIOException("Error: writeString failed"); |
251 } | 580 } |
252 return result; | 581 return result; |
253 } | 582 } |
254 | 583 |
255 int _writeString(String string) native "File_WriteString"; | 584 void position() { |
256 | 585 _asyncUsed = true; |
257 int position() { | 586 var handler = (_positionHandler != null) ? _positionHandler : (pos) => null; |
258 throw "Unimplemented"; | 587 var handlePositionResult = (result, ignored) { |
| 588 if (result == -1 && _errorHandler != null) { |
| 589 _errorHandler("position failed"); |
| 590 return; |
| 591 } |
| 592 handler(result); |
| 593 }; |
| 594 Map params = { |
| 595 "type": _FileOperationIsolate.POSITION, |
| 596 "id": _id |
| 597 }; |
| 598 _scheduler.enqueue(params, handlePositionResult); |
259 } | 599 } |
260 | 600 |
261 int positionSync() { | 601 int positionSync() { |
262 int result = _position; | 602 if (_asyncUsed) { |
263 if (result == -1) { | 603 throw new FileIOException( |
264 throw new FileIOException("Error: get position failed"); | 604 "Mixed use of synchronous and asynchronous API"); |
265 } | 605 } |
266 return result; | 606 int result = _position(_id); |
267 } | 607 if (result == -1) { |
268 | 608 throw new FileIOException("position failed"); |
269 int get _position() native "File_Position"; | 609 } |
270 | 610 return result; |
271 int length() { | 611 } |
272 throw "Unimplemented"; | 612 |
| 613 void length() { |
| 614 _asyncUsed = true; |
| 615 var handler = (_lengthHandler != null) ? _lengthHandler : (pos) => null; |
| 616 var handleLengthResult = (result, ignored) { |
| 617 if (result == -1 && _errorHandler != null) { |
| 618 _errorHandler("length failed"); |
| 619 return; |
| 620 } |
| 621 handler(result); |
| 622 }; |
| 623 Map params = { |
| 624 "type": _FileOperationIsolate.LENGTH, |
| 625 "id": _id |
| 626 }; |
| 627 _scheduler.enqueue(params, handleLengthResult); |
273 } | 628 } |
274 | 629 |
275 int lengthSync() { | 630 int lengthSync() { |
276 int result = _length; | 631 if (_asyncUsed) { |
277 if (result == -1) { | 632 throw new FileIOException( |
278 throw new FileIOException("Error: get length failed"); | 633 "Mixed use of synchronous and asynchronous API"); |
279 } | 634 } |
280 return result; | 635 int result = _length(_id); |
281 } | 636 if (result == -1) { |
282 | 637 throw new FileIOException("length failed"); |
283 int get _length() native "File_Length"; | 638 } |
| 639 return result; |
| 640 } |
284 | 641 |
285 void flush() { | 642 void flush() { |
286 throw "Unimplemented"; | 643 _asyncUsed = true; |
| 644 var handler = (_flushHandler != null) ? _flushHandler : (pos) => null; |
| 645 var handleFlushResult = (result, ignored) { |
| 646 if (result == -1 && _errorHandler != null) { |
| 647 _errorHandler("flush failed"); |
| 648 return; |
| 649 } |
| 650 handler(); |
| 651 }; |
| 652 Map params = { |
| 653 "type": _FileOperationIsolate.FLUSH, |
| 654 "id": _id |
| 655 }; |
| 656 _scheduler.enqueue(params, handleFlushResult); |
287 } | 657 } |
288 | 658 |
289 void flushSync() { | 659 void flushSync() { |
290 int result = _flush(); | 660 if (_asyncUsed) { |
291 if (result == -1) { | 661 throw new FileIOException( |
292 throw new FileIOException("Error: flush failed"); | 662 "Mixed use of synchronous and asynchronous API"); |
293 } | 663 } |
294 } | 664 int result = _flush(_id); |
295 | 665 if (result == -1) { |
296 int _flush() native "File_Flush"; | 666 throw new FileIOException("flush failed"); |
| 667 } |
| 668 } |
297 | 669 |
298 InputStream openInputStream() { | 670 InputStream openInputStream() { |
299 return new _FileInputStream(this); | 671 return new _FileInputStream(this); |
300 } | 672 } |
301 | 673 |
302 OutputStream openOutputStream() { | 674 OutputStream openOutputStream() { |
303 return new _FileOutputStream(this); | 675 return new _FileOutputStream(this); |
304 } | 676 } |
305 | 677 |
306 String get name() { | 678 String get name() { |
(...skipping 21 matching lines...) Expand all Loading... |
328 } | 700 } |
329 | 701 |
330 void set readListHandler(void handler(int read)) { | 702 void set readListHandler(void handler(int read)) { |
331 _readListHandler = handler; | 703 _readListHandler = handler; |
332 } | 704 } |
333 | 705 |
334 void set noPendingWriteHandler(void handler()) { | 706 void set noPendingWriteHandler(void handler()) { |
335 _noPendingWriteHandler = handler; | 707 _noPendingWriteHandler = handler; |
336 } | 708 } |
337 | 709 |
| 710 void set positionHandler(void handler(int pos)) { |
| 711 _positionHandler = handler; |
| 712 } |
| 713 |
| 714 void set lengthHandler(void handler(int length)) { |
| 715 _lengthHandler = handler; |
| 716 } |
| 717 |
| 718 void set flushHandler(void handler()) { |
| 719 _flushHandler = handler; |
| 720 } |
| 721 |
338 void set errorHandler(void handler(String error)) { | 722 void set errorHandler(void handler(String error)) { |
339 _errorHandler = handler; | 723 _errorHandler = handler; |
340 } | 724 } |
341 | 725 |
342 String _name; | 726 String _name; |
343 int _id; | 727 int _id; |
| 728 bool _asyncUsed; |
| 729 |
| 730 _FileOperationScheduler _scheduler; |
344 | 731 |
345 var _existsHandler; | 732 var _existsHandler; |
346 var _createHandler; | 733 var _createHandler; |
347 var _openHandler; | 734 var _openHandler; |
348 var _closeHandler; | 735 var _closeHandler; |
349 var _readByteHandler; | 736 var _readByteHandler; |
350 var _readListHandler; | 737 var _readListHandler; |
351 var _noPendingWriteHandler; | 738 var _noPendingWriteHandler; |
| 739 var _positionHandler; |
| 740 var _lengthHandler; |
| 741 var _flushHandler; |
352 var _errorHandler; | 742 var _errorHandler; |
353 } | 743 } |
OLD | NEW |