/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 | } |