Skip to content

FileSeek

Description

Adjust the file offset relative to whence.

Success

Returns the new absolute file offset (>= 0).

Failure

Returns -1 on error (typically ESPIPE for a pipe/tty).

Usage example (Cross-references)

Usage examples (Cross-references)
    }
    
    i64 FileSeek(File *f, i64 offset, FileWhence whence) {
        if (!FileIsOpen(f)) {
            return -1;
    
    i64 FileTell(File *f) {
        return FileSeek(f, 0, FILE_SEEK_CUR);
    }
        // channel is positionable; if it returns -1 (ESPIPE / Windows
        // equivalent) treat the input as a stream and pull bytes until EOF.
        i64 probe = FileSeek(file, 0, FILE_SEEK_CUR);
        if (probe < 0 || fd == 0 || fd == 1 || fd == 2) {
            LOG_INFO("Reading from non-seekable channel.");
            // actually consumed".
            i64 cur_pos = probe;
            i64 end_pos = FileSeek(file, 0, FILE_SEEK_END);
            if (end_pos < 0) {
                LOG_ERROR("FileSeek(END) failed during f_read_fmt");
            i64 end_pos = FileSeek(file, 0, FILE_SEEK_END);
            if (end_pos < 0) {
                LOG_ERROR("FileSeek(END) failed during f_read_fmt");
                StrDeinit(&buffer);
                DefaultAllocatorDeinit(&scratch);
            }
            i64 file_len = end_pos - cur_pos;
            (void)FileSeek(file, cur_pos, FILE_SEEK_SET);
    
            if (file_len > 0) {
                if (!new_pos) {
                    LOG_ERROR("Parse failed, rolling back...");
                    (void)FileSeek(file, cur_pos, FILE_SEEK_SET);
                } else {
                    // Advance the channel position past the bytes we consumed.
                    // Advance the channel position past the bytes we consumed.
                    i64 consumed = (i64)(new_pos - StrBegin(&buffer));
                    (void)FileSeek(file, cur_pos + consumed, FILE_SEEK_SET);
                }
            }
        ok              = ok && (FileRead(&f, scratch, sizeof(scratch)) == -1);
        ok              = ok && (FileWrite(&f, "x", 1) == -1);
        ok              = ok && (FileSeek(&f, 0, FILE_SEEK_SET) == -1);
        ok              = ok && (FileTell(&f) == -1);
    // observable values.
    bool test_write_seek_read_roundtrip(void) {
        WriteFmt("Testing FileWrite/FileSeek/FileTell/FileRead round-trip\n");
    
        DefaultAllocator alloc      = DefaultAllocatorInit();
    
        // Seek to absolute offset 2 and confirm Tell agrees.
        ok = ok && (FileSeek(&f, 2, FILE_SEEK_SET) == 2);
        ok = ok && (FileTell(&f) == 2);
    
        // Seek to end yields the file length.
        ok = ok && (FileSeek(&f, 0, FILE_SEEK_END) == 8);
    
        FileClose(&f);
        // FileWrite must report exactly 12 bytes written.
        bool ok = (FileWrite(&f, "ABCDEFGHIJKL", 12) == 12);
        ok      = ok && (FileSeek(&f, 0, FILE_SEEK_SET) == 0);
    
        char buf[5] = {0};
    // the eof flag so a subsequent read can succeed again.
    bool test_fm_317_seek_clears_eof(void) {
        WriteFmt("Testing FileSeek clears eof and returns the new offset\n");
    
        DefaultAllocator alloc      = DefaultAllocatorInit();
    
        // Seek back to start: returns offset 0 and clears the eof flag.
        ok = ok && (FileSeek(&f, 0, FILE_SEEK_SET) == 0);
        ok = ok && !FileIsEof(&f);
        // And reading now succeeds again from the top.
    // result return, line 328/332).
    bool test_fm_328_seek_cur_offset(void) {
        WriteFmt("Testing FileSeek SEEK_CUR returns the running absolute offset\n");
    
        DefaultAllocator alloc      = DefaultAllocatorInit();
        }
        bool ok = (FileWrite(&f, "0123456789", 10) == 10);
        ok      = ok && (FileSeek(&f, 0, FILE_SEEK_SET) == 0);
        // Advance 3 from current (0 -> 3).
        ok = ok && (FileSeek(&f, 3, FILE_SEEK_CUR) == 3);
        ok      = ok && (FileSeek(&f, 0, FILE_SEEK_SET) == 0);
        // Advance 3 from current (0 -> 3).
        ok = ok && (FileSeek(&f, 3, FILE_SEEK_CUR) == 3);
        // Advance 4 more (3 -> 7).
        ok          = ok && (FileSeek(&f, 4, FILE_SEEK_CUR) == 7);
        ok = ok && (FileSeek(&f, 3, FILE_SEEK_CUR) == 3);
        // Advance 4 more (3 -> 7).
        ok          = ok && (FileSeek(&f, 4, FILE_SEEK_CUR) == 7);
        char buf[2] = {0};
        ok          = ok && (FileRead(&f, buf, 1) == 1) && (buf[0] == '7');
        ok     = ok && FileIsOpen(&f);
        // Move the cursor to offset 10; remaining size must be 16 - 10 = 6.
        ok = ok && (FileSeek(&f, 10, FILE_SEEK_SET) == 10);
    
        Str body = StrInit(alloc_base);
        // Round-trip a payload through the freshly created temp file.
        ok           = ok && (FileWrite(&f, "temp-data", 9) == 9);
        ok           = ok && (FileSeek(&f, 0, FILE_SEEK_SET) == 0);
        char buf[10] = {0};
        ok           = ok && (FileRead(&f, buf, 9) == 9) && (MemCompare(buf, "temp-data", 9) == 0);
            LOG_FATAL("capture_help: expected ARG_RUN_HELP, got {}", (int)rc);
    
        FileSeek(&tmp, 0, FILE_SEEK_SET);
        FileRead(&tmp, out);
        FileClose(&tmp);
    
        bool ok = (rc == ARG_RUN_HELP);
        FileSeek(&tmp, 0, FILE_SEEK_SET);
        FileRead(&tmp, out);
        FileClose(&tmp);
        p->out    = NULL;
    
        FileSeek(&tmp, 0, FILE_SEEK_SET);
        FileRead(&tmp, out);
        FileClose(&tmp);
            return f;
        FileWrite(&f, content, len);
        FileSeek(&f, 0, FILE_SEEK_SET);
        return f;
    }
            return f;
        FileWrite(&f, content, len);
        FileSeek(&f, 0, FILE_SEEK_SET);
        return f;
    }
        if (ok) {
            FileWrite(&f, "42", 2);
            FileSeek(&f, 0, FILE_SEEK_SET);
            i32 v = 0;
            FReadFmt(&f, "{}", v);
        if (ok) {
            FileWrite(&f, "xx", 2);
            FileSeek(&f, 0, FILE_SEEK_SET);
            i32 v = 123;
            FReadFmt(&f, "{}", v); // fails -> rollback
Last updated on