diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5F.c | 1 | ||||
-rw-r--r-- | src/H5FDwindows.c | 2037 |
2 files changed, 1020 insertions, 1018 deletions
@@ -3594,6 +3594,7 @@ H5Fget_info(hid_t obj_id, H5F_info_t *finfo) herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(H5Fget_info, FAIL) + H5TRACE2("e", "i*x", obj_id, finfo); /* Check args */ if(!finfo) diff --git a/src/H5FDwindows.c b/src/H5FDwindows.c index 9d2b3f9..08a8e69 100644 --- a/src/H5FDwindows.c +++ b/src/H5FDwindows.c @@ -1,1020 +1,1021 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Copyright by The HDF Group. *
- * Copyright by the Board of Trustees of the University of Illinois. *
- * All rights reserved. *
- * *
- * This file is part of HDF5. The full HDF5 copyright notice, including *
- * terms governing use, modification, and redistribution, is contained in *
- * the files COPYING and Copyright.html. COPYING can be found at the root *
- * of the source code distribution tree; Copyright.html can be found at the *
- * root level of an installed copy of the electronic HDF5 document set and *
- * is linked from the top-level documents page. It can also be found at *
- * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
- * access to either file, you may request a copy from help@hdfgroup.org. *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-/*
- * Programmer: Scott Wegner <swegner@hdfgroup.org>
- * Based on code by Robb Matzke
- * May 24, 2007
- *
- * Purpose: We would like to create a driver specifically for Windows
- * to utilize the Win32 API, and reduce the maintenence demands
- * for the other file drivers. Our other motivation is that
- * the Windows system calls of the existing sec2 driver differ
- * from those on other platforms, and are not 64-bit compatible.
- * From the start, this will have the structure very similar
- * to our sec2 driver, but make system calls more similar to
- * our stdio driver.
- */
-
-/* Interface initialization */
-#define H5_INTERFACE_INIT_FUNC H5FD_windows_init_interface
-
-
-#include "H5private.h" /* Generic Functions */
-#include "H5Eprivate.h" /* Error handling */
-#include "H5Fprivate.h" /* File access */
-#include "H5FDprivate.h" /* File drivers */
-#include "H5FDwindows.h" /* Windows file driver */
-#include "H5FLprivate.h" /* Free Lists */
-#include "H5Iprivate.h" /* IDs */
-#include "H5MMprivate.h" /* Memory management */
-#include "H5Pprivate.h" /* Property lists */
-
-#ifdef H5_HAVE_WINDOWS
-
-/* The driver identification number, initialized at runtime */
-static hid_t H5FD_WINDOWS_g = 0;
-
-/* File operations */
-#define OP_UNKNOWN 0
-#define OP_READ 1
-#define OP_WRITE 2
-
-/*
- * The description of a file belonging to this driver. The `eoa' and `eof'
- * determine the amount of hdf5 address space in use and the high-water mark
- * of the file (the current size of the underlying file). The `pos'
- * value is used to eliminate file position updates when they would be a
- * no-op. Unfortunately we've found systems that use separate file position
- * indicators for reading and writing so the lseek can only be eliminated if
- * the current operation is the same as the previous operation. When opening
- * a file the `eof' will be set to the current file size, `eoa' will be set
- * to zero, `pos' will be set to H5F_ADDR_UNDEF (as it is when an error
- * occurs), and `op' will be set to H5F_OP_UNKNOWN.
- */
-typedef struct H5FD_windows_t {
- H5FD_t pub; /*public stuff, must be first */
- /*
- * .NET doesn't support our 64-bit safe stdio functions,
- * so we will use io.h functions instead.
- */
-#ifndef WINDOWS_USE_STDIO
- int fd; /*the file descriptor */
-#else
- FILE *fp; /*the file handle */
-#endif /*MSC_VER */
- haddr_t eoa; /*end of allocated region */
- haddr_t eof; /*end of file; current file size*/
- haddr_t pos; /*current file I/O position */
- int op; /*last operation */
- unsigned write_access; /*flag to indicate the file was opened with write access */
- /*
- * On _WIN32 the low-order word of a unique identifier associated with the
- * file and the volume serial number uniquely identify a file. This number
- * may change when the system is restarted or when the
- * file is opened. After a process opens a file, the identifier is
- * constant until the file is closed. An application can use this
- * identifier and the volume serial number to determine whether two
- * handles refer to the same file.
- */
- DWORD fileindexlo;
- DWORD fileindexhi;
- DWORD volumeserialnumber;
-} H5FD_windows_t;
-
-
-/* These are used by the macros below */
-#define file_offset_t __int64
-#define fseek_offset_t __int64
-
-/*
- * These macros check for overflow of various quantities. These macros
- * assume that fseek_offset_t is signed and haddr_t and size_t are unsigned.
- *
- * ADDR_OVERFLOW: Checks whether a file address of type `haddr_t'
- * is too large to be represented by the second argument
- * of the file seek function.
- *
- * SIZE_OVERFLOW: Checks whether a buffer size of type `hsize_t' is too
- * large to be represented by the `size_t' type.
- *
- * REGION_OVERFLOW: Checks whether an address and size pair describe data
- * which can be addressed entirely by the second
- * argument of the file seek function.
- */
-#define MAXADDR (((haddr_t)1<<(8*sizeof(file_offset_t)-1))-1)
-#define ADDR_OVERFLOW(A) (HADDR_UNDEF==(A) || \
- ((A) & ~(haddr_t)MAXADDR))
-#define SIZE_OVERFLOW(Z) ((Z) & ~(hsize_t)MAXADDR)
-#define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \
- HADDR_UNDEF==(A)+(Z) || \
- (fseek_offset_t)((A)+(Z))<(fseek_offset_t)(A))
-
-/* Prototypes */
-static H5FD_t *H5FD_windows_open(const char *name, unsigned flags, hid_t fapl_id,
- haddr_t maxaddr);
-static herr_t H5FD_windows_close(H5FD_t *_file);
-static int H5FD_windows_cmp(const H5FD_t *_f1, const H5FD_t *_f2);
-static herr_t H5FD_windows_query(const H5FD_t *_f1, unsigned long *flags);
-static haddr_t H5FD_windows_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id,
- hsize_t size);
-static haddr_t H5FD_windows_get_eoa(const H5FD_t *_file, H5FD_mem_t type);
-static herr_t H5FD_windows_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr);
-static haddr_t H5FD_windows_get_eof(const H5FD_t *_file);
-static herr_t H5FD_windows_get_handle(H5FD_t *_file, hid_t fapl, void** file_handle);
-static herr_t H5FD_windows_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr,
- size_t size, void *buf);
-static herr_t H5FD_windows_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr,
- size_t size, const void *buf);
-static herr_t H5FD_windows_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing);
-
-static const H5FD_class_t H5FD_windows_g = {
- "windows", /*name */
- MAXADDR, /*maxaddr */
- H5F_CLOSE_WEAK, /* fc_degree */
- NULL, /*sb_size */
- NULL, /*sb_encode */
- NULL, /*sb_decode */
- 0, /*fapl_size */
- NULL, /*fapl_get */
- NULL, /*fapl_copy */
- NULL, /*fapl_free */
- 0, /*dxpl_size */
- NULL, /*dxpl_copy */
- NULL, /*dxpl_free */
- H5FD_windows_open, /*open */
- H5FD_windows_close, /*close */
- H5FD_windows_cmp, /*cmp */
- H5FD_windows_query, /*query */
- NULL, /*alloc */
- NULL, /*free */
- H5FD_windows_get_eoa, /*get_eoa */
- H5FD_windows_set_eoa, /*set_eoa */
- H5FD_windows_get_eof, /*get_eof */
- H5FD_windows_get_handle,/*get_handle */
- H5FD_windows_read, /*read */
- H5FD_windows_write, /*write */
- H5FD_windows_flush, /*flush */
- NULL, /*lock */
- NULL, /*unlock */
- H5FD_FLMAP_SINGLE /*fl_map */
-};
-
-/* Declare a free list to manage the H5FD_windows_t struct */
-H5FL_DEFINE_STATIC(H5FD_windows_t);
-
-/*--------------------------------------------------------------------------
-NAME
- H5FD_windows_init_interface -- Initialize interface-specific information
-USAGE
- herr_t H5FD_windows_init_interface()
-
-RETURNS
- Non-negative on success/Negative on failure
-DESCRIPTION
- Initializes any interface-specific data or routines. (Just calls
- H5FD_windows_init currently).
-
---------------------------------------------------------------------------*/
-static herr_t
-H5FD_windows_init_interface(void)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_windows_init_interface)
-
- FUNC_LEAVE_NOAPI(H5FD_windows_init())
-} /* H5FD_windows_init_interface() */
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_init
- *
- * Purpose: Initialize this driver by registering the driver with the
- * library.
- *
- * Return: Success: The driver ID for the windows driver.
- * Failure: Negative.
- *
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, May 24, 2007
- *
- *-------------------------------------------------------------------------
- */
-hid_t
-H5FD_windows_init(void)
-{
- hid_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_windows_init, FAIL)
-
- if(H5I_VFL != H5I_get_type(H5FD_WINDOWS_g))
- H5FD_WINDOWS_g = H5FD_register(&H5FD_windows_g, sizeof(H5FD_class_t));
-
- /* Set return value */
- ret_value = H5FD_WINDOWS_g;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_windows_init() */
-
-/*---------------------------------------------------------------------------
- * Function: H5FD_windows_term
- *
- * Purpose: Shut down the VFD
- *
- * Return: <none>
- *
- * Programmer: Scott Wegner
- * Based on code by Quincey Koziol
- * Thursday, May 24 2007
- *
- * Modification:
- *
- *---------------------------------------------------------------------------
- */
-void
-H5FD_windows_term(void)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_windows_term)
-
- /* Reset VFL ID */
- H5FD_WINDOWS_g=0;
-
- FUNC_LEAVE_NOAPI_VOID
-} /* end H5FD_windows_term() */
-
-/*-------------------------------------------------------------------------
- * Function: H5Pset_fapl_windows
- *
- * Purpose: Modify the file access property list to use the H5FD_WINDOWS
- * driver defined in this source file. There are no driver
- * specific properties.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Scott Wegner <swegner@hdfgroup.org> + * Based on code by Robb Matzke + * May 24, 2007 + * + * Purpose: We would like to create a driver specifically for Windows + * to utilize the Win32 API, and reduce the maintenence demands + * for the other file drivers. Our other motivation is that + * the Windows system calls of the existing sec2 driver differ + * from those on other platforms, and are not 64-bit compatible. + * From the start, this will have the structure very similar + * to our sec2 driver, but make system calls more similar to + * our stdio driver. + */ + +/* Interface initialization */ +#define H5_INTERFACE_INIT_FUNC H5FD_windows_init_interface + + +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fprivate.h" /* File access */ +#include "H5FDprivate.h" /* File drivers */ +#include "H5FDwindows.h" /* Windows file driver */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Pprivate.h" /* Property lists */ + +#ifdef H5_HAVE_WINDOWS + +/* The driver identification number, initialized at runtime */ +static hid_t H5FD_WINDOWS_g = 0; + +/* File operations */ +#define OP_UNKNOWN 0 +#define OP_READ 1 +#define OP_WRITE 2 + +/* + * The description of a file belonging to this driver. The `eoa' and `eof' + * determine the amount of hdf5 address space in use and the high-water mark + * of the file (the current size of the underlying file). The `pos' + * value is used to eliminate file position updates when they would be a + * no-op. Unfortunately we've found systems that use separate file position + * indicators for reading and writing so the lseek can only be eliminated if + * the current operation is the same as the previous operation. When opening + * a file the `eof' will be set to the current file size, `eoa' will be set + * to zero, `pos' will be set to H5F_ADDR_UNDEF (as it is when an error + * occurs), and `op' will be set to H5F_OP_UNKNOWN. + */ +typedef struct H5FD_windows_t { + H5FD_t pub; /*public stuff, must be first */ + /* + * .NET doesn't support our 64-bit safe stdio functions, + * so we will use io.h functions instead. + */ +#ifndef WINDOWS_USE_STDIO + int fd; /*the file descriptor */ +#else + FILE *fp; /*the file handle */ +#endif /*MSC_VER */ + haddr_t eoa; /*end of allocated region */ + haddr_t eof; /*end of file; current file size*/ + haddr_t pos; /*current file I/O position */ + int op; /*last operation */ + unsigned write_access; /*flag to indicate the file was opened with write access */ + /* + * On _WIN32 the low-order word of a unique identifier associated with the + * file and the volume serial number uniquely identify a file. This number + * may change when the system is restarted or when the + * file is opened. After a process opens a file, the identifier is + * constant until the file is closed. An application can use this + * identifier and the volume serial number to determine whether two + * handles refer to the same file. + */ + DWORD fileindexlo; + DWORD fileindexhi; + DWORD volumeserialnumber; +} H5FD_windows_t; + + +/* These are used by the macros below */ +#define file_offset_t __int64 +#define fseek_offset_t __int64 + +/* + * These macros check for overflow of various quantities. These macros + * assume that fseek_offset_t is signed and haddr_t and size_t are unsigned. + * + * ADDR_OVERFLOW: Checks whether a file address of type `haddr_t' + * is too large to be represented by the second argument + * of the file seek function. + * + * SIZE_OVERFLOW: Checks whether a buffer size of type `hsize_t' is too + * large to be represented by the `size_t' type. + * + * REGION_OVERFLOW: Checks whether an address and size pair describe data + * which can be addressed entirely by the second + * argument of the file seek function. + */ +#define MAXADDR (((haddr_t)1<<(8*sizeof(file_offset_t)-1))-1) +#define ADDR_OVERFLOW(A) (HADDR_UNDEF==(A) || \ + ((A) & ~(haddr_t)MAXADDR)) +#define SIZE_OVERFLOW(Z) ((Z) & ~(hsize_t)MAXADDR) +#define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \ + HADDR_UNDEF==(A)+(Z) || \ + (fseek_offset_t)((A)+(Z))<(fseek_offset_t)(A)) + +/* Prototypes */ +static H5FD_t *H5FD_windows_open(const char *name, unsigned flags, hid_t fapl_id, + haddr_t maxaddr); +static herr_t H5FD_windows_close(H5FD_t *_file); +static int H5FD_windows_cmp(const H5FD_t *_f1, const H5FD_t *_f2); +static herr_t H5FD_windows_query(const H5FD_t *_f1, unsigned long *flags); +static haddr_t H5FD_windows_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, + hsize_t size); +static haddr_t H5FD_windows_get_eoa(const H5FD_t *_file, H5FD_mem_t type); +static herr_t H5FD_windows_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr); +static haddr_t H5FD_windows_get_eof(const H5FD_t *_file); +static herr_t H5FD_windows_get_handle(H5FD_t *_file, hid_t fapl, void** file_handle); +static herr_t H5FD_windows_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, + size_t size, void *buf); +static herr_t H5FD_windows_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, + size_t size, const void *buf); +static herr_t H5FD_windows_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing); + +static const H5FD_class_t H5FD_windows_g = { + "windows", /*name */ + MAXADDR, /*maxaddr */ + H5F_CLOSE_WEAK, /* fc_degree */ + NULL, /*sb_size */ + NULL, /*sb_encode */ + NULL, /*sb_decode */ + 0, /*fapl_size */ + NULL, /*fapl_get */ + NULL, /*fapl_copy */ + NULL, /*fapl_free */ + 0, /*dxpl_size */ + NULL, /*dxpl_copy */ + NULL, /*dxpl_free */ + H5FD_windows_open, /*open */ + H5FD_windows_close, /*close */ + H5FD_windows_cmp, /*cmp */ + H5FD_windows_query, /*query */ + NULL, /*alloc */ + NULL, /*free */ + H5FD_windows_get_eoa, /*get_eoa */ + H5FD_windows_set_eoa, /*set_eoa */ + H5FD_windows_get_eof, /*get_eof */ + H5FD_windows_get_handle,/*get_handle */ + H5FD_windows_read, /*read */ + H5FD_windows_write, /*write */ + H5FD_windows_flush, /*flush */ + NULL, /*lock */ + NULL, /*unlock */ + H5FD_FLMAP_SINGLE /*fl_map */ +}; + +/* Declare a free list to manage the H5FD_windows_t struct */ +H5FL_DEFINE_STATIC(H5FD_windows_t); + +/*-------------------------------------------------------------------------- +NAME + H5FD_windows_init_interface -- Initialize interface-specific information +USAGE + herr_t H5FD_windows_init_interface() + +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. (Just calls + H5FD_windows_init currently). + +--------------------------------------------------------------------------*/ +static herr_t +H5FD_windows_init_interface(void) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_windows_init_interface) + + FUNC_LEAVE_NOAPI(H5FD_windows_init()) +} /* H5FD_windows_init_interface() */ + +/*------------------------------------------------------------------------- + * Function: H5FD_windows_init + * + * Purpose: Initialize this driver by registering the driver with the + * library. + * + * Return: Success: The driver ID for the windows driver. + * Failure: Negative. + * + * Programmer: Scott Wegner + * Based on code by Robb Matzke + * Thursday, May 24, 2007 + * + *------------------------------------------------------------------------- + */ +hid_t +H5FD_windows_init(void) +{ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5FD_windows_init, FAIL) + + if(H5I_VFL != H5I_get_type(H5FD_WINDOWS_g)) + H5FD_WINDOWS_g = H5FD_register(&H5FD_windows_g, sizeof(H5FD_class_t)); + + /* Set return value */ + ret_value = H5FD_WINDOWS_g; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD_windows_init() */ + +/*--------------------------------------------------------------------------- + * Function: H5FD_windows_term + * + * Purpose: Shut down the VFD + * + * Return: <none> + * + * Programmer: Scott Wegner + * Based on code by Quincey Koziol + * Thursday, May 24 2007 + * + * Modification: + * + *--------------------------------------------------------------------------- + */ +void +H5FD_windows_term(void) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_windows_term) + + /* Reset VFL ID */ + H5FD_WINDOWS_g=0; + + FUNC_LEAVE_NOAPI_VOID +} /* end H5FD_windows_term() */ + +/*------------------------------------------------------------------------- + * Function: H5Pset_fapl_windows + * + * Purpose: Modify the file access property list to use the H5FD_WINDOWS + * driver defined in this source file. There are no driver + * specific properties. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Scott Wegner + * Based on code by Robb Matzke + * Thursday, May 24 2007 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ herr_t H5Pset_fapl_windows(hid_t fapl_id) -{
- H5P_genplist_t *plist; /* Property list pointer */
- herr_t ret_value;
-
- FUNC_ENTER_API(H5Pset_fapl_windows, FAIL)
- H5TRACE1("e", "i", fapl_id);
-
- if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
-
- ret_value= H5P_set_driver(plist, H5FD_WINDOWS, NULL);
-
-done:
- FUNC_LEAVE_API(ret_value)
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_open
- *
- * Purpose: Create and/or opens a Windows file as an HDF5 file.
- *
- * Return: Success: A pointer to a new file data structure. The
- * public fields will be initialized by the
- * caller, which is always H5FD_open().
- *
- * Failure: NULL
- *
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-/* ARGSUSED */
-static H5FD_t *
-H5FD_windows_open(const char *name, unsigned flags, hid_t UNUSED fapl_id,
- haddr_t maxaddr)
-{
- int fd = -1;
- FILE *f = NULL;
- H5FD_windows_t *file = NULL;
- HANDLE filehandle;
- struct _BY_HANDLE_FILE_INFORMATION fileinfo;
- H5FD_t *ret_value;
- struct _stati64 sb;
-#ifndef WINDOWS_USE_STDIO
- int o_flags;
-#else
- unsigned write_access = 0;
-#endif /* WINDOWS_USE_STDIO */
-
- FUNC_ENTER_NOAPI(H5FD_windows_open, NULL)
-
- /* Sanity check on file offsets */
- assert(sizeof(file_offset_t)>=sizeof(size_t));
-
- /* Check arguments */
- if (!name || !*name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name")
- if (0==maxaddr || HADDR_UNDEF==maxaddr)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr")
- if (ADDR_OVERFLOW(maxaddr))
- HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr")
-
-#ifndef WINDOWS_USE_STDIO
- /* Build the open flags */
- o_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY;
- if (H5F_ACC_TRUNC & flags) o_flags |= O_TRUNC;
- if (H5F_ACC_CREAT & flags) o_flags |= O_CREAT;
- if (H5F_ACC_EXCL & flags) o_flags |= O_EXCL;
- /* Windows needs O_BINARY to correctly handle eol characters */
- o_flags |= O_BINARY;
-
- /* Open the file */
- if ((fd=_open(name, o_flags, 0666))<0)
- HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file")
- if (_fstati64(fd, &sb) == -1)
- HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file")
-
-#else /* WINDOWS_USE_STDIO */
- /* Translate our flags into a mode, and open the file */
- if (_access_s(name, F_OK)) {
- if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_RDWR)) {
- f = fopen(name, "wb+");
- write_access=1; /* Note the write access */
- }
- else
- HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file doesn't exist and CREAT wasn't specified")
- } else if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_EXCL)) {
- HSYS_GOTO_ERROR(H5E_FILE, H5E_FILEEXISTS, NULL, "file exists but CREAT and EXCL were specified")
- } else if (flags & H5F_ACC_RDWR) {
- if (flags & H5F_ACC_TRUNC)
- f = fopen(name, "wb+");
- else
- f = fopen(name, "rb+");
- write_access=1; /* Note the write access */
- } else
- f = fopen(name, "rb");
-
- if (!f)
- HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "fsopen failed")
-
- if (_stati64(name, &sb) == -1)
- HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to stat file")
-#endif /* WINDOWS_USE_STDIO */
-
- /* Create the new file struct */
- if (NULL==(file=H5FL_CALLOC(H5FD_windows_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct")
-
- H5_ASSIGN_OVERFLOW(file->eof,sb.st_size,h5_stat_size_t,haddr_t);
- file->pos = HADDR_UNDEF;
- file->op = OP_UNKNOWN;
-
-#ifndef WINDOWS_USE_STDIO
- file->fd = fd;
-#else
- file->fp = f;
- if((fd = _fileno(f)) == -1)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get file descriptor for file")
- file->write_access=write_access; /* Note the write_access for later */
-#endif /* WINDOWS_USE_STDIO */
-
- if( (filehandle = (HANDLE)_get_osfhandle(fd)) == INVALID_HANDLE_VALUE)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get file handle for file")
- if(!GetFileInformationByHandle(filehandle, &fileinfo))
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get file information")
- file->fileindexhi = fileinfo.nFileIndexHigh;
- file->fileindexlo = fileinfo.nFileIndexLow;
- file->volumeserialnumber = fileinfo.dwVolumeSerialNumber;
-
- /* Set return value */
- ret_value=(H5FD_t*)file;
-
-done:
- if(ret_value==NULL) {
-#ifndef WINDOWS_USE_STDIO
- if(fd>=0)
- _close(fd);
-#else
- if(f)
- fclose(file->fp);
-#endif /* WINDOWS_USE_STDIO */
- } /* end if */
-
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_close
- *
- * Purpose: Closes a Windows file.
- *
- * Return: Success: 0
- *
- * Failure: -1, file not closed.
- *
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5FD_windows_close(H5FD_t *_file)
-{
- H5FD_windows_t *file = (H5FD_windows_t*)_file;
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_windows_close, FAIL)
-
-#ifndef WINDOWS_USE_STDIO
- if (_close(file->fd)<0)
-#else
- if (fclose(file->fp)<0)
-#endif /* WINDOWS_USE_STDIO */
- HSYS_GOTO_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close file")
-
- H5FL_FREE(H5FD_windows_t,file);
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_cmp
- *
- * Purpose: Compares two files belonging to this driver using an
- * arbitrary (but consistent) ordering.
- *
- * Return: Success: A value like strcmp()
- *
- * Failure: never fails (arguments were checked by the
- * caller).
- *
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static int
-H5FD_windows_cmp(const H5FD_t *_f1, const H5FD_t *_f2)
-{
- const H5FD_windows_t *f1 = (const H5FD_windows_t*)_f1;
- const H5FD_windows_t *f2 = (const H5FD_windows_t*)_f2;
- int ret_value=0;
-
- FUNC_ENTER_NOAPI(H5FD_windows_cmp, H5FD_VFD_DEFAULT)
-
- if (f1->volumeserialnumber < f2->volumeserialnumber) HGOTO_DONE(-1)
- if (f1->volumeserialnumber > f2->volumeserialnumber) HGOTO_DONE(1)
-
- if (f1->fileindexhi < f2->fileindexhi) HGOTO_DONE(-1)
- if (f1->fileindexhi > f2->fileindexhi) HGOTO_DONE(1)
-
- if (f1->fileindexlo < f2->fileindexlo) HGOTO_DONE(-1)
- if (f1->fileindexlo > f2->fileindexlo) HGOTO_DONE(1)
-
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_query
- *
- * Purpose: Set the flags that this VFL driver is capable of supporting.
- * (listed in H5FDpublic.h)
- *
- * Return: Success: non-negative
- *
- * Failure: negative
- *
- * Programmer: Scott Wegner
- Based on code by Quincey Koziol
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-/* ARGSUSED */
-static herr_t
-H5FD_windows_query(const H5FD_t UNUSED * _f, unsigned long *flags /* out */)
-{
- herr_t ret_value=SUCCEED;
-
- FUNC_ENTER_NOAPI(H5FD_windows_query, FAIL)
-
- /* Set the VFL feature flags that this driver supports */
- if(flags) {
- *flags = 0;
- *flags|=H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */
- *flags|=H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */
- *flags|=H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
- *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
- }
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_get_eoa
- *
- * Purpose: Gets the end-of-address marker for the file. The EOA marker
- * is the first address past the last byte allocated in the
- * format address space.
- *
- * Return: Success: The end-of-address marker.
- *
- * Failure: HADDR_UNDEF
- *
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static haddr_t
-H5FD_windows_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type)
-{
- const H5FD_windows_t *file = (const H5FD_windows_t*)_file;
- haddr_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_windows_get_eoa, HADDR_UNDEF)
-
- /* Set return value */
- ret_value=file->eoa;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_set_eoa
- *
- * Purpose: Set the end-of-address marker for the file. This function is
- * called shortly after an existing HDF5 file is opened in order
- * to tell the driver where the end of the HDF5 data is located.
- *
- * Return: Success: 0
- *
- * Failure: -1
- *
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, July 29, 1999
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5FD_windows_set_eoa(H5FD_t *_file, H5FD_mem_t UNUSED type, haddr_t addr)
-{
- H5FD_windows_t *file = (H5FD_windows_t*)_file;
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_windows_set_eoa, FAIL)
-
- file->eoa = addr;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_get_eof
- *
- * Purpose: Returns the end-of-file marker, which is the greater of
- * either the Windows end-of-file or the HDF5 end-of-address
- * markers.
- *
- * Return: Success: End of file address, the first address past
- * the end of the "file", either the Unix file
- * or the HDF5 file.
- *
- * Failure: HADDR_UNDEF
- *
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static haddr_t
-H5FD_windows_get_eof(const H5FD_t *_file)
-{
- const H5FD_windows_t *file = (const H5FD_windows_t*)_file;
- haddr_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_windows_get_eof, HADDR_UNDEF)
-
- /* Set return value */
- ret_value=MAX(file->eof, file->eoa);
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_get_handle
- *
- * Purpose: Returns the file handle of windows file driver.
- *
- * Returns: Non-negative if succeed or negative if fails.
- *
- * Programmer: Scott Wegner
- Based on code by Raymond Lu
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-/* ARGSUSED */
-static herr_t
-H5FD_windows_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void** file_handle)
-{
- H5FD_windows_t *file = (H5FD_windows_t *)_file;
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI(H5FD_windows_get_handle, FAIL)
-
- if(!file_handle)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file handle not valid")
-#ifndef WINDOWS_USE_STDIO
- *file_handle = &(file->fd);
-#else
- *file_handle = &(file->fp);
-#endif /* WINDOWS_USE_STDIO */
- if(*file_handle==NULL)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "get handle failed")
-
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_alloc
- *
- * Purpose: Allocates file memory.
- *
- * Return: Success: Address of new memory
- *
- * Failure: HADDR_UNDEF
- *
- * Programmer: Scott Wegner
- Based on code by Raymond Lu
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static haddr_t
-H5FD_windows_alloc(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, hsize_t size)
-{
- H5FD_windows_t *file = (H5FD_windows_t*)_file;
- haddr_t addr;
- haddr_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_windows_alloc, HADDR_UNDEF)
-
- /* 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;
- }
-
-
- file->eoa = addr + size;
-
- /* Set return value */
- ret_value = addr;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_read
- *
- * Purpose: Reads SIZE bytes of data from FILE beginning at address ADDR
- * into buffer BUF according to data transfer properties in
- * DXPL_ID.
- *
- * Return: Success: Zero. Result is stored in caller-supplied
- * buffer BUF.
- *
- * Failure: -1, Contents of buffer BUF are undefined.
- *
- * Programmer: Scott Wegner
- Based on code by Robb Matzke
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-/* ARGSUSED */
-static herr_t
-H5FD_windows_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr,
- size_t size, void *buf/*out*/)
-{
- H5FD_windows_t *file = (H5FD_windows_t*)_file;
- int nbytes;
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_windows_read, FAIL)
-
- assert(file && file->pub.cls);
- assert(buf);
-
- /* Check for overflow conditions */
- if (HADDR_UNDEF==addr)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined")
- if (REGION_OVERFLOW(addr, size))
- HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
- if (addr+size>file->eoa)
- HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
-
- /* Seek to the correct location */
- if ((addr!=file->pos || OP_READ!=file->op))
-#ifndef WINDOWS_USE_STDIO
- if (_lseeki64(file->fd, addr, SEEK_SET) == -1) {
-#else
- if (_fseeki64(file->fp, addr, SEEK_SET) == -1) {
-#endif /* WINDOWS_USE_STDIO */
- file->op = OP_UNKNOWN;
- file->pos = HADDR_UNDEF;
- HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
- }
-
- /*
- * Read data, being careful of interrupted system calls, partial results,
- * and the end of the file.
- */
- while (size>0) {
-#ifndef WINDOWS_USE_STDIO
- do {
- nbytes = _read(file->fd, buf, (unsigned)(size <= WINDOWS_MAX_BUF ? size: WINDOWS_MAX_BUF));
- } while (-1==nbytes && EINTR==errno);
- if (-1==nbytes) /* error */
- HSYS_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed")
- if (0==nbytes) {
- /* end of file but not end of format address space */
- HDmemset(buf, 0, size);
- break;
- }
-#else
- do {
- nbytes = fread(buf,(size_t)1,(size <= WINDOWS_MAX_BUF ? size: WINDOWS_MAX_BUF),file->fp);
- } while (!nbytes && EINTR==errno);
- if(!nbytes) {
- if (ferror(file->fp)) /* error */
- HSYS_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed")
- if (feof(file->fp)) {
- /* end of file but not end of format address space */
- HDmemset(buf, 0, size);
- break;
- }
- }
-#endif /* WINDOWS_USE_STDIO */
- assert(nbytes>=0);
- assert((size_t)nbytes<=size);
- H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t);
- size -= (size_t)nbytes;
- H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t);
- addr += (haddr_t)nbytes;
- buf = (char*)buf + nbytes;
- }
-
- /* Update current position */
- file->pos = addr;
- file->op = OP_READ;
-
-done:
- if(ret_value<0) {
- /* Reset last file I/O information */
- file->pos = HADDR_UNDEF;
- file->op = OP_UNKNOWN;
- } /* end if */
-
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_write
- *
- * Purpose: Writes SIZE bytes of data to FILE beginning at address ADDR
- * from buffer BUF according to data transfer properties in
- * DXPL_ID.
- *
- * Return: Success: Zero
- *
- * Failure: -1
- *
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-/* ARGSUSED */
-static herr_t
-H5FD_windows_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr,
- size_t size, const void *buf)
-{
- H5FD_windows_t *file = (H5FD_windows_t*)_file;
- ssize_t nbytes;
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_windows_write, FAIL)
-
- assert(file && file->pub.cls);
- assert(buf);
-
- /* Check for overflow conditions */
- if (HADDR_UNDEF==addr)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined")
- if (REGION_OVERFLOW(addr, size))
- HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
- if (addr+size>file->eoa)
- HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
-
- /* Seek to the correct location */
- if ((addr!=file->pos || OP_WRITE!=file->op))
- {
-#ifndef WINDOWS_USE_STDIO
- if (_lseeki64(file->fd, addr, SEEK_SET) == -1) {
-#else
- if (_fseeki64(file->fp, addr, SEEK_SET) == -1) {
-#endif /* WINDOWS_USE_STDIO */
- file->op = OP_UNKNOWN;
- file->pos = HADDR_UNDEF;
- HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
- }
- }
-
- /*
- * Write the data, being careful of interrupted system calls and partial
- * results
- */
- while (size>0) {
- do {
-#ifndef WINDOWS_USE_STDIO
- nbytes = _write(file->fd, buf, (unsigned)(size <= WINDOWS_MAX_BUF ? size: WINDOWS_MAX_BUF));
- } while (-1==nbytes && EINTR==errno);
- if (-1==nbytes) /* error */
-#else
-
-
- /* Write 1GB or less at a time */
- nbytes = fwrite(buf, 1, (size <= WINDOWS_MAX_BUF ? size: WINDOWS_MAX_BUF),file->fp);
- } while (!nbytes && EINTR==errno);
- if (!nbytes) /* error */
-#endif /* WINDOWS_USE_STDIO */
- HSYS_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed")
- assert(nbytes>0);
- assert((size_t)nbytes<=size);
- H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t);
- size -= (size_t)nbytes;
- H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t);
- addr += (haddr_t)nbytes;
- buf = (const char*)buf + nbytes;
- }
-
- /* Update current position and eof */
- file->pos = addr;
- file->op = OP_WRITE;
- if (file->pos>file->eof)
- file->eof = file->pos;
-
-done:
- if(ret_value<0) {
- /* Reset last file I/O information */
- file->pos = HADDR_UNDEF;
- file->op = OP_UNKNOWN;
- } /* end if */
-
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_flush
- *
- * Purpose: Makes sure that the true file size is the same (or larger)
- * than the end-of-address.
- *
- * Return: Success: Non-negative
- *
- * Failure: Negative
- *
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-/* ARGSUSED */
-static herr_t
-H5FD_windows_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned closing)
-{
- H5FD_windows_t *file = (H5FD_windows_t*)_file;
- herr_t ret_value=SUCCEED; /* Return value */
-#ifndef WINDOWS_USE_STDIO
- LARGE_INTEGER li;
- HANDLE filehandle;
-#else
- int fd;
-#endif /* WINDOWS_USE_STDIO */
-
- FUNC_ENTER_NOAPI(H5FD_windows_flush, FAIL)
-
- assert(file);
-
- if (file->eoa != file->eof) {
-#ifndef WINDOWS_USE_STDIO
-
- /* Extend the file to make sure it's large enough */
- if( (filehandle = (HANDLE)_get_osfhandle(file->fd)) == INVALID_HANDLE_VALUE)
- HGOTO_ERROR(H5E_FILE, H5E_FILEOPEN, FAIL, "unable to get file handle for file")
-
- li.QuadPart = (__int64)file->eoa;
- (void)SetFilePointer((HANDLE)filehandle,li.LowPart,&li.HighPart,FILE_BEGIN);
- if(SetEndOfFile(filehandle) == 0)
- HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
-
-#else /* WINDOWS_USE_STDIO */
- /* Only try to flush if we have write access */
- if(!file->write_access)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot flush without write access")
-
- if((fd = _fileno(file->fp)) == -1)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to get file descriptor for file")
- if(_chsize_s(fd, file->eoa))
- HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
-
- /* Flush */
- if(!closing)
- if (fflush(file->fp) == EOF)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "fflush failed")
-#endif /* WINDOWS_USE_STDIO */
-
- /* Update the eof value */
- file->eof = file->eoa;
-
- /* Reset last file I/O information */
- file->pos = HADDR_UNDEF;
- file->op = OP_UNKNOWN;
-
- }
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-#endif /* H5_HAVE_WINDOWS */
\ No newline at end of file +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value; + + FUNC_ENTER_API(H5Pset_fapl_windows, FAIL) + H5TRACE1("e", "i", fapl_id); + + if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") + + ret_value= H5P_set_driver(plist, H5FD_WINDOWS, NULL); + +done: + FUNC_LEAVE_API(ret_value) +} + +/*------------------------------------------------------------------------- + * Function: H5FD_windows_open + * + * Purpose: Create and/or opens a Windows file as an HDF5 file. + * + * Return: Success: A pointer to a new file data structure. The + * public fields will be initialized by the + * caller, which is always H5FD_open(). + * + * Failure: NULL + * + * Programmer: Scott Wegner + * Based on code by Robb Matzke + * Thursday, May 24 2007 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +static H5FD_t * +H5FD_windows_open(const char *name, unsigned flags, hid_t UNUSED fapl_id, + haddr_t maxaddr) +{ + int fd = -1; + FILE *f = NULL; + H5FD_windows_t *file = NULL; + HANDLE filehandle; + struct _BY_HANDLE_FILE_INFORMATION fileinfo; + H5FD_t *ret_value; + struct _stati64 sb; +#ifndef WINDOWS_USE_STDIO + int o_flags; +#else + unsigned write_access = 0; +#endif /* WINDOWS_USE_STDIO */ + + FUNC_ENTER_NOAPI(H5FD_windows_open, NULL) + + /* Sanity check on file offsets */ + assert(sizeof(file_offset_t)>=sizeof(size_t)); + + /* Check arguments */ + if (!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name") + if (0==maxaddr || HADDR_UNDEF==maxaddr) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr") + if (ADDR_OVERFLOW(maxaddr)) + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr") + +#ifndef WINDOWS_USE_STDIO + /* Build the open flags */ + o_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY; + if (H5F_ACC_TRUNC & flags) o_flags |= O_TRUNC; + if (H5F_ACC_CREAT & flags) o_flags |= O_CREAT; + if (H5F_ACC_EXCL & flags) o_flags |= O_EXCL; + /* Windows needs O_BINARY to correctly handle eol characters */ + o_flags |= O_BINARY; + + /* Open the file */ + if ((fd=_open(name, o_flags, 0666))<0) + HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file") + if (_fstati64(fd, &sb) == -1) + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file") + +#else /* WINDOWS_USE_STDIO */ + /* Translate our flags into a mode, and open the file */ + if (_access_s(name, F_OK)) { + if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_RDWR)) { + f = fopen(name, "wb+"); + write_access=1; /* Note the write access */ + } + else + HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file doesn't exist and CREAT wasn't specified") + } else if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_EXCL)) { + HSYS_GOTO_ERROR(H5E_FILE, H5E_FILEEXISTS, NULL, "file exists but CREAT and EXCL were specified") + } else if (flags & H5F_ACC_RDWR) { + if (flags & H5F_ACC_TRUNC) + f = fopen(name, "wb+"); + else + f = fopen(name, "rb+"); + write_access=1; /* Note the write access */ + } else + f = fopen(name, "rb"); + + if (!f) + HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "fsopen failed") + + if (_stati64(name, &sb) == -1) + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to stat file") +#endif /* WINDOWS_USE_STDIO */ + + /* Create the new file struct */ + if (NULL==(file=H5FL_CALLOC(H5FD_windows_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct") + + H5_ASSIGN_OVERFLOW(file->eof,sb.st_size,h5_stat_size_t,haddr_t); + file->pos = HADDR_UNDEF; + file->op = OP_UNKNOWN; + +#ifndef WINDOWS_USE_STDIO + file->fd = fd; +#else + file->fp = f; + if((fd = _fileno(f)) == -1) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get file descriptor for file") + file->write_access=write_access; /* Note the write_access for later */ +#endif /* WINDOWS_USE_STDIO */ + + if( (filehandle = (HANDLE)_get_osfhandle(fd)) == INVALID_HANDLE_VALUE) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get file handle for file") + if(!GetFileInformationByHandle(filehandle, &fileinfo)) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get file information") + file->fileindexhi = fileinfo.nFileIndexHigh; + file->fileindexlo = fileinfo.nFileIndexLow; + file->volumeserialnumber = fileinfo.dwVolumeSerialNumber; + + /* Set return value */ + ret_value=(H5FD_t*)file; + +done: + if(ret_value==NULL) { +#ifndef WINDOWS_USE_STDIO + if(fd>=0) + _close(fd); +#else + if(f) + fclose(file->fp); +#endif /* WINDOWS_USE_STDIO */ + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} + +/*------------------------------------------------------------------------- + * Function: H5FD_windows_close + * + * Purpose: Closes a Windows file. + * + * Return: Success: 0 + * + * Failure: -1, file not closed. + * + * Programmer: Scott Wegner + * Based on code by Robb Matzke + * Thursday, May 24 2007 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_windows_close(H5FD_t *_file) +{ + H5FD_windows_t *file = (H5FD_windows_t*)_file; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5FD_windows_close, FAIL) + +#ifndef WINDOWS_USE_STDIO + if (_close(file->fd)<0) +#else + if (fclose(file->fp)<0) +#endif /* WINDOWS_USE_STDIO */ + HSYS_GOTO_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close file") + + H5FL_FREE(H5FD_windows_t,file); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} + +/*------------------------------------------------------------------------- + * Function: H5FD_windows_cmp + * + * Purpose: Compares two files belonging to this driver using an + * arbitrary (but consistent) ordering. + * + * Return: Success: A value like strcmp() + * + * Failure: never fails (arguments were checked by the + * caller). + * + * Programmer: Scott Wegner + * Based on code by Robb Matzke + * Thursday, May 24 2007 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +H5FD_windows_cmp(const H5FD_t *_f1, const H5FD_t *_f2) +{ + const H5FD_windows_t *f1 = (const H5FD_windows_t*)_f1; + const H5FD_windows_t *f2 = (const H5FD_windows_t*)_f2; + int ret_value=0; + + FUNC_ENTER_NOAPI(H5FD_windows_cmp, H5FD_VFD_DEFAULT) + + if (f1->volumeserialnumber < f2->volumeserialnumber) HGOTO_DONE(-1) + if (f1->volumeserialnumber > f2->volumeserialnumber) HGOTO_DONE(1) + + if (f1->fileindexhi < f2->fileindexhi) HGOTO_DONE(-1) + if (f1->fileindexhi > f2->fileindexhi) HGOTO_DONE(1) + + if (f1->fileindexlo < f2->fileindexlo) HGOTO_DONE(-1) + if (f1->fileindexlo > f2->fileindexlo) HGOTO_DONE(1) + + +done: + FUNC_LEAVE_NOAPI(ret_value) +} + +/*------------------------------------------------------------------------- + * Function: H5FD_windows_query + * + * Purpose: Set the flags that this VFL driver is capable of supporting. + * (listed in H5FDpublic.h) + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Scott Wegner + Based on code by Quincey Koziol + * Thursday, May 24 2007 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +static herr_t +H5FD_windows_query(const H5FD_t UNUSED * _f, unsigned long *flags /* out */) +{ + herr_t ret_value=SUCCEED; + + FUNC_ENTER_NOAPI(H5FD_windows_query, FAIL) + + /* Set the VFL feature flags that this driver supports */ + if(flags) { + *flags = 0; + *flags|=H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */ + *flags|=H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */ + *flags|=H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */ + *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */ + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} + +/*------------------------------------------------------------------------- + * Function: H5FD_windows_get_eoa + * + * Purpose: Gets the end-of-address marker for the file. The EOA marker + * is the first address past the last byte allocated in the + * format address space. + * + * Return: Success: The end-of-address marker. + * + * Failure: HADDR_UNDEF + * + * Programmer: Scott Wegner + * Based on code by Robb Matzke + * Thursday, May 24 2007 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static haddr_t +H5FD_windows_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type) +{ + const H5FD_windows_t *file = (const H5FD_windows_t*)_file; + haddr_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5FD_windows_get_eoa, HADDR_UNDEF) + + /* Set return value */ + ret_value=file->eoa; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_windows_set_eoa + * + * Purpose: Set the end-of-address marker for the file. This function is + * called shortly after an existing HDF5 file is opened in order + * to tell the driver where the end of the HDF5 data is located. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Scott Wegner + * Based on code by Robb Matzke + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_windows_set_eoa(H5FD_t *_file, H5FD_mem_t UNUSED type, haddr_t addr) +{ + H5FD_windows_t *file = (H5FD_windows_t*)_file; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5FD_windows_set_eoa, FAIL) + + file->eoa = addr; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} + +/*------------------------------------------------------------------------- + * Function: H5FD_windows_get_eof + * + * Purpose: Returns the end-of-file marker, which is the greater of + * either the Windows end-of-file or the HDF5 end-of-address + * markers. + * + * Return: Success: End of file address, the first address past + * the end of the "file", either the Unix file + * or the HDF5 file. + * + * Failure: HADDR_UNDEF + * + * Programmer: Scott Wegner + * Based on code by Robb Matzke + * Thursday, May 24 2007 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static haddr_t +H5FD_windows_get_eof(const H5FD_t *_file) +{ + const H5FD_windows_t *file = (const H5FD_windows_t*)_file; + haddr_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5FD_windows_get_eof, HADDR_UNDEF) + + /* Set return value */ + ret_value=MAX(file->eof, file->eoa); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_windows_get_handle + * + * Purpose: Returns the file handle of windows file driver. + * + * Returns: Non-negative if succeed or negative if fails. + * + * Programmer: Scott Wegner + Based on code by Raymond Lu + * Thursday, May 24 2007 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +static herr_t +H5FD_windows_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void** file_handle) +{ + H5FD_windows_t *file = (H5FD_windows_t *)_file; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(H5FD_windows_get_handle, FAIL) + + if(!file_handle) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file handle not valid") +#ifndef WINDOWS_USE_STDIO + *file_handle = &(file->fd); +#else + *file_handle = &(file->fp); +#endif /* WINDOWS_USE_STDIO */ + if(*file_handle==NULL) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "get handle failed") + + +done: + FUNC_LEAVE_NOAPI(ret_value) +} + +/*------------------------------------------------------------------------- + * Function: H5FD_windows_alloc + * + * Purpose: Allocates file memory. + * + * Return: Success: Address of new memory + * + * Failure: HADDR_UNDEF + * + * Programmer: Scott Wegner + Based on code by Raymond Lu + * Thursday, May 24 2007 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static haddr_t +H5FD_windows_alloc(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, hsize_t size) +{ + H5FD_windows_t *file = (H5FD_windows_t*)_file; + haddr_t addr; + haddr_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5FD_windows_alloc, HADDR_UNDEF) + + /* 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; + } + + + file->eoa = addr + size; + + /* Set return value */ + ret_value = addr; + +done: + FUNC_LEAVE_NOAPI(ret_value) + +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_windows_read + * + * Purpose: Reads SIZE bytes of data from FILE beginning at address ADDR + * into buffer BUF according to data transfer properties in + * DXPL_ID. + * + * Return: Success: Zero. Result is stored in caller-supplied + * buffer BUF. + * + * Failure: -1, Contents of buffer BUF are undefined. + * + * Programmer: Scott Wegner + Based on code by Robb Matzke + * Thursday, May 24 2007 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +static herr_t +H5FD_windows_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, + size_t size, void *buf/*out*/) +{ + H5FD_windows_t *file = (H5FD_windows_t*)_file; + int nbytes; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5FD_windows_read, FAIL) + + assert(file && file->pub.cls); + assert(buf); + + /* Check for overflow conditions */ + if (HADDR_UNDEF==addr) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined") + if (REGION_OVERFLOW(addr, size)) + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow") + if (addr+size>file->eoa) + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow") + + /* Seek to the correct location */ + if ((addr!=file->pos || OP_READ!=file->op)) +#ifndef WINDOWS_USE_STDIO + if (_lseeki64(file->fd, addr, SEEK_SET) == -1) { +#else + if (_fseeki64(file->fp, addr, SEEK_SET) == -1) { +#endif /* WINDOWS_USE_STDIO */ + file->op = OP_UNKNOWN; + file->pos = HADDR_UNDEF; + HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") + } + + /* + * Read data, being careful of interrupted system calls, partial results, + * and the end of the file. + */ + while (size>0) { +#ifndef WINDOWS_USE_STDIO + do { + nbytes = _read(file->fd, buf, (unsigned)(size <= WINDOWS_MAX_BUF ? size: WINDOWS_MAX_BUF)); + } while (-1==nbytes && EINTR==errno); + if (-1==nbytes) /* error */ + HSYS_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed") + if (0==nbytes) { + /* end of file but not end of format address space */ + HDmemset(buf, 0, size); + break; + } +#else + do { + nbytes = fread(buf,(size_t)1,(size <= WINDOWS_MAX_BUF ? size: WINDOWS_MAX_BUF),file->fp); + } while (!nbytes && EINTR==errno); + if(!nbytes) { + if (ferror(file->fp)) /* error */ + HSYS_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed") + if (feof(file->fp)) { + /* end of file but not end of format address space */ + HDmemset(buf, 0, size); + break; + } + } +#endif /* WINDOWS_USE_STDIO */ + assert(nbytes>=0); + assert((size_t)nbytes<=size); + H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t); + size -= (size_t)nbytes; + H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t); + addr += (haddr_t)nbytes; + buf = (char*)buf + nbytes; + } + + /* Update current position */ + file->pos = addr; + file->op = OP_READ; + +done: + if(ret_value<0) { + /* Reset last file I/O information */ + file->pos = HADDR_UNDEF; + file->op = OP_UNKNOWN; + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_windows_write + * + * Purpose: Writes SIZE bytes of data to FILE beginning at address ADDR + * from buffer BUF according to data transfer properties in + * DXPL_ID. + * + * Return: Success: Zero + * + * Failure: -1 + * + * Programmer: Scott Wegner + * Based on code by Robb Matzke + * Thursday, May 24 2007 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +static herr_t +H5FD_windows_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, + size_t size, const void *buf) +{ + H5FD_windows_t *file = (H5FD_windows_t*)_file; + ssize_t nbytes; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5FD_windows_write, FAIL) + + assert(file && file->pub.cls); + assert(buf); + + /* Check for overflow conditions */ + if (HADDR_UNDEF==addr) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined") + if (REGION_OVERFLOW(addr, size)) + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow") + if (addr+size>file->eoa) + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow") + + /* Seek to the correct location */ + if ((addr!=file->pos || OP_WRITE!=file->op)) + { +#ifndef WINDOWS_USE_STDIO + if (_lseeki64(file->fd, addr, SEEK_SET) == -1) { +#else + if (_fseeki64(file->fp, addr, SEEK_SET) == -1) { +#endif /* WINDOWS_USE_STDIO */ + file->op = OP_UNKNOWN; + file->pos = HADDR_UNDEF; + HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") + } + } + + /* + * Write the data, being careful of interrupted system calls and partial + * results + */ + while (size>0) { + do { +#ifndef WINDOWS_USE_STDIO + nbytes = _write(file->fd, buf, (unsigned)(size <= WINDOWS_MAX_BUF ? size: WINDOWS_MAX_BUF)); + } while (-1==nbytes && EINTR==errno); + if (-1==nbytes) /* error */ +#else + + + /* Write 1GB or less at a time */ + nbytes = fwrite(buf, 1, (size <= WINDOWS_MAX_BUF ? size: WINDOWS_MAX_BUF),file->fp); + } while (!nbytes && EINTR==errno); + if (!nbytes) /* error */ +#endif /* WINDOWS_USE_STDIO */ + HSYS_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") + assert(nbytes>0); + assert((size_t)nbytes<=size); + H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t); + size -= (size_t)nbytes; + H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t); + addr += (haddr_t)nbytes; + buf = (const char*)buf + nbytes; + } + + /* Update current position and eof */ + file->pos = addr; + file->op = OP_WRITE; + if (file->pos>file->eof) + file->eof = file->pos; + +done: + if(ret_value<0) { + /* Reset last file I/O information */ + file->pos = HADDR_UNDEF; + file->op = OP_UNKNOWN; + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} + +/*------------------------------------------------------------------------- + * Function: H5FD_windows_flush + * + * Purpose: Makes sure that the true file size is the same (or larger) + * than the end-of-address. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Scott Wegner + * Based on code by Robb Matzke + * Thursday, May 24 2007 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +static herr_t +H5FD_windows_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned closing) +{ + H5FD_windows_t *file = (H5FD_windows_t*)_file; + herr_t ret_value=SUCCEED; /* Return value */ +#ifndef WINDOWS_USE_STDIO + LARGE_INTEGER li; + HANDLE filehandle; +#else + int fd; +#endif /* WINDOWS_USE_STDIO */ + + FUNC_ENTER_NOAPI(H5FD_windows_flush, FAIL) + + assert(file); + + if (file->eoa != file->eof) { +#ifndef WINDOWS_USE_STDIO + + /* Extend the file to make sure it's large enough */ + if( (filehandle = (HANDLE)_get_osfhandle(file->fd)) == INVALID_HANDLE_VALUE) + HGOTO_ERROR(H5E_FILE, H5E_FILEOPEN, FAIL, "unable to get file handle for file") + + li.QuadPart = (__int64)file->eoa; + (void)SetFilePointer((HANDLE)filehandle,li.LowPart,&li.HighPart,FILE_BEGIN); + if(SetEndOfFile(filehandle) == 0) + HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly") + +#else /* WINDOWS_USE_STDIO */ + /* Only try to flush if we have write access */ + if(!file->write_access) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot flush without write access") + + if((fd = _fileno(file->fp)) == -1) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to get file descriptor for file") + if(_chsize_s(fd, file->eoa)) + HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly") + + /* Flush */ + if(!closing) + if (fflush(file->fp) == EOF) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "fflush failed") +#endif /* WINDOWS_USE_STDIO */ + + /* Update the eof value */ + file->eof = file->eoa; + + /* Reset last file I/O information */ + file->pos = HADDR_UNDEF; + file->op = OP_UNKNOWN; + + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} + +#endif /* H5_HAVE_WINDOWS */ + |