Merge remote-tracking branch 'Unidata/master'

This commit is contained in:
Dennis Heimbigner 2020-07-15 10:36:38 -06:00
commit dc6e2ef447
7 changed files with 188 additions and 7 deletions

View File

@ -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_ */

View File

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

View File

@ -58,7 +58,7 @@ projection:
segmentlist
{$$=projection(parsestate,$1);}
| function
{$$=$1;}
{$$=projection(parsestate,$1);}
;
function:

View File

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

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */