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