@@ -9,40 +9,33 @@ The full license is in the LICENSE file, distributed with this software.
9
9
10
10
#include "io.h"
11
11
12
- #include <sys/types.h>
13
- #include <sys/stat.h>
14
- #include <fcntl.h>
15
-
16
12
/*
17
13
On-disk FILE, uncompressed
18
14
*/
19
15
20
16
void *new_file_source(char *fname, size_t buffer_size) {
21
17
file_source *fs = (file_source *)malloc(sizeof(file_source));
22
- if (fs == NULL) {
18
+ fs->fp = fopen(fname, "rb");
19
+
20
+ if (fs->fp == NULL) {
21
+ free(fs);
23
22
return NULL;
24
23
}
24
+ setbuf(fs->fp, NULL);
25
25
26
- fs->fd = open(fname, O_RDONLY);
27
- if (fs->fd == -1) {
28
- goto err_free;
29
- }
26
+ fs->initial_file_pos = ftell(fs->fp);
30
27
31
28
// Only allocate this heap memory if we are not memory-mapping the file
32
29
fs->buffer = (char *)malloc((buffer_size + 1) * sizeof(char));
33
30
34
31
if (fs->buffer == NULL) {
35
- goto err_free ;
32
+ return NULL ;
36
33
}
37
34
38
- memset(fs->buffer, '\0' , buffer_size + 1);
39
- fs->size = buffer_size ;
35
+ memset(fs->buffer, 0 , buffer_size + 1);
36
+ fs->buffer[buffer_size] = '\0' ;
40
37
41
38
return (void *)fs;
42
-
43
- err_free:
44
- free(fs);
45
- return NULL;
46
39
}
47
40
48
41
void *new_rd_source(PyObject *obj) {
@@ -63,12 +56,12 @@ void *new_rd_source(PyObject *obj) {
63
56
64
57
*/
65
58
66
- int del_file_source(void *ptr) {
67
- file_source *fs = ptr;
59
+ int del_file_source(void *fs) {
68
60
if (fs == NULL) return 0;
69
61
70
- free(fs->buffer);
71
- close(fs->fd);
62
+ /* allocated on the heap */
63
+ free(FS(fs)->buffer);
64
+ fclose(FS(fs)->fp);
72
65
free(fs);
73
66
74
67
return 0;
@@ -90,31 +83,17 @@ int del_rd_source(void *rds) {
90
83
91
84
void *buffer_file_bytes(void *source, size_t nbytes, size_t *bytes_read,
92
85
int *status) {
93
- file_source *fs = FS(source);
94
- ssize_t rv;
86
+ file_source *src = FS(source);
95
87
96
- if (nbytes > fs->size) {
97
- nbytes = fs->size;
98
- }
88
+ *bytes_read = fread((void *)src->buffer, sizeof(char), nbytes, src->fp);
99
89
100
- rv = read(fs->fd, fs->buffer, nbytes);
101
- switch (rv) {
102
- case -1:
103
- *status = CALLING_READ_FAILED;
104
- *bytes_read = 0;
105
- return NULL;
106
- case 0:
90
+ if (*bytes_read == 0) {
107
91
*status = REACHED_EOF;
108
- *bytes_read = 0;
109
- return NULL;
110
- default:
92
+ } else {
111
93
*status = 0;
112
- *bytes_read = rv;
113
- fs->buffer[rv] = '\0';
114
- break;
115
94
}
116
95
117
- return (void *)fs ->buffer;
96
+ return (void *)src ->buffer;
118
97
}
119
98
120
99
void *buffer_rd_bytes(void *source, size_t nbytes, size_t *bytes_read,
@@ -173,86 +152,81 @@ void *buffer_rd_bytes(void *source, size_t nbytes, size_t *bytes_read,
173
152
#ifdef HAVE_MMAP
174
153
175
154
#include <sys/mman.h>
155
+ #include <sys/stat.h>
176
156
177
157
void *new_mmap(char *fname) {
158
+ struct stat buf;
159
+ int fd;
178
160
memory_map *mm;
179
- struct stat stat;
180
- size_t filesize;
161
+ off_t filesize;
181
162
182
163
mm = (memory_map *)malloc(sizeof(memory_map));
164
+ mm->fp = fopen(fname, "rb");
165
+
166
+ fd = fileno(mm->fp);
167
+ if (fstat(fd, &buf) == -1) {
168
+ fprintf(stderr, "new_file_buffer: fstat() failed. errno =%d\n", errno);
169
+ return NULL;
170
+ }
171
+ filesize = buf.st_size; /* XXX This might be 32 bits. */
172
+
183
173
if (mm == NULL) {
174
+ /* XXX Eventually remove this print statement. */
184
175
fprintf(stderr, "new_file_buffer: malloc() failed.\n");
185
- return (NULL);
186
- }
187
- mm->fd = open(fname, O_RDONLY);
188
- if (mm->fd == -1) {
189
- fprintf(stderr, "new_file_buffer: open(%s) failed. errno =%d\n",
190
- fname, errno);
191
- goto err_free;
176
+ return NULL;
192
177
}
178
+ mm->size = (off_t)filesize;
179
+ mm->line_number = 0;
193
180
194
- if (fstat(mm->fd, &stat) == -1) {
195
- fprintf(stderr, "new_file_buffer: fstat() failed. errno =%d\n",
196
- errno);
197
- goto err_close;
198
- }
199
- filesize = stat.st_size; /* XXX This might be 32 bits. */
181
+ mm->fileno = fd;
182
+ mm->position = ftell(mm->fp);
183
+ mm->last_pos = (off_t)filesize;
200
184
201
- mm->memmap = mmap(NULL, filesize, PROT_READ, MAP_SHARED, mm-> fd, 0);
202
- if (mm->memmap == MAP_FAILED ) {
185
+ mm->memmap = mmap(NULL, filesize, PROT_READ, MAP_SHARED, fd, 0);
186
+ if (mm->memmap == NULL ) {
203
187
/* XXX Eventually remove this print statement. */
204
188
fprintf(stderr, "new_file_buffer: mmap() failed.\n");
205
- goto err_close;
189
+ free(mm);
190
+ mm = NULL;
206
191
}
207
192
208
- mm->size = (off_t)filesize;
209
- mm->position = 0;
210
-
211
- return mm;
212
-
213
- err_close:
214
- close(mm->fd);
215
- err_free:
216
- free(mm);
217
- return NULL;
193
+ return (void *)mm;
218
194
}
219
195
220
- int del_mmap(void *ptr) {
221
- memory_map *mm = ptr;
222
-
223
- if (mm == NULL) return 0;
196
+ int del_mmap(void *src) {
197
+ munmap(MM(src)->memmap, MM(src)->size);
224
198
225
- munmap(mm->memmap, mm->size);
226
- close(mm->fd);
227
- free(mm);
199
+ fclose(MM(src)->fp);
200
+ free(src);
228
201
229
202
return 0;
230
203
}
231
204
232
205
void *buffer_mmap_bytes(void *source, size_t nbytes, size_t *bytes_read,
233
206
int *status) {
234
207
void *retval;
235
- memory_map *src = source;
236
- size_t remaining = src->size - src->position;
208
+ memory_map *src = MM(source);
237
209
238
- if (remaining == 0 ) {
210
+ if (src->position == src->last_pos ) {
239
211
*bytes_read = 0;
240
212
*status = REACHED_EOF;
241
213
return NULL;
242
214
}
243
215
244
- if (nbytes > remaining) {
245
- nbytes = remaining;
246
- }
247
-
248
216
retval = src->memmap + src->position;
249
217
250
- /* advance position in mmap data structure */
251
- src->position += nbytes;
218
+ if (src->position + (off_t)nbytes > src->last_pos) {
219
+ // fewer than nbytes remaining
220
+ *bytes_read = src->last_pos - src->position;
221
+ } else {
222
+ *bytes_read = nbytes;
223
+ }
252
224
253
- *bytes_read = nbytes;
254
225
*status = 0;
255
226
227
+ /* advance position in mmap data structure */
228
+ src->position += *bytes_read;
229
+
256
230
return retval;
257
231
}
258
232
0 commit comments