2
0
mirror of https://github.com/HDFGroup/hdf5.git synced 2025-03-19 16:50:46 +08:00

[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.
This commit is contained in:
Robb Matzke 1997-10-22 17:08:14 -05:00
parent 4fe5ac0999
commit e1e488bd47
19 changed files with 1433 additions and 424 deletions

@ -49,6 +49,9 @@
./src/H5Epublic.h
./src/H5F.c
./src/H5Fistore.c
./src/H5Flow.c
./src/H5Fsec2.c
./src/H5Fstdio.c
./src/H5Fprivate.h
./src/H5Fpublic.h
./src/H5G.c

@ -1,5 +1,5 @@
/* Define if the __attribute__(()) extension is present */
/* #define HAVE_ATTRIBUTE */
#undef HAVE_ATTRIBUTE
/* Define if the compiler understands the __FUNCTION__ keyword. */
/* #define HAVE_FUNCTION */
#undef HAVE_FUNCTION

@ -2,9 +2,9 @@
CFLAGS_WARN="-Wall -Wshadow -Wpointer-arith -Wcast-qual -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs"
CFLAGS_DEBUG="-g -DH5AC_DEBUG_PROTECT -DFILELIB=1 -fverbose-asm"
CFLAGS_DEBUG="-g -DH5AC_DEBUG_PROTECT -DH5F_LOW_DFLT=H5F_LOW_STDIO -DH5F_OPT_SEEK -fverbose-asm"
CFLAGS_PROFILE="-pg"
CFLAGS_PRODUCTION="-O3 -UH5AC_DEBUG_PROTECT -DNDEBUG -finline-functions -funroll-loops -malign-double -fomit-frame-pointer"
CFLAGS_PRODUCTION="-O3 -UH5AC_DEBUG_PROTECT -DNDEBUG -DH5F_LOW_DFLT=H5F_LOW_STDIO -DH5F_OPT_SEEK -finline-functions -funroll-loops -malign-double -fomit-frame-pointer"
if test "x$CFLAGS" = "x"; then

@ -113,12 +113,14 @@ AC_C_INLINE
AC_MSG_CHECKING(for __attribute__ extension)
AC_TRY_COMPILE(,[int __attribute__((unused)) f(void){return 1;}],
AC_DEFINE(HAVE_ATTRIBUTE) AC_MSG_RESULT(yes),
AC_DEFINE(HAVE_ATTRIBUTE)
AC_MSG_RESULT(yes),
AC_MSG_RESULT(no))
AC_MSG_CHECKING(for __FUNCTION__ extension)
AC_TRY_COMPILE(,[int f(void){return __FUNCTION__;}],
AC_DEFINE(HAVE_FUNCTION) AC_MSG_RESULT(yes),
AC_DEFINE(HAVE_FUNCTION)
AC_MSG_RESULT(yes),
AC_MSG_RESULT(no))

@ -29,8 +29,8 @@ static hbool_t interface_initialize_g = FALSE;
/* PRIVATE PROTOTYPES */
static size_t H5F_istore_sizeof_rkey (H5F_t *f, const void *_udata);
static haddr_t H5F_istore_new (H5F_t *f, void *_lt_key, void *_udata,
void *_rt_key);
static haddr_t H5F_istore_new_node (H5F_t *f, void *_lt_key, void *_udata,
void *_rt_key);
static intn H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata,
void *_rt_key);
static herr_t H5F_istore_found (H5F_t *f, haddr_t addr, const void *_lt_key,
@ -43,10 +43,12 @@ static herr_t H5F_istore_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
void *_key);
static herr_t H5F_istore_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
void *_key);
static herr_t H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore,
H5F_isop_t op, size_t offset_f[],
size_t size[], size_t offset_m[],
size_t size_m[], void *buf);
static herr_t H5F_istore_copy_hyperslab (H5F_t *f, const H5O_istore_t *istore,
H5F_isop_t op,
const size_t offset_f[],
const size_t size[],
const size_t offset_m[],
const size_t size_m[], void *buf);
/*
@ -79,7 +81,7 @@ H5B_class_t H5B_ISTORE[1] = {{
H5B_ISTORE_ID, /*id */
sizeof (H5F_istore_key_t), /*sizeof_nkey */
H5F_istore_sizeof_rkey, /*get_sizeof_rkey */
H5F_istore_new, /*new */
H5F_istore_new_node, /*new */
H5F_istore_cmp, /*cmp */
H5F_istore_found, /*found */
H5F_istore_insert, /*insert */
@ -262,7 +264,7 @@ H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
/*-------------------------------------------------------------------------
* Function: H5F_istore_new
* Function: H5F_istore_new_node
*
* Purpose: Adds a new entry to an i-storage B-tree. We can assume that
* the domain represented by UDATA doesn't intersect the domain
@ -281,7 +283,7 @@ H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
*-------------------------------------------------------------------------
*/
static haddr_t
H5F_istore_new (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
H5F_istore_new_node (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
{
H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
@ -289,7 +291,7 @@ H5F_istore_new (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
size_t nbytes;
intn i;
FUNC_ENTER (H5F_istore_new, NULL, FAIL);
FUNC_ENTER (H5F_istore_new_node, NULL, FAIL);
/* check args */
assert (f);
@ -519,9 +521,10 @@ H5F_istore_insert (H5F_t *f, haddr_t addr, H5B_ins_t *parent_ins,
*-------------------------------------------------------------------------
*/
static herr_t
H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore, H5F_isop_t op,
size_t offset_f[], size_t size[],
size_t offset_m[], size_t size_m[], void *buf)
H5F_istore_copy_hyperslab (H5F_t *f, const H5O_istore_t *istore, H5F_isop_t op,
const size_t offset_f[], const size_t size[],
const size_t offset_m[], const size_t size_m[],
void *buf)
{
intn i, carry;
size_t idx_cur[H5O_ISTORE_NDIMS];
@ -542,6 +545,7 @@ H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore, H5F_isop_t op,
/* check args */
assert (f);
assert (istore);
assert (istore->btree_addr>0);
assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
assert (H5F_ISTORE_READ==op || H5F_ISTORE_WRITE==op);
assert (size);
@ -559,22 +563,6 @@ H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore, H5F_isop_t op,
}
#endif
/*
* Does the B-tree exist?
*/
if (istore->btree_addr<=0) {
if (H5F_ISTORE_WRITE==op) {
udata.mesg.ndims = istore->ndims;
if ((istore->btree_addr=H5B_new (f, H5B_ISTORE, &udata))<0) {
/* Can't create B-tree */
HGOTO_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
}
} else {
H5V_hyper_fill (istore->ndims, size, size_m, offset_m, buf, 0);
HRETURN (SUCCEED);
}
}
/* Initialize indices */
for (i=0; i<istore->ndims; i++) {
idx_min[i] = (offset_f?offset_f[i]:0) / istore->alignment[i];
@ -677,8 +665,8 @@ H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore, H5F_isop_t op,
*-------------------------------------------------------------------------
*/
herr_t
H5F_istore_read (H5F_t *f, struct H5O_istore_t *istore,
size_t offset[], size_t size[], void *buf)
H5F_istore_read (H5F_t *f, const H5O_istore_t *istore,
const size_t offset[], const size_t size[], void *buf)
{
FUNC_ENTER (H5F_istore_read, NULL, FAIL);
@ -717,8 +705,8 @@ H5F_istore_read (H5F_t *f, struct H5O_istore_t *istore,
*-------------------------------------------------------------------------
*/
herr_t
H5F_istore_write (H5F_t *f, struct H5O_istore_t *istore,
size_t offset[], size_t size[], void *buf)
H5F_istore_write (H5F_t *f, const H5O_istore_t *istore,
const size_t offset[], const size_t size[], void *buf)
{
FUNC_ENTER (H5F_istore_write, NULL, FAIL);
@ -738,3 +726,58 @@ H5F_istore_write (H5F_t *f, struct H5O_istore_t *istore,
FUNC_LEAVE (SUCCEED);
}
/*-------------------------------------------------------------------------
* Function: H5F_istore_new
*
* Purpose: Creates a new indexed-storage B-tree and initializes the
* istore struct with information about the storage. The
* struct should be immediately written to the object header.
*
* This function must be called before passing ISTORE to any of
* the other indexed storage functions!
*
* Return: Success: SUCCEED with the ISTORE argument initialized
* and ready to write to an object header.
*
* Failure: FAIL
*
* Programmer: Robb Matzke
* Tuesday, October 21, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
herr_t
H5F_istore_new (H5F_t *f, struct H5O_istore_t *istore,
uintn ndims, const size_t alignment[])
{
H5F_istore_ud1_t udata;
int i;
FUNC_ENTER (H5F_istore_new, NULL, FAIL);
/* Check args */
assert (f);
assert (istore);
assert (ndims>0 && ndims<=H5O_ISTORE_NDIMS);
assert (alignment);
#ifndef NDEBUG
for (i=0; i<ndims; i++) {
assert (alignment[i]>0);
}
#endif
udata.mesg.ndims = istore->ndims = ndims;
if ((istore->btree_addr=H5B_new (f, H5B_ISTORE, &udata))<0) {
HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL); /* Can't create B-tree */
}
for (i=0; i<ndims; i++) {
istore->alignment[i] = alignment[i];
}
FUNC_LEAVE (SUCCEED);
}

@ -84,6 +84,7 @@ static const hdf_min_error_messages_t hdf_min_error_messages[] =
{H5E_SEEKERROR, "Seek failed"},
{H5E_READERROR, "Read failed"},
{H5E_WRITEERROR, "Write failed"},
{H5E_CLOSEERROR, "Close failed"},
{H5E_CANTINIT, "Can't initialize interface"},
{H5E_ALREADYINIT, "Object already initialized"},
{H5E_BADATOM, "Can't find atom information"},

@ -72,6 +72,7 @@ typedef enum
H5E_SEEKERROR, /* Seek failed */
H5E_READERROR, /* Read failed */
H5E_WRITEERROR, /* Write failed */
H5E_CLOSEERROR, /* Close failed */
/* Function entry/exit interface errors */
H5E_CANTINIT, /* Can't initialize interface */

138
src/H5F.c

@ -54,7 +54,7 @@ static char RcsId[] = "@(#)$Revision$";
* keep track of the file position and attempt to minimize calls to the file
* seek method.
*/
#define H5F_OPT_SEEK
/* #define H5F_OPT_SEEK */
#define PABLO_MASK H5F_mask
@ -325,7 +325,7 @@ done:
--------------------------------------------------------------------------*/
hbool_t H5Fis_hdf5(const char *filename)
{
hdf_file_t f_handle=H5F_INVALID_FILE; /* file handle */
H5F_low_t *f_handle=NULL; /* file handle */
uint8 temp_buf[H5F_SIGNATURE_LEN]; /* temporary buffer for checking file signature */
haddr_t curr_off=0; /* The current offset to check in the file */
size_t file_len=0; /* The length of the file we are checking */
@ -339,41 +339,31 @@ hbool_t H5Fis_hdf5(const char *filename)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, BFAIL); /*no filename specified*/
/* Open the file */
f_handle=H5F_OPEN(filename,0);
if(H5F_OPENERR(f_handle)) {
if (NULL==(f_handle=H5F_low_open (H5F_LOW_DFLT, filename, 0))) {
/* Low-level file open failure */
HGOTO_ERROR(H5E_FILE, H5E_BADFILE, BFAIL);
}
/* Get the length of the file */
if(H5F_SEEKEND(f_handle)==FAIL) {
/* Unable to determine length of file due to seek failure */
HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, BFAIL);
}
file_len=H5F_TELL(f_handle);
file_len = H5F_low_size (f_handle);
/* Check the offsets where the file signature is possible */
while(curr_off<file_len)
{
if(H5F_SEEK(f_handle,curr_off)==FAIL)
HGOTO_ERROR(H5E_IO, H5E_READERROR, BFAIL); /*seek error*/
if(H5F_READ(f_handle,temp_buf, H5F_SIGNATURE_LEN)==FAIL)
HGOTO_ERROR(H5E_IO, H5E_READERROR, BFAIL); /*read error*/
if(HDmemcmp(temp_buf,H5F_SIGNATURE,H5F_SIGNATURE_LEN)==0)
{
ret_value=BTRUE;
break;
} /* end if */
if(curr_off==0)
curr_off=512;
else
curr_off*=2;
} /* end while */
while(curr_off<file_len) {
if (H5F_low_read (f_handle, curr_off, H5F_SIGNATURE_LEN, temp_buf)<0) {
HGOTO_ERROR(H5E_IO, H5E_READERROR, BFAIL); /*read error*/
}
if(HDmemcmp(temp_buf,H5F_SIGNATURE,H5F_SIGNATURE_LEN)==0) {
ret_value=BTRUE;
break;
}
if(curr_off==0)
curr_off=512;
else
curr_off*=2;
} /* end while */
done:
if(f_handle!=H5F_INVALID_FILE)
H5F_CLOSE(f_handle); /* close the file we opened */
H5F_low_close(f_handle); /* close the file we opened */
FUNC_LEAVE(ret_value);
}
@ -510,6 +500,10 @@ H5F_dest (H5F_t *f)
* The CREATE_PARMS argument is optional. A null pointer will
* cause the default file creation parameters to be used.
*
* The TYPE argument determins the low-level type of file that
* is opened. The special value H5F_LOW_DFLT uses the default
* method which is defined at compile time.
*
* Errors:
* ATOM BADATOM Can't unatomize default template
* id.
@ -557,7 +551,7 @@ H5F_dest (H5F_t *f)
*-------------------------------------------------------------------------
*/
H5F_t *
H5F_open (const char *name, uintn flags,
H5F_open (const H5F_low_class_t *type, const char *name, uintn flags,
const file_create_temp_t *create_parms)
{
H5F_t *f = NULL; /*return value */
@ -565,7 +559,7 @@ H5F_open (const char *name, uintn flags,
H5F_t *old = NULL; /*a file already opened */
struct stat sb; /*file stat info */
H5F_search_t search; /*file search key */
hdf_file_t fd = H5F_INVALID_FILE; /*low level file desc */
H5F_low_t *fd = NULL; /*low level file desc */
hbool_t empty_file = FALSE; /*is file empty? */
hbool_t file_exists = FALSE; /*file already exists */
uint8 buf[256], *p=NULL; /*I/O buffer and ptr into it */
@ -628,14 +622,14 @@ H5F_open (const char *name, uintn flags,
}
if ((flags & H5F_ACC_WRITE) &&
0==(old->shared->flags & H5F_ACC_WRITE)) {
if (H5F_INVALID_FILE==(fd = H5F_OPEN (name, H5ACC_WRITE))) {
if (NULL==(fd=H5F_low_open (type, name, H5F_ACC_WRITE))) {
/* File cannot be reopened with write access */
HRETURN_ERROR (H5E_FILE, H5E_CANTOPENFILE, NULL);
}
H5F_CLOSE (old->shared->file_handle);
H5F_low_close (old->shared->file_handle);
old->shared->file_handle = fd;
old->shared->flags |= H5F_ACC_WRITE;
fd = H5F_INVALID_FILE; /*so we don't close it during error*/
fd = NULL; /*so we don't close it during error*/
}
f = H5F_new (old->shared);
@ -645,7 +639,8 @@ H5F_open (const char *name, uintn flags,
/* Can't truncate without write intent */
HRETURN_ERROR (H5E_FILE, H5E_BADVALUE, NULL);
}
if (H5F_INVALID_FILE==(fd=H5F_CREATE (name))) {
fd = H5F_low_open (type, name, H5F_ACC_WRITE|H5F_ACC_TRUNC);
if (!fd) {
/* Can't truncate file */
HRETURN_ERROR (H5E_FILE, H5E_CANTCREATE, NULL);
}
@ -657,8 +652,8 @@ H5F_open (const char *name, uintn flags,
empty_file = TRUE;
} else {
fd = H5F_OPEN (name, (flags & H5F_ACC_WRITE)?H5ACC_WRITE : 0);
if (H5F_INVALID_FILE==fd) {
fd = H5F_low_open (type, name, (flags & H5F_ACC_WRITE));
if (!fd) {
/* Cannot open existing file */
HRETURN_ERROR (H5E_FILE, H5E_CANTOPENFILE, NULL);
}
@ -673,12 +668,13 @@ H5F_open (const char *name, uintn flags,
/* Can't create file without write intent */
HRETURN_ERROR (H5E_FILE, H5E_BADVALUE, NULL);
}
if (H5F_INVALID_FILE==(fd=H5F_CREATE (name))) {
fd = H5F_low_open (type, name, H5F_ACC_WRITE|H5F_ACC_CREAT|H5F_ACC_EXCL);
if (!fd) {
/* Can't create file */
HRETURN_ERROR (H5E_FILE, H5E_CANTCREATE, NULL);
}
if (stat (name, &sb)<0) {
/* Can't stat file */
/* Can't stat file - can't get dev or inode */
HRETURN_ERROR (H5E_FILE, H5E_CANTCREATE, NULL);
}
f = H5F_new (NULL);
@ -835,13 +831,7 @@ H5F_open (const char *name, uintn flags,
}
/* What is the current size of the file? */
if (H5F_SEEKEND (f->shared->file_handle)<0) {
/* Cannot determine file size */
HGOTO_ERROR (H5E_FILE, H5E_CANTINIT, NULL);
}
f->shared->logical_len = H5F_TELL (f->shared->file_handle);
f->shared->last_op=OP_SEEK; /* change the last operation to a seek */
f->shared->logical_len = H5F_low_size (f->shared->file_handle);
/* Success! */
ret_value = f;
@ -849,7 +839,7 @@ H5F_open (const char *name, uintn flags,
done:
if (!ret_value) {
if (f) H5F_dest (f);
if (H5F_INVALID_FILE!=fd) H5F_CLOSE (fd);
H5F_low_close (fd);
}
FUNC_LEAVE (ret_value);
@ -941,7 +931,8 @@ hid_t H5Fcreate(const char *filename, uintn flags, hid_t create_temp,
/*
* Create a new file or truncate an existing file.
*/
if (NULL==(new_file = H5F_open (filename, flags, create_parms))) {
if (NULL==(new_file = H5F_open (H5F_LOW_DFLT, filename, flags,
create_parms))) {
HGOTO_ERROR (H5E_FILE, H5E_CANTOPENFILE, FAIL); /*can't create file */
}
@ -1023,7 +1014,7 @@ hid_t H5Fopen(const char *filename, uintn flags, hid_t access_temp)
#endif
/* Open the file */
if (NULL==(new_file=H5F_open (filename, flags, NULL))) {
if (NULL==(new_file=H5F_open (H5F_LOW_DFLT, filename, flags, NULL))) {
HGOTO_ERROR (H5E_FILE, H5E_CANTOPENFILE, FAIL); /*cant open file*/
}
@ -1213,7 +1204,7 @@ H5F_close (H5F_t *f)
/*can't flush cache*/
HRETURN_ERROR (H5E_CACHE, H5E_CANTFLUSH, FAIL);
}
H5F_CLOSE(f->shared->file_handle);
H5F_low_close (f->shared->file_handle);
H5F_dest (f);
/* Did the H5F_flush() fail because of open objects? */
@ -1291,8 +1282,7 @@ done:
* The data is contiguous.
*
* Errors:
* IO READERROR Low-level read failure.
* IO SEEKERROR Low-level seek failure.
* IO READERROR Low-level read failed.
*
* Return: Success: SUCCEED
*
@ -1313,25 +1303,10 @@ H5F_block_read (H5F_t *f, haddr_t addr, size_t size, void *buf)
if (0==size) return 0;
addr += f->shared->file_create_parms.userblock_size;
/* Check for switching file access operations or mis-placed seek offset */
#ifdef H5F_OPT_SEEK
if(f->shared->last_op!=OP_READ || f->shared->f_cur_off!=addr)
{
#endif
f->shared->last_op=OP_READ;
if (H5F_SEEK (f->shared->file_handle, addr)<0) {
/* low-level seek failure */
HRETURN_ERROR (H5E_IO, H5E_SEEKERROR, FAIL);
} /* end if */
#ifdef H5F_OPT_SEEK
} /* end if */
#endif
if (H5F_READ (f->shared->file_handle, buf, size)<0) {
/* low-level read failure */
HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL);
if (H5F_low_read (f->shared->file_handle, addr, size, buf)<0) {
HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL); /*low-level read failed*/
}
f->shared->f_cur_off=addr+size;
FUNC_LEAVE (SUCCEED);
}
@ -1344,8 +1319,7 @@ H5F_block_read (H5F_t *f, haddr_t addr, size_t size, void *buf)
* data is contiguous.
*
* Errors:
* IO SEEKERROR Low-level seek failure.
* IO WRITEERROR Low-level write failure.
* IO WRITEERROR Low-level write failed.
* IO WRITEERROR No write intent.
*
* Return: Success: SUCCEED
@ -1373,25 +1347,9 @@ H5F_block_write (H5F_t *f, haddr_t addr, size_t size, void *buf)
HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL);
}
/* Check for switching file access operations or mis-placed seek offset */
#ifdef H5F_OPT_SEEK
if(f->shared->last_op!=OP_WRITE || f->shared->f_cur_off!=addr)
{
#endif
f->shared->last_op=OP_WRITE;
if (H5F_SEEK (f->shared->file_handle, addr)<0) {
/* low-level seek failure */
HRETURN_ERROR (H5E_IO, H5E_SEEKERROR, FAIL);
}
#ifdef H5F_OPT_SEEK
} /* end if */
#endif
if (H5F_WRITE (f->shared->file_handle, buf, size)<0) {
/* low-level write failure */
HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL);
if (H5F_low_write (f->shared->file_handle, addr, size, buf)) {
HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL);/*low-level write failed*/
}
f->shared->f_cur_off=addr+size;
FUNC_LEAVE (SUCCEED);
}

@ -29,8 +29,8 @@ static hbool_t interface_initialize_g = FALSE;
/* PRIVATE PROTOTYPES */
static size_t H5F_istore_sizeof_rkey (H5F_t *f, const void *_udata);
static haddr_t H5F_istore_new (H5F_t *f, void *_lt_key, void *_udata,
void *_rt_key);
static haddr_t H5F_istore_new_node (H5F_t *f, void *_lt_key, void *_udata,
void *_rt_key);
static intn H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata,
void *_rt_key);
static herr_t H5F_istore_found (H5F_t *f, haddr_t addr, const void *_lt_key,
@ -43,10 +43,12 @@ static herr_t H5F_istore_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
void *_key);
static herr_t H5F_istore_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
void *_key);
static herr_t H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore,
H5F_isop_t op, size_t offset_f[],
size_t size[], size_t offset_m[],
size_t size_m[], void *buf);
static herr_t H5F_istore_copy_hyperslab (H5F_t *f, const H5O_istore_t *istore,
H5F_isop_t op,
const size_t offset_f[],
const size_t size[],
const size_t offset_m[],
const size_t size_m[], void *buf);
/*
@ -79,7 +81,7 @@ H5B_class_t H5B_ISTORE[1] = {{
H5B_ISTORE_ID, /*id */
sizeof (H5F_istore_key_t), /*sizeof_nkey */
H5F_istore_sizeof_rkey, /*get_sizeof_rkey */
H5F_istore_new, /*new */
H5F_istore_new_node, /*new */
H5F_istore_cmp, /*cmp */
H5F_istore_found, /*found */
H5F_istore_insert, /*insert */
@ -262,7 +264,7 @@ H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
/*-------------------------------------------------------------------------
* Function: H5F_istore_new
* Function: H5F_istore_new_node
*
* Purpose: Adds a new entry to an i-storage B-tree. We can assume that
* the domain represented by UDATA doesn't intersect the domain
@ -281,7 +283,7 @@ H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
*-------------------------------------------------------------------------
*/
static haddr_t
H5F_istore_new (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
H5F_istore_new_node (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
{
H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
@ -289,7 +291,7 @@ H5F_istore_new (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
size_t nbytes;
intn i;
FUNC_ENTER (H5F_istore_new, NULL, FAIL);
FUNC_ENTER (H5F_istore_new_node, NULL, FAIL);
/* check args */
assert (f);
@ -519,9 +521,10 @@ H5F_istore_insert (H5F_t *f, haddr_t addr, H5B_ins_t *parent_ins,
*-------------------------------------------------------------------------
*/
static herr_t
H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore, H5F_isop_t op,
size_t offset_f[], size_t size[],
size_t offset_m[], size_t size_m[], void *buf)
H5F_istore_copy_hyperslab (H5F_t *f, const H5O_istore_t *istore, H5F_isop_t op,
const size_t offset_f[], const size_t size[],
const size_t offset_m[], const size_t size_m[],
void *buf)
{
intn i, carry;
size_t idx_cur[H5O_ISTORE_NDIMS];
@ -542,6 +545,7 @@ H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore, H5F_isop_t op,
/* check args */
assert (f);
assert (istore);
assert (istore->btree_addr>0);
assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
assert (H5F_ISTORE_READ==op || H5F_ISTORE_WRITE==op);
assert (size);
@ -559,22 +563,6 @@ H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore, H5F_isop_t op,
}
#endif
/*
* Does the B-tree exist?
*/
if (istore->btree_addr<=0) {
if (H5F_ISTORE_WRITE==op) {
udata.mesg.ndims = istore->ndims;
if ((istore->btree_addr=H5B_new (f, H5B_ISTORE, &udata))<0) {
/* Can't create B-tree */
HGOTO_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
}
} else {
H5V_hyper_fill (istore->ndims, size, size_m, offset_m, buf, 0);
HRETURN (SUCCEED);
}
}
/* Initialize indices */
for (i=0; i<istore->ndims; i++) {
idx_min[i] = (offset_f?offset_f[i]:0) / istore->alignment[i];
@ -677,8 +665,8 @@ H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore, H5F_isop_t op,
*-------------------------------------------------------------------------
*/
herr_t
H5F_istore_read (H5F_t *f, struct H5O_istore_t *istore,
size_t offset[], size_t size[], void *buf)
H5F_istore_read (H5F_t *f, const H5O_istore_t *istore,
const size_t offset[], const size_t size[], void *buf)
{
FUNC_ENTER (H5F_istore_read, NULL, FAIL);
@ -717,8 +705,8 @@ H5F_istore_read (H5F_t *f, struct H5O_istore_t *istore,
*-------------------------------------------------------------------------
*/
herr_t
H5F_istore_write (H5F_t *f, struct H5O_istore_t *istore,
size_t offset[], size_t size[], void *buf)
H5F_istore_write (H5F_t *f, const H5O_istore_t *istore,
const size_t offset[], const size_t size[], void *buf)
{
FUNC_ENTER (H5F_istore_write, NULL, FAIL);
@ -738,3 +726,58 @@ H5F_istore_write (H5F_t *f, struct H5O_istore_t *istore,
FUNC_LEAVE (SUCCEED);
}
/*-------------------------------------------------------------------------
* Function: H5F_istore_new
*
* Purpose: Creates a new indexed-storage B-tree and initializes the
* istore struct with information about the storage. The
* struct should be immediately written to the object header.
*
* This function must be called before passing ISTORE to any of
* the other indexed storage functions!
*
* Return: Success: SUCCEED with the ISTORE argument initialized
* and ready to write to an object header.
*
* Failure: FAIL
*
* Programmer: Robb Matzke
* Tuesday, October 21, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
herr_t
H5F_istore_new (H5F_t *f, struct H5O_istore_t *istore,
uintn ndims, const size_t alignment[])
{
H5F_istore_ud1_t udata;
int i;
FUNC_ENTER (H5F_istore_new, NULL, FAIL);
/* Check args */
assert (f);
assert (istore);
assert (ndims>0 && ndims<=H5O_ISTORE_NDIMS);
assert (alignment);
#ifndef NDEBUG
for (i=0; i<ndims; i++) {
assert (alignment[i]>0);
}
#endif
udata.mesg.ndims = istore->ndims = ndims;
if ((istore->btree_addr=H5B_new (f, H5B_ISTORE, &udata))<0) {
HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL); /* Can't create B-tree */
}
for (i=0; i<ndims; i++) {
istore->alignment[i] = alignment[i];
}
FUNC_LEAVE (SUCCEED);
}

234
src/H5Flow.c Normal file

@ -0,0 +1,234 @@
/*
* Copyright (C) 1997 NCSA
* All rights reserved.
*
* Programmer: Robb Matzke <matzke@viper.llnl.gov>
* Wednesday, October 22, 1997
*
* Purpose: This file contains virtual functions for the H5F_low
* class. These are functions that operate on various kinds
* of files at a level where the file is just a one-dimensional
* array of bytes.
*/
#include <H5private.h>
#include <H5Eprivate.h>
#include <H5Fprivate.h>
#include <H5MMprivate.h>
#define PABLO_MASK H5F_low
static hbool_t interface_initialize_g = FALSE;
/*-------------------------------------------------------------------------
* Function: H5F_low_open
*
* Purpose: Opens a file of type TYPE with name NAME according to the
* field of bit flags FLAGS which are:
*
* H5F_ACC_WRITE: The file is open for read/write access.
* Without this bit set, the file would be open
* for read-only access.
*
* H5F_ACC_CREAT: The file is created if it doesn't already
* exist. On unix, the file permissions are set
* to 0666 modified by the umask.
*
* H5F_ACC_EXCL: This function will fail if the file already
* exists.
*
* H5F_ACC_TRUNC: Truncate the file to a zero-length file as it
* is opened. This allows existing files to be
* overwritten.
*
* Errors:
* IO CANTOPENFILE Open failed.
*
* Return: Success: Pointer to the new file descriptor.
*
* Failure: NULL
*
* Programmer: Robb Matzke
* Wednesday, October 22, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
H5F_low_t *
H5F_low_open (const H5F_low_class_t *type, const char *name, uintn flags)
{
H5F_low_t *lf = NULL;
FUNC_ENTER (H5F_low_open, NULL, NULL);
assert (type && type->open);
assert (name && *name);
if (NULL==(lf=(type->open)(name, flags))) {
HRETURN_ERROR (H5E_IO, H5E_CANTOPENFILE, NULL);/*open failed*/
}
lf->type = type;
FUNC_LEAVE (lf);
}
/*-------------------------------------------------------------------------
* Function: H5F_low_close
*
* Purpose: Closes a low-level file.
*
* Errors:
* IO CLOSEERROR Close failed.
*
* Return: Success: NULL
*
* Failure: NULL
*
* Programmer: Robb Matzke
* Wednesday, October 22, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
H5F_low_t *
H5F_low_close (H5F_low_t *lf)
{
FUNC_ENTER (H5F_low_close, NULL, NULL);
if (lf && (lf->type->close)(lf)<0) {
HRETURN_ERROR (H5E_IO, H5E_CLOSEERROR, NULL); /*close failed*/
H5MM_xfree (lf);
}
FUNC_LEAVE (NULL);
}
/*-------------------------------------------------------------------------
* Function: H5F_low_read
*
* Purpose: Reads SIZE bytes of data beginning at address ADDR of the
* file LF and puts the result in BUF.
*
* Errors:
* IO READERROR Read failed.
* IO UNSUPPORTED No read method.
*
* Return: Success: SUCCEED
*
* Failure: FAIL
*
* Programmer: Robb Matzke
* Wednesday, October 22, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
herr_t
H5F_low_read (H5F_low_t *lf, haddr_t addr, size_t size, uint8 *buf)
{
herr_t ret_value = FAIL;
FUNC_ENTER (H5F_low_read, NULL, FAIL);
assert (lf && lf->type);
assert (buf);
if (lf->type->read) {
if ((ret_value = (lf->type->read)(lf, addr, size, buf))<0) {
HRETURN_ERROR (H5E_IO, H5E_READERROR, ret_value);/*read failed*/
}
} else {
HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, FAIL);/*no read method*/
}
FUNC_LEAVE (ret_value);
}
/*-------------------------------------------------------------------------
* Function: H5F_low_write
*
* Purpose: Writes SIZE bytes of data from BUF into the file LF beginning
* at address ADDR of the file.
*
* Errors:
* IO UNSUPPORTED No write method.
* IO WRITEERROR Write failed.
*
* Return: Success: SUCCEED
*
* Failure: FAIL
*
* Programmer: Robb Matzke
* Wednesday, October 22, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
herr_t
H5F_low_write (H5F_low_t *lf, haddr_t addr, size_t size, const uint8 *buf)
{
herr_t ret_value = FAIL;
FUNC_ENTER (H5F_low_write, NULL, FAIL);
assert (lf && lf->type);
assert (buf);
if (lf->type->write) {
if ((ret_value = (lf->type->write)(lf, addr, size, buf))<0) {
HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, ret_value);/*write failed*/
}
} else {
HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, FAIL);/*no write method*/
}
FUNC_LEAVE (ret_value);
}
/*-------------------------------------------------------------------------
* Function: H5F_low_size
*
* Purpose: Returns the current size of the file in bytes.
*
* Errors:
* IO UNSUPPORTED No size method.
*
* Return: Success: Current size of file
*
* Failure: 0
*
* Programmer: Robb Matzke
* Wednesday, October 22, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
size_t
H5F_low_size (H5F_low_t *lf)
{
size_t size;
FUNC_ENTER (H5F_low_size, NULL, 0);
assert (lf && lf->type);
if (lf->type->size) {
size = (lf->type->size)(lf);
} else {
HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, 0);/*no size method*/
}
FUNC_LEAVE (size);
}

