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