Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 1565

Show
Ignore:
Timestamp:
05/29/10 06:00:53 (15 years ago)
Author:
rsinfu
Message:

Made rawRead/rawWrite always operate in binary mode on Windows.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/phobos/std/stdio.d

    r1519 r1565  
    2424private import core.memory, core.stdc.errno, core.stdc.stddef, 
    2525    core.stdc.stdlib, core.stdc.string, core.stdc.wchar_; 
    2626private import std.algorithm, std.array, std.contracts, std.conv, std.file, std.format, 
    2727    /*std.metastrings,*/ std.range, std.string, std.traits, std.typecons, 
    2828    std.typetuple, std.utf; 
    2929 
    3030version (DigitalMars) version (Windows) 
    3131{ 
    3232    // Specific to the way Digital Mars C does stdio 
    3333    version = DIGITAL_MARS_STDIO; 
    34     import std.c.stdio : __fhnd_info, FHND_WCHAR
     34    import std.c.stdio : __fhnd_info, FHND_WCHAR, FHND_TEXT
    3535} 
    3636 
    3737version (linux) 
    3838{ 
    3939    // Specific to the way Gnu C does stdio 
    4040    version = GCC_IO; 
    4141    extern(C) FILE* fopen64(const char*, const char*); 
    4242} 
    4343 
    4444version (OSX) 
     
    6666         * Digital Mars under-the-hood C I/O functions. 
    6767     * Use _iobuf* for the unshared version of FILE*, 
    6868     * usable when the FILE is locked. 
    6969         */ 
    7070        int _fputc_nlock(int, _iobuf*); 
    7171        int _fputwc_nlock(int, _iobuf*); 
    7272        int _fgetc_nlock(_iobuf*); 
    7373        int _fgetwc_nlock(_iobuf*); 
    7474        int __fp_lock(FILE*); 
    7575        void __fp_unlock(FILE*); 
     76 
     77        int setmode(int, int); 
    7678    } 
    7779    alias _fputc_nlock FPUTC; 
    7880    alias _fputwc_nlock FPUTWC; 
    7981    alias _fgetc_nlock FGETC; 
    8082    alias _fgetwc_nlock FGETWC; 
    8183 
    8284    alias __fp_lock FLOCK; 
    8385    alias __fp_unlock FUNLOCK; 
     86 
     87    alias setmode _setmode; 
     88    enum _O_BINARY = 0x8000; 
     89    int _fileno(FILE* f) { return f._file; } 
    8490} 
    8591else version (GCC_IO) 
    8692{ 
    8793    /* ** 
    8894     * Gnu under-the-hood C I/O functions; see 
    8995     * http://www.gnu.org/software/libc/manual/html_node/I_002fO-on-Streams.html#I_002fO-on-Streams 
    9096     */ 
    9197    //private import std.c.linux.linux; 
    9298    private import core.sys.posix.stdio; 
    9399    extern (C) 
     
    429435    { 
    430436        errnoEnforce 
    431437        (.fflush(enforce(p.handle, "Calling fflush() on an unopened file")) 
    432438                == 0); 
    433439    } 
    434440 
    435441/** 
    436442If the file is not opened, throws an exception. Otherwise, calls $(WEB 
    437443cplusplus.com/reference/clibrary/cstdio/fread.html, fread) for the 
    438444file handle and throws on error. 
     445 
     446$(D rawRead) always read in binary mode on Windows. 
    439447 */ 
    440448    T[] rawRead(T)(T[] buffer) 
    441449    { 
    442450        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        } 
    443464        immutable result = 
    444465            .fread(buffer.ptr, T.sizeof, buffer.length, p.handle); 
    445466        errnoEnforce(!error); 
    446467        return result ? buffer[0 .. result] : null; 
    447468    } 
    448469 
     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 
    449484/** 
    450485If the file is not opened, throws an exception. Otherwise, calls $(WEB 
    451486cplusplus.com/reference/clibrary/cstdio/fwrite.html, fwrite) for the 
    452487file handle and throws on error. 
     488 
     489$(D rawWrite) always write in binary mode on Windows. 
    453490 */ 
    454491    void rawWrite(T)(in T[] buffer) 
    455492    { 
     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        } 
    456508        auto result = 
    457509            .fwrite(buffer.ptr, T.sizeof, buffer.length, p.handle); 
    458510        if (result == result.max) result = 0; 
    459511        errnoEnforce(result == buffer.length, 
    460512                text("Wrote ", result, " instead of ", buffer.length, 
    461513                        " objects of type ", T.stringof, " to file `", 
    462514                        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        +/ 
    463527    } 
    464528 
    465529/** 
    466530If the file is not opened, throws an exception. Otherwise, calls $(WEB 
    467531cplusplus.com/reference/clibrary/cstdio/fseek.html, fseek) for the 
    468532file handle. Throws on error. 
    469533 */ 
    470534    void seek(long offset, int origin = SEEK_SET) 
    471535    { 
    472536        enforce(p && p.handle,