summaryrefslogtreecommitdiffstats
path: root/src/H5FDstdio.c
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2007-04-04 19:59:00 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2007-04-04 19:59:00 (GMT)
commit3431f74c438b25e7aeba9062ed1e948899457b46 (patch)
treeed7a1aa1282e74a0a4646762ce82f29b1749dbec /src/H5FDstdio.c
parentea63d5fb19e8b260178e6f76e8ed0504ded148a3 (diff)
downloadhdf5-3431f74c438b25e7aeba9062ed1e948899457b46.zip
hdf5-3431f74c438b25e7aeba9062ed1e948899457b46.tar.gz
hdf5-3431f74c438b25e7aeba9062ed1e948899457b46.tar.bz2
[svn-r13588] A support of files bigger than 2GB for STDIO driver. Configure will
check if fseeko is available. Using it instead of fseek can support big files because the offset is of type off_t not long int. Also added the test for STDIO in big.c.
Diffstat (limited to 'src/H5FDstdio.c')
-rw-r--r--src/H5FDstdio.c102
1 files changed, 89 insertions, 13 deletions
diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c
index e299311..87eb1dd 100644
--- a/src/H5FDstdio.c
+++ b/src/H5FDstdio.c
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
+#include <errno.h>
/* Disable certain warnings in PC-Lint: */
/*lint --emacro( {534, 830}, H5P_FILE_ACCESS) */
@@ -113,6 +114,18 @@ typedef struct H5FD_stdio_t {
#endif
} H5FD_stdio_t;
+#ifdef H5_HAVE_LSEEK64
+# define file_offset_t off64_t
+# define file_truncate ftruncate64
+#elif defined (WIN32) && !defined(__MWERKS__)
+# /*MSVC*/
+# define file_offset_t __int64
+# define file_truncate _chsize
+#else
+# define file_offset_t off_t
+# define file_truncate ftruncate
+#endif
+
/*
* These macros check for overflow of various quantities. These macros
* assume that file_offset_t is signed and haddr_t and size_t are unsigned.
@@ -135,17 +148,8 @@ typedef struct H5FD_stdio_t {
#define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \
HADDR_UNDEF==(A)+(Z) || (file_offset_t)((A)+(Z))<(file_offset_t)(A))
-#ifdef H5_HAVE_LSEEK64
-# define file_offset_t off64_t
-# define file_truncate ftruncate64
-#elif defined (WIN32) && !defined(__MWERKS__)
-# /*MSVC*/
-# define file_offset_t __int64
-# define file_truncate _chsize
-#else
-# define file_offset_t off_t
-# define file_truncate ftruncate
-#endif
+/* Define big file as 2GB */
+#define BIG_FILE 0x80000000UL
/* Prototypes */
static H5FD_t *H5FD_stdio_open(const char *name, unsigned flags,
@@ -153,6 +157,7 @@ static H5FD_t *H5FD_stdio_open(const char *name, unsigned flags,
static herr_t H5FD_stdio_close(H5FD_t *lf);
static int H5FD_stdio_cmp(const H5FD_t *_f1, const H5FD_t *_f2);
static herr_t H5FD_stdio_query(const H5FD_t *_f1, unsigned long *flags);
+static haddr_t H5FD_stdio_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
static haddr_t H5FD_stdio_get_eoa(const H5FD_t *_file, H5FD_mem_t type);
static herr_t H5FD_stdio_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr);
static haddr_t H5FD_stdio_get_eof(const H5FD_t *_file);
@@ -181,7 +186,7 @@ static const H5FD_class_t H5FD_stdio_g = {
H5FD_stdio_close, /*close */
H5FD_stdio_cmp, /*cmp */
H5FD_stdio_query, /*query */
- NULL, /*alloc */
+ H5FD_stdio_alloc, /*alloc */
NULL, /*free */
H5FD_stdio_get_eoa, /*get_eoa */
H5FD_stdio_set_eoa, /*set_eoa */
@@ -372,10 +377,18 @@ H5FD_stdio_open( const char *name, unsigned flags, hid_t fapl_id,
file->op = H5FD_STDIO_OP_SEEK;
file->pos = HADDR_UNDEF;
file->write_access=write_access; /* Note the write_access for later */
- if(fseek(file->fp, (long)0, SEEK_END) < 0) {
+#ifdef H5_HAVE_FSEEKO
+ if(fseeko(file->fp, (off_t)0, SEEK_END) < 0) {
+#else
+ if(fseek(file->fp, (long)0L, SEEK_END) < 0) {
+#endif
file->op = H5FD_STDIO_OP_UNKNOWN;
} else {
+#ifdef H5_HAVE_FTELLO
+ off_t x = ftello (file->fp);
+#else
long x = ftell (file->fp);
+#endif
assert (x>=0);
file->eof = (haddr_t)x;
}
@@ -525,6 +538,61 @@ H5FD_stdio_query(const H5FD_t *_f, unsigned long *flags /* out */)
/*-------------------------------------------------------------------------
+ * Function: H5FD_stdio_alloc
+ *
+ * Purpose: Allocates file memory. If fseeko isn't available, makes
+ * sure the file size isn't bigger than 2GB because the
+ * parameter OFFSET of fseek is of the type LONG INT, limiting
+ * the file size to 2GB.
+ *
+ * Return: Success: Address of new memory
+ *
+ * Failure: HADDR_UNDEF
+ *
+ * Programmer: Raymond Lu
+ * 30 March 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static haddr_t
+H5FD_stdio_alloc(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxpl_id, hsize_t size)
+{
+ H5FD_stdio_t *file = (H5FD_stdio_t*)_file;
+ haddr_t addr;
+ static const char *func="H5FD_stdio_alloc"; /* Function Name for error reporting */
+ haddr_t ret_value; /* Return value */
+
+ /* Clear the error stack */
+ H5Eclear_stack(H5E_DEFAULT);
+
+ /* Compute the address for the block to allocate */
+ addr = file->eoa;
+
+ /* Check if we need to align this block */
+ if(size>=file->pub.threshold) {
+ /* Check for an already aligned block */
+ if(addr%file->pub.alignment!=0)
+ addr=((addr/file->pub.alignment)+1)*file->pub.alignment;
+ } /* end if */
+
+#ifndef H5_HAVE_FSEEKO
+ /* If fseeko isn't available, big files (>2GB) won't be supported. */
+ if(addr+size>BIG_FILE)
+ H5Epush_ret (func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "can't write file bigger than 2GB because fseek isn't available", -1)
+#endif
+
+ file->eoa = addr+size;
+
+ /* Set return value */
+ ret_value=addr;
+
+ return(ret_value);
+} /* H5FD_stdio_alloc() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5FD_stdio_get_eoa
*
* Purpose: Gets the end-of-address marker for the file. The EOA marker
@@ -727,7 +795,11 @@ H5FD_stdio_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, siz
*/
if (!(file->op == H5FD_STDIO_OP_READ || file->op==H5FD_STDIO_OP_SEEK) ||
file->pos != addr) {
+#ifdef H5_HAVE_FSEEKO
+ if (fseeko(file->fp, (off_t)addr, SEEK_SET) < 0) {
+#else
if (fseek(file->fp, (long)addr, SEEK_SET) < 0) {
+#endif
file->op = H5FD_STDIO_OP_UNKNOWN;
file->pos = HADDR_UNDEF;
H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "fseek failed", -1)
@@ -817,7 +889,11 @@ H5FD_stdio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr,
*/
if ((file->op != H5FD_STDIO_OP_WRITE && file->op != H5FD_STDIO_OP_SEEK) ||
file->pos != addr) {
+#ifdef H5_HAVE_FSEEKO
+ if (fseeko(file->fp, (off_t)addr, SEEK_SET) < 0) {
+#else
if (fseek(file->fp, (long)addr, SEEK_SET) < 0) {
+#endif
file->op = H5FD_STDIO_OP_UNKNOWN;
file->pos = HADDR_UNDEF;
H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "fseek failed", -1)