@ -23,6 +23,16 @@
/* This is a near top-level header! Try not to include much! */
#include <H5private.h>
/*
* Feature: Define this constant to be non-zero if you want to enable code
* that minimizes the number of calls to lseek(). This has a huge
* performance benefit on some systems. Set this constant to zero
* on the compiler command line to disable that optimization.
*/
#ifndef H5F_OPT_SEEK
# define H5F_OPT_SEEK 1
#endif
/* Maximum size of boot-block buffer */
#define H5F_BOOTBLOCK_SIZE 1024
@ -42,120 +52,6 @@
#define H5F_ACC_EXCL 0x0004 /* Fail if file exists */
#define H5F_ACC_TRUNC 0x0008 /* Truncate existing file */
/*
* Define the low-level file interface.
*/
#if FILELIB == POSIXBUFIO
typedef FILE *hdf_file_t;
# ifdef VMS
# define H5F_OPEN(p, a) (((a) & H5ACC_WRITE) ? \
fopen ((p), "r+", "mbc=64") : \
fopen ((p), "r", "mbc=64"))
# define H5F_CREATE(p) fopen ((p), "w+", "mbc=64")
# elif defined SUN && defined (__GNUC__)
# define H5F_OPEN(p, a) (((a) & H5ACC_WRITE) ? \
fopen ((p), "r+") : \
fopen ((p), "r"))
# define H5F_CREATE(p) fopen ((p), "w+")
# else
# define H5F_OPEN(p, a) (((a) & H5ACC_WRITE) ? \
fopen ((p), "rb+") : \
fopen((p), "rb"))
# define H5F_CREATE(p) fopen((p), "wb+")
# endif
# define H5F_READ(f, b, n) (((size_t)(n) == (size_t)fread ((b), 1, \
(size_t)(n), \
(f))) ? \
SUCCEED : FAIL)
# define H5F_WRITE(f, b, n) (((size_t)(n) == (size_t)fwrite ((b), 1, \
(size_t)(n), \
(f))) ? \
SUCCEED : FAIL)
# define H5F_CLOSE(f) fclose (f)
# define H5F_FLUSH(f) (0==fflush (f) ? SUCCEED : FAIL)
# define H5F_SEEK(f,o) (0==fseek ((f), (long)(o), SEEK_SET) ? \
SUCCEED : FAIL)
# define H5F_SEEK_CUR(f,o) (0==fseek ((f), (long)(o), SEEK_CUR) ? \
SUCCEED : FAIL)
# define H5F_SEEKEND(f) (0==fseek ((f), (long)0, SEEK_END) ? \
SUCCEED : FAIL)
# define H5F_TELL(f) ftell (f)
# define H5F_OPENERR(f) (!f)
# define H5F_INVALID_FILE ((FILE *)NULL)
#elif FILELIB == POSIXUNBUFIO
typedef int hdf_file_t;
# define H5F_OPEN(p, a) (((a) & H5ACC_WRITE) ? \
open ((p), O_RDWR) : \
open ((p), O_RDONLY))
# define H5F_CREATE(p) open ((p), O_RDWR | O_CREAT | O_TRUNC, 0666)
# define H5F_CLOSE(f) close(f)
# define H5F_FLUSH(f) SUCCEED
# define H5F_READ(f, b, n) (((n)==read ((f), (char*)(b), (n))) ? \
SUCCEED : FAIL)
# define H5F_WRITE(f, b, n) (((n)==write ((f), (char*)(b), (n))) ? \
SUCCEED : FAIL)
# define H5F_SEEK(f, o) (lseek ((f), (off_t)(o), SEEK_SET)<0 ? \
FAIL : SUCCEED)
# define H5F_SEEKEND(f) (lseek ((f), (off_t)0, SEEK_END)<0 ? \
FAIL : SUCCEED)
# define H5F_TELL(f) lseek ((f), (off_t)0, SEEK_CUR)
# define H5F_OPENERR(f) ((f) < 0)
# define H5F_INVALID_FILE (-1)
#elif FILELIB == MACIO
typedef short hdf_file_t;
# define H5F_OPEN(x,y) mopen (x, y)
# define H5F_CREATE(name) mopen (name, H5ACC_CREATE)
# define H5F_CLOSE(x) mclose (x)
# define H5F_FLUSH(a) SUCCEED
# define H5F_READ(a,b,c) mread (a, (char*)b, (int32)c)
# define H5F_WRITE(a,b,c) mwrite (a, (char*)b, (int32)c)
# define H5F_SEEK(x,y) mlseek (x, (int32)y, 0)
# define H5F_SEEKEND(x) mlseek (x, 0L, 2)
# define H5F_TELL(x) mlseek (x, 0L, 1)
# define H5F_OPENERR(f) (f < 0)
# define H5F_INVALID_FILE (-1)
#elif FILELIB == WINNTIO
typedef HFILE hdf_file_t;
# define H5F_OPEN(p, a) (((a) & H5ACC_WRITE) ? \
_lopen ((p), OF_READWRITE) : \
_lopen ((p), OF_READ))
# define H5F_CREATE(p) _lcreat ((p), 0)
# define H5F_READ(f, b, n) (((int32)(n) == _hread ((f), (b), (n))) ? \
SUCCEED : FAIL)
# define H5F_WRITE(f, b, n) (((int32)(n) == _hwrite ((f), (b), (n))) ? \
SUCCEED : FAIL)
# define H5F_CLOSE(f) (_lclose(f)==0 ? SUCCEED : FAIL)
# define H5F_FLUSH(f) 0
# define H5F_SEEK(f, o) _llseek ((f), (long)(o), 0)
# define H5F_SEEKEND(f) _llseek ((f), (long)0, 2)
# define H5F_TELL(f) _llseek ((f), 0l, 1)
# define H5F_OPENERR(f) ((f) == (HFILE)HFILE_ERROR)
# define H5F_INVALID_FILE ((HFILE)HFILE_ERROR)
#elif FILELIB == PAGEBUFIO
# include "fmpio.h"
typedef MPFILE *hdf_file_t;
# define H5F_OPEN(p, a) MPopen ((p), (a))
# define H5F_CREATE(p) MPopen ((p), H5ACC_CREATE)
# define H5F_CLOSE(f) MPclose (f)
# define H5F_FLUSH(f) MPflush (f)
# define H5F_READ(f, b, n) MPread ((f), (char *)(b), (n))
# define H5F_WRITE(f, b, n) MPwrite ((f), (char *)(b), (n))
# define H5F_SEEK(f, o) MPseek ((f), (off_t)(o), SEEK_SET)
# define H5F_SEEKEND(f) MPseek ((f), (off_t)0, SEEK_END)
# define H5F_TELL(f) MPseek ((f), (off_t)0, SEEK_CUR)
# define H5F_OPENERR(f) ((f) == (MPFILE *)NULL)
# define H5F_INVALID_FILE ((MPFILE *)NULL)
#endif
/*
* Encode and decode macros for file meta-data.
@ -188,45 +84,30 @@ typedef MPFILE *hdf_file_t;
*(p) = (uint8)(((i) >> 24) & 0xff); (p)++; \
}
# define INT64ENCODE(p, i) { \
*(p) = (uint8)( (uint64)(i) & 0xff); (p)++; \
*(p) = (uint8)(((uint64)(i) >> 8) & 0xff); (p)++; \
*(p) = (uint8)(((uint64)(i) >> 16) & 0xff); (p)++; \
*(p) = (uint8)(((uint64)(i) >> 24) & 0xff); (p)++; \
if (sizeof(int64)>4) { \
*(p) = (uint8)(((uint64)(i) >> 32) & 0xff); (p)++; \
*(p) = (uint8)(((uint64)(i) >> 40) & 0xff); (p)++; \
*(p) = (uint8)(((uint64)(i) >> 48) & 0xff); (p)++; \
*(p) = (uint8)(((uint64)(i) >> 56) & 0xff); (p)++; \
} else if ((i)<0) { \
*(p)++ = 0xff; \
*(p)++ = 0xff; \
*(p)++ = 0xff; \
*(p)++ = 0xff; \
} else { \
*(p)++ = 0x00; \
*(p)++ = 0x00; \
*(p)++ = 0x00; \
*(p)++ = 0x00; \
# define INT64ENCODE(p, n) { \
int64 _n = (n); \
intn _i; \
uint8 *_p = (uint8*)(p); \
for (_i=0; _i<sizeof(int64); _i++, _n>>=8) { \
*_p++ = _n & 0xff; \
} \
for (/*void*/; _i<8; _i++) { \
*_p++ = (n)<0 ? 0xff : 0; \
} \
(p) = (uint8*)(p)+8; \
}
# define UINT64ENCODE(p, i) { \
*(p) = (uint8)( (i) & 0xff); (p)++; \
*(p) = (uint8)(((i) >> 8) & 0xff); (p)++; \
*(p) = (uint8)(((i) >> 16) & 0xff); (p)++; \
*(p) = (uint8)(((i) >> 24) & 0xff); (p)++; \
if (sizeof(uint64)>4) { \
*(p) = (uint8)(((i) >> 32) & 0xff); (p)++; \
*(p) = (uint8)(((i) >> 40) & 0xff); (p)++; \
*(p) = (uint8)(((i) >> 48) & 0xff); (p)++; \
*(p) = (uint8)(((i) >> 56) & 0xff); (p)++; \
} else { \
*(p)++ = 0x00; \
*(p)++ = 0x00; \
*(p)++ = 0x00; \
*(p)++ = 0x00; \
# define UINT64ENCODE(p, n) { \
uint64 _n = (n); \
intn _i; \
uint8 *_p = (uint8*)(p); \
for (_i=0; _i<sizeof(uint64); _i++, _n>>=8) { \
*_p++ = _n & 0xff; \
} \
for (/*void*/; _i<8; _i++) { \
*_p++ = 0; \
} \
(p) = (uint8*)(p)+8; \
}
# define INT16DECODE(p, i) { \
@ -253,34 +134,26 @@ typedef MPFILE *hdf_file_t;
(i) |= ((uint32)(*(p) & 0xff) << 24); (p)++; \
}
# define INT64DECODE(p, i) { \
(i) = ( *(p) & 0xff); (p)++; \
(i) |= ((int64)(*(p) & 0xff) << 8); (p)++; \
(i) |= ((int64)(*(p) & 0xff) << 16); (p)++; \
(i) |= ((int64)(*(p) & 0xff) << 24); (p)++; \
if (sizeof(int64)>4) { \
(i) |= ((int64)(*(p) & 0xff) << 32); (p)++; \
(i) |= ((int64)(*(p) & 0xff) << 40); (p)++; \
(i) |= ((int64)(*(p) & 0xff) << 48); (p)++; \
(i) |= ((int64)(*(p) & 0xff) << 56); (p)++; \
} else { \
(p) += 4; \
# define INT64DECODE(p, n) { \
/* WE DON'T CHECK FOR OVERFLOW! */ \
int64 _n = 0; \
intn _i; \
uint8 *_p = (uint8*)(p)+8; \
for (_i=0; _i<sizeof(int64); _i++, _n<<=8) { \
_n |= *(--_p); \
} \
(p) = (uint8*)(p)+8; \
}
# define UINT64DECODE(p, i) { \
(i) = (uint64)(*(p) & 0xff); (p)++; \
(i) |= ((uint64)(*(p) & 0xff) << 8); (p)++; \
(i) |= ((uint64)(*(p) & 0xff) << 16); (p)++; \
(i) |= ((uint64)(*(p) & 0xff) << 24); (p)++; \
if (sizeof(uint64)>4) { \
(i) |= ((uint64)(*(p) & 0xff) << 32); (p)++; \
(i) |= ((uint64)(*(p) & 0xff) << 40); (p)++; \
(i) |= ((uint64)(*(p) & 0xff) << 48); (p)++; \
(i) |= ((uint64)(*(p) & 0xff) << 56); (p)++; \
} else { \
(p) += 4; \
# define UINT64DECODE(p, n) { \
/* WE DON'T CHECK FOR OVERFLOW! */ \
uint64 _n = 0; \
intn _i; \
uint8 *_p = (uint8*)(p)+8; \
for (_i=0; _i<sizeof(uint64); _i++, _n<<=8) { \
_n |= *(--_p); \
} \
(p) = (uint8*)(p)+8; \
}
#else
@ -352,27 +225,62 @@ typedef struct H5F_search_t {
} H5F_search_t;
/* For determining what the last file operation was */
typedef enum
{
OP_UNKNOWN = 0, /* Don't know what the last operation was (after fopen frex) */
OP_SEEK, /* Last operation was a seek */
OP_WRITE, /* Last operation was a write */
OP_READ /* Last operation was a read */
}
H5F_fileop_t;
typedef enum {
H5F_OP_UNKNOWN, /* Don't know what the last operation was */
H5F_OP_SEEK, /* Last operation was a seek */
H5F_OP_WRITE, /* Last operation was a write */
H5F_OP_READ /* Last operation was a read */
} H5F_fileop_t;
/*
* Define the low-level file interface.
*/
typedef struct H5F_low_class_t {
struct H5F_low_t *(*open)(const char*, uintn);
herr_t (*close)(struct H5F_low_t*);
herr_t (*read)(struct H5F_low_t*, haddr_t, size_t, uint8*);
herr_t (*write)(struct H5F_low_t*, haddr_t, size_t, const uint8*);
herr_t (*flush)(struct H5F_low_t*);
size_t (*size)(struct H5F_low_t*);
} H5F_low_class_t;
typedef struct H5F_low_t {
const H5F_low_class_t *type; /* What type of file is this? */
union {
/* Posix section 2 I/O */
struct {
int fd; /* The unix file descriptor */
H5F_fileop_t op; /* Previous file operation */
haddr_t cur; /* Current file position */
} sec2;
/* Posix stdio */
struct {
FILE *f; /* Posix stdio file */
H5F_fileop_t op; /* Previous file operation */
haddr_t cur; /* Current file position */
} stdio;
} u;
} H5F_low_t;
/* What types of low-level files are there? */
#ifndef H5F_LOW_DFLT
# define H5F_LOW_DFLT H5F_LOW_STDIO /* The default type */
#endif
extern const H5F_low_class_t H5F_LOW_SEC2[]; /* Posix section 2 */
extern const H5F_low_class_t H5F_LOW_STDIO[]; /* Posix stdio */
/*
* Define the structure to store the file information for HDF5 files. One of
* these structures is allocated per file, not per H5Fopen().
*/
typedef struct H5F_file_t {
/* Seek caching info */
haddr_t f_cur_off; /* Current location in the file */
H5F_fileop_t last_op; /* the last file operation performed */
H5F_search_t key; /* The key for looking up files */
uintn flags; /* Access Permissions for file */
hdf_file_t file_handle; /* File handle for actual I/O */
H5F_low_t *file_handle; /* Lower level file handle for I/O */
uintn nrefs; /* Ref count for times file is opened */
uint32 consist_flags; /* File Consistency Flags */
haddr_t smallobj_off; /* Offset of small-obj heap within the file */
@ -452,16 +360,33 @@ struct H5O_istore_t; /*forward decl for prototype arguments*/
/* Private functions, not part of the publicly documented API */
void H5F_encode_length_unusual(const H5F_t *f, uint8 **p, uint8 *l);
void H5F_encode_offset_unusual(const H5F_t *f, uint8 **p, uint8 *o);
H5F_t *H5F_open (const char *name, uintn flags,
H5F_t *H5F_open (const H5F_low_class_t *type, const char *name, uintn flags,
const file_create_temp_t *create_parms);
herr_t H5F_close (H5F_t *f);
herr_t H5F_block_read (H5F_t *f, haddr_t addr, size_t size, void *buf);
herr_t H5F_block_write (H5F_t *f, haddr_t addr, size_t size, void *buf);
herr_t H5F_istore_read (H5F_t *f, struct H5O_istore_t *mesg,
size_t offset[], size_t size[], void *buf);
herr_t H5F_istore_write (H5F_t *f, struct H5O_istore_t *mesg,
size_t offset[], size_t size[], void *buf);
herr_t H5F_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent,
intn fwidth);
/* Functions that operate on indexed storage */
herr_t H5F_istore_new (H5F_t *f, struct H5O_istore_t *istore,
uintn ndims, const size_t alignment[]);
herr_t H5F_istore_read (H5F_t *f, const struct H5O_istore_t *mesg,
const size_t offset[], const size_t size[],
void *buf);
herr_t H5F_istore_write (H5F_t *f, const struct H5O_istore_t *mesg,
const size_t offset[], const size_t size[],
void *buf);
/* Functions that operate on contiguous storage wrt boot block */
herr_t H5F_block_read (H5F_t *f, haddr_t addr, size_t size, void *buf);
herr_t H5F_block_write (H5F_t *f, haddr_t addr, size_t size, void *buf);
/* Functions that operate directly on low-level files */
H5F_low_t *H5F_low_open (const H5F_low_class_t *type, const char *name,
uintn flags);
H5F_low_t *H5F_low_close (H5F_low_t *lf);
size_t H5F_low_size (H5F_low_t *lf);
herr_t H5F_low_read (H5F_low_t *lf, haddr_t addr, size_t size, uint8 *buf);
herr_t H5F_low_write (H5F_low_t *lf, haddr_t addr, size_t size,
const uint8 *buf);
#endif

314
src/H5Fsec2.c Normal file

@ -0,0 +1,314 @@
/*
* Copyright (C) 1997 NCSA
* All rights reserved.
*
* Programmer: Robb Matzke <matzke@llnl.gov>
* Wednesday, October 22, 1997
*
* Purpose: This is the Posix section-2 I/O subclass of H5Flow.
*
* Notes: This driver keeps track of its own file position in order to
* minimize the number of calls to lseek(). We assume that
* opening a file sets the current file position to the beginning
* and that read() and write() modify the file position as
* expected when they return successfully (unsuccessful return
* leaves the file position undefined).
*/
#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_sec2_open (const char *name, uintn flags);
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,
uint8 *buf);
static herr_t H5F_sec2_write (H5F_low_t *lf, 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] = {{
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 */
}};
/*-------------------------------------------------------------------------
* Function: H5F_sec2_open
*
* Purpose: Opens a file with name NAME. The FLAGS are a bit field with
* the possible values defined in H5F_low_open().
*
* Errors:
* IO CANTOPENFILE Open failed.
*
* Return: Success: Low-level file pointer
*
* Failure: NULL
*
* Programmer: Robb Matzke
* Wednesday, October 22, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static H5F_low_t *
H5F_sec2_open (const char *name, uintn flags)
{
uintn oflags;
H5F_low_t *lf = NULL;
int fd;
FUNC_ENTER (H5F_sec2_open, NULL, NULL);
oflags = (flags & H5F_ACC_WRITE) ? O_RDWR : O_RDONLY;
oflags |= (flags & H5F_ACC_CREAT) ? O_CREAT : 0;
oflags |= (flags & H5F_ACC_EXCL) ? O_EXCL : 0;
oflags |= (flags & H5F_ACC_TRUNC) ? O_TRUNC : 0;
if ((fd=open (name, oflags, 0666))<0) {
HRETURN_ERROR (H5E_IO, H5E_CANTOPENFILE, NULL);/*open failed*/
}
lf = H5MM_xcalloc (1, sizeof(H5F_low_t));
lf->u.sec2.fd = fd;
lf->u.sec2.op = H5F_OP_SEEK;
lf->u.sec2.cur = 0;
FUNC_LEAVE (lf);
}
/*-------------------------------------------------------------------------
* Function: H5F_sec2_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_sec2_close (H5F_low_t *lf)
{
FUNC_ENTER (H5F_sec2_close, NULL, FAIL);
if (close (lf->u.sec2.fd)<0) {
HRETURN_ERROR (H5E_IO, H5E_CLOSEERROR, FAIL); /*close failed*/
}
lf->u.sec2.fd = -1;
FUNC_LEAVE (SUCCEED);
}
/*-------------------------------------------------------------------------
* 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.
*
* Errors:
* IO READERROR Read failed.
* IO SEEKERROR Lseek failed.
*
* Return: Success: SUCCEED
*
* Failure: FAIL
*
* Programmer: Robb Matzke
* Wednesday, October 22, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
H5F_sec2_read (H5F_low_t *lf, haddr_t addr, size_t size, uint8 *buf)
{
ssize_t n;
FUNC_ENTER (H5F_sec2_read, NULL, FAIL);
/*
* Optimize seeking. If that optimization is disabled then alwasy 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) {
HRETURN_ERROR (H5E_IO, H5E_SEEKERROR, FAIL); /*lseek failed*/
}
lf->u.sec2.cur = addr;
}
/*
* Read the data. If a read error occurs then set the last file operation
* to UNKNOWN because the file position isn't guaranteed by Posix.
*/
if ((n=read (lf->u.sec2.fd, buf, size))<0) {
lf->u.sec2.op = H5F_OP_UNKNOWN;
HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL); /*read failed*/
} else if (n<size) {
HDmemset (buf+n, 0, size-n);
}
/*
* Update the file position with the number of bytes actually read. This
* might be different than the number requested.
*/
lf->u.sec2.op = H5F_OP_READ;
lf->u.sec2.cur = addr + n;
FUNC_LEAVE (SUCCEED);
}
/*-------------------------------------------------------------------------
* Function: H5F_sec2_write
*
* Purpose: Writes SIZE bytes from the beginning of BUF into file LF at
* file address ADDR.
*
* Errors:
* IO SEEKERROR Lseek failed.
* IO WRITEERROR Write failed.
*
* Return: Success: SUCCEED
*
* Failure: FAIL
*
* Programmer: Robb Matzke
* Wednesday, October 22, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
H5F_sec2_write (H5F_low_t *lf, haddr_t addr, size_t size, const uint8 *buf)
{
FUNC_ENTER (H5F_sec2_write, NULL, FAIL);
/*
* 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) {
HRETURN_ERROR (H5E_IO, H5E_SEEKERROR, FAIL); /*lseek failed*/
}
lf->u.sec2.cur = addr;
}
/*
* Read the data from 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)) {
lf->u.sec2.op = H5F_OP_UNKNOWN;
HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL); /*write failed*/
}
/*
* 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 */
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);
}

