Skip to content
FileReadAndClose

FileReadAndClose

Description

Slurp a file from disk in one call: open, read-to-EOF into out, close. out may be a Buf * (binary) or Str * (text). Removes the open/read/close ceremony that’s nearly identical across every parser caller. The fast path inside file_read_to_{buf,str} (one- shot reserve via FileSeek(END)) still applies.

Parameters

Name Direction Description
path in Path to open. Str * / Zstr (NUL-terminated).
out out Already-init’d Buf * or Str *. Existing content is overwritten; the destination’s allocator drives growth.

Success

Returns bytes loaded (>= 0); file is closed.

Failure

Returns -1; file is closed; out may be in a partial state – caller should BufDeinit / StrDeinit if it was a fresh container.

Usage example (Cross-references)

Usage examples (Cross-references)
        }
        Buf data = BufInit(alloc);
        if (FileReadAndClose(path, &data) < 0) {
            BufDeinit(&data);
            LOG_ERROR("PeOpen: failed to read {}", path);
        }
        Buf data = BufInit(alloc);
        if (FileReadAndClose(path, &data) < 0) {
            BufDeinit(&data);
            LOG_ERROR("PdbOpen: failed to read {}", path);
    bool TzifLocalOffsetSeconds(i64 unix_seconds, i32 *out_offset_seconds, Allocator *alloc) {
        Buf data = BufInit(alloc);
        if (FileReadAndClose("/etc/localtime", &data) < 0) {
            BufDeinit(&data);
            LOG_ERROR("Tzif: cannot read /etc/localtime");
        StrDeinit(&response->body);
        response->body = StrInit(response->allocator);
        if (FileReadAndClose(filepath, &response->body) < 0) {
            LOG_ERROR("failed to read file: {}", filepath);
            return NULL;
        }
        Buf data = BufInit(alloc);
        if (FileReadAndClose(path, &data) < 0) {
            BufDeinit(&data);
            LOG_ERROR("MachoOpen: failed to read {}", path);
        }
        Buf data = BufInit(alloc);
        if (FileReadAndClose(path, &data) < 0) {
            BufDeinit(&data);
            LOG_ERROR("ElfOpen: failed to read {}", path);
    // the open+op+close convenience round-trip.
    bool test_write_and_read_and_close(void) {
        WriteFmt("Testing FileWriteAndClose + FileReadAndClose round-trip\n");
    
        DefaultAllocator alloc      = DefaultAllocatorInit();
    
        Str body = StrInit(alloc_base);
        i64 got  = FileReadAndClose(&path, &body);
        ok       = ok && (got == (i64)n) && (StrLen(&body) == (size)n) && ZstrCompare(StrBegin(&body), payload) == 0;
    // failed) rather than a bogus byte count.
    bool test_read_and_close_missing_path(void) {
        WriteFmt("Testing FileReadAndClose on a missing path returns -1\n");
    
        DefaultAllocator alloc      = DefaultAllocatorInit();
    
        Str  body = StrInit(alloc_base);
        i64  got  = FileReadAndClose(&path, &body);
        bool ok   = (got == -1);
    
        Str body = StrInit(alloc_base);
        i64 got  = FileReadAndClose(&path, &body);
        ok       = ok && (got == 10) && ZstrCompare(StrBegin(&body), "helloworld") == 0;
    // content and length.
    bool test_fm_498_write_close_read_close_roundtrip(void) {
        WriteFmt("Testing FileWriteAndClose + FileReadAndClose exact round-trip\n");
    
        DefaultAllocator alloc      = DefaultAllocatorInit();
    
        Str body = StrInit(alloc_base);
        i64 got  = FileReadAndClose(&path, &body);
        ok       = ok && (got == (i64)n) && (StrLen(&body) == (size)n) && ZstrCompare(StrBegin(&body), payload) == 0;
    
        Str body = StrInit(alloc_base);
        i64 got  = FileReadAndClose(&path, &body);
        ok       = ok && (got == 0) && (StrLen(&body) == 0);
    
        Str body = StrInit(alloc_base);
        i64 got  = FileReadAndClose(&path, &body);
        ok       = ok && (got == 5) && ZstrCompare(StrBegin(&body), "12345") == 0;
    
        Str body = StrInit(alloc_base);
        i64 got  = FileReadAndClose(&path, &body);
        ok       = ok && (got == (i64)StrLen(&in)) && ZstrCompare(StrBegin(&body), "string-content") == 0;
        Str b1 = StrInit(alloc_base);
        Str b2 = StrInit(alloc_base);
        ok     = ok && (FileReadAndClose(&p1, &b1) == 3) && ZstrCompare(StrBegin(&b1), "one") == 0;
        ok     = ok && (FileReadAndClose(&p2, &b2) == 6) && ZstrCompare(StrBegin(&b2), "twotwo") == 0;
        Str b2 = StrInit(alloc_base);
        ok     = ok && (FileReadAndClose(&p1, &b1) == 3) && ZstrCompare(StrBegin(&b1), "one") == 0;
        ok     = ok && (FileReadAndClose(&p2, &b2) == 6) && ZstrCompare(StrBegin(&b2), "twotwo") == 0;
    
        StrDeinit(&b1);
        // The file was truncated to empty.
        Str body = StrInit(alloc_base);
        i64 got  = FileReadAndClose(&path, &body);
        ok       = ok && (got == 0) && (StrLen(&body) == 0);
Last updated on