Coverage Report

Created: 2025-07-18 06:08

/src/readstat/src/readstat_io_unistd.c
Line
Count
Source (jump to first uncovered line)
1
2
#include <fcntl.h>
3
#include <stdlib.h>
4
#include <wchar.h>
5
6
#if defined _WIN32
7
#   include <windows.h>
8
#   include <io.h>
9
#endif
10
11
#if !defined(_MSC_VER)
12
#   include <unistd.h>
13
#else
14
#define open _open
15
#define read _read
16
#define close _close
17
#endif
18
19
#if defined _WIN32 || defined __CYGWIN__
20
#define UNISTD_OPEN_OPTIONS O_RDONLY | O_BINARY
21
#elif defined _AIX
22
#define UNISTD_OPEN_OPTIONS O_RDONLY | O_LARGEFILE
23
#else
24
0
#define UNISTD_OPEN_OPTIONS O_RDONLY
25
#endif
26
27
#if defined _WIN32
28
#define lseek _lseeki64
29
#elif defined _AIX
30
#define lseek lseek64
31
#endif
32
33
#include "readstat.h"
34
#include "readstat_io_unistd.h"
35
36
int open_with_unicode(const char *path, int options)
37
0
{
38
#if defined _WIN32
39
    const int buffer_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
40
41
    if(buffer_size <= 0)
42
        return -1;
43
44
    wchar_t* wpath = malloc((buffer_size + 1) * sizeof(wchar_t));
45
    const int res = MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, buffer_size);
46
    wpath[buffer_size] = 0;
47
48
    if(res <= 0)
49
    {
50
        free(wpath);
51
        return -1;
52
    }
53
54
    int fd = _wopen(wpath, options);
55
56
    free(wpath);
57
    return fd;
58
#else
59
0
    return open(path, options);
60
0
#endif
61
0
}
62
63
0
int unistd_open_handler(const char *path, void *io_ctx) {
64
0
    int fd = open_with_unicode(path, UNISTD_OPEN_OPTIONS);
65
0
    ((unistd_io_ctx_t*) io_ctx)->fd = fd;
66
0
    return fd;
67
0
}
68
69
0
int unistd_close_handler(void *io_ctx) {
70
0
    int fd = ((unistd_io_ctx_t*) io_ctx)->fd;
71
0
    if (fd != -1)
72
0
        return close(fd);
73
0
    else
74
0
        return 0;
75
0
}
76
77
readstat_off_t unistd_seek_handler(readstat_off_t offset,
78
0
        readstat_io_flags_t whence, void *io_ctx) {
79
0
    int flag = 0;
80
0
    switch(whence) {
81
0
        case READSTAT_SEEK_SET:
82
0
            flag = SEEK_SET;
83
0
            break;
84
0
        case READSTAT_SEEK_CUR:
85
0
            flag = SEEK_CUR;
86
0
            break;
87
0
        case READSTAT_SEEK_END:
88
0
            flag = SEEK_END;
89
0
            break;
90
0
        default:
91
0
            return -1;
92
0
    }
93
0
    int fd = ((unistd_io_ctx_t*) io_ctx)->fd;
94
0
    return lseek(fd, offset, flag);
95
0
}
96
97
0
ssize_t unistd_read_handler(void *buf, size_t nbyte, void *io_ctx) {
98
0
    int fd = ((unistd_io_ctx_t*) io_ctx)->fd;
99
0
    ssize_t out = read(fd, buf, nbyte);
100
0
    return out;
101
0
}
102
103
readstat_error_t unistd_update_handler(long file_size, 
104
        readstat_progress_handler progress_handler, void *user_ctx,
105
0
        void *io_ctx) {
106
0
    if (!progress_handler)
107
0
        return READSTAT_OK;
108
109
0
    int fd = ((unistd_io_ctx_t*) io_ctx)->fd;
110
0
    readstat_off_t current_offset = lseek(fd, 0, SEEK_CUR);
111
112
0
    if (current_offset == -1)
113
0
        return READSTAT_ERROR_SEEK;
114
115
0
    if (progress_handler(1.0 * current_offset / file_size, user_ctx))
116
0
        return READSTAT_ERROR_USER_ABORT;
117
118
0
    return READSTAT_OK;
119
0
}
120
121
21.0k
readstat_error_t unistd_io_init(readstat_parser_t *parser) {
122
21.0k
    readstat_error_t retval = READSTAT_OK;
123
21.0k
    unistd_io_ctx_t *io_ctx = NULL;
124
125
21.0k
    if ((retval = readstat_set_open_handler(parser, unistd_open_handler)) != READSTAT_OK)
126
0
        return retval;
127
128
21.0k
    if ((retval = readstat_set_close_handler(parser, unistd_close_handler)) != READSTAT_OK)
129
0
        return retval;
130
131
21.0k
    if ((retval = readstat_set_seek_handler(parser, unistd_seek_handler)) != READSTAT_OK)
132
0
        return retval;
133
134
21.0k
    if ((retval = readstat_set_read_handler(parser, unistd_read_handler)) != READSTAT_OK)
135
0
        return retval;
136
137
21.0k
    if ((readstat_set_update_handler(parser, unistd_update_handler)) != READSTAT_OK)
138
0
        return retval;
139
140
21.0k
    io_ctx = calloc(1, sizeof(unistd_io_ctx_t));
141
21.0k
    io_ctx->fd = -1;
142
143
21.0k
    retval = readstat_set_io_ctx(parser, (void*) io_ctx);
144
21.0k
    parser->io->io_ctx_needs_free = 1;
145
146
21.0k
    return retval;
147
21.0k
}