341
src/H5Fstdio.c Normal file

@ -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);
}

@ -519,7 +519,7 @@ H5H_insert (H5F_t *f, haddr_t addr, size_t buf_size, const void *buf)
H5H_t *heap=NULL;
H5H_free_t *fl=NULL, *max_fl=NULL;
off_t offset = -1;
size_t need, old_size, need_more;
size_t old_size, need_more;
#ifndef NDEBUG
static nmessages = 0;
#endif
@ -533,10 +533,6 @@ H5H_insert (H5F_t *f, haddr_t addr, size_t buf_size, const void *buf)
assert (buf_size>0);
assert (buf);
/* allocate aligned file memory */
need = buf_size;
H5H_ALIGN (need);
if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL);
}
@ -547,12 +543,12 @@ H5H_insert (H5F_t *f, haddr_t addr, size_t buf_size, const void *buf)
* leave zero or at least H5G_SIZEOF_FREE bytes left over.
*/
for (fl=heap->freelist; fl; fl=fl->next) {
if (fl->size>need && fl->size-need>=H5H_SIZEOF_FREE(f)) {
if (fl->size>buf_size && fl->size-buf_size>=H5H_SIZEOF_FREE(f)) {
offset = fl->offset;
fl->offset += need;
fl->size -= need;
fl->offset += buf_size;
fl->size -= buf_size;
break;
} else if (fl->size==need) {
} else if (fl->size==buf_size) {
offset = fl->offset;
fl = H5H_remove_free (heap, fl);
break;
@ -570,15 +566,15 @@ H5H_insert (H5F_t *f, haddr_t addr, size_t buf_size, const void *buf)
*/
if (offset<0) {
need_more = MAX3 (need, heap->mem_alloc, H5H_SIZEOF_FREE(f));
need_more = MAX3 (buf_size, heap->mem_alloc, H5H_SIZEOF_FREE(f));
if (max_fl && max_fl->offset+max_fl->size==heap->mem_alloc) {
/*
* Increase the size of the maximum free block.
*/
offset = max_fl->offset;
max_fl->offset += need;
max_fl->size += need_more - need;
max_fl->offset += buf_size;
max_fl->size += need_more - buf_size;
if (max_fl->size < H5H_SIZEOF_FREE(f)) {
#ifndef NDEBUG
@ -600,18 +596,18 @@ H5H_insert (H5F_t *f, haddr_t addr, size_t buf_size, const void *buf)
* take some space out of it right away.
*/
offset = heap->mem_alloc;
if (need_more-need >= H5H_SIZEOF_FREE(f)) {
if (need_more-buf_size >= H5H_SIZEOF_FREE(f)) {
fl = H5MM_xmalloc (sizeof(H5H_free_t));
fl->offset = heap->mem_alloc + need;
fl->size = need_more - need;
fl->offset = heap->mem_alloc + buf_size;
fl->size = need_more - buf_size;
fl->prev = NULL;
fl->next = heap->freelist;
if (heap->freelist) heap->freelist->prev = fl;
heap->freelist = fl;
#ifndef NDEBUG
} else if (need_more>need) {
} else if (need_more>buf_size) {
fprintf (stderr, "H5H_insert: lost %d bytes at line %d\n",
need_more-need, __LINE__);
need_more-buf_size, __LINE__);
if (0==nmessages++) {
fprintf (stderr, "Messages from H5H_insert() will go away "
"when assertions are turned off.\n");

@ -24,7 +24,6 @@
#define H5H_MAGIC "HEAP" /*heap magic number */
#define H5H_SIZEOF_MAGIC 4
#define H5H_ALIGN(X) ((X)=((X)+1) & ~0x01)
#define H5H_SIZEOF_HDR(F) \
(H5H_SIZEOF_MAGIC + /*heap signature */ \

@ -20,10 +20,10 @@
#undef WORDS_BIGENDIAN
/* Define if the __attribute__(()) extension is present */
/* #define HAVE_ATTRIBUTE */
#undef HAVE_ATTRIBUTE
/* Define if the compiler understands the __FUNCTION__ keyword. */
/* #define HAVE_FUNCTION */
#undef HAVE_FUNCTION
/* The number of bytes in a double. */
#undef SIZEOF_DOUBLE

@ -55,18 +55,6 @@
# include "ProcIDS.h"
#endif
/*
* Low level I/O library
*/
#define POSIXBUFIO 0
#define POSIXUNBUFIO 1
#define MACIO 2
#define WINNTIO 3
#define PAGEBUFIO 4
#ifndef FILELIB
# define FILELIB POSIXBUFIO
#endif
/* Does the compiler support the __attribute__(()) syntax? */
#ifndef HAVE_ATTRIBUTE
# define __attribute__(X) /*void*/

@ -15,9 +15,10 @@ PROGS=debug
# Source and object files for the library (lexicographically)...
LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5C.c H5D.c H5Dconv.c H5E.c H5F.c H5Fistore.c \
H5G.c H5Gent.c H5Gnode.c H5Gshad.c H5Gstab.c H5H.c H5M.c H5MF.c \
H5MM.c H5O.c H5Ocont.c H5Oistore.c H5Oname.c H5Onull.c H5Osdtyp.c \
H5Osdim.c H5Ostab.c H5Ostdst.c H5P.c H5T.c H5V.c
H5Flow.c H5Fsec2.c H5Fstdio.c H5G.c H5Gent.c H5Gnode.c H5Gshad.c \
H5Gstab.c H5H.c H5M.c H5MF.c H5MM.c H5O.c H5Ocont.c H5Oistore.c \
H5Oname.c H5Onull.c H5Osdtyp.c H5Osdim.c H5Ostab.c H5Ostdst.c H5P.c \
H5T.c H5V.c
LIB_OBJ=$(LIB_SRC:.c=.o)

@ -16,6 +16,9 @@
#define FILENAME "istore.h5"
#define TEST_SMALL 0x0001
#define TEST_MEDIUM 0x0002
#define AT() printf (" at %s:%d in %s()...\n", \
__FILE__, __LINE__, __FUNCTION__);
@ -82,6 +85,7 @@ new_object (H5F_t *f, const char *name, size_t ndims)
{
H5G_entry_t *handle = NULL;
H5O_istore_t istore;
size_t alignment[H5O_ISTORE_NDIMS];
intn i;
/* Create the object symbol table entry and header */
@ -95,10 +99,8 @@ new_object (H5F_t *f, const char *name, size_t ndims)
}
/* Add the indexed-storage message */
memset (&istore, 0, sizeof istore);
istore.ndims = ndims;
for (i=0; i<ndims; i++) istore.alignment[i] = 2;
for (i=0; i<ndims; i++) alignment[i] = 2;
H5F_istore_new (f, &istore, ndims, alignment);
if (H5O_modify (f, H5O_NO_ADDR, handle, H5O_ISTORE, H5O_NEW_MESG,
&istore)<0) {
printf ("*FAILED*\n");
@ -156,7 +158,8 @@ test_create (H5F_t *f, const char *prefix)
* Function: test_extend
*
* Purpose: Creates an empty object and then writes to it in such a way
* as to always extend the object's domain.
* as to always extend the object's domain without creating
* holes and without causing the object to become concave.
*
* Return: Success: SUCCEED
*
@ -181,6 +184,7 @@ test_extend (H5F_t *f, const char *prefix,
size_t max_corner[3];
size_t size[3];
size_t whole_size[3];
size_t nelmts;
H5O_istore_t istore;
if (!nz) {
@ -245,16 +249,17 @@ test_extend (H5F_t *f, const char *prefix,
if (0==ctr) {
offset[0] = offset[1] = offset[2] = 0;
size[0] = size[1] = size[2] = 1;
nelmts = 1;
} else {
for (i=0; i<ndims; i++) {
for (i=0, nelmts=1; i<ndims; i++) {
if (ctr % ndims == i) {
offset[i] = max_corner[i];
size[i] = 1;
if (offset[i]+size[i]>whole_size[i]) continue;
size[i] = MIN (1, whole_size[i]-offset[i]);
} else {
offset[i] = 0;
size[i] = max_corner[i];
}
nelmts *= size[i];
}
}
@ -266,11 +271,15 @@ test_extend (H5F_t *f, const char *prefix,
printf ("), size=(%d", size[0]);
if (ndims>1) printf (",%d", size[1]);
if (ndims>2) printf (",%d", size[2]);
printf (")\n");
printf ("), %d element%s", nelmts, 1==nelmts?"":"s");
if (0==nelmts) printf (" *SKIPPED*");
printf ("\n");
fflush (stdout);
#endif
/* Fill the source array */
memset (buf, 128+ctr, size[0]*size[1]*size[2]);
if (0==nelmts) continue;
memset (buf, 128+ctr, nelmts);
/* Write to disk */
if (H5F_istore_write (f, &istore, offset, size, buf)<0) {
@ -283,7 +292,7 @@ test_extend (H5F_t *f, const char *prefix,
}
/* Read from disk */
memset (check, 0xff, size[0]*size[1]*size[2]);
memset (check, 0xff, nelmts);
if (H5F_istore_read (f, &istore, offset, size, check)<0) {
puts ("*FAILED*");
if (!isatty (1)) {
@ -292,7 +301,7 @@ test_extend (H5F_t *f, const char *prefix,
}
goto error;
}
if (memcmp (buf, check, size[0]*size[1]*size[2])) {
if (memcmp (buf, check, nelmts)) {
puts ("*FAILED*");
if (!isatty (1)) {
AT ();
@ -316,10 +325,6 @@ test_extend (H5F_t *f, const char *prefix,
}
}
/* Update the object header */
H5O_modify (f, H5O_NO_ADDR, handle, H5O_ISTORE, 0, &istore);
/* Now read the entire array back out and check it */
memset (buf, 0xff, nx*ny*nz);
if (H5F_istore_read (f, &istore, H5V_ZERO, whole_size, buf)<0) {
@ -339,8 +344,8 @@ test_extend (H5F_t *f, const char *prefix,
AT ();
printf (" Check failed at i=%d", i);
if (ndims>1) printf (", j=%d", j);
if (ndims>2) printf (", k=%d\n", k);
printf (" Check array is:\n");
if (ndims>2) printf (", k=%d", k);
printf ("\n Check array is:\n");
print_array (whole, nx, ny, nz);
printf (" Value read is:\n");
print_array (buf, nx, ny, nz);
@ -364,7 +369,115 @@ test_extend (H5F_t *f, const char *prefix,
H5MM_xfree (whole);
return FAIL;
}
/*-------------------------------------------------------------------------
* Function: test_sparse
*
* Purpose: Creates a sparse matrix consisting of NBLOCKS randomly placed
* blocks each of size NX,NY,NZ.
*
* Return: Success: SUCCEED
*
* Failure: FAIL
*
* Programmer: Robb Matzke
* Wednesday, October 22, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
test_sparse (H5F_t *f, const char *prefix, size_t nblocks,
size_t nx, size_t ny, size_t nz)
{
intn ndims, ctr;
char dims[64], s[256], name[256];
size_t offset[3], size[3];
H5G_entry_t *handle = NULL;
H5O_istore_t istore;
uint8 *buf = NULL;
if (!nz) {
if (!ny) {
ndims = 1;
ny = nz = 1;
sprintf (dims, "%d", nx);
} else {
ndims = 2;
nz = 1;
sprintf (dims, "%dx%d", nx, ny);
}
} else {
ndims = 3;
sprintf (dims, "%dx%dx%d", nx, ny, nz);
}
sprintf (s, "Testing istore sparse: %s", dims);
printf ("%-70s", s);
fflush (stdout);
buf = H5MM_xmalloc (nx*ny*nz);
/* Build the new empty object */
sprintf (name, "%s_%s", prefix, dims);
if (NULL==(handle=new_object (f, name, ndims))) {
if (!isatty (1)) {
AT ();
printf (" Cannot create %d-d object `%s'\n", ndims, name);
}
goto error;
}
if (NULL==H5O_read (f, H5O_NO_ADDR, handle, H5O_ISTORE, 0, &istore)) {
puts ("*FAILED*");
if (!isatty (1)) {
AT ();
printf (" Unable to read istore message\n");
}
goto error;
}
for (ctr=0; ctr<nblocks; ctr++) {
offset[0] = rand () % 1000000;
offset[1] = rand () % 1000000;
offset[2] = rand () % 1000000;
size[0] = nx;
size[1] = ny;
size[2] = nz;
memset (buf, 128+ctr, nx*ny*nz);
/* write to disk */
if (H5F_istore_write (f, &istore, offset, size, buf)<0) {
puts ("*FAILED*");
if (!isatty (1)) {
AT ();
printf (" Write failed: ctr=%d\n", ctr);
printf (" offset=(%d", offset[0]);
if (ndims>1) printf (",%d", offset[1]);
if (ndims>2) printf (",%d", offset[2]);
printf ("), size=(%d", size[0]);
if (ndims>1) printf (",%d", size[1]);
if (ndims>2) printf (",%d", size[2]);
printf (")\n");
}
goto error;
}
/* We don't test reading yet.... */
}
H5G_close (f, handle);
puts (" PASSED");
H5MM_xfree (buf);
return SUCCEED;
error:
H5MM_xfree (buf);
return FAIL;
}
/*-------------------------------------------------------------------------
* Function: main
@ -383,37 +496,84 @@ test_extend (H5F_t *f, const char *prefix,
*-------------------------------------------------------------------------
*/
int
main (void)
main (int argc, char *argv[])
{
H5F_t *f;
herr_t status;
int nerrors = 0;
uintn size_of_test;
/* Parse arguments or assume `small' */
if (1==argc) {
size_of_test = TEST_SMALL;
} else {
intn i;
for (i=1,size_of_test=0; i<argc; i++) {
if (!strcmp (argv[i], "small")) {
size_of_test |= TEST_SMALL;
} else if (!strcmp (argv[i], "medium")) {
size_of_test |= TEST_MEDIUM;
} else {
printf ("unrecognized argument: %s\n", argv[i]);
exit (1);
}
}
}
printf ("Test sizes: ");
if (size_of_test & TEST_SMALL) printf (" SMALL");
if (size_of_test & TEST_MEDIUM) printf (" MEDIUM");
printf ("\n");
/* Create the test file */
if (NULL==(f=H5F_open (FILENAME, H5F_ACC_CREAT|H5F_ACC_WRITE|H5F_ACC_TRUNC,
if (NULL==(f=H5F_open (H5F_LOW_DFLT, FILENAME,
H5F_ACC_CREAT|H5F_ACC_WRITE|H5F_ACC_TRUNC,
NULL))) {
printf ("Cannot create file %s; test aborted\n", FILENAME);
exit (1);
}
/*----------------------
* INDEXED STORAGE TESTS
*----------------------
/*
* Creation test: Creates empty objects with various raw data sizes
* and alignments.
*/
status = test_create (f, "test_create_1");
status = test_create (f, "create");
nerrors += status<0 ? 1 : 0;
status = test_extend (f, "test_extend_1", 10, 0, 0);
nerrors += status<0 ? 1 : 0;
status = test_extend (f, "test_extend_1", 10, 10, 0);
nerrors += status<0 ? 1 : 0;
status = test_extend (f, "test_extend_1", 10, 10, 10);
nerrors += status<0 ? 1 : 0;
if (size_of_test & TEST_SMALL) {
status = test_extend (f, "extend", 10, 0, 0);
nerrors += status<0 ? 1 : 0;
status = test_extend (f, "extend", 10, 10, 0);
nerrors += status<0 ? 1 : 0;
status = test_extend (f, "extend", 10, 10, 10);
nerrors += status<0 ? 1 : 0;
}
if (size_of_test & TEST_MEDIUM) {
status = test_extend (f, "extend", 10000, 0, 0);
nerrors += status<0 ? 1 : 0;
status = test_extend (f, "extend", 2500, 10, 0);
nerrors += status<0 ? 1 : 0;
status = test_extend (f, "extend", 10, 400, 10);
nerrors += status<0 ? 1 : 0;
}
if (size_of_test & TEST_SMALL) {
status = test_sparse (f, "sparse", 100, 5, 0, 0);
nerrors += status<0 ? 1 : 0;
status = test_sparse (f, "sparse", 100, 3, 4, 0);
nerrors += status<0 ? 1 : 0;
status = test_sparse (f, "sparse", 100, 2, 3, 4);
nerrors += status<0 ? 1 : 0;
}
if (size_of_test & TEST_MEDIUM) {
status = test_sparse (f, "sparse", 1000, 30, 0, 0);
nerrors += status<0 ? 1 : 0;
status = test_sparse (f, "sparse", 2000, 7, 3, 0);
nerrors += status<0 ? 1 : 0;
status = test_sparse (f, "sparse", 2000, 4, 2, 3);
nerrors += status<0 ? 1 : 0;
}
/* Close the test file and exit */
H5F_close (f);
if (nerrors) {