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.onError = (String s) { | 10 _file.onError = (e) { |
11 if (_clientErrorHandler != null) { | 11 if (_clientErrorHandler != null) { |
12 _clientErrorHandler(); | 12 _clientErrorHandler(); |
13 } | 13 } |
14 }; | 14 }; |
15 _file.open(FileMode.READ, (openedFile) { | 15 _file.open(FileMode.READ, (openedFile) { |
16 _readDataFromFile(openedFile); | 16 _readDataFromFile(openedFile); |
17 }); | 17 }); |
18 } | 18 } |
19 | 19 |
20 _FileInputStream.fromStdio(int fd) { | 20 _FileInputStream.fromStdio(int fd) { |
21 assert(fd == 0); | 21 assert(fd == 0); |
22 _file = _File._openStdioSync(fd); | 22 _file = _File._openStdioSync(fd); |
23 _data = []; | 23 _data = []; |
24 _position = 0; | 24 _position = 0; |
25 _readDataFromFile(_file); | 25 _readDataFromFile(_file); |
26 } | 26 } |
27 | 27 |
28 void _readDataFromFile(RandomAccessFile openedFile) { | 28 void _readDataFromFile(RandomAccessFile openedFile) { |
29 openedFile.onError = (String s) { | 29 openedFile.onError = (e) { |
30 if (_clientErrorHandler != null) { | 30 if (_clientErrorHandler != null) { |
31 _clientErrorHandler(); | 31 _clientErrorHandler(); |
32 } | 32 } |
33 }; | 33 }; |
34 openedFile.length((length) { | 34 openedFile.length((length) { |
35 var contents = new ByteArray(length); | 35 var contents = new ByteArray(length); |
36 if (length != 0) { | 36 if (length != 0) { |
37 openedFile.readList(contents, 0, length, (read) { | 37 openedFile.readList(contents, 0, length, (read) { |
38 if (read != length) { | 38 if (read != length) { |
39 if (_clientErrorHandler != null) { | 39 if (_clientErrorHandler != null) { |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 static final kSetPositionRequest = 8; | 217 static final kSetPositionRequest = 8; |
218 static final kTruncateRequest = 9; | 218 static final kTruncateRequest = 9; |
219 static final kLengthRequest = 10; | 219 static final kLengthRequest = 10; |
220 static final kFlushRequest = 11; | 220 static final kFlushRequest = 11; |
221 static final kReadByteRequest = 12; | 221 static final kReadByteRequest = 12; |
222 static final kWriteByteRequest = 13; | 222 static final kWriteByteRequest = 13; |
223 static final kReadListRequest = 14; | 223 static final kReadListRequest = 14; |
224 static final kWriteListRequest = 15; | 224 static final kWriteListRequest = 15; |
225 static final kWriteStringRequest = 16; | 225 static final kWriteStringRequest = 16; |
226 | 226 |
| 227 static final kSuccessResponse = 0; |
| 228 static final kIllegalArgumentResponse = 1; |
| 229 static final kOSErrorResponse = 2; |
| 230 |
227 static List ensureFastAndSerializableBuffer( | 231 static List ensureFastAndSerializableBuffer( |
228 List buffer, int offset, int bytes) { | 232 List buffer, int offset, int bytes) { |
229 // When using the Dart C API to access raw data, using a ByteArray is | 233 // When using the Dart C API to access raw data, using a ByteArray is |
230 // currently much faster. This function will make a copy of the | 234 // currently much faster. This function will make a copy of the |
231 // supplied List to a ByteArray if it isn't already. | 235 // supplied List to a ByteArray if it isn't already. |
232 List outBuffer; | 236 List outBuffer; |
233 int outOffset = offset; | 237 int outOffset = offset; |
234 if (buffer is ByteArray || buffer is ObjectArray) { | 238 if (buffer is ByteArray || buffer is ObjectArray) { |
235 outBuffer = buffer; | 239 outBuffer = buffer; |
236 } else { | 240 } else { |
237 outBuffer = new ByteArray(bytes); | 241 outBuffer = new ByteArray(bytes); |
238 outOffset = 0; | 242 outOffset = 0; |
239 int j = offset; | 243 int j = offset; |
240 for (int i = 0; i < bytes; i++) { | 244 for (int i = 0; i < bytes; i++) { |
241 int value = buffer[j]; | 245 int value = buffer[j]; |
242 if (value is! int) { | 246 if (value is! int) { |
243 throw new FileIOException( | 247 throw new FileIOException( |
244 "List element is not an integer at index $j"); | 248 "List element is not an integer at index $j"); |
245 } | 249 } |
246 outBuffer[i] = value; | 250 outBuffer[i] = value; |
247 j++; | 251 j++; |
248 } | 252 } |
249 } | 253 } |
250 return [outBuffer, outOffset]; | 254 return [outBuffer, outOffset]; |
251 } | 255 } |
252 | 256 |
253 static bool exists(String name) native "File_Exists"; | 257 static exists(String name) native "File_Exists"; |
254 static int open(String name, int mode) native "File_Open"; | 258 static open(String name, int mode) native "File_Open"; |
255 static bool create(String name) native "File_Create"; | 259 static create(String name) native "File_Create"; |
256 static bool delete(String name) native "File_Delete"; | 260 static delete(String name) native "File_Delete"; |
257 static String fullPath(String name) native "File_FullPath"; | 261 static fullPath(String name) native "File_FullPath"; |
258 static String directory(String name) native "File_Directory"; | 262 static directory(String name) native "File_Directory"; |
259 static int close(int id) native "File_Close"; | 263 static int close(int id) native "File_Close"; |
260 static int readByte(int id) native "File_ReadByte"; | 264 static int readByte(int id) native "File_ReadByte"; |
261 static int readList(int id, List<int> buffer, int offset, int bytes) | 265 static int readList(int id, List<int> buffer, int offset, int bytes) |
262 native "File_ReadList"; | 266 native "File_ReadList"; |
263 static int writeByte(int id, int value) native "File_WriteByte"; | 267 static int writeByte(int id, int value) native "File_WriteByte"; |
264 static int writeList(int id, List<int> buffer, int offset, int bytes) { | 268 static int writeList(int id, List<int> buffer, int offset, int bytes) { |
265 List result = | 269 List result = |
266 _FileUtils.ensureFastAndSerializableBuffer(buffer, offset, bytes); | 270 _FileUtils.ensureFastAndSerializableBuffer(buffer, offset, bytes); |
267 List outBuffer = result[0]; | 271 List outBuffer = result[0]; |
268 int outOffset = result[1]; | 272 int outOffset = result[1]; |
269 return writeListNative(id, outBuffer, outOffset, bytes); | 273 return writeListNative(id, outBuffer, outOffset, bytes); |
270 } | 274 } |
271 static int writeListNative(int id, List<int> buffer, int offset, int bytes) | 275 static int writeListNative(int id, List<int> buffer, int offset, int bytes) |
272 native "File_WriteList"; | 276 native "File_WriteList"; |
273 static int writeString(int id, String string) native "File_WriteString"; | 277 static int writeString(int id, String string) native "File_WriteString"; |
274 static int position(int id) native "File_Position"; | 278 static int position(int id) native "File_Position"; |
275 static bool setPosition(int id, int position) native "File_SetPosition"; | 279 static bool setPosition(int id, int position) native "File_SetPosition"; |
276 static bool truncate(int id, int length) native "File_Truncate"; | 280 static bool truncate(int id, int length) native "File_Truncate"; |
277 static int length(int id) native "File_Length"; | 281 static int length(int id) native "File_Length"; |
278 static int flush(int id) native "File_Flush"; | 282 static int flush(int id) native "File_Flush"; |
279 static int openStdio(int fd) native "File_OpenStdio"; | 283 static int openStdio(int fd) native "File_OpenStdio"; |
280 static SendPort newServicePort() native "File_NewServicePort"; | 284 static SendPort newServicePort() native "File_NewServicePort"; |
281 | 285 |
| 286 static bool checkedExists(String name) { |
| 287 if (name is !String) { |
| 288 throw new IllegalArgumentException(); |
| 289 } |
| 290 var result = exists(name); |
| 291 if (result is OSError) { |
| 292 throw new FileIOException("Cannot check existence of file", result); |
| 293 } |
| 294 return result; |
| 295 } |
| 296 |
282 static int checkedOpen(String name, int mode) { | 297 static int checkedOpen(String name, int mode) { |
283 if (name is !String || mode is !int) return 0; | 298 if (name is !String || mode is !int) { |
284 return open(name, mode); | 299 throw new IllegalArgumentException(); |
| 300 }; |
| 301 var result = open(name, mode); |
| 302 if (result is OSError) { |
| 303 throw new FileIOException("Cannot open file", result); |
| 304 } |
| 305 return result; |
285 } | 306 } |
286 | 307 |
287 static bool checkedCreate(String name) { | 308 static bool checkedCreate(String name) { |
288 if (name is !String) return false; | 309 if (name is !String) { |
289 return create(name); | 310 throw new IllegalArgumentException(); |
| 311 }; |
| 312 var result = create(name); |
| 313 if (result is OSError) { |
| 314 throw new FileIOException("Cannot create file", result); |
| 315 } |
| 316 return true; |
290 } | 317 } |
291 | 318 |
292 static bool checkedDelete(String name) { | 319 static bool checkedDelete(String name) { |
293 if (name is !String) return false; | 320 if (name is !String) { |
294 return delete(name); | 321 throw new IllegalArgumentException(); |
| 322 }; |
| 323 var result = delete(name); |
| 324 if (result is OSError) { |
| 325 throw new FileIOException("Cannot delete file", result); |
| 326 } |
| 327 return true; |
295 } | 328 } |
296 | 329 |
297 static String checkedFullPath(String name) { | 330 static String checkedFullPath(String name) { |
298 if (name is !String) return null; | 331 if (name is !String) { |
299 return fullPath(name); | 332 throw new IllegalArgumentException(); |
| 333 }; |
| 334 var result = fullPath(name); |
| 335 if (result is OSError) { |
| 336 throw new FileIOException("Cannot retrieve full path", result); |
| 337 } |
| 338 return result; |
| 339 } |
| 340 |
| 341 static String checkedDirectory(String name) { |
| 342 if (name is !String) { |
| 343 throw new IllegalArgumentException(); |
| 344 } |
| 345 var result = directory(name); |
| 346 if (result is OSError) { |
| 347 throw new FileIOException("Cannot retrieve directory for file", result); |
| 348 } |
| 349 return result; |
300 } | 350 } |
301 | 351 |
302 static int checkReadWriteListArguments(int length, int offset, int bytes) { | 352 static int checkReadWriteListArguments(int length, int offset, int bytes) { |
303 if (offset < 0) return offset; | 353 if (offset < 0) return offset; |
304 if (bytes < 0) return bytes; | 354 if (bytes < 0) return bytes; |
305 if ((offset + bytes) > length) return offset + bytes; | 355 if ((offset + bytes) > length) return offset + bytes; |
306 return 0; | 356 return 0; |
307 } | 357 } |
308 | 358 |
309 static int checkedWriteString(int id, String string) { | 359 static int checkedWriteString(int id, String string) { |
310 if (string is !String) return -1; | 360 if (string is !String) return -1; |
311 return writeString(id, string); | 361 return writeString(id, string); |
312 } | 362 } |
| 363 |
313 } | 364 } |
314 | 365 |
315 | 366 |
316 // Class for encapsulating the native implementation of files. | 367 // Class for encapsulating the native implementation of files. |
317 class _File implements File { | 368 class _File implements File { |
318 // Constructor for file. | 369 // Constructor for file. |
319 _File(String this._name) : _asyncUsed = false; | 370 _File(String this._name) : _asyncUsed = false; |
320 | 371 |
321 void exists(void callback(bool exists)) { | 372 void exists(void callback(bool exists)) { |
322 _ensureFileService(); | 373 _ensureFileService(); |
323 _asyncUsed = true; | 374 _asyncUsed = true; |
324 if (_name is !String) { | |
325 if (_onError != null) { | |
326 _onError('File name is not a string: $_name'); | |
327 } | |
328 return; | |
329 } | |
330 List request = new List(2); | 375 List request = new List(2); |
331 request[0] = _FileUtils.kExistsRequest; | 376 request[0] = _FileUtils.kExistsRequest; |
332 request[1] = _name; | 377 request[1] = _name; |
333 _fileService.call(request).then((exists) { | 378 _fileService.call(request).then((response) { |
334 callback(exists); | 379 if (_isErrorResponse(response)) { |
| 380 _reportError(response, "Cannot open file"); |
| 381 } else { |
| 382 callback(response); |
| 383 } |
335 }); | 384 }); |
336 } | 385 } |
337 | 386 |
338 bool existsSync() { | 387 bool existsSync() { |
339 if (_asyncUsed) { | 388 if (_asyncUsed) { |
340 throw new FileIOException( | 389 throw new FileIOException( |
341 "Mixed use of synchronous and asynchronous API"); | 390 "Mixed use of synchronous and asynchronous API"); |
342 } | 391 } |
343 if (_name is !String) { | 392 return _FileUtils.checkedExists(_name); |
344 throw new FileIOException('File name is not a string: $_name'); | |
345 } | |
346 return _FileUtils.exists(_name); | |
347 } | 393 } |
348 | 394 |
349 void create(void callback()) { | 395 void create(void callback()) { |
350 _ensureFileService(); | 396 _ensureFileService(); |
351 _asyncUsed = true; | 397 _asyncUsed = true; |
352 List request = new List(2); | 398 List request = new List(2); |
353 request[0] = _FileUtils.kCreateRequest; | 399 request[0] = _FileUtils.kCreateRequest; |
354 request[1] = _name; | 400 request[1] = _name; |
355 _fileService.call(request).then((created) { | 401 _fileService.call(request).then((response) { |
356 if (created) { | 402 if (_isErrorResponse(response)) { |
| 403 _reportError(response, "Cannot create file"); |
| 404 } else { |
357 callback(); | 405 callback(); |
358 } else if (_onError != null) { | |
359 _onError("Cannot create file: $_name"); | |
360 } | 406 } |
361 }); | 407 }); |
362 } | 408 } |
363 | 409 |
364 void createSync() { | 410 void createSync() { |
365 if (_asyncUsed) { | 411 if (_asyncUsed) { |
366 throw new FileIOException( | 412 throw new FileIOException( |
367 "Mixed use of synchronous and asynchronous API"); | 413 "Mixed use of synchronous and asynchronous API"); |
368 } | 414 } |
369 bool created = _FileUtils.checkedCreate(_name); | 415 bool created = _FileUtils.checkedCreate(_name); |
370 if (!created) { | 416 if (!created) { |
371 throw new FileIOException("Cannot create file: $_name"); | 417 throw new FileIOException("Cannot create file: $_name"); |
372 } | 418 } |
373 } | 419 } |
374 | 420 |
375 void delete(void callback()) { | 421 void delete(void callback()) { |
376 _ensureFileService(); | 422 _ensureFileService(); |
377 _asyncUsed = true; | 423 _asyncUsed = true; |
378 List request = new List(2); | 424 List request = new List(2); |
379 request[0] = _FileUtils.kDeleteRequest; | 425 request[0] = _FileUtils.kDeleteRequest; |
380 request[1] = _name; | 426 request[1] = _name; |
381 _fileService.call(request).then((deleted) { | 427 _fileService.call(request).then((response) { |
382 if (deleted) { | 428 if (_isErrorResponse(response)) { |
| 429 _reportError(response, "Cannot delete file"); |
| 430 } else { |
383 callback(); | 431 callback(); |
384 } else if (_onError != null) { | |
385 _onError("Cannot delete file: $_name"); | |
386 } | 432 } |
387 }); | 433 }); |
388 } | 434 } |
389 | 435 |
390 void deleteSync() { | 436 void deleteSync() { |
391 if (_asyncUsed) { | 437 if (_asyncUsed) { |
392 throw new FileIOException( | 438 throw new FileIOException( |
393 "Mixed use of synchronous and asynchronous API"); | 439 "Mixed use of synchronous and asynchronous API"); |
394 } | 440 } |
395 bool deleted = _FileUtils.checkedDelete(_name); | 441 _FileUtils.checkedDelete(_name); |
396 if (!deleted) { | |
397 throw new FileIOException("Cannot delete file: $_name"); | |
398 } | |
399 } | 442 } |
400 | 443 |
401 void directory(void callback(Directory dir)) { | 444 void directory(void callback(Directory dir)) { |
402 _ensureFileService(); | 445 _ensureFileService(); |
403 _asyncUsed = true; | 446 _asyncUsed = true; |
404 List request = new List(2); | 447 List request = new List(2); |
405 request[0] = _FileUtils.kDirectoryRequest; | 448 request[0] = _FileUtils.kDirectoryRequest; |
406 request[1] = _name; | 449 request[1] = _name; |
407 _fileService.call(request).then((path) { | 450 _fileService.call(request).then((response) { |
408 if (path != null) { | 451 if (_isErrorResponse(response)) { |
409 callback(new Directory(path)); | 452 _reportError(response, "Cannot retrieve directory for file"); |
410 } else if (_onError != null) { | 453 } else { |
411 _onError("Cannot get directory for: ${_name}"); | 454 callback(new Directory(response)); |
412 } | 455 } |
413 }); | 456 }); |
414 } | 457 } |
415 | 458 |
416 Directory directorySync() { | 459 Directory directorySync() { |
417 if (_asyncUsed) { | 460 if (_asyncUsed) { |
418 throw new FileIOException( | 461 throw new FileIOException( |
419 "Mixed use of synchronous and asynchronous API"); | 462 "Mixed use of synchronous and asynchronous API"); |
420 } | 463 } |
421 if (!existsSync()) { | 464 _FileUtils.checkedDirectory(_name); |
422 throw new FileIOException("Cannot get directory for: $_name"); | |
423 } | |
424 return new Directory(_FileUtils.directory(_name)); | 465 return new Directory(_FileUtils.directory(_name)); |
425 } | 466 } |
426 | 467 |
427 void open(FileMode mode, void callback(RandomAccessFile file)) { | 468 void open(FileMode mode, void callback(RandomAccessFile file)) { |
428 _ensureFileService(); | 469 _ensureFileService(); |
429 _asyncUsed = true; | 470 _asyncUsed = true; |
430 if (mode != FileMode.READ && | 471 if (mode != FileMode.READ && |
431 mode != FileMode.WRITE && | 472 mode != FileMode.WRITE && |
432 mode != FileMode.APPEND) { | 473 mode != FileMode.APPEND) { |
433 if (_onError != null) { | 474 if (_onError != null) { |
434 _onError("Unknown file mode. Use FileMode.READ, FileMode.WRITE " + | 475 _onError(new IllegalArgumentException()); |
435 "or FileMode.APPEND."); | |
436 return; | 476 return; |
437 } | 477 } |
438 } | 478 } |
439 List request = new List(3); | 479 List request = new List(3); |
440 request[0] = _FileUtils.kOpenRequest; | 480 request[0] = _FileUtils.kOpenRequest; |
441 request[1] = _name; | 481 request[1] = _name; |
442 request[2] = mode._mode; // Direct int value for serialization. | 482 request[2] = mode._mode; // Direct int value for serialization. |
443 _fileService.call(request).then((id) { | 483 _fileService.call(request).then((response) { |
444 if (id != 0) { | 484 if (_isErrorResponse(response)) { |
445 callback(new _RandomAccessFile(id, _name)); | 485 _reportError(response, "Cannot open file"); |
446 } else if (_onError != null) { | 486 } else { |
447 _onError("Cannot open file: $_name"); | 487 callback(new _RandomAccessFile(response, _name)); |
448 } | 488 } |
449 }); | 489 }); |
450 } | 490 } |
451 | 491 |
452 RandomAccessFile openSync([FileMode mode = FileMode.READ]) { | 492 RandomAccessFile openSync([FileMode mode = FileMode.READ]) { |
453 if (_asyncUsed) { | 493 if (_asyncUsed) { |
454 throw new FileIOException( | 494 throw new FileIOException( |
455 "Mixed use of synchronous and asynchronous API"); | 495 "Mixed use of synchronous and asynchronous API"); |
456 } | 496 } |
457 if (mode != FileMode.READ && | 497 if (mode != FileMode.READ && |
458 mode != FileMode.WRITE && | 498 mode != FileMode.WRITE && |
459 mode != FileMode.APPEND) { | 499 mode != FileMode.APPEND) { |
460 throw new FileIOException("Unknown file mode. Use FileMode.READ, " + | 500 throw new FileIOException("Unknown file mode. Use FileMode.READ, " + |
461 "FileMode.WRITE or FileMode.APPEND."); | 501 "FileMode.WRITE or FileMode.APPEND."); |
462 } | 502 } |
463 var id = _FileUtils.checkedOpen(_name, mode._mode); | 503 var id = _FileUtils.checkedOpen(_name, mode._mode); |
464 if (id == 0) { | 504 assert(id != 0); |
465 throw new FileIOException("Cannot open file: $_name"); | |
466 } | |
467 return new _RandomAccessFile(id, _name); | 505 return new _RandomAccessFile(id, _name); |
468 } | 506 } |
469 | 507 |
470 static RandomAccessFile _openStdioSync(int fd) { | 508 static RandomAccessFile _openStdioSync(int fd) { |
471 var id = _FileUtils.openStdio(fd); | 509 var id = _FileUtils.openStdio(fd); |
472 if (id == 0) { | 510 if (id == 0) { |
473 throw new FileIOException("Cannot open stdio file for: $fd"); | 511 throw new FileIOException("Cannot open stdio file for: $fd"); |
474 } | 512 } |
475 return new _RandomAccessFile(id, ""); | 513 return new _RandomAccessFile(id, ""); |
476 } | 514 } |
477 | 515 |
478 void fullPath(void callback(String result)) { | 516 void fullPath(void callback(String result)) { |
479 _ensureFileService(); | 517 _ensureFileService(); |
480 _asyncUsed = true; | 518 _asyncUsed = true; |
481 List request = new List(2); | 519 List request = new List(2); |
482 request[0] = _FileUtils.kFullPathRequest; | 520 request[0] = _FileUtils.kFullPathRequest; |
483 request[1] = _name; | 521 request[1] = _name; |
484 _fileService.call(request).then((result) { | 522 _fileService.call(request).then((response) { |
485 if (result != null) { | 523 if (_isErrorResponse(response)) { |
486 callback(result); | 524 _reportError(response, "Cannot retrieve full path"); |
487 } else if (_onError != null) { | 525 } else { |
488 _onError("fullPath failed"); | 526 callback(response); |
489 } | 527 } |
490 }); | 528 }); |
491 } | 529 } |
492 | 530 |
493 String fullPathSync() { | 531 String fullPathSync() { |
494 if (_asyncUsed) { | 532 if (_asyncUsed) { |
495 throw new FileIOException( | 533 throw new FileIOException( |
496 "Mixed use of synchronous and asynchronous API"); | 534 "Mixed use of synchronous and asynchronous API"); |
497 } | 535 } |
498 String result = _FileUtils.checkedFullPath(_name); | 536 return _FileUtils.checkedFullPath(_name); |
499 if (result == null) { | |
500 throw new FileIOException("fullPath failed"); | |
501 } | |
502 return result; | |
503 } | 537 } |
504 | 538 |
505 InputStream openInputStream() { | 539 InputStream openInputStream() { |
506 return new _FileInputStream(_name); | 540 return new _FileInputStream(_name); |
507 } | 541 } |
508 | 542 |
509 OutputStream openOutputStream([FileMode mode = FileMode.WRITE]) { | 543 OutputStream openOutputStream([FileMode mode = FileMode.WRITE]) { |
510 if (mode != FileMode.WRITE && | 544 if (mode != FileMode.WRITE && |
511 mode != FileMode.APPEND) { | 545 mode != FileMode.APPEND) { |
512 throw new FileIOException( | 546 throw new FileIOException( |
513 "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND"); | 547 "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND"); |
514 } | 548 } |
515 return new _FileOutputStream(_name, mode); | 549 return new _FileOutputStream(_name, mode); |
516 } | 550 } |
517 | 551 |
518 void readAsBytes(void callback(List<int> bytes)) { | 552 void readAsBytes(void callback(List<int> bytes)) { |
519 _asyncUsed = true; | 553 _asyncUsed = true; |
520 var chunks = new _BufferList(); | 554 var chunks = new _BufferList(); |
521 var stream = openInputStream(); | 555 var stream = openInputStream(); |
522 stream.onClosed = () { | 556 stream.onClosed = () { |
523 callback(chunks.readBytes(chunks.length)); | 557 callback(chunks.readBytes(chunks.length)); |
524 }; | 558 }; |
525 stream.onData = () { | 559 stream.onData = () { |
526 var chunk = stream.read(); | 560 var chunk = stream.read(); |
527 chunks.add(chunk); | 561 chunks.add(chunk); |
528 }; | 562 }; |
529 stream.onError = () { | 563 stream.onError = () { |
530 if (_onError != null) { | 564 if (_onError != null) { |
531 _onError("Failed to read file as bytes: $_name"); | 565 _onError("Failed to read file"); |
532 } | 566 } |
533 }; | 567 }; |
534 } | 568 } |
535 | 569 |
536 List<int> readAsBytesSync() { | 570 List<int> readAsBytesSync() { |
537 if (_asyncUsed) { | 571 if (_asyncUsed) { |
538 throw new FileIOException( | 572 throw new FileIOException( |
539 "Mixed use of synchronous and asynchronous API"); | 573 "Mixed use of synchronous and asynchronous API"); |
540 } | 574 } |
541 var opened = openSync(); | 575 var opened = openSync(); |
542 var length = opened.lengthSync(); | 576 var length = opened.lengthSync(); |
543 var result = new ByteArray(length); | 577 var result = new ByteArray(length); |
544 var read = opened.readListSync(result, 0, length); | 578 var read = opened.readListSync(result, 0, length); |
545 if (read != length) { | 579 if (read != length) { |
546 throw new FileIOException("Failed reading file as bytes: $_name"); | 580 throw new FileIOException("Failed to read file"); |
547 } | 581 } |
548 opened.closeSync(); | 582 opened.closeSync(); |
549 return result; | 583 return result; |
550 } | 584 } |
551 | 585 |
552 void readAsText(Encoding encoding, void callback(String text)) { | 586 void readAsText(Encoding encoding, void callback(String text)) { |
553 _asyncUsed = true; | 587 _asyncUsed = true; |
554 var decoder = _StringDecoders.decoder(encoding); | 588 var decoder = _StringDecoders.decoder(encoding); |
555 readAsBytes((bytes) { | 589 readAsBytes((bytes) { |
556 try { | 590 try { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 void set onError(void handler(String error)) { | 658 void set onError(void handler(String error)) { |
625 _onError = handler; | 659 _onError = handler; |
626 } | 660 } |
627 | 661 |
628 void _ensureFileService() { | 662 void _ensureFileService() { |
629 if (_fileService == null) { | 663 if (_fileService == null) { |
630 _fileService = _FileUtils.newServicePort(); | 664 _fileService = _FileUtils.newServicePort(); |
631 } | 665 } |
632 } | 666 } |
633 | 667 |
| 668 bool _isErrorResponse(response) { |
| 669 return response is List && response[0] != _FileUtils.kSuccessResponse; |
| 670 } |
| 671 |
| 672 bool _reportError(response, String message) { |
| 673 assert(_isErrorResponse(response)); |
| 674 if (_onError != null) { |
| 675 switch (response[0]) { |
| 676 case _FileUtils.kIllegalArgumentResponse: |
| 677 _onError(new IllegalArgumentException()); |
| 678 break; |
| 679 case _FileUtils.kOSErrorResponse: |
| 680 _onError(new FileIOException(message, |
| 681 new OSError(response[2], response[1]))); |
| 682 break; |
| 683 default: |
| 684 _onError(new Exception("Unknown error")); |
| 685 } |
| 686 } |
| 687 } |
| 688 |
634 String _name; | 689 String _name; |
635 bool _asyncUsed; | 690 bool _asyncUsed; |
636 | 691 |
637 SendPort _fileService; | 692 SendPort _fileService; |
638 | 693 |
639 Function _onError; | 694 Function _onError; |
640 } | 695 } |
641 | 696 |
642 | 697 |
643 class _RandomAccessFile implements RandomAccessFile { | 698 class _RandomAccessFile implements RandomAccessFile { |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1043 bool _asyncUsed; | 1098 bool _asyncUsed; |
1044 int _pendingWrites = 0; | 1099 int _pendingWrites = 0; |
1045 | 1100 |
1046 SendPort _fileService; | 1101 SendPort _fileService; |
1047 | 1102 |
1048 Timer _noPendingWriteTimer; | 1103 Timer _noPendingWriteTimer; |
1049 | 1104 |
1050 Function _onNoPendingWrites; | 1105 Function _onNoPendingWrites; |
1051 Function _onError; | 1106 Function _onError; |
1052 } | 1107 } |
OLD | NEW |