Code_Saturne
CFD tool
ecs_file.h
Go to the documentation of this file.
1 #ifndef __ECS_FILE_H__
2 #define __ECS_FILE_H__
3 
4 /*============================================================================
5  * Base file wrapper type and associated functions
6  *============================================================================*/
7 
8 /*
9  This file is part of Code_Saturne, a general-purpose CFD tool.
10 
11  Copyright (C) 1998-2012 EDF S.A.
12 
13  This program is free software; you can redistribute it and/or modify it under
14  the terms of the GNU General Public License as published by the Free Software
15  Foundation; either version 2 of the License, or (at your option) any later
16  version.
17 
18  This program is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
21  details.
22 
23  You should have received a copy of the GNU General Public License along with
24  this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
25  Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 */
27 
28 /*----------------------------------------------------------------------------*/
29 
30 #include "ecs_def.h"
31 
33 
34 /*============================================================================
35  * Public types
36  *============================================================================*/
37 
38 /* ECS file descriptor */
39 
40 typedef struct _ecs_file_t ecs_file_t;
41 
42 /* ECS file types */
43 
44 typedef enum {
45 
46  ECS_FILE_TYPE_TEXT, /* Text file */
47  ECS_FILE_TYPE_BINARY, /* Simple C binary file */
48  ECS_FILE_TYPE_FORTRAN_BINARY /* Common Fortran binary file */
49 
51 
52 /* ECS file modes */
53 
54 typedef enum {
55 
56  ECS_FILE_MODE_READ, /* Read mode */
57  ECS_FILE_MODE_WRITE, /* Write mode */
58  ECS_FILE_MODE_APPEND /* Append mode */
59 
61 
62 /* Offset for ECS file position indicator */
63 
64 #if defined(SIZEOF_LONG_LONG)
65 typedef long long ecs_file_off_t;
66 #else
67 typedef long ecs_file_off_t;
68 #endif
69 
70 /* Possibilities for the third argument of ecs_file_seek() */
71 
72 typedef enum {
73 
74  ECS_FILE_SEEK_SET, /* Seek from beginning of file */
75  ECS_FILE_SEEK_CUR, /* Seek from current position */
76  ECS_FILE_SEEK_END /* Seek from end of file */
77 
79 
80 /*============================================================================
81  * Public function prototypes
82  *============================================================================*/
83 
84 /*
85  * Create a `ecs_file_t' file descriptor and open the associated file.
86  *
87  * The associated file is also opened. By default, data is written
88  * or read as big-endian data. This behavior may be modified by
89  * ecs_file_set_swap_endian().
90  *
91  * parameters:
92  * name: <-- file name.
93  * mode: <-- file acces mode: read, write, or append.
94  * type: <-- file type: text, binary, or Fortran binary.
95  *
96  * returns:
97  * pointer to ecs_file_t file descriptor (NULL in case of failure).
98  */
99 
100 ecs_file_t *
101 ecs_file_open(const char *name,
102  const ecs_file_mode_t mode,
103  const ecs_file_type_t type);
104 
105 /*
106  * Destroy a `ecs_file_t' descriptor and close the associated file.
107  *
108  * The descriptor may only be destroyed if the file was successfully
109  * closed. To force destruction of a ecs_file_t descriptor even
110  * if the associated file was not closed, use (ecs_file_free_force()).
111  *
112  * The associated file is only closed if this was not already the case.
113  *
114  * parameters:
115  * f: <-- ecs_file_t descriptor.
116  *
117  * returns:
118  * pointer to ecs_file_t file descriptor (NULL in case of success,
119  * f in case of failure).
120  */
121 
122 ecs_file_t *
124 
125 /*
126  * Destroy a `ecs_file_t' descriptor without closing its associated file.
127  *
128  * parameters:
129  * f: -> ecs_file_t descriptor.
130  *
131  * returns:
132  * NULL pointer.
133  */
134 
135 ecs_file_t *
137 
138 /*
139  * Open `ecs_file_t' descriptor's associated file.
140  *
141  * If the file is already open, this function does nothing.
142  *
143  * parameters:
144  * f: <-- ecs_file_t descriptor.
145  * mode: <-- file acces mode: read, write, or append.
146  *
147  * returns:
148  * 0 in case of success, system error code in case of failure
149  * (or Zlib error code in case of Zlib memory allocation problem
150  * for a gzipped file).
151  */
152 
153 int
155  ecs_file_mode_t mode);
156 
157 /*
158  * Close a ecs_file_t file descriptor's associated file.
159  *
160  * If the file is already closed, this function does nothing.
161  *
162  * parameter:
163  * f: <-- ecs_file_t descriptor.
164  *
165  * returns:
166  * 0 in case of success, system error code in case of failure
167  * (or Zlib error code in case of a Zlib specific error
168  * for a gzipped file).
169  */
170 
171 int
173 
174 /*
175  * Test the end-of-file indicator for a given file.
176  *
177  * parameter:
178  * f: <-- ecs_file_t descriptor.
179  *
180  * returns:
181  * 0 if the end-of-file has not been reached, or non-zero
182  * (1 or feof() return value) otherwise.
183  */
184 
185 int
186 ecs_file_eof(const ecs_file_t *f);
187 
188 /*
189  * Force write of all user-space buffered data for a given file.
190  *
191  * parameter:
192  * f: <-- ecs_file_t descriptor.
193  *
194  * returns:
195  * 0 upon successful completion, system error code otherwise.
196  */
197 
198 int
200 
201 /*
202  * Obtain the current value of a file's position indicator.
203  *
204  * parameter:
205  * f: <-- ecs_file_t descriptor.
206  *
207  * returns:
208  * current value of the file's position indicator, or -1 in case of failure.
209  */
210 
213 
214 /*
215  * Sets the file position indicator to the beginning of the file.
216  *
217  * A successful call to this function clears the end-of-file indicator for
218  * this file.
219  *
220  * parameter:
221  * f: <-- ecs_file_t descriptor.
222  */
223 
224 void
226 
227 /*
228  * This function may call the libc's fseek() function, or Zlib's gzseek()
229  * function. The C 99 standard draft specifies that for a text file, the offset
230  * argument to fseek() should be zero or a value returned by an earlier
231  * successful call to ftell() (here ecs_file_ftell()) on a stream (here a
232  * ecs_file_t structure). Zlib's gzseek() does not support SEEK_END, at least
233  * as of version 1.2.1.
234  *
235  * A successful call to this function clears the end-of-file indicator for
236  * this file.
237  *
238  * parameters:
239  * f: <-- ecs_file_t descriptor.
240  * offset: <-- add to position specified to whence to obtain new position,
241  * measured in characters from the beginning of the file.
242  * whence: <-- beginning if ECS_FILE_SEEK_SET, current if ECS_FILE_SEEK_CUR,
243  * or end-of-file if ECS_FILE_SEEK_END.
244  *
245  * returns:
246  * 0 upon success, nonzero otherwise.
247  */
248 
249 int
251  const ecs_file_off_t offset,
252  const ecs_file_seek_t whence);
253 
254 /*
255  * Return a file's name.
256  *
257  * parameter:
258  * f: <-- ecs_file_t descriptor.
259  *
260  * returns:
261  * pointer to file's name.
262  */
263 
264 const char *
265 ecs_file_get_name(const ecs_file_t *f);
266 
267 /*
268  * Return a file's type.
269  *
270  * parameter:
271  * f: <-- ecs_file_t descriptor.
272  *
273  * returns:
274  * file's type.
275  */
276 
278 ecs_file_get_type(const ecs_file_t *f);
279 
280 /*
281  * Change a file's type.
282  *
283  * Using this function assumes one is familiar with a file's coding
284  * or structure; use with caution.
285  *
286  * parameters:
287  * f: <-> ecs_file_t descriptor.
288  * type: <-- text, binary, or Fortran binary type descriptor.
289  */
290 
291 void
293  const ecs_file_type_t type);
294 
295 /*
296  * Ensure that data is read or written in big-endian
297  * (network standard) format.
298  *
299  * By default, data is written or read in native format (as regards
300  * big-endian or little-endian)..
301  *
302  * parameter:
303  * f: <-> ecs_file_t descriptor.
304  */
305 
306 void
308 
309 /*
310  * Return a file's byte-swapping behavior.
311  *
312  * parameter:
313  * f: <-- ecs_file_t descriptor.
314  *
315  * returns:
316  * 0 if file's endianness is the same as the system's, 1 otherwise.
317  */
318 
319 int
321 
322 /*
323  * Set a file's byte-swapping behavior.
324  *
325  * Using this function assumes one is familiar with a file's coding
326  * or structure; use with caution.
327  *
328  * parameters:
329  * f: <-> ecs_file_t descriptor.
330  * swap: <-- 1 if bytes must be swapped, 0 therwise.
331  */
332 
333 void
335  const int swap);
336 
337 /*
338  * Test a file's error or EOF condition.
339  *
340  * parameters:
341  * f: <-- ecs_file_t descriptor.
342  * line: <-- file line number if available, or 0.
343  *
344  * returns:
345  * 0 if no error, system error code, or -1 if EOF.
346  */
347 
348 int
350  const int line);
351 
352 /*
353  * Formatted output to a text file (as fprintf()).
354  *
355  * parameters:
356  * f: <-- ecs_file_t descriptor.
357  * format: <-- format string, as printf() and family.
358  * ... : <-- variable arguments based on format string.
359  *
360  * returns:
361  * number of characters printed, not counting the trailing '\0'
362  * used to end output strings
363  */
364 
365 int
366 ecs_file_printf(const ecs_file_t *const f,
367  const char *const format,
368  ...);
369 
370 /*
371  * Formatted input from a text file (as fgets()).
372  *
373  * parameters:
374  * s: --> buffer to which string is to be read.
375  * size: <-- maximum number of characters to be read plus one.
376  * f: <-- ecs_file_t descriptor.
377  * line: <-> file line number if available, or NULL.
378  *
379  * returns:
380  * s on success, NULL on error or when end of file occurs and
381  * no characters have been read.
382  */
383 
384 char *
385 ecs_file_gets(char *s,
386  const int size,
387  const ecs_file_t *f,
388  int *line);
389 
390 /*
391  * Formatted input from a text file if possible (as fgets()).
392  *
393  * This function is similar to ecs_file_gets(), but failure to read
394  * a line du to an end-of-file condition is not considered an error with
395  * this variant, which may be used to read text files or sections thereof
396  * of unknown length
397  *
398  * parameters:
399  * s: --> buffer to which string is to be read.
400  * size: <-- maximum number of characters to be read plus one.
401  * f: <-- ecs_file_t descriptor.
402  * line: <-> file line number if available, or NULL.
403  *
404  * returns:
405  * s on success, NULL on error or when end of file occurs and
406  * no characters have been read.
407  */
408 
409 char *
410 ecs_file_gets_try(char *s,
411  const int size,
412  const ecs_file_t *f,
413  int *line);
414 
415 /*
416  * Read a binary C or Fortran type record.
417  *
418  * A Fortran record compatible with most compilers is structured
419  * as follows:
420  * - a 4-byte integer indicating the number of bytes in the record.
421  * - the raw data
422  * - a 4-byte integer indicating the number of bytes in the record.
423  *
424  * A C record contains only the raw data.
425  *
426  * parameters:
427  * rec: --> pointer to location receiving data.
428  * size: <-- size of each item of data in bytes.
429  * ni: <-- number of items to read.
430  * f: <-- ecs_file_t descriptor.
431  *
432  * returns:
433  * the number of items (not bytes) sucessfully read; for a Fortran
434  * record, if the whole record could not be read, returns 0.
435  */
436 
437 size_t
438 ecs_file_read(void *rec,
439  const size_t size,
440  const size_t ni,
441  const ecs_file_t *f);
442 
443 /*
444  * Read a binary C or Fortran type record.
445  *
446  * This function is similar to ecs_file_read(), but failure to read
447  * a record due to an end-of-file condition is not considered an error with
448  * this variant, which may be used to read records whose presence in the
449  * file is unknown.
450  *
451  * A Fortran record compatible with most compilers is structured
452  * as follows:
453  * - a 4-byte integer indicating the number of bytes in the record.
454  * - the raw data
455  * - a 4-byte integer indicating the number of bytes in the record.
456  *
457  * A C record contains only the raw data.
458  *
459  * parameters:
460  * rec: --> pointer to location receiving data.
461  * size: <-- size of each item of data in bytes.
462  * ni: <-- number of items to read.
463  * f: <-- ecs_file_t descriptor.
464  *
465  * returns:
466  * the number of items (not bytes) sucessfully read; for a Fortran
467  * record, if the whole record could not be read, returns 0.
468  */
469 
470 size_t
471 ecs_file_read_try(void *rec,
472  const size_t size,
473  const size_t ni,
474  const ecs_file_t *f);
475 
476 /*
477  * Write a binary C or Fortran type record.
478  *
479  * A Fortran record compatible with most compilers is structured
480  * as follows:
481  * - a 4-byte integer indicating the number of bytes in the record.
482  * - the raw data
483  * - a 4-byte integer indicating the number of bytes in the record.
484  *
485  * A C record contains only the raw data.
486  *
487  * parameters:
488  * rec: <-- pointer to location containing data.
489  * size: <-- size of each item of data in bytes.
490  * ni: <-- number of items to write.
491  * f: <-- ecs_file_t descriptor.
492  *
493  * returns:
494  * the number of items (not bytes) sucessfully written.
495  */
496 
497 size_t
498 ecs_file_write(const void *rec,
499  const size_t size,
500  const size_t ni,
501  const ecs_file_t *f);
502 
503 /*
504  * Convert data from "little-endian" to "big-endian" or the reverse.
505  *
506  * The memory areas pointed to by src and dest should overlap either
507  * exactly or not at all.
508  *
509  * parameters:
510  * dest: --> pointer to converted data location.
511  * src: <-- pointer to source data location.
512  * size: <-- size of each item of data in bytes.
513  * ni: <-- number of data items.
514  */
515 
516 void
517 ecs_file_swap_endian(void *dest,
518  const void *src,
519  const size_t size,
520  const size_t ni);
521 
522 /*
523  * Create a new directory using default permissions.
524  *
525  * This function is similar to the POSIX function mkdir(), except that
526  * it has no "mode" argument: by default, on a POSIX type system,
527  * permissions include read, write, and execute access for the user,
528  * group and others, modified by the users umask value (so with a
529  * typical configuration, the user will have read, write, and execute
530  * pemission, the group and others will only have read and execute
531  * permission, but this behavior may be modified).
532  *
533  * Also, contrary to the usual mkdir(), if the directory already
534  * exists (and is truly a directory), this is considered a success
535  * and not a failure, and 0 is returned: the aim of this function
536  * is to make a directory available, so if it already exists,
537  * this is considered acceptable.
538  *
539  * parameters:
540  * pathname: <-- name of new directory.
541  *
542  * returns:
543  * 0 on success, -1 if an error occured (in which case errno
544  * contains the appropriate error code). If the underlying
545  * system has no mkdir() function or it was not detected
546  * upon ECS configuration, 1 is returned.
547  */
548 
549 int
550 ecs_file_mkdir_default(const char *pathname);
551 
552 /*
553  * Check if a file exists and is a regular file.
554  *
555  * parameters:
556  * name: <-- file name.
557  *
558  * returns:
559  * 1 if file exists and is a regular file, 0 otherwise.
560  */
561 
562 int
563 ecs_file_isreg(const char *name);
564 
565 /*
566  * Check if a directory exists.
567  *
568  * parameters:
569  * name: <-- directory name.
570  *
571  * returns:
572  * 1 if directory exists, 0 otherwise.
573  */
574 
575 int
576 ecs_file_isdir(const char *name);
577 
578 /*
579  * Indicate Zlib version available at run time.
580  *
581  * It may be useful to compare the Zlib version used at compile
582  * and run time in case we use dynamic libraries.
583  *
584  * returns:
585  * pointer to string indicating Zlib version in use, or NULL
586  * if Zlib support is not available.
587  */
588 
589 const char *
591 
592 /*
593  * Indicate Zlib version available at compilation time.
594  *
595  * It may be useful to compare the Zlib version used at compile
596  * and link time in case we use dynamic libraries.
597  *
598  * returns:
599  * pointer to string indicating Zlib version at compilation, or NULL
600  * if Zlib support is not available.
601  */
602 
603 const char *
605 
606 /*----------------------------------------------------------------------------*/
607 
609 
610 #endif /* __ECS_FILE_H__ */
int ecs_file_close_stream(ecs_file_t *f)
Close a ecs_file_t file descriptor&#39;s associated file.
Definition: ecs_file.c:790
typedefBEGIN_C_DECLS struct _ecs_file_t ecs_file_t
Pointer to opaque file descriptor.
Definition: ecs_file.h:40
char * ecs_file_gets(char *s, const int size, const ecs_file_t *f, int *line)
Formatted input from a text file (as fgets()).
Definition: ecs_file.c:1333
Definition: ecs_file.h:74
ecs_file_type_t
Definition: ecs_file.h:44
void ecs_file_set_big_endian(ecs_file_t *f)
Ensure that data is read or written in big-endian (network standard) format.
Definition: ecs_file.c:1194
#define BEGIN_C_DECLS
Definition: ecs_def.h:234
Definition: ecs_file.h:46
ecs_file_seek_t
Definition: ecs_file.h:72
int ecs_file_read_check_error(const ecs_file_t *f, const int line)
Test a file&#39;s error or EOF condition.
Definition: ecs_file.c:1263
char * ecs_file_gets_try(char *s, const int size, const ecs_file_t *f, int *line)
Formatted input from a text file if possible (as fgets()).
Definition: ecs_file.c:1359
void ecs_file_set_type(ecs_file_t *f, const ecs_file_type_t type)
Change a file&#39;s type.
Definition: ecs_file.c:1175
void ecs_file_rewind(ecs_file_t *f)
Sets the file position indicator to the beginning of the file.
Definition: ecs_file.c:971
int ecs_file_flush(ecs_file_t *f)
Force write of all user-space buffered data for a given file.
Definition: ecs_file.c:863
int ecs_file_isdir(const char *name)
Check if a directory exists.
Definition: ecs_file.c:1733
ecs_file_t * ecs_file_free(ecs_file_t *f)
Destroy a `ecs_file_t&#39; descriptor and close the associated file.
Definition: ecs_file.c:628
int ecs_file_seek(ecs_file_t *f, const ecs_file_off_t offset, const ecs_file_seek_t whence)
Sets a file&#39;s position indicator.
Definition: ecs_file.c:1035
Definition: ecs_file.h:76
int ecs_file_get_swap_endian(const ecs_file_t *f)
Return a file&#39;s byte-swapping behavior.
Definition: ecs_file.c:1227
ecs_file_t * ecs_file_open(const char *name, const ecs_file_mode_t mode, const ecs_file_type_t type)
Create a `ecs_file_t&#39; file descriptor and open the associated file.
Definition: ecs_file.c:576
Definition: ecs_file.h:57
void ecs_file_swap_endian(void *dest, const void *src, const size_t size, const size_t ni)
Convert data from "little-endian" to "big-endian" or the reverse.
Definition: ecs_file.c:1560
int ecs_file_eof(const ecs_file_t *f)
Test the end-of-file indicator for a given file.
Definition: ecs_file.c:835
ecs_file_t * ecs_file_free_descriptor(ecs_file_t *f)
Definition: ecs_file.c:650
Definition: ecs_file.h:48
Definition: ecs_file.h:47
int ecs_file_mkdir_default(const char *pathname)
Create a new directory using default permissions.
Definition: ecs_file.c:1615
int ecs_file_printf(const ecs_file_t *const f, const char *const format,...)
Formatted output to a text file (as fprintf()).
Definition: ecs_file.c:259
void ecs_file_set_swap_endian(ecs_file_t *f, const int swap)
Set a file&#39;s byte-swapping behavior.
Definition: ecs_file.c:1245
int ecs_file_isreg(const char *name)
Check if a file exists and is a regular file.
Definition: ecs_file.c:1688
Definition: ecs_file.h:58
const char * ecs_file_version_zlib(void)
Indicate Zlib version available at run time.
Definition: ecs_file.c:1775
Definition: ecs_file.h:56
#define END_C_DECLS
Definition: ecs_def.h:235
size_t ecs_file_write(const void *rec, const size_t size, const size_t ni, const ecs_file_t *f)
Write a binary C or Fortran type record.
Definition: ecs_file.c:1450
long long ecs_file_off_t
Definition: ecs_file.h:65
const char * ecs_file_version_build_zlib(void)
Indicate Zlib version available at compilation time.
Definition: ecs_file.c:1795
size_t ecs_file_read(void *rec, const size_t size, const size_t ni, const ecs_file_t *f)
Read a binary C or Fortran type record.
Definition: ecs_file.c:1388
ecs_file_type_t ecs_file_get_type(const ecs_file_t *f)
Return a file&#39;s type.
Definition: ecs_file.c:1157
const char * ecs_file_get_name(const ecs_file_t *f)
Return a file&#39;s name.
Definition: ecs_file.c:1141
int ecs_file_open_stream(ecs_file_t *f, ecs_file_mode_t mode)
Open `ecs_file_t&#39; descriptor&#39;s associated file.
Definition: ecs_file.c:673
ecs_file_mode_t
Definition: ecs_file.h:54
ecs_file_off_t ecs_file_tell(ecs_file_t *f)
Obtain the current value of a file&#39;s position indicator.
Definition: ecs_file.c:910
size_t ecs_file_read_try(void *rec, const size_t size, const size_t ni, const ecs_file_t *f)
Read a binary C or Fortran type record.
Definition: ecs_file.c:1422
Definition: ecs_file.h:75