mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-27 07:30:33 +08:00
Merge remote-tracking branch 'Unidata/master'
This commit is contained in:
commit
dc6e2ef447
@ -197,4 +197,23 @@ extern int NC4_isnetcdf4(struct NC_FILE_INFO*); /*libsrc4/nc4hdf.c*/
|
||||
|
||||
extern int nc4_find_default_chunksizes2(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* Maxinum length of a typical path in UTF-8.
|
||||
* When converting from ANSI to UTF-8, the length will be up to 3 times,
|
||||
* so round up 260*3 to 1024. (260=MAX_PATH) */
|
||||
#define MAX_PATHBUF_SIZE 1024
|
||||
|
||||
/* Struct for converting ANSI to UTF-8. */
|
||||
typedef struct pathbuf
|
||||
{
|
||||
void *ptr;
|
||||
char buffer[MAX_PATHBUF_SIZE];
|
||||
} pathbuf_t;
|
||||
|
||||
const char *nc4_ndf5_ansi_to_utf8(pathbuf_t *pb, const char *path);
|
||||
void nc4_hdf5_free_pathbuf(pathbuf_t *pb);
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#endif /* _HDF5INTERNAL_ */
|
||||
|
@ -114,6 +114,7 @@ qualifyprojectionnames(DCEprojection* proj)
|
||||
NCerror ncstat = NC_NOERR;
|
||||
NClist* fullpath = nclistnew();
|
||||
|
||||
if (proj->discrim == CES_VAR) {
|
||||
ASSERT((proj->discrim == CES_VAR
|
||||
&& proj->var->annotation != NULL
|
||||
&& ((CDFnode*)proj->var->annotation)->ocnode != NULL));
|
||||
@ -129,6 +130,7 @@ fprintf(stderr,"qualify: %s -> ",
|
||||
fprintf(stderr,"%s\n",
|
||||
dumpprojection(proj));
|
||||
#endif
|
||||
}
|
||||
nclistfree(fullpath);
|
||||
return ncstat;
|
||||
}
|
||||
@ -138,6 +140,7 @@ static NCerror
|
||||
qualifyprojectionsizes(DCEprojection* proj)
|
||||
{
|
||||
size_t i,j;
|
||||
if (proj->discrim == CES_VAR) {
|
||||
ASSERT(proj->discrim == CES_VAR);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,"qualifyprojectionsizes.before: %s\n",
|
||||
@ -168,6 +171,7 @@ fprintf(stderr,"qualifyprojectionsizes.before: %s\n",
|
||||
fprintf(stderr,"qualifyprojectionsizes.after: %s\n",
|
||||
dumpprojection(proj));
|
||||
#endif
|
||||
}
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ projection:
|
||||
segmentlist
|
||||
{$$=projection(parsestate,$1);}
|
||||
| function
|
||||
{$$=$1;}
|
||||
{$$=projection(parsestate,$1);}
|
||||
;
|
||||
|
||||
function:
|
||||
|
@ -1305,7 +1305,7 @@ yyreduce:
|
||||
|
||||
case 13:
|
||||
#line 61 "dce.y" /* yacc.c:1646 */
|
||||
{(yyval)=(yyvsp[0]);}
|
||||
{(yyval)=projection(parsestate,(yyvsp[0]));}
|
||||
#line 1310 "dcetab.c" /* yacc.c:1646 */
|
||||
break;
|
||||
|
||||
|
@ -22,6 +22,12 @@ static const int ILLEGAL_CREATE_FLAGS = (NC_NOWRITE|NC_MMAP|NC_64BIT_OFFSET|NC_C
|
||||
/* From nc4mem.c */
|
||||
extern int NC4_create_image_file(NC_FILE_INFO_T* h5, size_t);
|
||||
|
||||
#ifdef _WIN32
|
||||
static hid_t nc4_H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id);
|
||||
#else
|
||||
#define nc4_H5Fcreate H5Fcreate
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @internal Create a netCDF-4/HDF5 file.
|
||||
*
|
||||
@ -217,13 +223,13 @@ nc4_create_file(const char *path, int cmode, size_t initialsz,
|
||||
/* Configure FAPL to use the core file driver */
|
||||
if (H5Pset_fapl_core(fapl_id, alloc_incr, (nc4_info->mem.persist?1:0)) < 0)
|
||||
BAIL(NC_EHDFERR);
|
||||
if ((hdf5_info->hdfid = H5Fcreate(path, flags, fcpl_id, fapl_id)) < 0)
|
||||
if ((hdf5_info->hdfid = nc4_H5Fcreate(path, flags, fcpl_id, fapl_id)) < 0)
|
||||
BAIL(EACCES);
|
||||
}
|
||||
else /* Normal file */
|
||||
{
|
||||
/* Create the HDF5 file. */
|
||||
if ((hdf5_info->hdfid = H5Fcreate(path, flags, fcpl_id, fapl_id)) < 0)
|
||||
if ((hdf5_info->hdfid = nc4_H5Fcreate(path, flags, fcpl_id, fapl_id)) < 0)
|
||||
BAIL(EACCES);
|
||||
}
|
||||
|
||||
@ -306,3 +312,31 @@ NC4_create(const char* path, int cmode, size_t initialsz, int basepe,
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/**
|
||||
* Wrapper function for H5Fcreate.
|
||||
* Converts the filename from ANSI to UTF-8 as needed before calling H5Fcreate.
|
||||
*
|
||||
* @param filename The filename encoded ANSI to access.
|
||||
* @param flags File access flags.
|
||||
* @param fcpl_id File creation property list identifier.
|
||||
* @param fapl_id File access property list identifier.
|
||||
* @return A file identifier if succeeded. A negative value if failed.
|
||||
*/
|
||||
static hid_t
|
||||
nc4_H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
|
||||
{
|
||||
pathbuf_t pb;
|
||||
hid_t hid;
|
||||
|
||||
filename = nc4_ndf5_ansi_to_utf8(&pb, filename);
|
||||
if (!filename)
|
||||
return H5I_INVALID_HID;
|
||||
hid = H5Fcreate(filename, flags, fcpl_id, fapl_id);
|
||||
nc4_hdf5_free_pathbuf(&pb);
|
||||
return hid;
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
@ -17,6 +17,9 @@
|
||||
#include "config.h"
|
||||
#include "hdf5internal.h"
|
||||
#include "ncfilter.h"
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#undef DEBUGH5
|
||||
|
||||
@ -1027,3 +1030,91 @@ hdf5_set_log_level()
|
||||
return NC_NOERR;
|
||||
}
|
||||
#endif /* LOGGING */
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/**
|
||||
* Converts the filename from ANSI to UTF-8 if HDF5 >= 1.10.6.
|
||||
* nc4_hdf5_free_pathbuf must be called to free pb.
|
||||
*
|
||||
* @param pb Pointer that conversion information is stored.
|
||||
* @param path The filename to be converted.
|
||||
*
|
||||
* @return The converted filename if succeeded. NULL if failed.
|
||||
*/
|
||||
const char *
|
||||
nc4_ndf5_ansi_to_utf8(pathbuf_t *pb, const char *path)
|
||||
{
|
||||
const uint UTF8_MAJNUM = 1;
|
||||
const uint UTF8_MINNUM = 10;
|
||||
const uint UTF8_RELNUM = 6;
|
||||
static enum {UNDEF, ANSI, UTF8} hdf5_encoding = UNDEF;
|
||||
wchar_t wbuf[MAX_PATH];
|
||||
wchar_t *ws = NULL;
|
||||
char *ns = NULL;
|
||||
int n;
|
||||
|
||||
if (hdf5_encoding == UNDEF) {
|
||||
uint majnum, minnum, relnum;
|
||||
H5get_libversion(&majnum, &minnum, &relnum);
|
||||
hdf5_encoding = (((majnum == UTF8_MAJNUM && minnum == UTF8_MINNUM && relnum >= UTF8_RELNUM)
|
||||
|| (majnum == UTF8_MAJNUM && minnum > UTF8_MINNUM)
|
||||
|| majnum > UTF8_MAJNUM)
|
||||
? UTF8 : ANSI);
|
||||
}
|
||||
if (hdf5_encoding == ANSI) {
|
||||
pb->ptr = NULL;
|
||||
return path;
|
||||
}
|
||||
|
||||
n = MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0);
|
||||
if (!n) {
|
||||
errno = EILSEQ;
|
||||
goto done;
|
||||
}
|
||||
ws = n <= _countof(wbuf) ? wbuf : malloc(sizeof *ws * n);
|
||||
if (!ws)
|
||||
goto done;
|
||||
if (!MultiByteToWideChar(CP_ACP, 0, path, -1, ws, n)) {
|
||||
errno = EILSEQ;
|
||||
goto done;
|
||||
}
|
||||
|
||||
n = WideCharToMultiByte(CP_UTF8, 0, ws, -1, NULL, 0, NULL, NULL);
|
||||
if (!n) {
|
||||
errno = EILSEQ;
|
||||
goto done;
|
||||
}
|
||||
ns = n <= sizeof pb->buffer ? pb->buffer : malloc(n);
|
||||
if (!ns)
|
||||
goto done;
|
||||
if (!WideCharToMultiByte(CP_UTF8, 0, ws, -1, ns, n, NULL, NULL)) {
|
||||
if (ns != pb->buffer)
|
||||
free(ns);
|
||||
ns = NULL;
|
||||
errno = EILSEQ;
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
if (ws != wbuf)
|
||||
free (ws);
|
||||
|
||||
pb->ptr = ns;
|
||||
return ns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the conversion information used by nc4_ndf5_ansi_to_utf8.
|
||||
*
|
||||
* @param pb Pointer that hold conversion information to be freed.
|
||||
*/
|
||||
void
|
||||
nc4_hdf5_free_pathbuf(pathbuf_t *pb)
|
||||
{
|
||||
if (pb->ptr && pb->ptr != pb->buffer)
|
||||
free(pb->ptr);
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
@ -62,6 +62,12 @@ extern int NC4_open_image_file(NC_FILE_INFO_T* h5);
|
||||
/* Defined later in this file. */
|
||||
static int rec_read_metadata(NC_GRP_INFO_T *grp);
|
||||
|
||||
#ifdef _WIN32
|
||||
static hid_t nc4_H5Fopen(const char *filename, unsigned flags, hid_t fapl_id);
|
||||
#else
|
||||
#define nc4_H5Fopen H5Fopen
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @internal Struct to track HDF5 object info, for
|
||||
* rec_read_metadata(). We get this info for every object in the
|
||||
@ -833,7 +839,7 @@ nc4_open_file(const char *path, int mode, void* parameters, int ncid)
|
||||
if (H5Pset_fapl_core(fapl_id, min_incr, (nc4_info->mem.persist?1:0)) < 0)
|
||||
BAIL(NC_EHDFERR);
|
||||
/* Open the HDF5 file. */
|
||||
if ((h5->hdfid = H5Fopen(path, flags, fapl_id)) < 0)
|
||||
if ((h5->hdfid = nc4_H5Fopen(path, flags, fapl_id)) < 0)
|
||||
BAIL(NC_EHDFERR);
|
||||
}
|
||||
#ifdef ENABLE_BYTERANGE
|
||||
@ -843,14 +849,14 @@ nc4_open_file(const char *path, int mode, void* parameters, int ncid)
|
||||
if (H5Pset_fapl_http(fapl_id) < 0)
|
||||
BAIL(NC_EHDFERR);
|
||||
/* Open the HDF5 file. */
|
||||
if ((h5->hdfid = H5Fopen(path, flags, fapl_id)) < 0)
|
||||
if ((h5->hdfid = nc4_H5Fopen(path, flags, fapl_id)) < 0)
|
||||
BAIL(NC_EHDFERR);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
/* Open the HDF5 file. */
|
||||
if ((h5->hdfid = H5Fopen(path, flags, fapl_id)) < 0)
|
||||
if ((h5->hdfid = nc4_H5Fopen(path, flags, fapl_id)) < 0)
|
||||
BAIL(NC_EHDFERR);
|
||||
}
|
||||
|
||||
@ -2707,3 +2713,30 @@ exit:
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/**
|
||||
* Wrapper function for H5Fopen.
|
||||
* Converts the filename from ANSI to UTF-8 as needed before calling H5Fopen.
|
||||
*
|
||||
* @param filename The filename encoded ANSI to access.
|
||||
* @param flags File access flags.
|
||||
* @param fapl_id File access property list identifier.
|
||||
* @return A file identifier if succeeded. A negative value if failed.
|
||||
*/
|
||||
static hid_t
|
||||
nc4_H5Fopen(const char *filename, unsigned flags, hid_t fapl_id)
|
||||
{
|
||||
pathbuf_t pb;
|
||||
hid_t hid;
|
||||
|
||||
filename = nc4_ndf5_ansi_to_utf8(&pb, filename);
|
||||
if (!filename)
|
||||
return H5I_INVALID_HID;
|
||||
hid = H5Fopen(filename, flags, fapl_id);
|
||||
nc4_hdf5_free_pathbuf(&pb);
|
||||
return hid;
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
Loading…
Reference in New Issue
Block a user