]> git.donarmstrong.com Git - biopieces.git/blob - code_c/Maasha/src/lib/filesys.c
read_fasta fix for stupid \r
[biopieces.git] / code_c / Maasha / src / lib / filesys.c
1 #include "common.h"
2 #include "mem.h"
3 #include "filesys.h"
4
5
6 FILE *read_open( char *file )
7 {
8     /* Martin A. Hansen, November 2005 */
9
10     /* Unit test done. */
11
12     /* Given a file name, read-opens the file, */
13     /* and returns a file pointer. */
14     
15     FILE *fp;
16
17     if ( ( fp = fopen( file, "r" ) ) == NULL )
18     {
19         fprintf( stderr, "ERROR: Could not read-open file '%s': %s\n", file, strerror( errno ) );
20         abort();
21     }
22
23     return fp;
24 }
25
26
27 FILE *write_open( char *file )
28 {
29     /* Martin A. Hansen, November 2005 */
30
31     /* Unit test done. */
32
33     /* Given a file name, write-opens the file, */
34     /* and returns a file pointer. */
35     
36     FILE *fp;
37
38     if ( ( fp = fopen( file, "w" ) ) == NULL )
39     {
40         fprintf( stderr, "ERROR: Could not write-open file '%s': %s\n", file, strerror( errno ) );
41         abort();
42     }
43
44     return fp;
45 }
46
47
48 FILE *append_open( char *file )
49 {
50     /* Martin A. Hansen, November 2005 */
51
52     /* Unit test done. */
53
54     /* Given a file name, append-opens the file, */
55     /* and returns a file pointer. */
56     
57     FILE *fp;
58
59     if ( ( fp = fopen( file, "a" ) ) == NULL )
60     {
61         fprintf( stderr, "ERROR: Could not append-open file '%s': %s\n", file, strerror( errno ) );
62         abort();
63     }
64
65     return fp;
66 }
67
68
69 void close_stream( FILE *fp )
70 {
71     /* Martin A. Hansen, May 2008 */
72
73     /* Unit test done. */
74
75     /* Closes a stream or file associated with a given file pointer. */
76
77     if ( ( fclose( fp ) ) != 0 )
78     {
79         fprintf( stderr, "ERROR: Could not close stream: %s\n", strerror( errno ) );    
80         abort();
81     }
82 }
83
84
85 size_t file_read( FILE *fp, char **string_ppt, size_t len )
86 {
87     /* Martin A. Hansen, June 2008 */
88
89     /* Read in len number of bytes from the current position of a */
90     /* file pointer into a string that is allocated and null terminated. */
91     /* The number of read chars is returned. */
92
93     char   *string = *string_ppt;
94     size_t  num    = 0;
95
96     assert( len > 0 );
97
98     string = mem_get( len + 1 );
99
100     num = fread( string, 1, len, fp );
101
102     if ( ferror( fp ) != 0 )
103     {
104         fprintf( stderr, "ERROR: file_read failed\n" );
105         abort();
106     }
107
108     string[ num ] = '\0';
109
110     *string_ppt = string;
111
112     return num;
113 }
114
115
116 void file_unlink( char *file )
117 {
118     /* Martin A. Hansen, June 2008 */
119
120     /* Unit test done. */
121
122     /* Delete a file. */
123
124     if ( unlink( file ) == -1 )
125     {
126         fprintf( stderr, "ERROR: Could not unlink file '%s': %s\n", file, strerror( errno ) );    
127         abort();
128     }
129 }
130
131
132 void file_rename( char *old_name, char *new_name )
133 {
134     /* Martin A. Hansen, June 2008 */
135
136     /* Unit test done. */
137
138     /* Rename a file. */
139
140     if ( rename( old_name, new_name ) != 0 )
141     {
142         fprintf( stderr, "ERROR: Could not rename file '%s' -> '%s': %s\n", old_name, new_name, strerror( errno ) );
143
144         abort();
145     }
146 }
147
148
149 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FILE BUFFER <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
150
151
152 size_t buffer_new( char *file, file_buffer **buffer_ppt, size_t size )
153 {
154     /* Martin A. Hansen, June 2008 */
155
156     /* Opens a file for reading and loads a new buffer.*/
157     /* The number of read chars is returned. */
158
159     file_buffer *buffer = *buffer_ppt;
160     FILE        *fp     = NULL;
161     size_t       num    = 0;
162
163     buffer = mem_get( sizeof( file_buffer ) );
164
165     fp = read_open( file );
166
167     buffer->fp          = fp;
168     buffer->str         = NULL;
169     buffer->token_pos   = 0;
170     buffer->token_len   = 0;
171     buffer->buffer_pos  = 0;
172     buffer->buffer_end  = 0;
173     buffer->buffer_size = size;
174     buffer->eof         = FALSE;
175
176     num = buffer_read( &buffer );
177
178     *buffer_ppt = buffer;
179
180     return num;
181 }
182
183
184 size_t buffer_read( file_buffer **buffer_ppt )
185 {
186     /* Martin A. Hansen, June 2008 */
187
188     /* Read in buffer->buffer_size bytes from file and appends to buffer string. */
189  
190     file_buffer *buffer  = *buffer_ppt;
191     char        *str     = NULL;
192     size_t       str_len = 0;
193     size_t       new_end = 0;
194     size_t       num     = 0;
195
196     num = file_read( buffer->fp, &str, buffer->buffer_size );
197
198     if ( num != 0 )
199     {
200         str_len = num;
201         new_end = buffer->buffer_end + str_len;
202
203         buffer->str = mem_resize( buffer->str, new_end );
204
205         memcpy( &buffer->str[ buffer->buffer_end ], str, str_len );
206
207         buffer->str[ new_end ] = '\0';
208         buffer->buffer_end     = new_end;
209
210         mem_free( &str );
211     }
212
213     buffer->eof = feof( buffer->fp ) ? TRUE : FALSE;
214
215     *buffer_ppt = buffer;
216
217     return num;
218 }
219
220
221 char buffer_getc( file_buffer *buffer )
222 {
223     /* Martin A. Hansen, June 2008 */
224
225     /* Get the next char from a file buffer, which is resized if necessary, until EOF.*/
226
227     while ( 1 )
228     {
229         if ( buffer->buffer_pos == buffer->buffer_end )
230         {
231             if ( buffer->eof )
232             {
233                 return EOF;
234             }
235             else
236             {
237                 buffer->token_pos = buffer->buffer_pos;
238                 buffer_new_size( buffer, buffer->buffer_pos );  // MOVE THIS TO buffer_resize !!!!! ??????
239
240                 if ( ( buffer_resize( buffer ) == FALSE ) ) {
241                     return EOF;
242                 }
243             }
244         }
245     
246         return buffer->str[ buffer->buffer_pos++ ];
247     }
248 }
249
250
251 void buffer_ungetc( file_buffer *buffer )
252 {
253     /* Martin A. Hansen, August 2008. */
254
255     /* Rewinds the file buffer one char, */
256     /* i.e. put one char back on the buffer. */
257
258     assert( buffer->buffer_pos > 0 );
259
260     buffer->buffer_pos--;
261 }
262
263
264 char *buffer_gets( file_buffer *buffer )
265 {
266     /* Martin A. Hansen, June 2008 */
267
268     /* Get the next line that is terminated by \n or EOF from a file buffer. */
269
270     char   *pt        = NULL;
271     char   *line      = NULL;
272     size_t  line_size = 0;
273
274     while ( 1 )
275     {
276         if ( ( pt = memchr( &buffer->str[ buffer->buffer_pos ], '\n', buffer->buffer_end + 1 - buffer->buffer_pos ) ) != NULL )
277         {
278             line_size = pt - &buffer->str[ buffer->buffer_pos ] + 1;
279
280             line = mem_get( line_size + 1 );
281
282             memcpy( line, &buffer->str[ buffer->buffer_pos ], line_size );
283
284             line[ line_size ] = '\0';
285
286             buffer->token_len   = line_size;
287             buffer->buffer_pos += line_size;
288
289             buffer_new_size( buffer, line_size );
290
291             return line;
292         }
293         else
294         {
295             if ( buffer->eof )
296             {
297                 if ( buffer->buffer_pos < buffer->buffer_end )
298                 {
299                     line_size = buffer->buffer_end - buffer->buffer_pos + 1;
300
301                     line = mem_get( line_size + 1 );
302
303                     memcpy( line, &buffer->str[ buffer->buffer_pos ], line_size );
304
305                     line[ line_size ] = '\0';
306
307                     buffer->token_len   = line_size;
308                     buffer->buffer_pos += line_size;
309
310                     return line;
311                 }
312                 else
313                 {
314                     return NULL;
315                 }
316             }
317             else
318             {
319                 buffer_resize( buffer );
320             }
321         }
322     }
323 }
324
325
326 void buffer_ungets( file_buffer *buffer )
327 {
328     /* Martin A. Hansen, August 2008 */
329
330     /* Rewind the file buffer one line, */
331     /* i.e. put one line back on the buffer. */
332
333     assert( buffer->buffer_pos >= buffer->token_len );
334
335     buffer->buffer_pos -= buffer->token_len;
336 }
337
338
339 void buffer_new_size( file_buffer *buffer, long len )
340 {
341     /* Martin A. Hansen, June 2008 */
342
343     /* Doubles buffer size until it is larger than len. */
344
345     while ( buffer->buffer_size <= len )
346     {
347         buffer->buffer_size <<= 1;
348
349         if ( buffer->buffer_size <= 0 )
350         {
351             fprintf( stderr, "ERROR: buffer_new_size failed.\n" );
352             abort();
353         }
354     }
355 }
356
357
358 bool buffer_resize( file_buffer *buffer )
359 {
360     /* Martin A. Hansen, June 2008 */
361
362     /* Resize file buffer. */
363
364     size_t num = 0;
365
366     if ( buffer->token_pos != 0 ) {
367         buffer_move( buffer, buffer->buffer_pos, buffer->token_pos );
368     }
369
370     num = buffer_read( &buffer );
371
372     if ( num == 0 ) {
373         return FALSE;
374     } else {
375         return TRUE;
376     }
377 }
378
379
380 size_t buffer_move( file_buffer *buffer, size_t size, size_t num )
381 {
382     /* Martin A. Hansen, August 2008 */
383
384     /* Moves file buffer of a given size num positions to the left. */
385     /* The size of the resulting string is returned. */
386
387     size_t len = 0;
388
389     assert( size > 0 );
390     assert( num > 0 );
391     assert( num <= size );
392
393     memmove( buffer->str, &buffer->str[ num ], size );
394
395     len = size - num;
396
397     buffer->buffer_end = len;
398     buffer->buffer_pos = 0;
399     buffer->token_pos  = 0;
400
401     return len;
402 }
403
404
405 void buffer_destroy( file_buffer **buffer_ppt )
406 {
407     /* Martin A. Hansen, June 2008 */
408
409     /* Deallocates memory and close stream used by file buffer. */
410
411     file_buffer *buffer = *buffer_ppt;
412
413     assert( buffer != NULL );
414
415     close_stream( buffer->fp );
416
417     mem_free( &buffer->str );
418     mem_free( &buffer );
419
420     buffer = NULL;
421 }
422
423
424 void buffer_print( file_buffer *buffer )
425 {
426     /* Martin A. Hansen, June 2008 */
427
428     /* Debug function that prints the content of a file_buffer. */
429
430     printf( "\nbuffer: {\n" );
431     printf( "   token_pos    : %zu\n",    buffer->token_pos );
432     printf( "   token_len    : %zu\n",    buffer->token_len );
433     printf( "   buffer_pos   : %zu\n",    buffer->buffer_pos );
434     printf( "   buffer_end   : %zu\n",    buffer->buffer_end );
435     printf( "   buffer_size  : %ld\n",    buffer->buffer_size );
436     printf( "   str          : ->%s<-\n", buffer->str );
437     printf( "   eof          : %d\n",     buffer->eof );
438
439     if ( buffer->str != NULL ) {
440         printf( "   _str_len_    : %zu\n", strlen( buffer->str ) );
441     }
442
443     printf( "}\n" );
444 }
445
446
447 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/