summaryrefslogtreecommitdiffstats
path: root/src/H5Fstdio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Fstdio.c')
-rw-r--r--src/H5Fstdio.c119
1 files changed, 52 insertions, 67 deletions
diff --git a/src/H5Fstdio.c b/src/H5Fstdio.c
index cc8f4c6..2cd613b 100644
--- a/src/H5Fstdio.c
+++ b/src/H5Fstdio.c
@@ -23,13 +23,11 @@ static hbool_t interface_initialize_g = FALSE;
static H5F_low_t *H5F_stdio_open (const char *name, uintn flags,
H5F_search_t *key);
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,
+static herr_t H5F_stdio_read (H5F_low_t *lf, const haddr_t *addr, size_t size,
uint8 *buf);
-static herr_t H5F_stdio_write (H5F_low_t *lf, haddr_t addr, size_t size,
+static herr_t H5F_stdio_write (H5F_low_t *lf, const 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] = {{
NULL, /* use default access(2) func */
@@ -38,10 +36,9 @@ const H5F_low_class_t H5F_LOW_STDIO[1] = {{
H5F_stdio_read, /* read method */
H5F_stdio_write, /* write method */
H5F_stdio_flush, /* flush method */
- H5F_stdio_size, /* file size method */
+ NULL, /* extend method */
}};
-
/*-------------------------------------------------------------------------
* Function: H5F_stdio_open
@@ -70,7 +67,7 @@ const H5F_low_class_t H5F_LOW_STDIO[1] = {{
*-------------------------------------------------------------------------
*/
static H5F_low_t *
-H5F_stdio_open (const char *name, uintn flags, H5F_search_t *key)
+H5F_stdio_open (const char *name, uintn flags, H5F_search_t *key/*out*/)
{
H5F_low_t *lf=NULL;
FILE *f=NULL;
@@ -104,6 +101,12 @@ H5F_stdio_open (const char *name, uintn flags, H5F_search_t *key)
lf->u.stdio.f = f;
lf->u.stdio.op = H5F_OP_SEEK;
lf->u.stdio.cur = 0;
+ H5F_addr_reset (&(lf->eof));
+ if (fseek (lf->u.stdio.f, 0, SEEK_END)<=0) {
+ lf->u.stdio.op = H5F_OP_UNKNOWN;
+ } else {
+ H5F_addr_inc (&(lf->eof), ftell (lf->u.stdio.f));
+ }
/* The unique key */
if (key) {
@@ -153,8 +156,8 @@ H5F_stdio_close (H5F_low_t *lf)
* 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.
+ * places them in buffer BUF. Reading past the logical or
+ * physical end of file returns zeros instead of failing.
*
* Errors:
* IO READERROR Fread failed.
@@ -172,22 +175,44 @@ 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)
+H5F_stdio_read (H5F_low_t *lf, const haddr_t *addr, size_t size, uint8 *buf)
{
size_t n;
+ off_t offset;
FUNC_ENTER (H5F_stdio_read, NULL, FAIL);
+ /* Check for overflow */
+ offset = addr->offset;
+ assert ("address overflowed" && offset==addr->offset);
+ assert ("overflow" && offset+size>=offset);
+
+ /* Check easy cases */
+ if (0==size) HRETURN (SUCCEED);
+ if (offset>=lf->eof.offset) {
+ HDmemset (buf, 0, size);
+ HRETURN (SUCCEED);
+ }
+
/*
* Seek to the correct file position.
*/
if (!H5F_OPT_SEEK ||
lf->u.stdio.op!=H5F_OP_READ ||
- lf->u.stdio.cur!=addr) {
- if (fseek (lf->u.stdio.f, addr, SEEK_SET)<0) {
+ lf->u.stdio.cur!=offset) {
+ if (fseek (lf->u.stdio.f, offset, SEEK_SET)<0) {
HRETURN_ERROR (H5E_IO, H5E_SEEKERROR, FAIL); /*fseek failed*/
}
- lf->u.stdio.cur = addr;
+ lf->u.stdio.cur = offset;
+ }
+
+ /*
+ * Read zeros past the logical end of file (physical is handled below)
+ */
+ if ((size_t)offset+size>lf->eof.offset) {
+ size_t nbytes = (size_t)offset+size - lf->eof.offset;
+ HDmemset (buf+size-nbytes, 0, nbytes);
+ size -= nbytes;
}
/*
@@ -207,11 +232,10 @@ H5F_stdio_read (H5F_low_t *lf, haddr_t addr, size_t size, uint8 *buf)
* Update the file position data.
*/
lf->u.stdio.op = H5F_OP_READ;
- lf->u.stdio.cur = addr + n;
+ lf->u.stdio.cur = offset + n;
FUNC_LEAVE (SUCCEED);
}
-
/*-------------------------------------------------------------------------
* Function: H5F_stdio_write
@@ -235,22 +259,28 @@ 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)
+H5F_stdio_write (H5F_low_t *lf, const haddr_t *addr, size_t size,
+ const uint8 *buf)
{
- int status;
+ off_t offset;
FUNC_ENTER (H5F_stdio_write, NULL, FAIL);
+ /* Check for overflow */
+ offset = addr->offset;
+ assert ("address overflowed" && offset==addr->offset);
+ assert ("overflow" && offset+size>=offset);
+
/*
* Seek to the correct file position.
*/
if (!H5F_OPT_SEEK ||
lf->u.stdio.op!=H5F_OP_WRITE ||
- lf->u.stdio.cur!=addr) {
- if (fseek (lf->u.stdio.f, addr, SEEK_SET)<0) {
+ lf->u.stdio.cur!=offset) {
+ if (fseek (lf->u.stdio.f, offset, SEEK_SET)<0) {
HRETURN_ERROR (H5E_IO, H5E_SEEKERROR, FAIL); /*fseek failed*/
}
- lf->u.stdio.cur = addr;
+ lf->u.stdio.cur = offset;
}
/*
@@ -258,8 +288,7 @@ H5F_stdio_write (H5F_low_t *lf, haddr_t addr, size_t size, const uint8 *buf)
* advanced by the number of bytes read. Otherwise nobody knows where it
* is.
*/
- status = fwrite (buf, 1, size, lf->u.stdio.f);
- if (size != status) {
+ 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*/
}
@@ -268,11 +297,10 @@ H5F_stdio_write (H5F_low_t *lf, haddr_t addr, size_t size, const uint8 *buf)
* Update seek optimizing data.
*/
lf->u.stdio.op = H5F_OP_WRITE;
- lf->u.stdio.cur = addr + size;
+ lf->u.stdio.cur = offset + size;
FUNC_LEAVE (SUCCEED);
}
-
/*-------------------------------------------------------------------------
* Function: H5F_stdio_flush
@@ -313,46 +341,3 @@ H5F_stdio_flush (H5F_low_t *lf)
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);
-}
-