diff options
author | Robb Matzke <matzke@llnl.gov> | 1997-10-22 22:08:14 (GMT) |
---|---|---|
committer | Robb Matzke <matzke@llnl.gov> | 1997-10-22 22:08:14 (GMT) |
commit | e1e488bd4758a0e5b85a8e04052146a93c3e5751 (patch) | |
tree | 78181af3453d7cac4e4fb971c85a35472b5e389a /src/H5Fstdio.c | |
parent | 4fe5ac09995cf3c0a93d942b205c091d266fe258 (diff) | |
download | hdf5-e1e488bd4758a0e5b85a8e04052146a93c3e5751.zip hdf5-e1e488bd4758a0e5b85a8e04052146a93c3e5751.tar.gz hdf5-e1e488bd4758a0e5b85a8e04052146a93c3e5751.tar.bz2 |
[svn-r133] ./MANIFEST
./src/Makefile.in
Added new files.
./html/H5.apiv2.html
Added documentation for group stuff.
./src/H5private.h
./src/H5E.c
./src/H5Epublic.h
./src/H5F.c
./src/H5Flow.c NEW
./src/H5Fprivate.h
./src/H5Fsec2.c NEW
./src/H5Fstdio.c NEW
Low-level file driver is selected at runtime.
./src/H5Fprivate.h
Got rid of `shift >= sizeof operand' warnings on big endian
machines.
./src/H5Fistore.c
./test/istore.c
Still working on indexed storage...
./src/H5H.c
./src/H5Hprivate.h
Removed alignment constraints.
Diffstat (limited to 'src/H5Fstdio.c')
-rw-r--r-- | src/H5Fstdio.c | 341 |
1 files changed, 341 insertions, 0 deletions
diff --git a/src/H5Fstdio.c b/src/H5Fstdio.c new file mode 100644 index 0000000..d2b868d --- /dev/null +++ b/src/H5Fstdio.c @@ -0,0 +1,341 @@ +/* + * Copyright (C) 1997 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Wednesday, October 22, 1997 + * + * Purpose: This is the Posix stdio.h I/O subclass of H5Flow. + */ +#include <H5private.h> +#include <H5private.h> +#include <H5Eprivate.h> +#include <H5Fprivate.h> +#include <H5MMprivate.h> + +#define PABLO_MASK H5F_sec2 +static hbool_t interface_initialize_g = FALSE; + +static H5F_low_t *H5F_stdio_open (const char *name, uintn flags); +static herr_t H5F_stdio_close (H5F_low_t *lf); +static herr_t H5F_stdio_read (H5F_low_t *lf, haddr_t addr, size_t size, + uint8 *buf); +static herr_t H5F_stdio_write (H5F_low_t *lf, haddr_t addr, size_t size, + const uint8 *buf); +static herr_t H5F_stdio_flush (H5F_low_t *lf); +static size_t H5F_stdio_size (H5F_low_t *lf); + + +const H5F_low_class_t H5F_LOW_STDIO[1] = {{ + H5F_stdio_open, /* open method */ + H5F_stdio_close, /* close method */ + H5F_stdio_read, /* read method */ + H5F_stdio_write, /* write method */ + H5F_stdio_flush, /* flush method */ + H5F_stdio_size, /* file size method */ +}}; + + + +/*------------------------------------------------------------------------- + * Function: H5F_stdio_open + * + * Purpose: Opens a file with name NAME. The FLAGS are a bit field with + * the possible values defined in H5F_low_open(). + * + * Bugs: H5F_ACC_EXCL has a race condition. + * + * Errors: + * IO CANTOPENFILE File doesn't exist and CREAT wasn't + * specified. + * IO CANTOPENFILE Fopen failed. + * IO FILEEXISTS File exists but CREAT and EXCL were + * specified. + * + * Return: Success: Low-level file pointer + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Wednesday, October 22, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static H5F_low_t * +H5F_stdio_open (const char *name, uintn flags) +{ + H5F_low_t *lf=NULL; + FILE *f=NULL; + + FUNC_ENTER (H5F_stdio_open, NULL, NULL); + + if (access (name, F_OK)<0) { + if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_WRITE)) { + f = fopen (name, "wb+"); + } else { + /* File doesn't exist and CREAT wasn't specified */ + HRETURN_ERROR (H5E_IO, H5E_CANTOPENFILE, NULL); + } + + } else if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_EXCL)) { + /* File exists but CREAT and EXCL were specified */ + HRETURN_ERROR (H5E_IO, H5E_FILEEXISTS, NULL); + + } else if (flags & H5F_ACC_WRITE) { + if (flags & H5F_ACC_TRUNC) f = fopen (name, "wb+"); + else f = fopen (name, "rb+"); + + } else { + f = fopen (name, "rb"); + } + if (!f) HRETURN_ERROR (H5E_IO, H5E_CANTOPENFILE, NULL); /*fopen failed*/ + + /* Build the return value */ + lf = H5MM_xcalloc (1, sizeof(H5F_low_t)); + lf->u.stdio.f = f; + lf->u.stdio.op = H5F_OP_SEEK; + lf->u.stdio.cur = 0; + + FUNC_LEAVE (lf); +} + + +/*------------------------------------------------------------------------- + * Function: H5F_stdio_close + * + * Purpose: Closes a file. + * + * Errors: + * IO CLOSEERROR Close failed. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, October 22, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_stdio_close (H5F_low_t *lf) +{ + FUNC_ENTER (H5F_stdio_close, NULL, FAIL); + + if (fclose (lf->u.stdio.f)<0) { + HRETURN_ERROR (H5E_IO, H5E_CLOSEERROR, FAIL); /*close failed*/ + } + lf->u.stdio.f = NULL; + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5F_stdio_read + * + * Purpose: Reads SIZE bytes beginning at address ADDR in file LF and + * places them in buffer BUF. Reading past the end of the + * file returns zeros instead of failing. + * + * Errors: + * IO READERROR Fread failed. + * IO SEEKERROR Fseek failed. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, October 22, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_stdio_read (H5F_low_t *lf, haddr_t addr, size_t size, uint8 *buf) +{ + size_t n; + + FUNC_ENTER (H5F_stdio_read, NULL, FAIL); + + /* + * Seek to the correct file position. + */ + if (!H5F_OPT_SEEK || + lf->u.stdio.op==H5F_OP_UNKNOWN || + lf->u.stdio.cur!=addr) { + if (fseek (lf->u.stdio.f, addr, SEEK_SET)<0) { + HRETURN_ERROR (H5E_IO, H5E_SEEKERROR, FAIL); /*fseek failed*/ + } + lf->u.stdio.cur = addr; + } + + /* + * Read the data. Since we're reading single-byte values, a partial read + * will advance the file position by N. If N is negative or an error + * occurs then the file position is undefined. + */ + n = fread (buf, 1, size, lf->u.stdio.f); + if (n<=0 && ferror (lf->u.stdio.f)) { + lf->u.stdio.op = H5F_OP_UNKNOWN; + HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL); /*fread failed*/ + } else if (n<size) { + HDmemset (buf+n, 0, size-n); + } + + /* + * Update the file position data. + */ + lf->u.stdio.op = H5F_OP_READ; + lf->u.stdio.cur = addr + n; + FUNC_LEAVE (SUCCEED); +} + + + +/*------------------------------------------------------------------------- + * Function: H5F_stdio_write + * + * Purpose: Writes SIZE bytes from the beginning of BUF into file LF at + * file address ADDR. + * + * Errors: + * IO SEEKERROR Fseek failed. + * IO WRITEERROR Fwrite failed. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, October 22, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_stdio_write (H5F_low_t *lf, haddr_t addr, size_t size, const uint8 *buf) +{ + FUNC_ENTER (H5F_stdio_write, NULL, FAIL); + + /* + * Seek to the correct file position. + */ + if (!H5F_OPT_SEEK || + lf->u.stdio.op==H5F_OP_UNKNOWN || + lf->u.stdio.cur!=addr) { + if (fseek (lf->u.stdio.f, addr, SEEK_SET)<0) { + HRETURN_ERROR (H5E_IO, H5E_SEEKERROR, FAIL); /*fseek failed*/ + } + lf->u.stdio.cur = addr; + } + + /* + * Write the buffer. On successful return, the file position will be + * advanced by the number of bytes read. Otherwise nobody knows where it + * is. + */ + if (size != fwrite (buf, 1, size, lf->u.stdio.f)) { + lf->u.stdio.op = H5F_OP_UNKNOWN; + HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL); /*fwrite failed*/ + } + + /* + * Update seek optimizing data. + */ + lf->u.stdio.op = H5F_OP_WRITE; + lf->u.stdio.cur = addr + size; + FUNC_LEAVE (SUCCEED); +} + + + +/*------------------------------------------------------------------------- + * Function: H5F_stdio_flush + * + * Purpose: Makes sure that all data is on disk. + * + * Errors: + * IO WRITEERROR Fflush failed. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, October 22, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_stdio_flush (H5F_low_t *lf) +{ + FUNC_ENTER (H5F_stdio_flush, NULL, FAIL); + + /* + * What happens to the file position? Is it guaranteed to be the same + * after the fflush() as it was before? + */ + lf->u.stdio.op = H5F_OP_UNKNOWN; + + /* + * Flush + */ + if (fflush (lf->u.stdio.f)<0) { + HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL); /*fflush failed*/ + } + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5F_stdio_size + * + * Purpose: Returns the current size of the file in bytes. + * + * Bugs: There is no way to determine if this function failed. + * + * Errors: + * IO SEEKERROR Fseek failed. + * + * Return: Success: Size of file in bytes + * + * Failure: 0 + * + * Programmer: Robb Matzke + * Wednesday, October 22, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static size_t +H5F_stdio_size (H5F_low_t *lf) +{ + off_t size; + + FUNC_ENTER (H5F_stdio_size, NULL, 0); + + /* Seek to the end and get the file offset */ + if (fseek (lf->u.stdio.f, 0, SEEK_END)<0) { + HRETURN_ERROR (H5E_IO, H5E_SEEKERROR, 0); /*fseek failed*/ + } + size = ftell (lf->u.stdio.f); + + /* Update seek opt data */ + lf->u.stdio.op = H5F_OP_SEEK; + lf->u.stdio.cur = size; + + FUNC_LEAVE (size); +} + |