summaryrefslogtreecommitdiffstats
path: root/src/H5Fsec2.c
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1997-11-14 14:42:14 (GMT)
committerRobb Matzke <matzke@llnl.gov>1997-11-14 14:42:14 (GMT)
commitcdeeb5553a3920565d87201761dadd1fe32aa3b1 (patch)
treea209c61f85983c1a76bf5c65d1f3285c4861ec46 /src/H5Fsec2.c
parent73897627660169de753597b9ff045d3112646506 (diff)
downloadhdf5-cdeeb5553a3920565d87201761dadd1fe32aa3b1.zip
hdf5-cdeeb5553a3920565d87201761dadd1fe32aa3b1.tar.gz
hdf5-cdeeb5553a3920565d87201761dadd1fe32aa3b1.tar.bz2
[svn-r136] ./MANIFEST
./src/Makefile.in Added H5Ffamily.c and H5Fsplit.c ./src/H5B.c ./src/H5Bprivate.h ./src/H5Gnode.c Added `const' to sublass arguments. ./src/H5F.c ./src/H5Flow.c ./src/H5Fsec2.c Make sure file buffers get flushed during a call to H5Fflush(). Check for overflow in address encoding and decoding. ./src/H5Ffam.c ./src/H5Fprivate.c ./test/istore.c Implementation of file families so 32-bit machines can access 64-bit files. ./src/H5Oprivate.h Removed H5O_NO_ADDR constant. ./config/freebsd2.2.1 ./config/linux Added -DH5G_DEBUG and -DH5F_DEBUG to the list of debugging flags. ./html/H5.format.html Changed some <offset>-sized things to <length>-sized things. ./src/H5AC.c ./src/H5ACprivate.h ./src/H5B.c ./src/H5Bprivate.h ./src/H5C.c ./src/H5D.c ./src/H5F.c ./src/H5Fcore.c ./src/H5Fistore.c ./src/H5Flow.c ./src/H5Fprivate.h ./src/H5Fsec2.c ./src/H5Fstdio.c ./src/H5G.c ./src/H5Gent.c ./src/H5Gnode.c ./src/H5Gpkg.h ./src/H5Gprivate.h ./src/H5Gshad.c ./src/H5Gstab.c ./src/H5H.c ./src/H5Hprivate.h ./src/H5MF.c ./src/H5MFprivate.h ./src/H5O.c ./src/H5Ocont.c ./src/H5Oistore.c ./src/H5Oprivate.h ./src/H5Ostab.c ./src/H5Ostdst.c ./src/H5pivate.h ./src/debug.c ./test/istore.c ./test/theap.c ./test/tohdr.c ./test/tstab.c Lots of changes caused by generalizing addresses. The haddr_t is now a struct, so you can no longer perform arithmetic on it. But since it's small, simple, and often used, storage is allocated like with an integer. But we always pass them around by reference. That is, when using an address in another struct, allocate space: struct my_struct { char *name; haddr_t address; } x; But when passing it to a function, pass by reference: H5F_addr_print (stderr, &(x.address)); Addresses should be initialized with H5F_addr_undef (&(x.address)); Functions for operating on addresses are in H5Flow.c and begin with H5F_addr_... Functions never return haddr_t or haddr_t*; they always pass them through arguments instead. A function that returns an address through an argument does so with its last argument and it is marked with `/*out*/'. Calls to such functions also mark output-only arguments with `/*out*/' ./src/H5Fsplit.c (new) A two-member family where all meta data goes in the first member and all raw data goes in the second member. ./src/H5B.c ./src/H5D.c ./src/H5F.c ./src/H5Ffamily.c ./src/H5Fistore.c ./src/H5Flow.c ./src/H5Fprivate.h ./src/H5Fsec2.c ./src/H5Fstdio.c ./src/H5Gnode.c ./src/H5H.c ./src/H5MF.c ./src/H5MFprivate.h ./src/H5O.c Differentiate between meta data storage and raw data storage. Provide a mechanism so that the file driver can extend the file to allocate more memory. ./src/H5E.c ./src/H5Epublic.c Added the error H5E_TRUNCATED to be reported when the file is shorter than the length recorded in the boot block. ./src/H5F.c Added H5F_locate_signature() so we only do it in one place now. ./INSTALL ./INSTALL_MAINT Just a couple clarifications. ./html/ExternalFiles.html ./html/storage.html Documents how external files work. ./test/hyperslab.c ./test/istore.c Fixed printf's on 64-bit machines. ./test/istore.c Added ifdef's to test the split file driver.
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);
-}