summaryrefslogtreecommitdiffstats
path: root/src/H5Fsec2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Fsec2.c')
-rw-r--r--src/H5Fsec2.c152
1 files changed, 57 insertions, 95 deletions
diff --git a/src/H5Fsec2.c b/src/H5Fsec2.c
index 5aa3e31..531bf10 100644
--- a/src/H5Fsec2.c
+++ b/src/H5Fsec2.c
@@ -28,22 +28,19 @@ static hbool_t interface_initialize_g = FALSE;
static H5F_low_t *H5F_sec2_open (const char *name, uintn flags, H5F_search_t*);
static herr_t H5F_sec2_close (H5F_low_t *lf);
-static herr_t H5F_sec2_read (H5F_low_t *lf, haddr_t addr, size_t size,
+static herr_t H5F_sec2_read (H5F_low_t *lf, const haddr_t *addr, size_t size,
uint8 *buf);
-static herr_t H5F_sec2_write (H5F_low_t *lf, haddr_t addr, size_t size,
+static herr_t H5F_sec2_write (H5F_low_t *lf, const haddr_t *addr, size_t size,
const uint8 *buf);
-static herr_t H5F_sec2_flush (H5F_low_t *lf);
-static size_t H5F_sec2_size (H5F_low_t *lf);
-
const H5F_low_class_t H5F_LOW_SEC2[1] = {{
- NULL, /* use default access(2) func */
+ NULL, /* access method */
H5F_sec2_open, /* open method */
H5F_sec2_close, /* close method */
H5F_sec2_read, /* read method */
H5F_sec2_write, /* write method */
- H5F_sec2_flush, /* flush method */
- H5F_sec2_size, /* file size method */
+ NULL, /* flush method */
+ NULL, /* extend method */
}};
@@ -69,7 +66,7 @@ const H5F_low_class_t H5F_LOW_SEC2[1] = {{
*-------------------------------------------------------------------------
*/
static H5F_low_t *
-H5F_sec2_open (const char *name, uintn flags, H5F_search_t *key)
+H5F_sec2_open (const char *name, uintn flags, H5F_search_t *key/*out*/)
{
uintn oflags;
H5F_low_t *lf = NULL;
@@ -91,9 +88,10 @@ H5F_sec2_open (const char *name, uintn flags, H5F_search_t *key)
lf->u.sec2.fd = fd;
lf->u.sec2.op = H5F_OP_SEEK;
lf->u.sec2.cur = 0;
+ fstat (fd, &sb);
+ lf->eof.offset = sb.st_size;
if (key) {
- fstat (fd, &sb);
key->dev = sb.st_dev;
key->ino = sb.st_ino;
}
@@ -101,7 +99,6 @@ H5F_sec2_open (const char *name, uintn flags, H5F_search_t *key)
FUNC_LEAVE (lf);
}
-
/*-------------------------------------------------------------------------
* Function: H5F_sec2_close
@@ -140,8 +137,8 @@ H5F_sec2_close (H5F_low_t *lf)
* Function: H5F_sec2_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 Read failed.
@@ -159,22 +156,46 @@ H5F_sec2_close (H5F_low_t *lf)
*-------------------------------------------------------------------------
*/
static herr_t
-H5F_sec2_read (H5F_low_t *lf, haddr_t addr, size_t size, uint8 *buf)
+H5F_sec2_read (H5F_low_t *lf, const haddr_t *addr, size_t size, uint8 *buf)
{
ssize_t n;
+ off_t offset;
FUNC_ENTER (H5F_sec2_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);
+ }
+
/*
- * Optimize seeking. If that optimization is disabled then alwasy call
+ * Optimize seeking. If that optimization is disabled then always call
* lseek().
*/
if (!H5F_OPT_SEEK ||
- lf->u.sec2.op==H5F_OP_UNKNOWN || lf->u.sec2.cur!=addr) {
- if (lseek (lf->u.sec2.fd, addr, SEEK_SET)<0) {
+ lf->u.sec2.op==H5F_OP_UNKNOWN ||
+ lf->u.sec2.cur!=offset) {
+ if (lseek (lf->u.sec2.fd, offset, SEEK_SET)<0) {
HRETURN_ERROR (H5E_IO, H5E_SEEKERROR, FAIL); /*lseek failed*/
}
- lf->u.sec2.cur = addr;
+ lf->u.sec2.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;
}
/*
@@ -193,12 +214,12 @@ H5F_sec2_read (H5F_low_t *lf, haddr_t addr, size_t size, uint8 *buf)
* might be different than the number requested.
*/
lf->u.sec2.op = H5F_OP_READ;
- lf->u.sec2.cur = addr + n;
+ lf->u.sec2.cur = offset + n;
+ assert ("address overflowed" && lf->u.sec2.cur>=offset);
FUNC_LEAVE (SUCCEED);
}
-
/*-------------------------------------------------------------------------
* Function: H5F_sec2_write
@@ -222,24 +243,33 @@ H5F_sec2_read (H5F_low_t *lf, haddr_t addr, size_t size, uint8 *buf)
*-------------------------------------------------------------------------
*/
static herr_t
-H5F_sec2_write (H5F_low_t *lf, haddr_t addr, size_t size, const uint8 *buf)
+H5F_sec2_write (H5F_low_t *lf, const haddr_t *addr, size_t size,
+ const uint8 *buf)
{
+ off_t offset;
+
FUNC_ENTER (H5F_sec2_write, NULL, FAIL);
+ /* Check for overflow */
+ offset = addr->offset;
+ assert ("address overflowed" && offset==addr->offset);
+ assert ("overflow" && offset+size>=offset);
+
/*
* Optimize seeking. If that optimization is disabled then always call
* lseek().
*/
if (!H5F_OPT_SEEK ||
- lf->u.sec2.op==H5F_OP_UNKNOWN || lf->u.sec2.cur!=addr) {
- if (lseek (lf->u.sec2.fd, addr, SEEK_SET)<0) {
+ lf->u.sec2.op==H5F_OP_UNKNOWN ||
+ lf->u.sec2.cur!=offset) {
+ if (lseek (lf->u.sec2.fd, offset, SEEK_SET)<0) {
HRETURN_ERROR (H5E_IO, H5E_SEEKERROR, FAIL); /*lseek failed*/
}
- lf->u.sec2.cur = addr;
+ lf->u.sec2.cur = offset;
}
/*
- * Read the data from the file. If the write failed then set the
+ * Write the data to the file. If the write failed then set the
* operation back to UNKNOWN since Posix doesn't gurantee its value.
*/
if (size != write (lf->u.sec2.fd, buf, size)) {
@@ -251,76 +281,8 @@ H5F_sec2_write (H5F_low_t *lf, haddr_t addr, size_t size, const uint8 *buf)
* Update the file position.
*/
lf->u.sec2.op = H5F_OP_WRITE;
- lf->u.sec2.cur = addr + size;
- FUNC_LEAVE (SUCCEED);
-}
-
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_sec2_flush
- *
- * Purpose: Makes sure that all data is on disk.
- *
- * Errors:
- *
- * Return: Success: SUCCEED
- *
- * Failure: FAIL
- *
- * Programmer: Robb Matzke
- * Wednesday, October 22, 1997
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5F_sec2_flush (H5F_low_t *lf)
-{
- FUNC_ENTER (H5F_sec2_flush, NULL, FAIL);
-
- /* Not necessary with this driver */
+ lf->u.sec2.cur = offset + size;
+ assert ("address overflowed" && lf->u.sec2.cur>=offset);
FUNC_LEAVE (SUCCEED);
}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_sec2_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 Lseek failed.
- *
- * Return: Success: Size of file in bytes
- *
- * Failure: 0
- *
- * Programmer: Robb Matzke
- * Wednesday, October 22, 1997
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static size_t
-H5F_sec2_size (H5F_low_t *lf)
-{
- off_t size;
-
- FUNC_ENTER (H5F_sec2_size, NULL, 0);
-
- if ((size=lseek (lf->u.sec2.fd, 0, SEEK_END))<0) {
- lf->u.sec2.op = H5F_OP_UNKNOWN;
- HRETURN_ERROR (H5E_IO, H5E_SEEKERROR, 0); /*lseek failed*/
- }
-
- lf->u.sec2.op = H5F_OP_SEEK;
- lf->u.sec2.cur = size;
-
- FUNC_LEAVE (size);
-}