std.file.read implementation contest

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Mon Feb 16 13:27:01 PST 2009


Steven Schveighoffer wrote:
> "Andrei Alexandrescu" wrote
>> Someone mentioned an old bug in std.file.read here:
>>
>> http://www.reddit.com/r/programming/comments/7xnty/walter_bright_on_porting_d_to_the_mac/
>>
>> Two programmers sent in patches for the function. Which is to be committed 
>> and why? (Linux versions shown. Apologies for noisy line breaks.)
> 
> Implementation 2, save 1 bug:
[snip]

Aha, cool. Thanks for the info. I've adapted the code to still only use 
one loop:

void[] read(string name)
{
     immutable fd = std.c.linux.linux.open(toStringz(name), O_RDONLY);
     cenforce(fd != -1, name);
     scope(exit) std.c.linux.linux.close(fd);

     struct_stat statbuf = void;
     cenforce(std.c.linux.linux.fstat(fd, &statbuf) == 0, name);

     immutable initialAlloc = statbuf.st_size
         ? (statbuf.st_size + 16) & 15
         : 1024;
     void[] result = GC.malloc(initialAlloc, GC.BlkAttr.NO_SCAN)
         [0 .. initialAlloc];
     scope(failure) delete result;
     size_t size = 0;

     for (;;)
     {
         immutable actual = std.c.linux.linux.read(fd, result.ptr + size,
                 result.length - size);
         cenforce(actual != -1, name);
         if (actual == 0) break;
         size += actual;
         if (size < result.length) continue;
         auto newAlloc = size + 1024 * 4;
         result = GC.realloc(result.ptr, newAlloc, GC.BlkAttr.NO_SCAN)
             [0 .. newAlloc];
     }

     return result[0 .. size];
}

One more improvement suggested by Walter - I allocate a multiple of 16 
because that's allocator's granularity.


Andrei



More information about the Digitalmars-d mailing list