4
/*============================================================================
5
* Base file wrapper type and associated functions
6
*============================================================================*/
9
This file is part of Code_Saturne, a general-purpose CFD tool.
11
Copyright (C) 1998-2011 EDF S.A.
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
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
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.
28
/*----------------------------------------------------------------------------*/
31
* Obtain definitions such as that of size_t through stddef.h (C99 standard)
32
* if available (preferred method), or through stdlib.h (which defines
33
* malloc() and family and so must define size_t some way) otherwise.
36
#if defined(__STDC_VERSION__)
37
# if (__STDC_VERSION__ == 199901L)
48
#include "cs_config.h"
51
/*-----------------------------------------------------------------------------*/
56
} /* Fake brace to force Emacs auto-indentation back to column 0 */
58
#endif /* __cplusplus */
60
/*============================================================================
62
*============================================================================*/
64
/* ECS file descriptor */
66
typedef struct _ecs_file_t ecs_file_t;
72
ECS_FILE_TYPE_TEXT, /* Text file */
73
ECS_FILE_TYPE_BINARY, /* Simple C binary file */
74
ECS_FILE_TYPE_FORTRAN_BINARY /* Common Fortran binary file */
82
ECS_FILE_MODE_READ, /* Read mode */
83
ECS_FILE_MODE_WRITE, /* Write mode */
84
ECS_FILE_MODE_APPEND /* Append mode */
88
/* Offset for ECS file position indicator */
90
#if defined(SIZEOF_LONG_LONG)
91
typedef long long ecs_file_off_t;
93
typedef long ecs_file_off_t;
96
/* Possibilities for the third argument of ecs_file_seek() */
100
ECS_FILE_SEEK_SET, /* Seek from beginning of file */
101
ECS_FILE_SEEK_CUR, /* Seek from current position */
102
ECS_FILE_SEEK_END /* Seek from end of file */
106
/*============================================================================
107
* Public function prototypes
108
*============================================================================*/
111
* Create a `ecs_file_t' file descriptor and open the associated file.
113
* The associated file is also opened. By default, data is written
114
* or read as big-endian data. This behavior may be modified by
115
* ecs_file_set_swap_endian().
118
* name: <-- file name.
119
* mode: <-- file acces mode: read, write, or append.
120
* type: <-- file type: text, binary, or Fortran binary.
123
* pointer to ecs_file_t file descriptor (NULL in case of failure).
127
ecs_file_open(const char *name,
128
const ecs_file_mode_t mode,
129
const ecs_file_type_t type);
132
* Destroy a `ecs_file_t' descriptor and close the associated file.
134
* The descriptor may only be destroyed if the file was successfully
135
* closed. To force destruction of a ecs_file_t descriptor even
136
* if the associated file was not closed, use (ecs_file_free_force()).
138
* The associated file is only closed if this was not already the case.
141
* f: <-- ecs_file_t descriptor.
144
* pointer to ecs_file_t file descriptor (NULL in case of success,
145
* f in case of failure).
149
ecs_file_free(ecs_file_t *f);
152
* Destroy a `ecs_file_t' descriptor without closing its associated file.
155
* f: -> ecs_file_t descriptor.
162
ecs_file_free_descriptor(ecs_file_t *f);
165
* Open `ecs_file_t' descriptor's associated file.
167
* If the file is already open, this function does nothing.
170
* f: <-- ecs_file_t descriptor.
171
* mode: <-- file acces mode: read, write, or append.
174
* 0 in case of success, system error code in case of failure
175
* (or Zlib error code in case of Zlib memory allocation problem
176
* for a gzipped file).
180
ecs_file_open_stream(ecs_file_t *f,
181
ecs_file_mode_t mode);
184
* Close a ecs_file_t file descriptor's associated file.
186
* If the file is already closed, this function does nothing.
189
* f: <-- ecs_file_t descriptor.
192
* 0 in case of success, system error code in case of failure
193
* (or Zlib error code in case of a Zlib specific error
194
* for a gzipped file).
198
ecs_file_close_stream(ecs_file_t *f);
201
* Test the end-of-file indicator for a given file.
204
* f: <-- ecs_file_t descriptor.
207
* 0 if the end-of-file has not been reached, or non-zero
208
* (1 or feof() return value) otherwise.
212
ecs_file_eof(const ecs_file_t *f);
215
* Force write of all user-space buffered data for a given file.
218
* f: <-- ecs_file_t descriptor.
221
* 0 upon successful completion, system error code otherwise.
225
ecs_file_flush(ecs_file_t *f);
228
* Obtain the current value of a file's position indicator.
231
* f: <-- ecs_file_t descriptor.
234
* current value of the file's position indicator, or -1 in case of failure.
238
ecs_file_tell(ecs_file_t *f);
241
* Sets the file position indicator to the beginning of the file.
243
* A successful call to this function clears the end-of-file indicator for
247
* f: <-- ecs_file_t descriptor.
251
ecs_file_rewind(ecs_file_t *f);
254
* This function may call the libc's fseek() function, or Zlib's gzseek()
255
* function. The C 99 standard draft specifies that for a text file, the offset
256
* argument to fseek() should be zero or a value returned by an earlier
257
* successful call to ftell() (here ecs_file_ftell()) on a stream (here a
258
* ecs_file_t structure). Zlib's gzseek() does not support SEEK_END, at least
259
* as of version 1.2.1.
261
* A successful call to this function clears the end-of-file indicator for
265
* f: <-- ecs_file_t descriptor.
266
* offset: <-- add to position specified to whence to obtain new position,
267
* measured in characters from the beginning of the file.
268
* whence: <-- beginning if ECS_FILE_SEEK_SET, current if ECS_FILE_SEEK_CUR,
269
* or end-of-file if ECS_FILE_SEEK_END.
272
* 0 upon success, nonzero otherwise.
276
ecs_file_seek(ecs_file_t *f,
277
const ecs_file_off_t offset,
278
const ecs_file_seek_t whence);
281
* Return a file's name.
284
* f: <-- ecs_file_t descriptor.
287
* pointer to file's name.
291
ecs_file_get_name(const ecs_file_t *f);
294
* Return a file's type.
297
* f: <-- ecs_file_t descriptor.
304
ecs_file_get_type(const ecs_file_t *f);
307
* Change a file's type.
309
* Using this function assumes one is familiar with a file's coding
310
* or structure; use with caution.
313
* f: <-> ecs_file_t descriptor.
314
* type: <-- text, binary, or Fortran binary type descriptor.
318
ecs_file_set_type(ecs_file_t *f,
319
const ecs_file_type_t type);
322
* Ensure that data is read or written in big-endian
323
* (network standard) format.
325
* By default, data is written or read in native format (as regards
326
* big-endian or little-endian)..
329
* f: <-> ecs_file_t descriptor.
333
ecs_file_set_big_endian(ecs_file_t *f);
336
* Return a file's byte-swapping behavior.
339
* f: <-- ecs_file_t descriptor.
342
* 0 if file's endianness is the same as the system's, 1 otherwise.
346
ecs_file_get_swap_endian(const ecs_file_t *f);
349
* Set a file's byte-swapping behavior.
351
* Using this function assumes one is familiar with a file's coding
352
* or structure; use with caution.
355
* f: <-> ecs_file_t descriptor.
356
* swap: <-- 1 if bytes must be swapped, 0 therwise.
360
ecs_file_set_swap_endian(ecs_file_t *f,
364
* Test a file's error or EOF condition.
367
* f: <-- ecs_file_t descriptor.
368
* line: <-- file line number if available, or 0.
371
* 0 if no error, system error code, or -1 if EOF.
375
ecs_file_read_check_error(const ecs_file_t *f,
379
* Formatted output to a text file (as fprintf()).
382
* f: <-- ecs_file_t descriptor.
383
* format: <-- format string, as printf() and family.
384
* ... : <-- variable arguments based on format string.
387
* number of characters printed, not counting the trailing '\0'
388
* used to end output strings
392
ecs_file_printf(const ecs_file_t *const f,
393
const char *const format,
397
* Formatted input from a text file (as fgets()).
400
* s: --> buffer to which string is to be read.
401
* size: <-- maximum number of characters to be read plus one.
402
* f: <-- ecs_file_t descriptor.
403
* line: <-> file line number if available, or NULL.
406
* s on success, NULL on error or when end of file occurs and
407
* no characters have been read.
411
ecs_file_gets(char *s,
417
* Formatted input from a text file if possible (as fgets()).
419
* This function is similar to ecs_file_gets(), but failure to read
420
* a line du to an end-of-file condition is not considered an error with
421
* this variant, which may be used to read text files or sections thereof
425
* s: --> buffer to which string is to be read.
426
* size: <-- maximum number of characters to be read plus one.
427
* f: <-- ecs_file_t descriptor.
428
* line: <-> file line number if available, or NULL.
431
* s on success, NULL on error or when end of file occurs and
432
* no characters have been read.
436
ecs_file_gets_try(char *s,
442
* Read a binary C or Fortran type record.
444
* A Fortran record compatible with most compilers is structured
446
* - a 4-byte integer indicating the number of bytes in the record.
448
* - a 4-byte integer indicating the number of bytes in the record.
450
* A C record contains only the raw data.
453
* rec: --> pointer to location receiving data.
454
* size: <-- size of each item of data in bytes.
455
* ni: <-- number of items to read.
456
* f: <-- ecs_file_t descriptor.
459
* the number of items (not bytes) sucessfully read; for a Fortran
460
* record, if the whole record could not be read, returns 0.
464
ecs_file_read(void *rec,
467
const ecs_file_t *f);
470
* Read a binary C or Fortran type record.
472
* This function is similar to ecs_file_read(), but failure to read
473
* a record due to an end-of-file condition is not considered an error with
474
* this variant, which may be used to read records whose presence in the
477
* A Fortran record compatible with most compilers is structured
479
* - a 4-byte integer indicating the number of bytes in the record.
481
* - a 4-byte integer indicating the number of bytes in the record.
483
* A C record contains only the raw data.
486
* rec: --> pointer to location receiving data.
487
* size: <-- size of each item of data in bytes.
488
* ni: <-- number of items to read.
489
* f: <-- ecs_file_t descriptor.
492
* the number of items (not bytes) sucessfully read; for a Fortran
493
* record, if the whole record could not be read, returns 0.
497
ecs_file_read_try(void *rec,
500
const ecs_file_t *f);
503
* Write a binary C or Fortran type record.
505
* A Fortran record compatible with most compilers is structured
507
* - a 4-byte integer indicating the number of bytes in the record.
509
* - a 4-byte integer indicating the number of bytes in the record.
511
* A C record contains only the raw data.
514
* rec: <-- pointer to location containing data.
515
* size: <-- size of each item of data in bytes.
516
* ni: <-- number of items to write.
517
* f: <-- ecs_file_t descriptor.
520
* the number of items (not bytes) sucessfully written.
524
ecs_file_write(const void *rec,
527
const ecs_file_t *f);
530
* Convert data from "little-endian" to "big-endian" or the reverse.
532
* The memory areas pointed to by src and dest should overlap either
533
* exactly or not at all.
536
* dest: --> pointer to converted data location.
537
* src: <-- pointer to source data location.
538
* size: <-- size of each item of data in bytes.
539
* ni: <-- number of data items.
543
ecs_file_swap_endian(void *dest,
549
* Create a new directory using default permissions.
551
* This function is similar to the POSIX function mkdir(), except that
552
* it has no "mode" argument: by default, on a POSIX type system,
553
* permissions include read, write, and execute access for the user,
554
* group and others, modified by the users umask value (so with a
555
* typical configuration, the user will have read, write, and execute
556
* pemission, the group and others will only have read and execute
557
* permission, but this behavior may be modified).
559
* Also, contrary to the usual mkdir(), if the directory already
560
* exists (and is truly a directory), this is considered a success
561
* and not a failure, and 0 is returned: the aim of this function
562
* is to make a directory available, so if it already exists,
563
* this is considered acceptable.
566
* pathname: <-- name of new directory.
569
* 0 on success, -1 if an error occured (in which case errno
570
* contains the appropriate error code). If the underlying
571
* system has no mkdir() function or it was not detected
572
* upon ECS configuration, 1 is returned.
576
ecs_file_mkdir_default(const char *pathname);
579
* Check if a file exists and is a regular file.
582
* name: <-- file name.
585
* 1 if file exists and is a regular file, 0 otherwise.
589
ecs_file_isreg(const char *name);
592
* Check if a directory exists.
595
* name: <-- directory name.
598
* 1 if directory exists, 0 otherwise.
602
ecs_file_isdir(const char *name);
605
* Indicate Zlib version available at run time.
607
* It may be useful to compare the Zlib version used at compile
608
* and run time in case we use dynamic libraries.
611
* pointer to string indicating Zlib version in use, or NULL
612
* if Zlib support is not available.
616
ecs_file_version_zlib(void);
619
* Indicate Zlib version available at compilation time.
621
* It may be useful to compare the Zlib version used at compile
622
* and link time in case we use dynamic libraries.
625
* pointer to string indicating Zlib version at compilation, or NULL
626
* if Zlib support is not available.
630
ecs_file_version_build_zlib(void);
632
/*----------------------------------------------------------------------------*/
636
#endif /* __cplusplus */
638
#endif /* __ECS_FILE_H__ */