From 96154d9303460d9ec006e3b0b588f361d302707a Mon Sep 17 00:00:00 2001 From: Ed Hartnett Date: Wed, 4 Apr 2018 14:11:44 -0600 Subject: [PATCH] added merged HDF4 changes --- hdf4_test/CMakeLists.txt | 1 + hdf4_test/Makefile.am | 4 +- hdf4_test/tst_chunk_hdf4.c | 2 +- hdf4_test/tst_hdf4_extra.c | 179 +++++++ include/hdf4dispatch.h | 286 ++--------- include/nc4internal.h | 22 +- include/ncdispatch.h | 61 +++ libdispatch/CMakeLists.txt | 2 +- libdispatch/Makefile.am | 7 +- libdispatch/dnotnc3.c | 41 ++ libdispatch/dnotnc4.c | 432 +++++++++++++++++ libdispatch/dreadonly.c | 261 +++++++++++ libhdf4/hdf4dispatch.c | 96 ++-- libhdf4/hdf4file.c | 939 +++++++++++++++++++------------------ libhdf4/hdf4func.c | 69 +-- libhdf4/hdf4var.c | 410 +++------------- liblib/nc_initialize.c | 10 +- libsrcp/ncpdispatch.c | 172 +------ 18 files changed, 1674 insertions(+), 1320 deletions(-) create mode 100644 hdf4_test/tst_hdf4_extra.c create mode 100644 libdispatch/dnotnc3.c create mode 100644 libdispatch/dnotnc4.c create mode 100644 libdispatch/dreadonly.c diff --git a/hdf4_test/CMakeLists.txt b/hdf4_test/CMakeLists.txt index 1d95d9b12..0b42eb25f 100644 --- a/hdf4_test/CMakeLists.txt +++ b/hdf4_test/CMakeLists.txt @@ -10,6 +10,7 @@ IF(USE_HDF4_FILE_TESTS AND NOT MSVC) build_bin_test_no_prefix(tst_interops3) add_bin_test(hdf4_test tst_chunk_hdf4) add_bin_test(hdf4_test tst_h4_lendian) + add_bin_test(hdf4_test tst_hdf4_extra) add_sh_test(hdf4_test run_get_hdf4_files) add_sh_test(hdf4_test run_formatx_hdf4) ENDIF() diff --git a/hdf4_test/Makefile.am b/hdf4_test/Makefile.am index ef0685e3b..b0295db59 100644 --- a/hdf4_test/Makefile.am +++ b/hdf4_test/Makefile.am @@ -14,8 +14,8 @@ include $(top_srcdir)/lib_flags.am AM_LDFLAGS += ${top_builddir}/liblib/libnetcdf.la # These are the C tests for HDF4. -check_PROGRAMS = tst_chunk_hdf4 tst_h4_lendian -TESTS = tst_chunk_hdf4 tst_h4_lendian +check_PROGRAMS = tst_chunk_hdf4 tst_h4_lendian tst_hdf4_extra +TESTS = tst_chunk_hdf4 tst_h4_lendian tst_hdf4_extra # This test script depends on ncdump and tst_interops2.c. if BUILD_UTILITIES diff --git a/hdf4_test/tst_chunk_hdf4.c b/hdf4_test/tst_chunk_hdf4.c index f9edb221d..1c4592e41 100644 --- a/hdf4_test/tst_chunk_hdf4.c +++ b/hdf4_test/tst_chunk_hdf4.c @@ -95,7 +95,7 @@ main(int argc, char **argv) if (nc_open(CONTIGFILE, 0, &ncid)) ERR; if (nc_inq_varid(ncid, CONTIGVAR, &varid)) ERR; - if (nc_def_var_deflate(ncid, varid, 0, 1, 4) != NC_EPERM) ERR; + if (nc_def_var_deflate(ncid, varid, 0, 1, 4) != NC_ENOTNC4) ERR; if (nc_close(ncid)) ERR; } diff --git a/hdf4_test/tst_hdf4_extra.c b/hdf4_test/tst_hdf4_extra.c new file mode 100644 index 000000000..5d055db87 --- /dev/null +++ b/hdf4_test/tst_hdf4_extra.c @@ -0,0 +1,179 @@ +/* This is part of the netCDF package. Copyright 2005-2011, + University Corporation for Atmospheric Research/Unidata. See + COPYRIGHT file for conditions of use. + + Test that NetCDF-4 can read HDF4 files. + Ed Hartnett +*/ +#include +#include +#include "err_macros.h" +#include +#include + +#define FILE_NAME "tst_hdf4_extra.h4" + +#define PRES_NAME "pres" +#define LAT_LEN 3 +#define LON_LEN 2 +#define NDIMS2 2 +#define ATT_NAME "Caesar" +#define NAME_DUMB "Bozo" + +int +create_hdf4_file() +{ + int32 sd_id, sds_id; + int32 dim_size[NDIMS2] = {LAT_LEN, LON_LEN}; + int32 start[NDIMS2] = {0, 0}, edge[NDIMS2] = {LAT_LEN, LON_LEN}; + int data_out[LAT_LEN][LON_LEN]; + int test_val = 42; + int i, j; + int count = 0; + + /* Create some data. */ + for (i = 0; i < LAT_LEN; i++) + for (j = 0; j < LON_LEN; j++) + data_out[i][j] = count++; + + /* Create a file with one SDS, containing our phony data. */ + sd_id = SDstart(FILE_NAME, DFACC_CREATE); + sds_id = SDcreate(sd_id, PRES_NAME, DFNT_INT32, NDIMS2, dim_size); + if (SDwritedata(sds_id, start, NULL, edge, (void *)data_out)) ERR; + + /* Add a global attribute. */ + if (SDsetattr(sd_id, ATT_NAME, DFNT_INT32, 1, &test_val)) ERR; + + /* Shut down. */ + if (SDendaccess(sds_id)) ERR; + if (SDend(sd_id)) ERR; + + return 0; +} + +int +main(int argc, char **argv) +{ + printf("\n*** Testing HDF4/NetCDF-4 interoperability extra stuff...\n"); + + /* Create our test file. */ + if (create_hdf4_file()) ERR; + + printf("*** testing data conversion..."); + { + int ncid; + size_t start[NDIMS2] = {0, 0}, count[NDIMS2] = {LAT_LEN, LON_LEN}; + int data_int[LAT_LEN * LON_LEN]; + short data_short[LAT_LEN * LON_LEN]; + int data_int2[LAT_LEN * LON_LEN]; + float data_float[LAT_LEN * LON_LEN]; + double data_double[LAT_LEN * LON_LEN]; + + /* Open HDF4 file with netCDF. */ + if (nc_open(FILE_NAME, 0, &ncid)) ERR; + + /* These won't work. */ + if (nc_get_vara_int(ncid, 0, NULL, count, data_int) != NC_EINVAL) ERR; + if (nc_get_vara_int(ncid, 0, start, count, NULL) != NC_EINVAL) ERR; + if (nc_get_vara_int(ncid + TEST_VAL_42, 0, start, count, data_int) != NC_EBADID) ERR; + + /* Read data as short. */ + if (nc_get_vara_short(ncid, 0, start, count, data_short)) ERR; + for (int i = 0; i < LAT_LEN * LON_LEN; i++) + if (data_short[i] != (short)i) ERR; + + /* Read data as int. */ + if (nc_get_vara_int(ncid, 0, start, count, data_int)) ERR; + for (int i = 0; i < LAT_LEN * LON_LEN; i++) + if (data_int[i] != i) ERR; + + /* NULL count is treated as meaing entire variable. */ + if (nc_get_vara_int(ncid, 0, start, NULL, data_int2)) ERR; + for (int i = 0; i < LAT_LEN * LON_LEN; i++) + if (data_int2[i] != i) ERR; + + /* Read data as float. */ + if (nc_get_vara_float(ncid, 0, start, count, data_float)) ERR; + for (int i = 0; i < LAT_LEN * LON_LEN; i++) + if (data_float[i] != (float)i) ERR; + + /* Read data as double. */ + if (nc_get_vara_double(ncid, 0, start, count, data_double)) ERR; + for (int i = 0; i < LAT_LEN * LON_LEN; i++) + if (data_double[i] != (double)i) ERR; + + /* Close the file. */ + if (nc_close(ncid)) ERR; + } + SUMMARIZE_ERR; + printf("*** testing bad parameters, read-only writes, and abort..."); + { + int ncid; + int ndims, nvars, ngatts, unlimdimid; + size_t start[NDIMS2] = {0, 0}, count[NDIMS2] = {1, 1}; + int test_val; + + /* These will not work. */ + if (nc_open(FILE_NAME, NC_MMAP, &ncid) != NC_EINVAL) ERR; + if (nc_open(FILE_NAME, NC_64BIT_OFFSET, &ncid) != NC_EINVAL) ERR; + if (nc_open(FILE_NAME, NC_MPIIO, &ncid) != NC_EINVAL) ERR; + if (nc_open(FILE_NAME, NC_MPIPOSIX, &ncid) != NC_EINVAL) ERR; + if (nc_open(FILE_NAME, NC_DISKLESS, &ncid) != NC_EINVAL) ERR; + + /* Now open with netCDF. */ + if (nc_open(FILE_NAME, 0, &ncid)) ERR; + + /* Check it out. */ + if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR; + if (ndims != 2 || nvars != 1 || ngatts != 1 || unlimdimid != -1) ERR; + if (nc_inq(ncid, NULL, NULL, NULL, NULL)) ERR; + if (nc_inq(ncid + TEST_VAL_42, NULL, NULL, NULL, NULL) != NC_EBADID) ERR; + + /* These only work for netCDF-3 files. */ + if (nc_set_base_pe(ncid, 0) != NC_ENOTNC3) ERR; + if (nc_inq_base_pe(ncid, NULL) != NC_ENOTNC3) ERR; + + /* Attempt to write. */ + if (nc_rename_att(ncid, NC_GLOBAL, ATT_NAME, NAME_DUMB) != NC_EPERM) ERR; + if (nc_del_att(ncid, NC_GLOBAL, ATT_NAME) != NC_EPERM) ERR; + if (nc_put_att_int(ncid, NC_GLOBAL, NAME_DUMB, NC_INT, 0, NULL) != NC_EPERM) ERR; + if (nc_def_dim(ncid, NAME_DUMB, 1, NULL) != NC_EPERM) ERR; + if (nc_def_var(ncid, "hh", NC_INT, 0, NULL, NULL) != NC_EPERM) ERR; + if (nc_def_var_fill(ncid, 0, 0, &test_val) != NC_EPERM) ERR; + if (nc_rename_var(ncid, 0, NAME_DUMB) != NC_EPERM) ERR; + if (nc_put_vara_int(ncid, 0, start, count, &test_val) != NC_EPERM) ERR; + if (nc_set_fill(ncid, 0, NULL) != NC_EPERM) ERR; + if (nc_rename_dim(ncid, 0, NULL) != NC_EPERM) ERR; + + /* These succeed but do nothing. */ + if (nc_enddef(ncid)) ERR; + if (nc_sync(ncid)) ERR; + + /* These netcdf-4 operations are not supported. */ + if (nc_def_var_filter(ncid, 0, 0, 0, NULL) != NC_ENOTNC4) ERR; + if (nc_def_var_fletcher32(ncid, 0, 0) != NC_ENOTNC4) ERR; + if (nc_def_var_endian(ncid, 0, 0) != NC_ENOTNC4) ERR; + if (nc_def_grp(ncid, NAME_DUMB, NULL) != NC_ENOTNC4) ERR; + if (nc_rename_grp(ncid, NAME_DUMB) != NC_ENOTNC4) ERR; + if (nc_def_compound(ncid, 1, NAME_DUMB, NULL) != NC_ENOTNC4) ERR; + if (nc_insert_compound(ncid, 1, NAME_DUMB, 1, 1) != NC_ENOTNC4) ERR; + if (nc_insert_array_compound(ncid, 1, NAME_DUMB, 1, 1, 1, NULL) != NC_ENOTNC4) ERR; + if (nc_inq_compound_field(ncid, 1, 1, NULL, NULL, NULL, NULL, NULL) != NC_ENOTNC4) ERR; + if (nc_inq_compound_fieldindex(ncid, 1, NULL, NULL) != NC_ENOTNC4) ERR; + if (nc_def_opaque(ncid, 1, NULL, NULL) != NC_ENOTNC4) ERR; + if (nc_def_vlen(ncid, NULL, 1, NULL) != NC_ENOTNC4) ERR; + if (nc_def_enum(ncid, 1, NULL, NULL) != NC_ENOTNC4) ERR; + if (nc_inq_enum_ident(ncid, 1, 1, NULL) != NC_ENOTNC4) ERR; + if (nc_inq_enum_member(ncid, 1, 1, NULL, NULL) != NC_ENOTNC4) ERR; + if (nc_insert_enum(ncid, 1, NULL, NULL) != NC_ENOTNC4) ERR; + if (nc_put_vlen_element(ncid, 1, NULL, 1, NULL) != NC_ENOTNC4) ERR; + if (nc_get_vlen_element(ncid, 1, NULL, NULL, NULL) != NC_ENOTNC4) ERR; + if (nc_set_var_chunk_cache(ncid, 1, 1, 1, 1.0) != NC_ENOTNC4) ERR; + if (nc_get_var_chunk_cache(ncid, 1, NULL, NULL, NULL) != NC_ENOTNC4) ERR; + + /* Abort is the same as nc_close, since HDF4 is read-only.) */ + if (nc_abort(ncid)) ERR; + } + SUMMARIZE_ERR; + FINAL_RESULTS; +} diff --git a/include/hdf4dispatch.h b/include/hdf4dispatch.h index f1cfaef7b..a0ddb5bda 100644 --- a/include/hdf4dispatch.h +++ b/include/hdf4dispatch.h @@ -1,9 +1,10 @@ /* Copyright 2018, UCAR/Unidata. See netcdf/COPYRIGHT file for copying * and redistribution conditions. */ /** - * @file - * This header file contains the prototypes for the HDF4 versions - * of the netCDF functions. + * @file @internal This header file contains the prototypes for the + * HDF4 versions of the netCDF functions. This is part of the HDF4 + * dispatch layer and this header should not be included by any file + * outside the libhdf4 directory. * * Ed Hartnett */ @@ -11,263 +12,48 @@ #define _HDF4DISPATCH_H #include "config.h" -#include /* size_t, ptrdiff_t */ -#include /* netcdf functions sometimes return system errors */ #include "ncdispatch.h" +/** This is the max size of an SD dataset name in HDF4 (from HDF4 + * documentation).*/ +#define NC_MAX_HDF4_NAME 64 + +/** This is the max number of dimensions for a HDF4 SD dataset (from + * HDF4 documentation). */ +#define NC_MAX_HDF4_DIMS 32 + +/* Stuff below is for hdf4 files. */ +typedef struct NC_VAR_HDF4_INFO +{ + int sdsid; + int hdf4_data_type; +} NC_VAR_HDF4_INFO_T; + +typedef struct NC_HDF4_FILE_INFO +{ + int sdid; +} NC_HDF4_FILE_INFO_T; + #if defined(__cplusplus) extern "C" { #endif -extern int -HDF4_create(const char *path, int cmode, - size_t initialsz, int basepe, size_t *chunksizehintp, - int useparallel, void* parameters, - NC_Dispatch*, NC*); + extern int + NC_HDF4_open(const char *path, int mode, int basepe, size_t *chunksizehintp, + int use_parallel, void* parameters, NC_Dispatch*, NC*); -extern int -HDF4_open(const char *path, int mode, - int basepe, size_t *chunksizehintp, - int use_parallel, void* parameters, - NC_Dispatch*, NC*); + extern int + NC_HDF4_close(int ncid); -extern int -HDF4_redef(int ncid); + extern int + NC_HDF4_inq_format(int ncid, int *formatp); -extern int -HDF4__enddef(int ncid, size_t h_minfree, size_t v_align, - size_t v_minfree, size_t r_align); + extern int + NC_HDF4_inq_format_extended(int ncid, int *formatp, int *modep); -extern int -HDF4_sync(int ncid); - -extern int -HDF4_abort(int ncid); - -extern int -HDF4_close(int ncid); - -extern int -HDF4_set_fill(int ncid, int fillmode, int *old_modep); - -extern int -HDF4_set_base_pe(int ncid, int pe); - -extern int -HDF4_inq_base_pe(int ncid, int *pe); - -extern int -HDF4_inq_format(int ncid, int *formatp); - -extern int -HDF4_inq_format_extended(int ncid, int *formatp, int *modep); - -extern int -HDF4_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp); - -extern int -HDF4_inq_type(int, nc_type, char *, size_t *); - -/* Begin _dim */ - -extern int -HDF4_def_dim(int ncid, const char *name, size_t len, int *idp); - -extern int -HDF4_inq_dimid(int ncid, const char *name, int *idp); - -extern int -HDF4_inq_dim(int ncid, int dimid, char *name, size_t *lenp); - -extern int -HDF4_inq_unlimdim(int ncid, int *unlimdimidp); - -extern int -HDF4_rename_dim(int ncid, int dimid, const char *name); - -/* End _dim */ -/* Begin _att */ - -extern int -HDF4_inq_att(int ncid, int varid, const char *name, - nc_type *xtypep, size_t *lenp); - -extern int -HDF4_inq_attid(int ncid, int varid, const char *name, int *idp); - -extern int -HDF4_inq_attname(int ncid, int varid, int attnum, char *name); - -extern int -HDF4_rename_att(int ncid, int varid, const char *name, const char *newname); - -extern int -HDF4_del_att(int ncid, int varid, const char*); - -/* End _att */ -/* Begin {put,get}_att */ - -extern int -HDF4_get_att(int ncid, int varid, const char *name, void *value, nc_type); - -extern int -HDF4_put_att(int ncid, int varid, const char *name, nc_type datatype, - size_t len, const void *value, nc_type); - -/* End {put,get}_att */ -/* Begin _var */ - -extern int -HDF4_def_var(int ncid, const char *name, - nc_type xtype, int ndims, const int *dimidsp, int *varidp); - -extern int -HDF4_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep, - int *ndimsp, int *dimidsp, int *nattsp, - int *shufflep, int *deflatep, int *deflate_levelp, - int *fletcher32p, int *contiguousp, size_t *chunksizesp, - int *no_fill, void *fill_valuep, int *endiannessp, - unsigned int* idp, size_t* nparamsp, unsigned int* params - ); - -extern int -HDF4_inq_varid(int ncid, const char *name, int *varidp); - -extern int -HDF4_rename_var(int ncid, int varid, const char *name); - -extern int -HDF4_put_vara(int ncid, int varid, - const size_t *start, const size_t *count, - const void *value, nc_type); - -extern int -HDF4_get_vara(int ncid, int varid, - const size_t *start, const size_t *count, - void *value, nc_type); - -/* End _var */ - -/* netCDF4 API only */ -extern int -HDF4_var_par_access(int, int, int); - -extern int -HDF4_inq_ncid(int, const char *, int *); - -extern int -HDF4_inq_grps(int, int *, int *); - -extern int -HDF4_inq_grpname(int, char *); - -extern int -HDF4_inq_grpname_full(int, size_t *, char *); - -extern int -HDF4_inq_grp_parent(int, int *); - -extern int -HDF4_inq_grp_full_ncid(int, const char *, int *); - -extern int -HDF4_inq_varids(int, int * nvars, int *); - -extern int -HDF4_inq_dimids(int, int * ndims, int *, int); - -extern int -HDF4_inq_typeids(int, int * ntypes, int *); - -extern int -HDF4_inq_type_equal(int, nc_type, int, nc_type, int *); - -extern int -HDF4_def_grp(int, const char *, int *); - -extern int -HDF4_rename_grp(int, const char *); - -extern int -HDF4_inq_user_type(int, nc_type, char *, size_t *, nc_type *, - size_t *, int *); - -extern int -HDF4_def_compound(int, size_t, const char *, nc_type *); - -extern int -HDF4_insert_compound(int, nc_type, const char *, size_t, nc_type); - -extern int -HDF4_insert_array_compound(int, nc_type, const char *, size_t, - nc_type, int, const int *); - -extern int -HDF4_inq_typeid(int, const char *, nc_type *); - -extern int -HDF4_inq_compound_field(int, nc_type, int, char *, size_t *, - nc_type *, int *, int *); - -extern int -HDF4_inq_compound_fieldindex(int, nc_type, const char *, int *); - -extern int -HDF4_def_vlen(int, const char *, nc_type base_typeid, nc_type *); - -extern int -HDF4_put_vlen_element(int, int, void *, size_t, const void *); - -extern int -HDF4_get_vlen_element(int, int, const void *, size_t *, void *); - -extern int -HDF4_def_enum(int, nc_type, const char *, nc_type *); - -extern int -HDF4_insert_enum(int, nc_type, const char *, const void *); - -extern int -HDF4_inq_enum_member(int, nc_type, int, char *, void *); - -extern int -HDF4_inq_enum_ident(int, nc_type, long long, char *); - -extern int -HDF4_def_opaque(int, size_t, const char *, nc_type *); - -extern int -HDF4_def_var_deflate(int, int, int, int, int); - -extern int -HDF4_def_var_fletcher32(int, int, int); - -extern int -HDF4_def_var_chunking(int, int, int, const size_t *); - -extern int -HDF4_def_var_fill(int, int, int, const void *); - -extern int -HDF4_def_var_endian(int, int, int); - -extern int -HDF4_def_var_filter(int, int, unsigned int, size_t, const unsigned int*); - -extern int -HDF4_set_var_chunk_cache(int, int, size_t, size_t, float); - -extern int -HDF4_get_var_chunk_cache(int, int, size_t *, size_t *, float *); - -extern int -HDF4_inq_unlimdims(int, int *, int *); - -extern int -HDF4_show_metadata(int); - -extern int -HDF4_initialize(void); + extern int + NC_HDF4_get_vara(int ncid, int varid, const size_t *start, const size_t *count, + void *value, nc_type); #if defined(__cplusplus) } diff --git a/include/nc4internal.h b/include/nc4internal.h index f2feb2dea..0f2c69bf7 100644 --- a/include/nc4internal.h +++ b/include/nc4internal.h @@ -1,9 +1,8 @@ -/** \file - This header file contains the definitions of structs used to hold - netCDF file metadata in memory. - - Copyright 2005-2011 University Corporation for Atmospheric - Research/Unidata. +/* Copyright 2005-2018 University Corporation for Atmospheric + Research/Unidata. */ +/** + * @file This header file contains the definitions of structs used to + * hold netCDF file metadata in memory. */ #ifndef _NC4INTERNAL_ @@ -30,10 +29,6 @@ /* Always needed */ #include "nc.h" -#ifdef USE_HDF4 -#include -#endif - #define FILE_ID_MASK (0xffff0000) #define GRP_ID_MASK (0x0000ffff) #define ID_SHIFT (16) @@ -200,9 +195,7 @@ typedef struct NC_VAR_INFO size_t chunk_cache_size, chunk_cache_nelems; float chunk_cache_preemption; #ifdef USE_HDF4 - /* Stuff below is for hdf4 files. */ - int sdsid; - int hdf4_data_type; + void *format_var_info; /* Pointer to any binary format info. */ #endif /* USE_HDF4 */ /* Stuff for arbitrary filters */ unsigned int filterid; @@ -330,8 +323,7 @@ typedef struct NC_HDF5_FILE_INFO NClist* alltypes; NClist* allgroups; /* including root group */ #ifdef USE_HDF4 - nc_bool_t hdf4; /* True for HDF4 file */ - int sdid; + void *format_file_info; #endif /* USE_HDF4 */ struct NCFILEINFO* fileinfo; } NC_HDF5_FILE_INFO_T; diff --git a/include/ncdispatch.h b/include/ncdispatch.h index c31d38287..439cdc225 100644 --- a/include/ncdispatch.h +++ b/include/ncdispatch.h @@ -413,4 +413,65 @@ NCDISPATCH_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep, extern int NCDISPATCH_get_att(int ncid, int varid, const char* name, void* value, nc_type t); +/* Read-only dispatch layers can use these functions to return + * NC_EPERM to all attempts to modify a file. */ + +int NC_RO_create(const char *path, int cmode, size_t initialsz, int basepe, + size_t *chunksizehintp, int useparallel, void* parameters, + NC_Dispatch*, NC*); +int NC_RO_redef(int ncid); +int NC_RO__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree, + size_t r_align); +int NC_RO_sync(int ncid); +int NC_RO_def_var_fill(int, int, int, const void *); +int NC_RO_rename_att(int ncid, int varid, const char *name, + const char *newname); +int NC_RO_del_att(int ncid, int varid, const char*); +int NC_RO_put_att(int ncid, int varid, const char *name, nc_type datatype, + size_t len, const void *value, nc_type); +int NC_RO_def_var(int ncid, const char *name, + nc_type xtype, int ndims, const int *dimidsp, int *varidp); +int NC_RO_rename_var(int ncid, int varid, const char *name); +int NC_RO_put_vara(int ncid, int varid, + const size_t *start, const size_t *count, + const void *value, nc_type); +int NC_RO_def_dim(int ncid, const char *name, size_t len, int *idp); +int NC_RO_rename_dim(int ncid, int dimid, const char *name); +int NC_RO_set_fill(int ncid, int fillmode, int *old_modep); + +/* These functions are for dispatch layers that don't implement these + * legacy functions. They return NC_ENOTNC3. */ +int NC_NOTNC3_set_base_pe(int ncid, int pe); +int NC_NOTNC3_inq_base_pe(int ncid, int *pe); + +/* These functions are for dispatch layers that don't implement the + * enhanced model. They return NC_ENOTNC4. */ +int NC_NOTNC4_def_var_filter(int, int, unsigned int, size_t, + const unsigned int*); +int NC_NOTNC4_def_grp(int, const char *, int *); +int NC_NOTNC4_rename_grp(int, const char *); +int NC_NOTNC4_def_compound(int, size_t, const char *, nc_type *); +int NC_NOTNC4_insert_compound(int, nc_type, const char *, size_t, nc_type); +int NC_NOTNC4_insert_array_compound(int, nc_type, const char *, size_t, + nc_type, int, const int *); +int NC_NOTNC4_inq_typeid(int, const char *, nc_type *); +int NC_NOTNC4_inq_compound_field(int, nc_type, int, char *, size_t *, + nc_type *, int *, int *); +int NC_NOTNC4_inq_compound_fieldindex(int, nc_type, const char *, int *); +int NC_NOTNC4_def_vlen(int, const char *, nc_type base_typeid, nc_type *); +int NC_NOTNC4_put_vlen_element(int, int, void *, size_t, const void *); +int NC_NOTNC4_get_vlen_element(int, int, const void *, size_t *, void *); +int NC_NOTNC4_def_enum(int, nc_type, const char *, nc_type *); +int NC_NOTNC4_insert_enum(int, nc_type, const char *, const void *); +int NC_NOTNC4_inq_enum_member(int, nc_type, int, char *, void *); +int NC_NOTNC4_inq_enum_ident(int, nc_type, long long, char *); +int NC_NOTNC4_def_opaque(int, size_t, const char *, nc_type *); +int NC_NOTNC4_def_var_deflate(int, int, int, int, int); +int NC_NOTNC4_def_var_fletcher32(int, int, int); +int NC_NOTNC4_def_var_chunking(int, int, int, const size_t *); +int NC_NOTNC4_def_var_endian(int, int, int); +int NC_NOTNC4_set_var_chunk_cache(int, int, size_t, size_t, float); +int NC_NOTNC4_get_var_chunk_cache(int, int, size_t *, size_t *, float *); +int NC_NOTNC4_var_par_access(int, int, int); + #endif /* _DISPATCH_H */ diff --git a/libdispatch/CMakeLists.txt b/libdispatch/CMakeLists.txt index 5dd29d115..8365f150e 100644 --- a/libdispatch/CMakeLists.txt +++ b/libdispatch/CMakeLists.txt @@ -1,4 +1,4 @@ -SET(libdispatch_SOURCES dparallel.c dcopy.c dfile.c ddim.c datt.c dattinq.c dattput.c dattget.c derror.c dvar.c dvarget.c dvarput.c dvarinq.c ddispatch.c nclog.c dstring.c dutf8.c dinternal.c doffsets.c ncuri.c nclist.c ncbytes.c nchashmap.c nctime.c nc.c nclistmgr.c utf8proc.h utf8proc.c dwinpath.c dutil.c drc.c dauth.c crc32.c) +SET(libdispatch_SOURCES dparallel.c dcopy.c dfile.c ddim.c datt.c dattinq.c dattput.c dattget.c derror.c dvar.c dvarget.c dvarput.c dvarinq.c ddispatch.c nclog.c dstring.c dutf8.c dinternal.c doffsets.c ncuri.c nclist.c ncbytes.c nchashmap.c nctime.c nc.c nclistmgr.c utf8proc.h utf8proc.c dwinpath.c dutil.c drc.c dauth.c dreadonly.c dnotnc4.c dnotnc3.c crc32.c) IF(USE_NETCDF4) SET(libdispatch_SOURCES ${libdispatch_SOURCES} dgroup.c dvlen.c dcompound.c dtype.c denum.c dopaque.c ncaux.c dfilter.c) diff --git a/libdispatch/Makefile.am b/libdispatch/Makefile.am index d63e3734d..141d53add 100644 --- a/libdispatch/Makefile.am +++ b/libdispatch/Makefile.am @@ -17,10 +17,9 @@ libdispatch_la_CPPFLAGS = ${AM_CPPFLAGS} # The source files. libdispatch_la_SOURCES = dparallel.c dcopy.c dfile.c ddim.c datt.c \ dattinq.c dattput.c dattget.c derror.c dvar.c dvarget.c dvarput.c \ -dvarinq.c dinternal.c ddispatch.c dutf8.c \ -nclog.c dstring.c \ -ncuri.c nclist.c ncbytes.c nchashmap.c nctime.c \ -nc.c nclistmgr.c drc.c dauth.c doffsets.c dwinpath.c dutil.c \ +dvarinq.c dinternal.c ddispatch.c dutf8.c nclog.c dstring.c ncuri.c \ +nclist.c ncbytes.c nchashmap.c nctime.c nc.c nclistmgr.c drc.c \ +dauth.c doffsets.c dwinpath.c dutil.c dreadonly.c dnotnc4.c dnotnc3.c \ crc32.c crc32.h # Add the utf8 codebase diff --git a/libdispatch/dnotnc3.c b/libdispatch/dnotnc3.c new file mode 100644 index 000000000..b7978783f --- /dev/null +++ b/libdispatch/dnotnc3.c @@ -0,0 +1,41 @@ +/* Copyright 2018, UCAR/Unidata See netcdf/COPYRIGHT file for copying + * and redistribution conditions.*/ +/** + * @file @internal This file handles the *_base_pe() + * functions for dispatch layers that need to return ::NC_ENOTNC3. + * + * @author Ed Hartnett +*/ + +#include "nc4dispatch.h" + +/** + * @internal This function only does anything for netcdf-3 files. + * + * @param ncid Ignored. + * @param pe Ignored. + * + * @return ::NC_ENOTNC3 Not a netCDF classic format file. + * @author Ed Hartnett + */ +int +NC_NOTNC3_set_base_pe(int ncid, int pe) +{ + return NC_ENOTNC3; +} + +/** + * @internal This function only does anything for netcdf-3 files. + * + * @param ncid Ignored. + * @param pe Ignored. + * + * @return ::NC_ENOTNC3 Not a netCDF classic format file. + * @author Ed Hartnett + */ +int +NC_NOTNC3_inq_base_pe(int ncid, int *pe) +{ + return NC_ENOTNC3; +} + diff --git a/libdispatch/dnotnc4.c b/libdispatch/dnotnc4.c new file mode 100644 index 000000000..b0ea106d5 --- /dev/null +++ b/libdispatch/dnotnc4.c @@ -0,0 +1,432 @@ +/* Copyright 2018, UCAR/Unidata See netcdf/COPYRIGHT file for copying + * and redistribution conditions.*/ +/** + * @file + * @internal This file contains functions that return NC_ENOTNC4, for + * dispatch layers that only implement the classic model. + * + * @author Ed Hartnett + */ + +#include "ncdispatch.h" + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param varid Ignored. + * @param id Ignored. + * @param nparams Ignored. + * @param parms Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett + */ +int +NC_NOTNC4_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, + const unsigned int* parms) +{ + return NC_ENOTNC4; +} + + +/** + * @internal Not allowed for classic model. + * + * @param parent_ncid Ignored. + * @param name Ignored. + * @param new_ncid Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett + */ +int +NC_NOTNC4_def_grp(int parent_ncid, const char *name, int *new_ncid) +{ + return NC_ENOTNC4; +} + +/** + * @internal Not allowed for classic model. + * + * @param grpid Ignored. + * @param name Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett + */ +int +NC_NOTNC4_rename_grp(int grpid, const char *name) +{ + return NC_ENOTNC4; +} + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param size Ignored. + * @param name Ignored. + * @param typeidp Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett + */ +int +NC_NOTNC4_def_compound(int ncid, size_t size, const char *name, nc_type *typeidp) +{ + return NC_ENOTNC4; +} + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param typeid1 Ignored. + * @param name Ignored. + * @param offset Ignored. + * @param field Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett + */ +int +NC_NOTNC4_insert_compound(int ncid, nc_type typeid1, const char *name, size_t offset, + nc_type field_typeid) +{ + return NC_ENOTNC4; +} + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param typeid1 Ignored. + * @param name Ignored. + * @param offset Ignored. + * @param field Ignored. + * @param ndims Ignored. + * @param dim Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett + */ +extern int +NC_NOTNC4_insert_array_compound(int ncid, int typeid1, const char *name, + size_t offset, nc_type field_typeid, + int ndims, const int *dim_sizesp) +{ + return NC_ENOTNC4; +} + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param typeid1 Ignored. + * @param fieldid Ignored. + * @param name Ignored. + * @param offsetp Ignored. + * @param field Ignored. + * @param ndimsp Ignored. + * @param dim Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett + */ +int +NC_NOTNC4_inq_compound_field(int ncid, nc_type typeid1, int fieldid, char *name, + size_t *offsetp, nc_type *field_typeidp, int *ndimsp, + int *dim_sizesp) +{ + return NC_ENOTNC4; +} + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param typeid1 Ignored. + * @param name Ignored. + * @param fieldidp Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett + */ +int +NC_NOTNC4_inq_compound_fieldindex(int ncid, nc_type typeid1, const char *name, int *fieldidp) +{ + return NC_ENOTNC4; +} + +/* Opaque type. */ + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param datum Ignored. + * @param name Ignored. + * @param typeidp Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett + */ +int +NC_NOTNC4_def_opaque(int ncid, size_t datum_size, const char *name, + nc_type *typeidp) +{ + return NC_ENOTNC4; +} + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param name Ignored. + * @param base_typeid Ignored. + * @param typeidp Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett + */ +int +NC_NOTNC4_def_vlen(int ncid, const char *name, nc_type base_typeid, + nc_type *typeidp) +{ + return NC_ENOTNC4; +} + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param base_typeid Ignored. + * @param name Ignored. + * @param typeidp Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett + */ +int +NC_NOTNC4_def_enum(int ncid, nc_type base_typeid, const char *name, + nc_type *typeidp) +{ + return NC_ENOTNC4; +} + + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param xtype Ignored. + * @param value Ignored. + * @param identifier Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett + */ +int +NC_NOTNC4_inq_enum_ident(int ncid, nc_type xtype, long long value, char *identifier) +{ + return NC_ENOTNC4; +} + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param typeid1 Ignored. + * @param idx Ignored. + * @param identifier Ignored. + * @param value Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett + */ +int +NC_NOTNC4_inq_enum_member(int ncid, nc_type typeid1, int idx, char *identifier, + void *value) +{ + return NC_ENOTNC4; +} + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param typeid1 Ignored. + * @param identifier Ignored. + * @param value Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett + */ +int +NC_NOTNC4_insert_enum(int ncid, nc_type typeid1, const char *identifier, + const void *value) +{ + return NC_ENOTNC4; +} + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param typeid1 Ignored. + * @param vlen_element Ignored. + * @param len Ignored. + * @param data Ignored. + * + * @return ::NC_NOERR No error. + * @author Ed Hartnett + */ +int +NC_NOTNC4_put_vlen_element(int ncid, int typeid1, void *vlen_element, + size_t len, const void *data) +{ + return NC_ENOTNC4; +} + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param typeid1 Ignored. + * @param vlen_element Ignored. + * @param len Ignored. + * @param data Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett + */ +int +NC_NOTNC4_get_vlen_element(int ncid, int typeid1, const void *vlen_element, + size_t *len, void *data) +{ + return NC_ENOTNC4; +} + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param varid Ignored. + * @param size Ignored. + * @param nelems Ignored. + * @param preemption Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett + */ +int +NC_NOTNC4_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems, + float preemption) +{ + return NC_ENOTNC4; +} + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param varid Ignored. + * @param sizep Ignored. + * @param nelemsp Ignored. + * @param preemptionp Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett + */ +int +NC_NOTNC4_get_var_chunk_cache(int ncid, int varid, size_t *sizep, + size_t *nelemsp, float *preemptionp) +{ + return NC_ENOTNC4; +} + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param varid Ignored. + * @param shuffle Ignored. + * @param deflate Ignored. + * @param deflate_level Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett, Dennis Heimbigner + */ +int +NC_NOTNC4_def_var_deflate(int ncid, int varid, int shuffle, int deflate, + int deflate_level) +{ + return NC_ENOTNC4; +} + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param varid Ignored. + * @param fletcher32 Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett, Dennis Heimbigner + */ +int +NC_NOTNC4_def_var_fletcher32(int ncid, int varid, int fletcher32) +{ + return NC_ENOTNC4; +} + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param varid Ignored. + * @param contiguous Ignored. + * @param chunksizesp Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett, Dennis Heimbigner + */ +int +NC_NOTNC4_def_var_chunking(int ncid, int varid, int contiguous, const size_t *chunksizesp) +{ + return NC_EPERM; +} + + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param varid Ignored. + * @param endianness Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett + */ +int +NC_NOTNC4_def_var_endian(int ncid, int varid, int endianness) +{ + return NC_ENOTNC4; +} + +/** + * @internal Not allowed for classic model. + * + * @param ncid Ignored. + * @param varid Ignored. + * @param par_access Ignored. + * + * @return ::NC_ENOTNC4 Not allowed for classic model. + * @author Ed Hartnett, Dennis Heimbigner + */ +int +NC_NOTNC4_var_par_access(int ncid, int varid, int par_access) +{ + return NC_ENOTNC4; +} diff --git a/libdispatch/dreadonly.c b/libdispatch/dreadonly.c new file mode 100644 index 000000000..c75ad632d --- /dev/null +++ b/libdispatch/dreadonly.c @@ -0,0 +1,261 @@ +/* Copyright 2018, UCAR/Unidata See netcdf/COPYRIGHT file for copying + * and redistribution conditions.*/ +/** + * @file + * @internal This file contains functions that return NC_EPERM, for + * read-only dispatch layers. + * + * @author Ed Hartnett + */ + +#include "nc.h" +#include "ncdispatch.h" + +/** + * @internal Not allowed for read-only access. + * + * @param ncid Ignored. + * @param varid Ignored. + * @param name Ignored. + * @param newname Ignored. + * + * @return ::NC_EPERM Not allowed. + * @author Ed Hartnett + */ +int +NC_RO_rename_att(int ncid, int varid, const char *name, const char *newname) +{ + return NC_EPERM; +} + +/** + * @internal Not allowed for read-only access. + * + * @param ncid Ignored. + * @param varid Ignored. + * @param name Ignored. + * + * @return ::NC_EPERM Not allowed. + * @author Ed Hartnett + */ +int +NC_RO_del_att(int ncid, int varid, const char *name) +{ + return NC_EPERM; +} + +/** + * @internal Not allowed for read-only access. + * + * @param ncid Ignored. + * @param varid Ignored. + * @param name Ignored. + * @param file_type Ignored. + * @param len Ignored. + * @param data Ignored. + * @param memtype Ignored. + * + * @return ::NC_EPERM Not allowed. + * @author Ed Hartnett + */ +int +NC_RO_put_att(int ncid, int varid, const char *name, nc_type file_type, + size_t len, const void *data, nc_type mem_type) +{ + return NC_EPERM; +} + +/** + * @internal Not allowed for read-only access. + * + * @param ncid Ignored. + * @param name Ignored. + * @param len Ignored. + * @param idp Ignored. + * + * @return ::NC_EPERM Not allowed. + * @author Ed Hartnett + */ +int +NC_RO_def_dim(int ncid, const char *name, size_t len, int *idp) +{ + return NC_EPERM; +} + +/** + * @internal Not allowed for read-only access. + * + * @param ncid Ignored. + * @param dimid Ignored. + * @param name Ignored. + * + * @return ::NC_EPERM Not allowed. + * @author Ed Hartnett + */ +int +NC_RO_rename_dim(int ncid, int dimid, const char *name) +{ + return NC_EPERM; +} + +/** + * @internal Not allowed for read-only access. + * + * @param ncid Ignored. + * @param name Ignored. + * @param xtype Ignored. + * @param ndims Ignored. + * @param dimidsp Ignored. + * @param varidp Ignored. + * + * @return ::NC_EPERM Not allowed. + * @author Ed Hartnett + */ +int +NC_RO_def_var(int ncid, const char *name, nc_type xtype, + int ndims, const int *dimidsp, int *varidp) +{ + return NC_EPERM; +} + + +/** + * @internal Not allowed for classic model access. + * + * @param ncid Ignored. + * @param varid Ignored. + * @param no_fill Ignored. + * @param fill_value Ignored. + * + * @return ::NC_EPERM Not allowed. + * @author Ed Hartnett + */ +int +NC_RO_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value) +{ + return NC_EPERM; +} + +/** + * @internal Not allowed for read-only access. + * + * @param ncid File ID. + * @param varid Variable ID + * @param name New name of the variable. + * + * @return ::NC_EPERM Not allowed. + * @author Ed Hartnett + */ +int +NC_RO_rename_var(int ncid, int varid, const char *name) +{ + return NC_EPERM; +} + +/** + * @internal Not allowed for read-only access. + * + * @param ncid File ID. + * @param varid Variable ID. + * @param startp Array of start indicies. + * @param countp Array of counts. + * @param op pointer that gets the data. + * @param memtype The type of these data in memory. + * + * @return ::NC_EPERM Not allowed. + * @author Ed Hartnett + */ +int +NC_RO_put_vara(int ncid, int varid, const size_t *startp, + const size_t *countp, const void *op, int memtype) +{ + return NC_EPERM; +} + +/** + * @internal Not allowed for read-only access. + * + * @param ncid File and group ID. + * @param fillmode File mode. + * @param old_modep Pointer that gets old mode. Ignored if NULL. + * + * @return ::NC_EPERM Not allowed. + * @author Ed Hartnett + */ +int +NC_RO_set_fill(int ncid, int fillmode, int *old_modep) +{ + return NC_EPERM; +} + +/** + * @internal Not allowed for read-only access. + * + * @param ncid Ignored. + * + * @return ::NC_EPERM Not allowed. + * @author Ed Hartnett + */ +int +NC_RO_redef(int ncid) +{ + return NC_EPERM; +} + +/** + * @internal Not allowed for read-only access. + * + * @param ncid Ignored. + * @param h_minfree Ignored. + * @param v_align Ignored. + * @param v_minfree Ignored. + * @param r_align Ignored. + * + * @return ::NC_EPERM Not allowed. + * @author Ed Hartnett + */ +int +NC_RO__enddef(int ncid, size_t h_minfree, size_t v_align, + size_t v_minfree, size_t r_align) +{ + return NC_NOERR; +} + +/** + * @internal Not allowed for read-only access. + * + * @param ncid Ignored. + * + * @return ::NC_EPERM Not allowed. + * @author Ed Hartnett + */ +int +NC_RO_sync(int ncid) +{ + return NC_NOERR; +} + +/** + * @internal Not allowed for read-only access. + * + * @param path Ignored. + * @param cmode Ignored. + * @param initialsz Ignored. + * @param basepe Ignored. + * @param chunksizehintp Ignored. + * @param use_parallel Ignored. + * @param parameters Ignored. + * @param dispatch Ignored. + * @param nc_file Ignored. + * + * @return ::NC_EPERM Cannot create files. + * @author Ed Hartnett + */ +int +NC_RO_create(const char* path, int cmode, size_t initialsz, int basepe, + size_t *chunksizehintp, int use_parallel, void *parameters, + NC_Dispatch *dispatch, NC* nc_file) +{ + return NC_EPERM; +} + diff --git a/libhdf4/hdf4dispatch.c b/libhdf4/hdf4dispatch.c index 5579a4190..d15d10c34 100644 --- a/libhdf4/hdf4dispatch.c +++ b/libhdf4/hdf4dispatch.c @@ -11,7 +11,6 @@ #include #include "hdf4dispatch.h" #include "nc4dispatch.h" -#include "nc.h" /* This is the dispatch object that holds pointers to all the * functions that make up the HDF4 dispatch interface. */ @@ -19,42 +18,42 @@ static NC_Dispatch HDF4_dispatcher = { NC_FORMATX_NC_HDF4, -HDF4_create, -HDF4_open, +NC_RO_create, +NC_HDF4_open, -HDF4_redef, -HDF4__enddef, -HDF4_sync, -HDF4_abort, -HDF4_close, -HDF4_set_fill, -HDF4_inq_base_pe, -HDF4_set_base_pe, -HDF4_inq_format, -HDF4_inq_format_extended, +NC_RO_redef, +NC_RO__enddef, +NC_RO_sync, +NC_HDF4_close, +NC_HDF4_close, +NC_RO_set_fill, +NC_NOTNC3_inq_base_pe, +NC_NOTNC3_set_base_pe, +NC_HDF4_inq_format, +NC_HDF4_inq_format_extended, NC4_inq, NC4_inq_type, -HDF4_def_dim, +NC_RO_def_dim, NC4_inq_dimid, NC4_inq_dim, NC4_inq_unlimdim, -HDF4_rename_dim, +NC_RO_rename_dim, NC4_inq_att, NC4_inq_attid, NC4_inq_attname, -HDF4_rename_att, -HDF4_del_att, +NC_RO_rename_att, +NC_RO_del_att, NC4_get_att, -HDF4_put_att, +NC_RO_put_att, -HDF4_def_var, +NC_RO_def_var, NC4_inq_varid, -HDF4_rename_var, -HDF4_get_vara, -HDF4_put_vara, +NC_RO_rename_var, +NC_HDF4_get_vara, +NC_RO_put_vara, NCDEFAULT_get_vars, NCDEFAULT_put_vars, NCDEFAULT_get_varm, @@ -62,8 +61,8 @@ NCDEFAULT_put_varm, NC4_inq_var_all, -HDF4_var_par_access, -HDF4_def_var_fill, +NC_NOTNC4_var_par_access, +NC_RO_def_var_fill, NC4_show_metadata, NC4_inq_unlimdims, @@ -78,32 +77,31 @@ NC4_inq_varids, NC4_inq_dimids, NC4_inq_typeids, NC4_inq_type_equal, -HDF4_def_grp, -HDF4_rename_grp, +NC_NOTNC4_def_grp, +NC_NOTNC4_rename_grp, NC4_inq_user_type, NC4_inq_typeid, -HDF4_def_compound, -HDF4_insert_compound, -HDF4_insert_array_compound, -HDF4_inq_compound_field, -HDF4_inq_compound_fieldindex, -HDF4_def_vlen, -HDF4_put_vlen_element, -HDF4_get_vlen_element, -HDF4_def_enum, -HDF4_insert_enum, -HDF4_inq_enum_member, -HDF4_inq_enum_ident, -HDF4_def_opaque, -HDF4_def_var_deflate, -HDF4_def_var_fletcher32, -HDF4_def_var_chunking, -HDF4_def_var_endian, -HDF4_def_var_filter, -HDF4_set_var_chunk_cache, -HDF4_get_var_chunk_cache, - +NC_NOTNC4_def_compound, +NC_NOTNC4_insert_compound, +NC_NOTNC4_insert_array_compound, +NC_NOTNC4_inq_compound_field, +NC_NOTNC4_inq_compound_fieldindex, +NC_NOTNC4_def_vlen, +NC_NOTNC4_put_vlen_element, +NC_NOTNC4_get_vlen_element, +NC_NOTNC4_def_enum, +NC_NOTNC4_insert_enum, +NC_NOTNC4_inq_enum_member, +NC_NOTNC4_inq_enum_ident, +NC_NOTNC4_def_opaque, +NC_NOTNC4_def_var_deflate, +NC_NOTNC4_def_var_fletcher32, +NC_NOTNC4_def_var_chunking, +NC_NOTNC4_def_var_endian, +NC_NOTNC4_def_var_filter, +NC_NOTNC4_set_var_chunk_cache, +NC_NOTNC4_get_var_chunk_cache }; NC_Dispatch* HDF4_dispatch_table = NULL; @@ -115,7 +113,7 @@ NC_Dispatch* HDF4_dispatch_table = NULL; * @author Ed Hartnett */ int -HDF4_initialize(void) +NC_HDF4_initialize(void) { HDF4_dispatch_table = &HDF4_dispatcher; return NC_NOERR; @@ -128,7 +126,7 @@ HDF4_initialize(void) * @author Ed Hartnett */ int -HDF4_finalize(void) +NC_HDF4_finalize(void) { return NC_NOERR; } diff --git a/libhdf4/hdf4file.c b/libhdf4/hdf4file.c index 25834f7a2..f02794036 100644 --- a/libhdf4/hdf4file.c +++ b/libhdf4/hdf4file.c @@ -7,98 +7,70 @@ */ #include "config.h" -#include /* netcdf functions sometimes return system errors */ -#include "nc.h" #include "nc4internal.h" #include "hdf4dispatch.h" #include +#define NUM_TYPES 12 /**< Number of netCDF atomic types. */ + extern int nc4_vararray_add(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var); /** @internal These flags may not be set for open mode. */ -static const int ILLEGAL_OPEN_FLAGS = (NC_MMAP|NC_64BIT_OFFSET|NC_MPIIO|NC_MPIPOSIX|NC_DISKLESS); +static const int +ILLEGAL_OPEN_FLAGS = (NC_MMAP|NC_64BIT_OFFSET|NC_MPIIO|NC_MPIPOSIX|NC_DISKLESS|NC_WRITE); + +/** @internal NetCDF atomic type names. */ +static const char* +nc_type_name_g[NUM_TYPES] = {"char", "byte", "short", "int", "float", "double", + "ubyte", "ushort", "uint", "int64", "uint64", + "string"}; + +/** @internal NetCDF atomic type sizes. */ +static const size_t +nc_type_size_g[NUM_TYPES] = {sizeof(char), sizeof(char), sizeof(short), + sizeof(int), sizeof(float), sizeof(double), + sizeof(unsigned char), sizeof(unsigned short), + sizeof(unsigned int), sizeof(long long), + sizeof(unsigned long long), sizeof(char *)}; /** - * @internal This function will free all allocated metadata memory, - * and close the HDF4 file. + * @internal Recursively delete the data for a group (and everything + * it contains) in our internal metadata store. * - * @param h5 Pointer to HDF5 file info struct. - * @param abort True if this is an abort. + * @param grp Pointer to group info struct. * * @return ::NC_NOERR No error. * @author Ed Hartnett -*/ -static int -close_hdf4_file(NC_HDF5_FILE_INFO_T *h5, int abort) -{ - int retval; - - assert(h5 && h5->controller->path && h5->root_grp && h5->no_write); - LOG((3, "%s: h5->controller->path %s abort %d", __func__, - h5->controller->path, abort)); - - /* According to the docs, always end define mode on close. */ - if (h5->flags & NC_INDEF) - h5->flags ^= NC_INDEF; - - /* Delete all the list contents for vars, dims, and atts, in each - * group. */ - if ((retval = nc4_rec_grp_del(h5->root_grp))) - return retval; - - /* Close hdf file. */ - if (SDend(h5->sdid)) - return NC_EHDFERR; - - /* Misc. Cleanup */ - nclistfree(h5->alldims); - nclistfree(h5->allgroups); - nclistfree(h5->alltypes); - - /* Free the nc4_info struct; above code should have reclaimed - everything else */ - free(h5); - - return NC_NOERR; -} - -#define NUM_TYPES 12 /**< Number of netCDF atomic types. */ - -/** @internal NetCDF atomic type names. */ -static const char* nc_type_name_g[NUM_TYPES] = {"char", "byte", "short", - "int", "float", "double", "ubyte", - "ushort", "uint", "int64", - "uint64", "string"}; - -/** @internal NetCDF atomic type sizes. */ -static const int nc_type_size_g[NUM_TYPES] = {sizeof(char), sizeof(char), sizeof(short), - sizeof(int), sizeof(float), sizeof(double), sizeof(unsigned char), - sizeof(unsigned short), sizeof(unsigned int), sizeof(long long), - sizeof(unsigned long long), sizeof(char *)}; - -/** - * @internal Create a HDF4 file. Since the HDF4 integration provides - * read-only access to HDF4 files, this returns error NC_ENOTNC4. - * - * @param path Ignored. - * @param cmode Ignored. - * @param initialsz Ignored. - * @param basepe Ignored. - * @param chunksizehintp Ignored. - * @param use_parallel Ignored. - * @param parameters Ignored. - * @param dispatch Ignored. - * @param nc_file Ignored. - * - * @return ::NC_ENOTNC4 Cannot create HDF4 files. - * @author Ed Hartnett */ -int -HDF4_create(const char* path, int cmode, size_t initialsz, int basepe, - size_t *chunksizehintp, int use_parallel, void *parameters, - NC_Dispatch *dispatch, NC* nc_file) +static int +hdf4_rec_grp_del(NC_GRP_INFO_T *grp) { - return NC_ENOTNC4; + NC_VAR_INFO_T *var; + int i; + + assert(grp); + LOG((3, "%s: grp->name %s", __func__, grp->hdr.name)); + + /* Delete all vars. */ + for (i = 0; i < ncindexsize(grp->vars); i++) + { + NC_VAR_HDF4_INFO_T *hdf4_var; + + var = (NC_VAR_INFO_T *)ncindexith(grp->vars, i); + if (var == NULL) continue; + LOG((4, "%s: deleting var %s", __func__, var->hdr.name)); + + /* Get the HDF4 specific var metadata. */ + hdf4_var = (NC_VAR_HDF4_INFO_T *)var->format_var_info; + + /* Close HDF4 dataset associated with this var, unless it's a + * scale. */ + if (hdf4_var->sdsid && SDendaccess(hdf4_var->sdsid) < 0) + return NC_EHDFERR; + free(hdf4_var); + } + + return NC_NOERR; } /** @@ -109,26 +81,22 @@ HDF4_create(const char* path, int cmode, size_t initialsz, int basepe, * * @param h5 Pointer to HDF5 file info struct. * @param hdf4_typeid Type ID for hdf4 datatype. - * @param xtype Pointer to netcdf type, where result will be stored. - * @param type_info Pointer to type info for the variable. + * @param xtype Pointer that gets netcdf type. Ignored if NULL. + * @param endniannessp Pointer that gets endianness. Ignored if NULL. + * @param type_sizep Pointer that gets type size. Ignored if NULL. + * @param type_name Pointer that gets the type name. Ignored if NULL. * * @return ::NC_NOERR No error. * @author Ed Hartnett */ static int -get_netcdf_type_from_hdf4(NC_HDF5_FILE_INFO_T *h5, int32 hdf4_typeid, - nc_type* xtypep, NC_TYPE_INFO_T **typep) +hdf4_type_info(NC_HDF5_FILE_INFO_T *h5, int32 hdf4_typeid, nc_type* xtypep, + int *endiannessp, size_t *type_sizep, char *type_name) { int t = 0; + int endianness = NC_ENDIAN_BIG; nc_type xtype; - /* Added this variable in the course of fixing NCF-332. - * Prior to the fix, all data types were assigned - * NC_ENDIAN_BIG, so I am preserving that here for now. - * Not sure why it wouldn't be NC_ENDIAN_NATIVE, although - * I can hazard a guess or two. - */ - int endianness = NC_ENDIAN_BIG; assert(h5); switch(hdf4_typeid) @@ -211,290 +179,401 @@ get_netcdf_type_from_hdf4(NC_HDF5_FILE_INFO_T *h5, int32 hdf4_typeid, endianness = NC_ENDIAN_LITTLE; break; default: - if(xtypep) *xtypep = NC_NAT; return NC_EBADTYPID; } - if(xtypep) *xtypep = xtype; - if (typep) + /* Return results to caller. */ + if (xtypep) + *xtypep = xtype; + if (endiannessp) + *endiannessp = endianness; + if (type_sizep) + *type_sizep = nc_type_size_g[t]; + if (type_name) + strncpy(type_name, nc_type_name_g[t], NC_MAX_NAME); + + return NC_NOERR; +} + +/** + * @internal Set the type of a netCDF-4 variable. + * + * @param xtype A netcdf type. + * @param endianness The endianness of the data. + * @param type_size The size in bytes of one element of this type. + * @param type_name A name for the type. + * @param typep Pointer to a pointer that gets the TYPE_INFO_T struct. + * + * @return ::NC_NOERR No error. + * @author Ed Hartnett + */ +static int +nc4_set_var_type(nc_type xtype, int endianness, size_t type_size, char *type_name, + NC_TYPE_INFO_T **typep) +{ + NC_TYPE_INFO_T *type; + + /* Check inputs. */ + assert(typep); + + /* Allocate space for the type info struct. */ + if (!(type = calloc(1, sizeof(NC_TYPE_INFO_T)))) + return NC_ENOMEM; + if (!(type->hdr.name = strdup(type_name))) { - NC_TYPE_INFO_T* type = NULL; + free(type); + return NC_ENOMEM; + } + type->hdr.sort = NCTYP; - if (!(type = calloc(1, sizeof(NC_TYPE_INFO_T)))) + /* Determine the type class. */ + if (xtype == NC_FLOAT) + type->nc_type_class = NC_FLOAT; + else if (xtype == NC_DOUBLE) + type->nc_type_class = NC_DOUBLE; + else if (xtype == NC_CHAR) + type->nc_type_class = NC_STRING; + else + type->nc_type_class = NC_INT; + + /* Set other type info values. */ + type->endianness = endianness; + type->size = type_size; + type->hdr.id = (size_t)xtype; + type->hdr.hashkey = NC_hashmapkey(type->hdr.name, strlen(type->hdr.name)); + + /* Return to caller. */ + *typep = type; + + return NC_NOERR; +} + +/** + * @internal Read an attribute from a HDF4 file. + * + * @param h5 Pointer to the file metadata struct. + * @param var Pointer to variable metadata struct or NULL for global + * attributes. + * @param a Index of attribute to read. + * + * @return ::NC_NOERR No error. + * @return ::NC_EHDFERR HDF4 error. + * @return ::NC_EATTMETA Error reading HDF4 attribute. + * @return ::NC_ENOMEM Out of memory. + * @author Ed Hartnett + */ +static int +hdf4_read_att(NC_HDF5_FILE_INFO_T *h5, NC_VAR_INFO_T *var, int a) +{ + NC_HDF4_FILE_INFO_T *hdf4_file; + NC_ATT_INFO_T *att; + NCindex *att_list; + int32 att_data_type, att_count; + size_t att_type_size; + char name[NC_MAX_HDF4_NAME+1]; + int sd_id; + int retval; + + LOG((3, "%s: a %d var %s", __func__, a, var ? var->hdr.name : "global")); + + /* Check inputs. */ + assert(h5 && h5->format_file_info); + + /* Get the HDF4 file info. */ + hdf4_file = h5->format_file_info; + + /* Decide what att list to use, global or from a var. */ + if (var) + { + NC_VAR_HDF4_INFO_T *hdf4_var; + assert(var->format_var_info); + att_list = var->att; + hdf4_var = var->format_var_info; + sd_id = hdf4_var->sdsid; + } else { + att_list = h5->root_grp->att; + sd_id = hdf4_file->sdid; + } + + /* Learn about this attribute. */ + if (SDattrinfo(sd_id, a, name, &att_data_type, &att_count)) + return NC_EATTMETA; + + /* Get information about the attribute type. */ + nc_type xtype; + if ((retval = hdf4_type_info(h5, att_data_type, &xtype, NULL, + &att_type_size, NULL))) + return retval; + + /* Add to the end of the list of atts for this var. */ + if ((retval = nc4_att_list_add(att_list, name, &att))) + return retval; + att->nc_typeid = xtype; + att->created = NC_TRUE; + att->len = att_count; + + /* Allocate memory to hold the data. */ + if (att->len) + if (!(att->data = malloc(att_type_size * att->len))) return NC_ENOMEM; - type->hdr.sort = NCTYP; - if (hdf4_typeid == DFNT_FLOAT32) - type->nc_type_class = NC_FLOAT; - else if (hdf4_typeid == DFNT_FLOAT64) - type->nc_type_class = NC_DOUBLE; - else if (hdf4_typeid == DFNT_CHAR) - type->nc_type_class = NC_STRING; - else - type->nc_type_class = NC_INT; - type->endianness = endianness; - type->size = nc_type_size_g[t]; - type->hdr.id = xtype; - type->hdr.name = strdup(nc_type_name_g[t]); - if(type->hdr.name == NULL) - return NC_ENOMEM; - type->hdr.hashkey = NC_hashmapkey(type->hdr.name,strlen(type->hdr.name)); - if(typep) *typep = type; + + /* Read the data. */ + if (SDreadattr(sd_id, a, att->data)) + return NC_EHDFERR; + + return NC_NOERR; +} + +/** + * @internal Read a HDF4 dimension. As new dimensions are found, add + * them to the metadata list of dimensions. + * + * @param h5 Pointer to the file metadata struct. + * @param var Pointer to variable metadata struct or NULL for global + * attributes. + * @param rec_dim_len Actual length of first dim for this SD. + * @param d Dimension index for this SD. + * + * @return ::NC_NOERR No error. + * @return ::NC_EHDFERR HDF4 error. + * @return ::NC_EDIMMETA Error reading HDF4 dimension info. + * @return ::NC_ENOMEM Out of memory. + * @return ::NC_EMAXNAME Name too long. + * @author Ed Hartnett + */ +static int +hdf4_read_dim(NC_HDF5_FILE_INFO_T *h5, NC_VAR_INFO_T *var, int rec_dim_len, int d) +{ + NC_VAR_HDF4_INFO_T *hdf4_var; + NC_DIM_INFO_T *dim = NULL; + int32 dimid, dim_len, dim_data_type, dim_num_attrs; + char dim_name[NC_MAX_NAME + 1]; + int i; + int retval; + + assert(h5 && h5->format_file_info && var && var->format_var_info); + hdf4_var = var->format_var_info; + + /* Get information about the dimension. */ + if ((dimid = SDgetdimid(hdf4_var->sdsid, d)) == FAIL) + return NC_EDIMMETA; + if (SDdiminfo(dimid, dim_name, &dim_len, &dim_data_type, &dim_num_attrs)) + return NC_EDIMMETA; + if (strlen(dim_name) > NC_MAX_HDF4_NAME) + return NC_EMAXNAME; + + /* Do we already have this dimension? HDF4 explicitly uses + * the name to tell. */ + for (i = 0; i < ncindexsize(h5->root_grp->dim); i++) + { + dim = (NC_DIM_INFO_T*)ncindexith(h5->root_grp->dim, i); + if (!strcmp(dim->hdr.name, dim_name)) + break; + dim = NULL; + } + + /* If we didn't find this dimension, add one. */ + if (!dim) + { + LOG((4, "adding dim %s for dataset %s", dim_name, var->hdr.name)); + if ((retval = nc4_dim_list_add(h5->root_grp, dim_name, + (dim_len ? dim_len : rec_dim_len), -1, &dim))) + return retval; + } + + /* Tell the variable the id of this dimension. */ + var->dimids[d] = dim->hdr.id; + var->dim[d] = dim; + + return NC_NOERR; +} + +/** + * @internal Create a new variable and insert int relevant lists + * + * @param grp the containing group + * @param name the name for the new variable + * @param ndims the rank of the new variable + * @param format_var_info Pointer to format-specific var info struct. + * @param var Pointer in which to return a pointer to the new var. + * + * @return ::NC_NOERR No error. + * @return ::NC_ENOMEM Out of memory. + * @author Ed Hartnett + */ +static int +nc4_var_list_add_full(NC_GRP_INFO_T* grp, const char* name, int ndims, nc_type xtype, + int endianness, size_t type_size, char *type_name, void *fill_value, + int contiguous, size_t *chunksizes, void *format_var_info, + NC_VAR_INFO_T **var) +{ + int d; + int retval; + + /* Add the VAR_INFO_T struct to our list of vars. */ + if ((retval = nc4_var_list_add(grp, name, ndims, var))) + return retval; + (*var)->created = NC_TRUE; + (*var)->written_to = NC_TRUE; + (*var)->format_var_info = format_var_info; + + /* Fill special type_info struct for variable type information. */ + if ((retval = nc4_set_var_type(xtype, endianness, type_size, type_name, + &(*var)->type_info))) + return retval; + + (*var)->type_info->rc++; + + /* Handle fill value, if provided. */ + if (fill_value) + { + if (!((*var)->fill_value = malloc(type_size))) + return NC_ENOMEM; + memcpy((*var)->fill_value, fill_value, type_size); + } + + /* Var contiguous or chunked? */ + (*var)->contiguous = contiguous; + + /* Were chunksizes provided? */ + if (chunksizes) + { + if (!((*var)->chunksizes = malloc(ndims * sizeof(size_t)))) + return NC_ENOMEM; + for (d = 0; d < ndims; d++) + (*var)->chunksizes[d] = chunksizes[d]; } return NC_NOERR; } /** - * @internal Open a HDF4 file. - * - * @param path The file name of the new file. - * @param mode The open mode flag. - * @param nc Pointer that gets the NC file info struct. + * @internal Read a HDF4 variable, including its associated dimensions + * and attributes. * + * @param h5 Pointer to the file metadata struct. + * @param v Index of variable to read. + * * @return ::NC_NOERR No error. + * @return ::NC_EHDFERR HDF4 error. + * @return ::NC_EDIMMETA Error reading HDF4 dimension info. + * @return ::NC_EVARMETA Error reading HDF4 dataset or att. + * @return ::NC_EATTMETA Error reading HDF4 attribute. + * @return ::NC_ENOMEM Out of memory. + * @return ::NC_EMAXNAME Name too long. * @author Ed Hartnett -*/ + */ static int -nc4_open_hdf4_file(const char *path, int mode, NC *nc) +hdf4_read_var(NC_HDF5_FILE_INFO_T *h5, int v) { - NC_HDF5_FILE_INFO_T *h5; - NC_GRP_INFO_T *grp; - NC_ATT_INFO_T *att; - NC_VAR_INFO_T *var = NULL; - int32 num_datasets, num_gatts; + NC_HDF4_FILE_INFO_T *hdf4_file; + NC_VAR_INFO_T *var; + NC_VAR_HDF4_INFO_T *hdf4_var; + HDF_CHUNK_DEF chunkdefs; + int32 data_type, num_atts; + int32 dimsize[NC_MAX_HDF4_DIMS]; + int32 rec_dim_len; int32 rank; - int v, d, a; - int retval = NC_NOERR; - NC_HDF5_FILE_INFO_T* nc4_info = NULL; - int32 *dimsize = NULL; + int32 sdsid; + int contiguous; + int d, a; + int flag; + char name[NC_MAX_HDF4_NAME+1]; + int xtype; + char type_name[NC_MAX_NAME + 1]; + int endianness; + size_t type_size; + void *fill_value; + size_t *chunksizes = NULL; + int retval; - LOG((3, "%s: path %s mode %d", __func__, path, mode)); - assert(path && nc); + /* Check inputs. */ + assert(h5 && h5->format_file_info); - /* Must be read-only access to hdf4 files. */ - if (mode & NC_WRITE) - return NC_EINVAL; + /* Get HDF4 file metadata. */ + hdf4_file = h5->format_file_info; - /* Add necessary structs to hold netcdf-4 file data. */ - if ((retval = nc4_nc4f_list_add(nc, path, mode))) + /* Open this dataset in HDF4 file. */ + if ((sdsid = SDselect(hdf4_file->sdid, v)) == FAIL) + return NC_EVARMETA; + + /* Learn about this dataset. */ + if (SDgetinfo(sdsid, name, &rank, dimsize, &data_type, &num_atts)) + return NC_EVARMETA; + rec_dim_len = dimsize[0]; + + /* Get chunking info from HDF4 file. */ + if (SDgetchunkinfo(sdsid, &chunkdefs, &flag)) + return NC_EVARMETA; + + /* Learn about the HDF4 type. */ + if ((retval = hdf4_type_info(h5, data_type, &xtype, &endianness, &type_size, + type_name))) return retval; - nc4_info = NC4_DATA(nc); - assert(nc4_info && nc4_info->root_grp); - h5 = nc4_info; - h5->hdf4 = NC_TRUE; - grp = h5->root_grp; - h5->no_write = NC_TRUE; - /* Open the file and initialize SD interface. */ - if ((h5->sdid = SDstart(path, DFACC_READ)) == FAIL) - return NC_EHDFERR; - - /* Learn how many datasets and global atts we have. */ - if (SDfileinfo(h5->sdid, &num_datasets, &num_gatts)) - return NC_EHDFERR; - - /* Read the atts. */ - for (a = 0; a < num_gatts; a++) + /* Get the fill value. */ + if (!(fill_value = malloc(type_size))) + return NC_ENOMEM; + if (SDgetfillvalue(sdsid, fill_value)) { - int32 att_data_type, att_count; - size_t att_type_size; - char name[NC_MAX_HDF4_NAME+1]; - - /* Learn about this attribute. */ - if (SDattrinfo(h5->sdid, a, name, &att_data_type, &att_count)) - return NC_EATTMETA; - - /* Add to the end of the list of atts for this var. */ - if ((retval = nc4_att_list_add(h5->root_grp->att, name, &att))) - return retval; - att->created = NC_TRUE; - - if ((retval = get_netcdf_type_from_hdf4(h5, att_data_type, &att->nc_typeid, NULL))) - return retval; - att->len = att_count; - - /* Allocate memory to hold the data. */ - if ((retval = nc4_get_typelen_mem(h5, att->nc_typeid, &att_type_size))) - return retval; - if (!(att->data = malloc(att_type_size * att->len))) - return NC_ENOMEM; - - /* Read the data. */ - if (SDreadattr(h5->sdid, a, att->data)) - return NC_EHDFERR; + /* Whoops! No fill value! */ + free(fill_value); + fill_value = NULL; } - /* Read each dataset. */ - for (v = 0; v < num_datasets; v++) + /* Is variable chunked or contiguous? */ + if (flag == HDF_NONE) + contiguous = NC_TRUE; + else if (flag & HDF_CHUNK) { - int32 data_type, num_atts; - int sdsid; + contiguous = NC_FALSE; + if (!(chunksizes = malloc(rank * sizeof(size_t)))) + return NC_ENOMEM; + for (d = 0; d < rank; d++) + chunksizes[d] = chunkdefs.chunk_lengths[d]; + } - /* Problem: Number of dims is returned by the call that requires - a pre-allocated array, 'dimsize'. - From SDS_SD website: - http://www.hdfgroup.org/training/HDFtraining/UsersGuide/SDS_SD.fm3.html - The maximum rank is 32, or MAX_VAR_DIMS (as defined in netcdf.h). + /* Malloc a struct to hold HDF4-specific variable + * information. */ + if (!(hdf4_var = malloc(sizeof(NC_VAR_HDF4_INFO_T)))) + return NC_ENOMEM; - int32 dimsize[MAX_VAR_DIMS]; - */ - size_t var_type_size; - int a; - char name[NC_MAX_HDF4_NAME+1]; + /* Remember these values. */ + hdf4_var->hdf4_data_type = data_type; + hdf4_var->sdsid = sdsid; - /* Open this dataset in HDF4 file. */ - if ((sdsid = SDselect(h5->sdid, v)) == FAIL) - {retval = NC_EVARMETA; goto fail;} + /* Add a variable to metadata structures. */ + LOG((3, "adding var for HDF4 dataset %s, rank %d netCDF type %d", name, + rank, xtype)); + retval = nc4_var_list_add_full(h5->root_grp, name, (int)rank, + xtype, endianness, type_size, type_name, + fill_value, contiguous, chunksizes, hdf4_var, + &var); - /* Invoke SDgetInfo with null dimsize to get rank. */ - if (SDgetinfo(sdsid, name, &rank, NULL, &data_type, &num_atts)) - {retval = NC_EVARMETA; goto fail;} + /* Free resources. */ + if (chunksizes) + free(chunksizes); + if (fill_value) + free(fill_value); - if(!(dimsize = (int32*)malloc(sizeof(int32)*rank))) - {retval = NC_ENOMEM; goto fail;} + /* Did the add fail? */ + if (retval) + { + free(hdf4_var); + return retval; + } - if (SDgetinfo(sdsid, name, &rank, dimsize, &data_type, &num_atts)) - {retval = NC_EVARMETA; goto fail;} - - /* Add a variable. */ - if ((retval = nc4_var_list_add(grp,name,rank,&var))) + /* Find the variable's dimensions. */ + for (d = 0; d < var->ndims; d++) + if ((retval = hdf4_read_dim(h5, var, rec_dim_len, d))) return retval; - var->created = NC_TRUE; - var->written_to = NC_TRUE; - var->hdf4_data_type = data_type; - var->sdsid = sdsid; - /* Fill special type_info struct for variable type information. */ - if ((retval = get_netcdf_type_from_hdf4(h5, data_type, NULL, &var->type_info))) - goto fail; - if ((retval = nc4_get_typelen_mem(h5, var->type_info->hdr.id, &var_type_size))) - goto fail; + /* Read the variable's attributes. */ + for (a = 0; a < num_atts; a++) + if ((retval = hdf4_read_att(h5, var, a))) + return retval; - /* Indicate that the variable has a pointer to the type */ - var->type_info->rc++; - - LOG((3, "reading HDF4 dataset %s, rank %d netCDF type %d", var->hdr.name, - rank, var->type_info->hdr.id)); - - /* Get the fill value. */ - if (!(var->fill_value = malloc(var_type_size))) - {retval = NC_ENOMEM; goto fail;} - - if (SDgetfillvalue(var->sdsid, var->fill_value)) - { - /* Whoops! No fill value! */ - free(var->fill_value); - var->fill_value = NULL; - } - - /* Allocate storage for dimension info in this variable. */ - if (var->ndims) - { - if (!(var->dim = malloc(sizeof(NC_DIM_INFO_T *) * var->ndims))) - {retval = NC_ENOMEM; goto fail;} - if (!(var->dimids = malloc(sizeof(int) * var->ndims))) - {retval = NC_ENOMEM; goto fail;} - } - - /* Find its dimensions. */ - for (d = 0; d < var->ndims; d++) - { - int i; - int32 dimid, dim_len, dim_data_type, dim_num_attrs; - char dim_name[NC_MAX_NAME + 1]; - NC_DIM_INFO_T *dim = NULL; - - if ((dimid = SDgetdimid(var->sdsid, d)) == FAIL) - {retval = NC_EDIMMETA; goto fail;} - if (SDdiminfo(dimid, dim_name, &dim_len, &dim_data_type, &dim_num_attrs)) - {retval = NC_EDIMMETA; goto fail;} - if (strlen(dim_name) > NC_MAX_HDF4_NAME) - {retval = NC_EMAXNAME; goto fail;} - - /* Do we already have this dimension? HDF4 explicitly uses - * the name to tell. */ - for(i=0;idim);i++) { - dim = (NC_DIM_INFO_T*)ncindexith(grp->dim,i); - if (!strcmp(dim->hdr.name, dim_name)) - break; - dim = NULL; - } - - /* If we didn't find this dimension, add one. */ - if (!dim) - { - LOG((4, "adding dimension %s for HDF4 dataset %s", - dim_name, var->hdr.name)); - if ((retval = nc4_dim_list_add(grp, dim_name, (dim_len?dim_len:*dimsize), -1, &dim))) - return retval; - } - - /* Tell the variable the id of this dimension. */ - var->dimids[d] = dim->hdr.id; - var->dim[d] = dim; - } - - /* Read the atts. */ - for (a = 0; a < num_atts; a++) - { - int32 att_data_type, att_count; - size_t att_type_size; - char name[NC_MAX_HDF4_NAME+1]; - - /* Learn about this attribute. */ - if (SDattrinfo(var->sdsid, a, name, &att_data_type, &att_count)) - {retval = NC_EATTMETA; goto fail;} - /* Add to the end of the list of atts for this var. */ - if ((retval = nc4_att_list_add(var->att, name, &att))) - goto fail; - att->created = NC_TRUE; - att->len = att_count; - - if ((retval = get_netcdf_type_from_hdf4(h5, att_data_type, &att->nc_typeid, NULL))) - goto fail; - - /* Allocate memory to hold the data. */ - if ((retval = nc4_get_typelen_mem(h5, att->nc_typeid, &att_type_size))) - goto fail; - if (!(att->data = malloc(att_type_size * att->len))) - {retval = NC_ENOMEM; goto fail;} - - /* Read the data. */ - if (SDreadattr(var->sdsid, a, att->data)) - {retval = NC_EHDFERR; goto fail;} - } - if(dimsize) {free(dimsize); dimsize = NULL;} - - { - /* HDF4 files can be chunked */ - HDF_CHUNK_DEF chunkdefs; - int flag; - if(!SDgetchunkinfo(var->sdsid, &chunkdefs, &flag)) { - if(flag == HDF_NONE) - var->contiguous = NC_TRUE; - else if((flag & HDF_CHUNK) != 0) { - var->contiguous = NC_FALSE; - if (!(var->chunksizes = malloc(var->ndims * sizeof(size_t)))) - return NC_ENOMEM; - for (d = 0; d < var->ndims; d++) { - var->chunksizes[d] = chunkdefs.chunk_lengths[d]; - } - } - } - } - } /* next var */ - -#ifdef LOGGING - /* This will print out the names, types, lens, etc of the vars and - atts in the file, if the logging level is 2 or greater. */ - log_metadata_nc(h5->root_grp->nc4_info->controller); -#endif - return retval; - -fail: - if(dimsize) free(dimsize); - if(var) nc4_var_list_del(grp,var); - return retval; + return NC_NOERR; } /** @@ -516,17 +595,22 @@ fail: * @author Ed Hartnett */ int -HDF4_open(const char *path, int mode, int basepe, size_t *chunksizehintp, - int use_parallel, void *parameters, NC_Dispatch *dispatch, - NC *nc_file) +NC_HDF4_open(const char *path, int mode, int basepe, size_t *chunksizehintp, + int use_parallel, void *parameters, NC_Dispatch *dispatch, + NC *nc_file) { - assert(nc_file && path); - - LOG((1, "%s: path %s mode %d params %x", __func__, path, mode, - parameters)); + NC_HDF5_FILE_INFO_T *h5; + NC_HDF4_FILE_INFO_T *hdf4_file; + int32 num_datasets, num_gatts; + int32 sdid; + int v, a; + NC_HDF5_FILE_INFO_T* nc4_info = NULL; + int retval = NC_NOERR; /* Check inputs. */ - assert(path && !use_parallel); + assert(nc_file && path && !use_parallel); + + LOG((1, "%s: path %s mode %d params %x", __func__, path, mode, parameters)); /* Check the mode for validity */ if (mode & ILLEGAL_OPEN_FLAGS) @@ -534,124 +618,69 @@ HDF4_open(const char *path, int mode, int basepe, size_t *chunksizehintp, /* Open the file. */ nc_file->int_ncid = nc_file->ext_ncid; - return nc4_open_hdf4_file(path, mode, nc_file); -} -/** - * @internal Unfortunately HDF only allows specification of fill value - * only when a dataset is created. Whereas in netcdf, you first create - * the variable and then (optionally) specify the fill value. To - * accomplish this in HDF5 I have to delete the dataset, and recreate - * it, with the fill value specified. - * - * @param ncid File and group ID. - * @param fillmode File mode. - * @param old_modep Pointer that gets old mode. Ignored if NULL. - * - * @return ::NC_NOERR No error. - * @author Ed Hartnett -*/ -int -HDF4_set_fill(int ncid, int fillmode, int *old_modep) -{ - return NC_EPERM; -} + /* Open the file and initialize SD interface. */ + if ((sdid = SDstart(path, DFACC_READ)) == FAIL) + return NC_EHDFERR; -/** - * @internal Not allowed for HDF4 files. - * - * @param ncid File and group ID. - * - * @return ::NC_ENOTNC4 No error. - * @author Ed Hartnett -*/ -int -HDF4_redef(int ncid) -{ - return NC_EPERM; -} + /* Learn how many datasets and global atts we have. */ + if (SDfileinfo(sdid, &num_datasets, &num_gatts)) + return NC_EHDFERR; -/** - * @internal This does nothing for HDF4 files. Since they are - * read-only, then can never be put into define mode. - * - * @param ncid File and group ID. - * @param h_minfree Ignored for netCDF-4 files. - * @param v_align Ignored for netCDF-4 files. - * @param v_minfree Ignored for netCDF-4 files. - * @param r_align Ignored for netCDF-4 files. - * - * @return ::NC_NOERR No error. - * @author Ed Hartnett -*/ -int -HDF4__enddef(int ncid, size_t h_minfree, size_t v_align, - size_t v_minfree, size_t r_align) -{ - return NC_NOERR; -} - -/** - * @internal Does nothing, since HDF4 files are read only. There can - * be no changes to sync to disk. - * - * @param ncid File and group ID. - * - * @return ::NC_NOERR No error. - * @author Ed Hartnett -*/ -int -HDF4_sync(int ncid) -{ - return NC_NOERR; -} - -/** - * @internal Closes the file. There can be no changes to abort since - * HDF4 files are read only. - * - * @param ncid File and group ID. - * - * @return ::NC_NOERR No error. - * @author Ed Hartnett - */ -int -HDF4_abort(int ncid) -{ - NC *nc; - NC_HDF5_FILE_INFO_T* nc4_info; - int retval; - - LOG((2, "%s: ncid 0x%x", __func__, ncid)); - - /* Find metadata for this file. */ - if (!(nc = nc4_find_nc_file(ncid, &nc4_info))) - return NC_EBADID; - assert(nc4_info); - - /* Free any resources the netcdf-4 library has for this file's - * metadata. */ - if ((retval = close_hdf4_file(nc4_info, 1))) + /* Add necessary structs to hold netcdf-4 file data. */ + if ((retval = nc4_nc4f_list_add(nc_file, path, mode))) return retval; + nc4_info = NC4_DATA(nc_file); + assert(nc4_info && nc4_info->root_grp); + h5 = nc4_info; + h5->no_write = NC_TRUE; - return NC_NOERR; + /* Allocate data to hold HDF4 specific file data. */ + if (!(hdf4_file = malloc(sizeof(NC_HDF4_FILE_INFO_T)))) + return NC_ENOMEM; + h5->format_file_info = hdf4_file; + hdf4_file->sdid = sdid; + + /* Read the global atts. */ + for (a = 0; a < num_gatts; a++) + if ((retval = hdf4_read_att(h5, NULL, a))) + break; + + /* Read each dataset. */ + if (!retval) + for (v = 0; v < num_datasets; v++) + if ((retval = hdf4_read_var(h5, v))) + break; + + /* If there is an error, free resources. */ + if (retval) + free(hdf4_file); + +#ifdef LOGGING + /* This will print out the names, types, lens, etc of the vars and + atts in the file, if the logging level is 2 or greater. */ + log_metadata_nc(h5->root_grp->nc4_info->controller); +#endif + + return retval; } /** - * @internal Close the HDF4 file. + * @internal Close the HDF4 file. * * @param ncid File ID. * * @return ::NC_NOERR No error. * @return ::NC_EBADID Bad ncid. * @author Ed Hartnett -*/ + */ int -HDF4_close(int ncid) +NC_HDF4_close(int ncid) { NC_GRP_INFO_T *grp; NC *nc; NC_HDF5_FILE_INFO_T *h5; + NC_HDF4_FILE_INFO_T *hdf4_file; int retval; LOG((1, "%s: ncid 0x%x", __func__, ncid)); @@ -661,10 +690,30 @@ HDF4_close(int ncid) return retval; assert(nc && h5 && grp && !grp->parent); - /* Call the nc4 close. */ - if ((retval = close_hdf4_file(grp->nc4_info, 0))) + /* Clean up HDF4 specific allocations. */ + if ((retval = hdf4_rec_grp_del(h5->root_grp))) return retval; + /* Delete all the list contents for vars, dims, and atts, in each + * group. */ + if ((retval = nc4_rec_grp_del(h5->root_grp))) + return retval; + + /* Close hdf4 file and free HDF4 file info. */ + hdf4_file = (NC_HDF4_FILE_INFO_T *)h5->format_file_info; + if (SDend(hdf4_file->sdid)) + return NC_EHDFERR; + free(hdf4_file); + + /* Misc. Cleanup */ + nclistfree(h5->alldims); + nclistfree(h5->allgroups); + nclistfree(h5->alltypes); + + /* Free the nc4_info struct; above code should have reclaimed + everything else */ + free(h5); + return NC_NOERR; } diff --git a/libhdf4/hdf4func.c b/libhdf4/hdf4func.c index f42e84d86..62cc8ca98 100644 --- a/libhdf4/hdf4func.c +++ b/libhdf4/hdf4func.c @@ -1,46 +1,15 @@ /* Copyright 2018, UCAR/Unidata See netcdf/COPYRIGHT file for copying * and redistribution conditions.*/ /** - * @file @internal This file handles the (useless) *_base_pe() - * functions, and the inq_format functions for the HDF4 dispatch - * layer. + * @file @internal HDF4 functions. * * @author Ed Hartnett -*/ + */ +#include "config.h" #include "nc4internal.h" -#include "nc4dispatch.h" - -/** - * @internal This function only does anything for netcdf-3 files. - * - * @param ncid File ID (ignored). - * @param pe Processor element (ignored). - * - * @return ::NC_ENOTNC3 Not a netCDF classic format file. - * @author Ed Hartnett - */ -int -HDF4_set_base_pe(int ncid, int pe) -{ - return NC_ENOTNC3; -} - -/** - * @internal This function only does anything for netcdf-3 files. - * - * @param ncid File ID (ignored). - * @param pe Pointer to processor element. Ignored if NULL. Gets a 0 - * if present. - * - * @return ::NC_ENOTNC3 Not a netCDF classic format file. - * @author Ed Hartnett - */ -int -HDF4_inq_base_pe(int ncid, int *pe) -{ - return NC_ENOTNC3; -} +#include "hdf4dispatch.h" +#include /** * @internal Get the format (i.e. NC_FORMAT_NC_HDF4) of an open HDF4 @@ -54,22 +23,11 @@ HDF4_inq_base_pe(int ncid, int *pe) * @author Ed Hartnett */ int -HDF4_inq_format(int ncid, int *formatp) +NC_HDF4_inq_format(int ncid, int *formatp) { - NC *nc; - NC_HDF5_FILE_INFO_T* nc4_info; - - LOG((2, "nc_inq_format: ncid 0x%x", ncid)); - - if (!formatp) - return NC_NOERR; - - /* Find the file metadata. */ - if (!(nc = nc4_find_nc_file(ncid, &nc4_info))) - return NC_EBADID; - /* HDF4 is the format. */ - *formatp = NC_FORMATX_NC_HDF4; + if (formatp) + *formatp = NC_FORMATX_NC_HDF4; return NC_NOERR; } @@ -78,10 +36,8 @@ HDF4_inq_format(int ncid, int *formatp) * @internal Return the extended format (i.e. the dispatch model), * plus the mode associated with an open file. * - * @param ncid File ID (ignored). - * @param formatp a pointer that gets the extended format. Note that - * this is not the same as the format provided by nc_inq_format(). The - * extended foramt indicates the dispatch layer model. HDF4 files + * @param ncid File ID. + * @param formatp a pointer that gets the extended format. HDF4 files * will always get NC_FORMATX_NC_HDF4. * @param modep a pointer that gets the open/create mode associated with * this file. Ignored if NULL. @@ -91,15 +47,14 @@ HDF4_inq_format(int ncid, int *formatp) * @author Ed Hartnett */ int -HDF4_inq_format_extended(int ncid, int *formatp, int *modep) +NC_HDF4_inq_format_extended(int ncid, int *formatp, int *modep) { NC *nc; NC_HDF5_FILE_INFO_T* h5; LOG((2, "%s: ncid 0x%x", __func__, ncid)); - /* Find the file metadata. */ - if (!(nc = nc4_find_nc_file(ncid,&h5))) + if (!(nc = nc4_find_nc_file(ncid, &h5))) return NC_EBADID; if (modep) diff --git a/libhdf4/hdf4var.c b/libhdf4/hdf4var.c index 6314b187f..e9890bfba 100644 --- a/libhdf4/hdf4var.c +++ b/libhdf4/hdf4var.c @@ -7,343 +7,11 @@ * @author Ed Hartnett */ +#include "config.h" #include +#include "hdf4dispatch.h" #include "nc4dispatch.h" - -/** - * @internal Set chunk cache size for a variable. This is the internal - * function called by nc_set_var_chunk_cache(). - * - * @param ncid File ID. - * @param varid Variable ID. - * @param size Size in bytes to set cache. - * @param nelems Number of elements in cache. - * @param preemption Controls cache swapping. - * - * @returns ::NC_NOERR No error. - * @returns ::NC_EBADID Bad ncid. - * @returns ::NC_ENOTVAR Invalid variable ID. - * @returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3 netcdf-4 file. - * @returns ::NC_EINVAL Invalid input. - * @returns ::NC_EHDFERR HDF5 error. - * @author Ed Hartnett - */ -int -HDF4_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems, - float preemption) -{ - return NC_ENOTNC4; -} - -/** - * @internal This is called by nc_get_var_chunk_cache(). Get chunk - * cache size for a variable. - * - * @param ncid File ID. - * @param varid Variable ID. - * @param sizep Gets size in bytes of cache. - * @param nelemsp Gets number of element slots in cache. - * @param preemptionp Gets cache swapping setting. - * - * @returns ::NC_NOERR No error. - * @returns ::NC_EBADID Bad ncid. - * @returns ::NC_ENOTVAR Invalid variable ID. - * @returns ::NC_ENOTNC4 Not a netCDF-4 file. - * @author Ed Hartnett - */ -int -HDF4_get_var_chunk_cache(int ncid, int varid, size_t *sizep, - size_t *nelemsp, float *preemptionp) -{ - return NC_ENOTNC4; -} - -/** - * @internal Not allowed for HDF4. - * - * @param ncid File ID. - * @param name Name. - * @param xtype Type. - * @param ndims Number of dims. - * @param dimidsp Array of dim IDs. - * @param varidp Gets the var ID. - * - * @returns ::NC_EPERM Not allowed for HDF4. - * @author Ed Hartnett - */ -int -HDF4_def_var(int ncid, const char *name, nc_type xtype, - int ndims, const int *dimidsp, int *varidp) -{ - return NC_EPERM; -} - -/** - * @internal Set compression settings on a variable. This is called by - * nc_def_var_deflate(). - * - * @param ncid File ID. - * @param varid Variable ID. - * @param shuffle True to turn on the shuffle filter. - * @param deflate True to turn on deflation. - * @param deflate_level A number between 0 (no compression) and 9 - * (maximum compression). - * - * @returns ::NC_NOERR No error. - * @returns ::NC_EBADID Bad ncid. - * @returns ::NC_ENOTVAR Invalid variable ID. - * @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is - * not netCDF-4/HDF5. - * @returns ::NC_ELATEDEF Too late to change settings for this variable. - * @returns ::NC_ENOTINDEFINE Not in define mode. - * @returns ::NC_EINVAL Invalid input - * @author Ed Hartnett, Dennis Heimbigner - */ -int -HDF4_def_var_deflate(int ncid, int varid, int shuffle, int deflate, - int deflate_level) -{ - return NC_EPERM; -} - -/** - * @internal Set checksum on a variable. This is called by - * nc_def_var_fletcher32(). - * - * @param ncid File ID. - * @param varid Variable ID. - * @param fletcher32 Pointer to fletcher32 setting. - * - * @returns ::NC_NOERR No error. - * @returns ::NC_EBADID Bad ncid. - * @returns ::NC_ENOTVAR Invalid variable ID. - * @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is - * not netCDF-4/HDF5. - * @returns ::NC_ELATEDEF Too late to change settings for this variable. - * @returns ::NC_ENOTINDEFINE Not in define mode. - * @returns ::NC_EINVAL Invalid input - * @author Ed Hartnett, Dennis Heimbigner - */ -int -HDF4_def_var_fletcher32(int ncid, int varid, int fletcher32) -{ - return NC_ENOTNC4; -} - -/** - * @internal Define chunking stuff for a var. This is called by - * nc_def_var_chunking(). Chunking is required in any dataset with one - * or more unlimited dimensions in HDF5, or any dataset using a - * filter. - * - * @param ncid File ID. - * @param varid Variable ID. - * @param contiguous Pointer to contiguous setting. - * @param chunksizesp Array of chunksizes. - * - * @returns ::NC_NOERR No error. - * @returns ::NC_EBADID Bad ncid. - * @returns ::NC_ENOTVAR Invalid variable ID. - * @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is - * not netCDF-4/HDF5. - * @returns ::NC_ELATEDEF Too late to change settings for this variable. - * @returns ::NC_ENOTINDEFINE Not in define mode. - * @returns ::NC_EINVAL Invalid input - * @returns ::NC_EBADCHUNK Bad chunksize. - * @author Ed Hartnett, Dennis Heimbigner - */ -int -HDF4_def_var_chunking(int ncid, int varid, int contiguous, const size_t *chunksizesp) -{ - return NC_EPERM; -} - -/** - * @internal This functions sets fill value and no_fill mode for a - * netCDF-4 variable. It is called by nc_def_var_fill(). - * - * @note All pointer parameters may be NULL, in which case they are ignored. - * @param ncid File ID. - * @param varid Variable ID. - * @param no_fill No_fill setting. - * @param fill_value Pointer to fill value. - * - * @returns ::NC_NOERR for success - * @returns ::NC_EBADID Bad ncid. - * @returns ::NC_ENOTVAR Invalid variable ID. - * @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is - * not netCDF-4/HDF5. - * @returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3 - * netcdf-4 file. - * @returns ::NC_ELATEDEF Too late to change settings for this variable. - * @returns ::NC_ENOTINDEFINE Not in define mode. - * @returns ::NC_EPERM File is read only. - * @returns ::NC_EINVAL Invalid input - * @author Ed Hartnett - */ -int -HDF4_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value) -{ - return NC_ENOTNC4; -} - -/** - * @internal This functions sets endianness for a netCDF-4 - * variable. Called by nc_def_var_endian(). - * - * @note All pointer parameters may be NULL, in which case they are ignored. - * @param ncid File ID. - * @param varid Variable ID. - * @param endianness Endianness setting. - * - * @returns ::NC_NOERR for success - * @returns ::NC_EBADID Bad ncid. - * @returns ::NC_ENOTVAR Invalid variable ID. - * @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is - * not netCDF-4/HDF5. - * @returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3 - * netcdf-4 file. - * @returns ::NC_ELATEDEF Too late to change settings for this variable. - * @returns ::NC_ENOTINDEFINE Not in define mode. - * @returns ::NC_EPERM File is read only. - * @returns ::NC_EINVAL Invalid input - * @author Ed Hartnett - */ -int -HDF4_def_var_endian(int ncid, int varid, int endianness) -{ - return NC_ENOTNC4; -} - -/** - * @internal Define filter settings. Called by nc_def_var_filter(). - * - * @param ncid File ID. - * @param varid Variable ID. - * @param id Filter ID - * @param nparams Number of parameters for filter. - * @param parms Filter parameters. - * - * @returns ::NC_NOERR for success - * @returns ::NC_EBADID Bad ncid. - * @returns ::NC_ENOTVAR Invalid variable ID. - * @returns ::NC_ENOTNC4 Attempting netcdf-4 operation on file that is - * not netCDF-4/HDF5. - * @returns ::NC_ELATEDEF Too late to change settings for this variable. - * @returns ::NC_EFILTER Filter error. - * @returns ::NC_EINVAL Invalid input - * @author Dennis Heimbigner - */ -int -HDF4_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, - const unsigned int* parms) -{ - return NC_ENOTNC4; -} - -/** - * @internal Not allowed for HDF4. - * - * @param ncid File ID. - * @param varid Variable ID - * @param name New name of the variable. - * - * @returns ::NC_EPERM Not allowed for HDF4. - * @author Ed Hartnett -*/ -int -HDF4_rename_var(int ncid, int varid, const char *name) -{ - return NC_EPERM; -} - -/** - * @internal - * - * This function will change the parallel access of a variable from - * independent to collective. - * - * @param ncid File ID. - * @param varid Variable ID. - * @param par_access NC_COLLECTIVE or NC_INDEPENDENT. - * - * @returns ::NC_NOERR No error. - * @returns ::NC_EBADID Invalid ncid passed. - * @returns ::NC_ENOTVAR Invalid varid passed. - * @returns ::NC_ENOPAR LFile was not opened with nc_open_par/nc_create_var. - * @returns ::NC_EINVAL Invalid par_access specified. - * @returns ::NC_NOERR for success - * @author Ed Hartnett, Dennis Heimbigner - */ -int -HDF4_var_par_access(int ncid, int varid, int par_access) -{ - return NC_ENOTNC4; -} - -/** - * @internal Get data from an HDF4 SD dataset. - * - * @param ncid File ID. - * @param varid Variable ID. - * @param startp Array of start indicies. - * @param countp Array of counts. - * @param mem_nc_type The type of these data after it is read into memory. - * @param is_long Ignored for HDF4. - * @param data pointer that gets the data. - * @returns ::NC_NOERR for success - * @author Ed Hartnett - */ -static int -nc4_get_hdf4_vara(NC *nc, int ncid, int varid, const size_t *startp, - const size_t *countp, nc_type mem_nc_type, int is_long, void *data) -{ - NC_GRP_INFO_T *grp; - NC_HDF5_FILE_INFO_T *h5; - NC_VAR_INFO_T *var; - int32 start32[NC_MAX_VAR_DIMS], edge32[NC_MAX_VAR_DIMS]; - int retval, d; - - /* Find our metadata for this file, group, and var. */ - assert(nc); - if ((retval = nc4_find_g_var_nc(nc, ncid, varid, &grp, &var))) - return retval; - h5 = NC4_DATA(nc); - assert(grp && h5 && var && var->hdr.name); - - for (d = 0; d < var->ndims; d++) - { - start32[d] = startp[d]; - edge32[d] = countp[d]; - } - - if (SDreaddata(var->sdsid, start32, NULL, edge32, data)) - return NC_EHDFERR; - - return NC_NOERR; -} - -/** - * @internal Write an array of data to a variable. This is called by - * nc_put_vara() and other nc_put_vara_* functions, for netCDF-4 - * files. - * - * @param ncid File ID. - * @param varid Variable ID. - * @param startp Array of start indicies. - * @param countp Array of counts. - * @param op pointer that gets the data. - * @param memtype The type of these data in memory. - * - * @returns ::NC_NOERR for success - * @author Ed Hartnett, Dennis Heimbigner - */ -int -HDF4_put_vara(int ncid, int varid, const size_t *startp, - const size_t *countp, const void *op, int memtype) -{ - return NC_EPERM; -} +#include /** * Read an array of values. This is called by nc_get_vara() for @@ -357,23 +25,83 @@ HDF4_put_vara(int ncid, int varid, const size_t *startp, * @param ip pointer that gets the data. * @param memtype The type of these data after it is read into memory. - * @returns ::NC_NOERR for success + * @return ::NC_NOERR for success. + * @return ::NC_EBADID Bad ncid. * @author Ed Hartnett, Dennis Heimbigner */ int -HDF4_get_vara(int ncid, int varid, const size_t *startp, - const size_t *countp, void *ip, int memtype) +NC_HDF4_get_vara(int ncid, int varid, const size_t *startp, + const size_t *countp, void *ip, int memtype) { NC *nc; NC_HDF5_FILE_INFO_T* h5; + NC_GRP_INFO_T *grp; + NC_VAR_HDF4_INFO_T *hdf4_var; + NC_VAR_INFO_T *var; + int32 start32[NC_MAX_VAR_DIMS], edge32[NC_MAX_VAR_DIMS]; + size_t nelem = 1; + void *data; + int retval, d; + int range_error; LOG((2, "%s: ncid 0x%x varid %d memtype %d", __func__, ncid, varid, memtype)); + /* No scalars in HDF4 SD API. Caller must also provide place to put + * data. */ + if (!startp || !countp || !ip) + return NC_EINVAL; + + /* Find file info. */ if (!(nc = nc4_find_nc_file(ncid, &h5))) return NC_EBADID; + + /* Find our metadata for this file, group, and var. */ + if ((retval = nc4_find_g_var_nc(nc, ncid, varid, &grp, &var))) + return retval; - /* Handle HDF4 cases. */ - return nc4_get_hdf4_vara(nc, ncid, varid, startp, countp, memtype, - 0, (void *)ip); + assert(grp && var && var->hdr.name && var->format_var_info); + + /* Get the HDF4 specific var metadata. */ + hdf4_var = (NC_VAR_HDF4_INFO_T *)var->format_var_info; + + h5 = NC4_DATA(nc); + assert(h5); + + /* Convert starts/edges to the int32 type HDF4 wants. Also learn + * how many elements of data are being read. */ + for (d = 0; d < var->ndims; d++) + { + start32[d] = startp[d]; + edge32[d] = countp[d]; + nelem *= countp[d]; + } + + /* If memtype was not give, use variable type. */ + if (memtype == NC_NAT) + memtype = var->type_info->hdr.id; + + /* If we need to convert data, allocate temp storage. */ + if (var->type_info->hdr.id == memtype) + data = ip; + else + if (!(data = malloc(var->type_info->size * nelem))) + return NC_ENOMEM; + + /* Read the data with HDF4. */ + if (SDreaddata(hdf4_var->sdsid, start32, NULL, edge32, data)) + return NC_EHDFERR; + + /* Do we need to convert data? */ + if (var->type_info->hdr.id != memtype) + { + if ((retval = nc4_convert_type(data, ip, var->type_info->hdr.id, memtype, nelem, + &range_error, NULL, 0, 0, 0))) + return retval; + free(data); + if (range_error) + return range_error; + } + + return NC_NOERR; } diff --git a/liblib/nc_initialize.c b/liblib/nc_initialize.c index de47c0cab..9f90b3cca 100644 --- a/liblib/nc_initialize.c +++ b/liblib/nc_initialize.c @@ -36,8 +36,8 @@ extern int NCP_finalize(void); #endif #ifdef USE_HDF4 -extern int HDF4_initialize(void); -extern int HDF4_finalize(void); +extern int NC_HDF4_initialize(void); +extern int NC_HDF4_finalize(void); #endif #ifdef _MSC_VER @@ -89,7 +89,7 @@ nc_initialize() if((stat = NCP_initialize())) goto done; #endif #ifdef USE_HDF4 - if((stat = HDF4_initialize())) goto done; + if((stat = NC_HDF4_initialize())) goto done; #endif #ifdef USE_NETCDF4 if((stat = NC4_initialize())) goto done; @@ -131,6 +131,10 @@ nc_finalize(void) if((stat = NCP_finalize())) return stat; #endif +#ifdef USE_HDF4 + if((stat = NC_HDF4_finalize())) return stat; +#endif /* USE_HDF4 */ + #ifdef USE_NETCDF4 if((stat = NC4_finalize())) return stat; #endif /* USE_NETCDF4 */ diff --git a/libsrcp/ncpdispatch.c b/libsrcp/ncpdispatch.c index 92b324c58..8bd2a5f7c 100644 --- a/libsrcp/ncpdispatch.c +++ b/libsrcp/ncpdispatch.c @@ -1381,138 +1381,6 @@ NCP_inq_user_type(int ncid, nc_type typeid, char *name, size_t *size, return NC_ENOTNC4; } -static int -NCP_def_compound(int ncid, size_t size, const char *name, nc_type *typeidp) -{ - return NC_ENOTNC4; -} - -static int -NCP_insert_compound(int ncid, nc_type typeid, const char *name, size_t offset, - nc_type field_typeid) -{ - return NC_ENOTNC4; -} - -static int -NCP_insert_array_compound(int ncid, nc_type typeid, const char *name, - size_t offset, nc_type field_typeid, - int ndims, const int *dim_sizes) -{ - return NC_ENOTNC4; -} - - -static int -NCP_inq_compound_field(int ncid, nc_type typeid, int fieldid, char *name, - size_t *offsetp, nc_type *field_typeidp, int *ndimsp, - int *dim_sizesp) -{ - return NC_ENOTNC4; -} - -static int -NCP_inq_compound_fieldindex(int ncid, nc_type typeid, const char *name, int *fieldidp) -{ - return NC_ENOTNC4; -} - -static int -NCP_def_opaque(int ncid, size_t datum_size, const char *name, nc_type* xtypep) -{ - return NC_ENOTNC4; -} - -static int -NCP_def_vlen(int ncid, const char *name, nc_type base_typeid, nc_type* xtypep) -{ - return NC_ENOTNC4; -} - -static int -NCP_def_enum(int ncid, nc_type base_typeid, const char *name, - nc_type *typeidp) -{ - return NC_ENOTNC4; -} - -static int -NCP_inq_enum_ident(int ncid, nc_type xtype, long long value, char *identifier) -{ - return NC_ENOTNC4; -} - -static int -NCP_inq_enum_member(int ncid, nc_type typeid, int idx, char *identifier, - void *value) -{ - return NC_ENOTNC4; -} - -static int -NCP_insert_enum(int ncid, nc_type typeid, const char *identifier, - const void *value) -{ - return NC_ENOTNC4; -} - -static int -NCP_put_vlen_element(int ncid, int typeid, void *vlen_element, - size_t len, const void *data) -{ - return NC_ENOTNC4; -} - -static int -NCP_get_vlen_element(int ncid, int typeid, const void *vlen_element, - size_t *len, void *data) -{ - return NC_ENOTNC4; -} - -static int -NCP_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems, float preemption) -{ - return NC_ENOTNC4; -} - -static int -NCP_get_var_chunk_cache(int ncid, int varid, size_t *sizep, size_t *nelemsp, float *preemptionp) -{ - return NC_ENOTNC4; -} - -static int -NCP_def_var_deflate(int ncid, int varid, int shuffle, int deflate, - int deflate_level) -{ - return NC_ENOTNC4; -} - -static int -NCP_def_var_fletcher32(int ncid, int varid, int fletcher32) -{ - return NC_ENOTNC4; -} - -static int -NCP_def_var_chunking(int ncid, int varid, int contiguous, const size_t *chunksizesp) -{ - return NC_ENOTNC4; -} - -static int -NCP_def_var_endian(int ncid, int varid, int endianness) -{ - return NC_ENOTNC4; -} - -static int -NCP_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int* parms) -{ - return NC_ENOTNC4; -} - #endif /*USE_NETCDF4*/ /**************************************************/ @@ -1587,26 +1455,26 @@ NCP_rename_grp, NCP_inq_user_type, NCP_inq_typeid, -NCP_def_compound, -NCP_insert_compound, -NCP_insert_array_compound, -NCP_inq_compound_field, -NCP_inq_compound_fieldindex, -NCP_def_vlen, -NCP_put_vlen_element, -NCP_get_vlen_element, -NCP_def_enum, -NCP_insert_enum, -NCP_inq_enum_member, -NCP_inq_enum_ident, -NCP_def_opaque, -NCP_def_var_deflate, -NCP_def_var_fletcher32, -NCP_def_var_chunking, -NCP_def_var_endian, -NCP_def_var_filter, -NCP_set_var_chunk_cache, -NCP_get_var_chunk_cache, +NC_NOTNC4_def_compound, +NC_NOTNC4_insert_compound, +NC_NOTNC4_insert_array_compound, +NC_NOTNC4_inq_compound_field, +NC_NOTNC4_inq_compound_fieldindex, +NC_NOTNC4_def_vlen, +NC_NOTNC4_put_vlen_element, +NC_NOTNC4_get_vlen_element, +NC_NOTNC4_def_enum, +NC_NOTNC4_insert_enum, +NC_NOTNC4_inq_enum_member, +NC_NOTNC4_inq_enum_ident, +NC_NOTNC4_def_opaque, +NC_NOTNC4_def_var_deflate, +NC_NOTNC4_def_var_fletcher32, +NC_NOTNC4_def_var_chunking, +NC_NOTNC4_def_var_endian, +NC_NOTNC4_def_var_filter, +NC_NOTNC4_set_var_chunk_cache, +NC_NOTNC4_get_var_chunk_cache, #endif /*USE_NETCDF4*/ };