Changeset 1565
- Timestamp:
- 05/29/10 06:00:53 (15 years ago)
- Files:
-
- trunk/phobos/std/stdio.d (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/phobos/std/stdio.d
r1519 r1565 24 24 private import core.memory, core.stdc.errno, core.stdc.stddef, 25 25 core.stdc.stdlib, core.stdc.string, core.stdc.wchar_; 26 26 private import std.algorithm, std.array, std.contracts, std.conv, std.file, std.format, 27 27 /*std.metastrings,*/ std.range, std.string, std.traits, std.typecons, 28 28 std.typetuple, std.utf; 29 29 30 30 version (DigitalMars) version (Windows) 31 31 { 32 32 // Specific to the way Digital Mars C does stdio 33 33 version = DIGITAL_MARS_STDIO; 34 import std.c.stdio : __fhnd_info, FHND_WCHAR ;34 import std.c.stdio : __fhnd_info, FHND_WCHAR, FHND_TEXT; 35 35 } 36 36 37 37 version (linux) 38 38 { 39 39 // Specific to the way Gnu C does stdio 40 40 version = GCC_IO; 41 41 extern(C) FILE* fopen64(const char*, const char*); 42 42 } 43 43 44 44 version (OSX) … … 66 66 * Digital Mars under-the-hood C I/O functions. 67 67 * Use _iobuf* for the unshared version of FILE*, 68 68 * usable when the FILE is locked. 69 69 */ 70 70 int _fputc_nlock(int, _iobuf*); 71 71 int _fputwc_nlock(int, _iobuf*); 72 72 int _fgetc_nlock(_iobuf*); 73 73 int _fgetwc_nlock(_iobuf*); 74 74 int __fp_lock(FILE*); 75 75 void __fp_unlock(FILE*); 76 77 int setmode(int, int); 76 78 } 77 79 alias _fputc_nlock FPUTC; 78 80 alias _fputwc_nlock FPUTWC; 79 81 alias _fgetc_nlock FGETC; 80 82 alias _fgetwc_nlock FGETWC; 81 83 82 84 alias __fp_lock FLOCK; 83 85 alias __fp_unlock FUNLOCK; 86 87 alias setmode _setmode; 88 enum _O_BINARY = 0x8000; 89 int _fileno(FILE* f) { return f._file; } 84 90 } 85 91 else version (GCC_IO) 86 92 { 87 93 /* ** 88 94 * Gnu under-the-hood C I/O functions; see 89 95 * http://www.gnu.org/software/libc/manual/html_node/I_002fO-on-Streams.html#I_002fO-on-Streams 90 96 */ 91 97 //private import std.c.linux.linux; 92 98 private import core.sys.posix.stdio; 93 99 extern (C) … … 429 435 { 430 436 errnoEnforce 431 437 (.fflush(enforce(p.handle, "Calling fflush() on an unopened file")) 432 438 == 0); 433 439 } 434 440 435 441 /** 436 442 If the file is not opened, throws an exception. Otherwise, calls $(WEB 437 443 cplusplus.com/reference/clibrary/cstdio/fread.html, fread) for the 438 444 file handle and throws on error. 445 446 $(D rawRead) always read in binary mode on Windows. 439 447 */ 440 448 T[] rawRead(T)(T[] buffer) 441 449 { 442 450 enforce(buffer.length); 451 version(Windows) 452 { 453 immutable fd = ._fileno(p.handle); 454 immutable mode = ._setmode(fd, _O_BINARY); 455 scope(exit) ._setmode(fd, mode); 456 version(DIGITAL_MARS_STDIO) 457 { 458 // @@@BUG@@@ 4243 459 immutable info = __fhnd_info[fd]; 460 __fhnd_info[fd] &= ~FHND_TEXT; 461 scope(exit) __fhnd_info[fd] = info; 462 } 463 } 443 464 immutable result = 444 465 .fread(buffer.ptr, T.sizeof, buffer.length, p.handle); 445 466 errnoEnforce(!error); 446 467 return result ? buffer[0 .. result] : null; 447 468 } 448 469 470 unittest 471 { 472 std.file.write("deleteme", "\r\n\n\r\n"); 473 scope(exit) std.file.remove("deleteme"); 474 auto f = File("deleteme", "r"); 475 auto buf = f.rawRead(new char[5]); 476 f.close(); 477 assert(buf == "\r\n\n\r\n"); 478 /+ 479 buf = stdin.rawRead(new char[5]); 480 assert(buf == "\r\n\n\r\n"); 481 +/ 482 } 483 449 484 /** 450 485 If the file is not opened, throws an exception. Otherwise, calls $(WEB 451 486 cplusplus.com/reference/clibrary/cstdio/fwrite.html, fwrite) for the 452 487 file handle and throws on error. 488 489 $(D rawWrite) always write in binary mode on Windows. 453 490 */ 454 491 void rawWrite(T)(in T[] buffer) 455 492 { 493 version(Windows) 494 { 495 flush(); // before changing translation mode 496 immutable fd = ._fileno(p.handle); 497 immutable mode = ._setmode(fd, _O_BINARY); 498 scope(exit) ._setmode(fd, mode); 499 version(DIGITAL_MARS_STDIO) 500 { 501 // @@@BUG@@@ 4243 502 immutable info = __fhnd_info[fd]; 503 __fhnd_info[fd] &= ~FHND_TEXT; 504 scope(exit) __fhnd_info[fd] = info; 505 } 506 scope(exit) flush(); // before restoring translation mode 507 } 456 508 auto result = 457 509 .fwrite(buffer.ptr, T.sizeof, buffer.length, p.handle); 458 510 if (result == result.max) result = 0; 459 511 errnoEnforce(result == buffer.length, 460 512 text("Wrote ", result, " instead of ", buffer.length, 461 513 " objects of type ", T.stringof, " to file `", 462 514 p.name, "'")); 515 } 516 517 unittest 518 { 519 auto f = File("deleteme", "w"); 520 scope(exit) std.file.remove("deleteme"); 521 f.rawWrite("\r\n\n\r\n"); 522 f.close(); 523 assert(std.file.read("deleteme") == "\r\n\n\r\n"); 524 /+ 525 stdout.rawWrite("\r\n\n\r\n"); 526 +/ 463 527 } 464 528 465 529 /** 466 530 If the file is not opened, throws an exception. Otherwise, calls $(WEB 467 531 cplusplus.com/reference/clibrary/cstdio/fseek.html, fseek) for the 468 532 file handle. Throws on error. 469 533 */ 470 534 void seek(long offset, int origin = SEEK_SET) 471 535 { 472 536 enforce(p && p.handle,
