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