19#include "nc4internal.h" 
   20#include "ncdispatch.h" 
   21#include "hdf5internal.h" 
   28#define __STDC_FORMAT_MACROS 
   32#define NC_HDF5_MAX_NAME 1024  
   43flag_atts_dirty(NCindex *attlist) {
 
   45    NC_ATT_INFO_T *att = NULL;
 
   51    for(
size_t i=0;i<ncindexsize(attlist);i++) {
 
   52        att = (NC_ATT_INFO_T*)ncindexith(attlist,i);
 
   53        if(att == NULL) 
continue;
 
   77rec_reattach_scales(NC_GRP_INFO_T *grp, 
int dimid, hid_t dimscaleid)
 
   80    NC_GRP_INFO_T *child_grp;
 
   84    assert(grp && grp->hdr.name && dimid >= 0 && dimscaleid >= 0);
 
   85    LOG((3, 
"%s: grp->hdr.name %s", __func__, grp->hdr.name));
 
   88    for (i = 0; i < ncindexsize(grp->children); i++)
 
   90        child_grp = (NC_GRP_INFO_T*)ncindexith(grp->children, i);
 
   92        if ((retval = rec_reattach_scales(child_grp, dimid, dimscaleid)))
 
   97    for (i = 0; i < ncindexsize(grp->vars); i++)
 
   99        NC_HDF5_VAR_INFO_T *hdf5_var;
 
  101        var = (NC_VAR_INFO_T*)ncindexith(grp->vars,i);
 
  102        assert(var && var->format_var_info);
 
  104    hdf5_var = (NC_HDF5_VAR_INFO_T*)var->format_var_info;   
 
  105    assert(hdf5_var != NULL);
 
  106        for (
unsigned int d = 0; d < var->ndims; d++)
 
  108            if (var->dimids[d] == dimid && !hdf5_var->dimscale)
 
  110                LOG((2, 
"%s: attaching scale for dimid %d to var %s",
 
  111                     __func__, var->dimids[d], var->hdr.name));
 
  114                    if (H5DSattach_scale(hdf5_var->hdf_datasetid,
 
  117                    hdf5_var->dimscale_attached[d] = NC_TRUE;
 
  142rec_detach_scales(NC_GRP_INFO_T *grp, 
int dimid, hid_t dimscaleid)
 
  145    NC_GRP_INFO_T *child_grp;
 
  149    assert(grp && grp->hdr.name && dimid >= 0 && dimscaleid >= 0);
 
  150    LOG((3, 
"%s: grp->hdr.name %s", __func__, grp->hdr.name));
 
  153    for(i=0;i<ncindexsize(grp->children);i++) {
 
  154        child_grp = (NC_GRP_INFO_T*)ncindexith(grp->children,i);
 
  155        if(child_grp == NULL) 
continue;
 
  156        if ((retval = rec_detach_scales(child_grp, dimid, dimscaleid)))
 
  161    for (i = 0; i < ncindexsize(grp->vars); i++)
 
  163        NC_HDF5_VAR_INFO_T *hdf5_var;
 
  164        var = (NC_VAR_INFO_T*)ncindexith(grp->vars, i);
 
  165        assert(var && var->format_var_info);
 
  166        hdf5_var = (NC_HDF5_VAR_INFO_T *)var->format_var_info;
 
  168        for (
unsigned int d = 0; d < var->ndims; d++)
 
  170            if (var->dimids[d] == dimid && !hdf5_var->dimscale)
 
  172                LOG((2, 
"%s: detaching scale for dimid %d to var %s",
 
  173                     __func__, var->dimids[d], var->hdr.name));
 
  176                    if (hdf5_var->dimscale_attached && hdf5_var->dimscale_attached[d])
 
  178                        if (H5DSdetach_scale(hdf5_var->hdf_datasetid,
 
  181                        hdf5_var->dimscale_attached[d] = NC_FALSE;
 
  202nc4_open_var_grp2(NC_GRP_INFO_T *grp, 
int varid, hid_t *dataset)
 
  205    NC_HDF5_VAR_INFO_T *hdf5_var;
 
  207    assert(grp && grp->format_grp_info && dataset);
 
  210    if (!(var = (NC_VAR_INFO_T *)ncindexith(grp->vars, (
size_t)varid)))
 
  212    assert(var && var->hdr.id == varid && var->format_var_info);
 
  213    hdf5_var = (NC_HDF5_VAR_INFO_T *)var->format_var_info;
 
  216    if (!hdf5_var->hdf_datasetid)
 
  218        NC_HDF5_GRP_INFO_T *hdf5_grp;
 
  219        hdf5_grp = (NC_HDF5_GRP_INFO_T *)grp->format_grp_info;
 
  221        if ((hdf5_var->hdf_datasetid = H5Dopen2(hdf5_grp->hdf_grpid,
 
  222                                                var->hdr.name, H5P_DEFAULT)) < 0)
 
  226    *dataset = hdf5_var->hdf_datasetid;
 
  249nc4_get_hdf_typeid(NC_FILE_INFO_T *h5, 
nc_type xtype,
 
  250                   hid_t *hdf_typeid, 
int endianness)
 
  252    NC_TYPE_INFO_T *type;
 
  256    assert(hdf_typeid && h5);
 
  268            if ((
typeid = H5Tcopy(H5T_C_S1)) < 0)
 
  270            if (H5Tset_strpad(
typeid, H5T_STR_NULLTERM) < 0)
 
  272            if(H5Tset_cset(
typeid, H5T_CSET_ASCII) < 0)
 
  276            *hdf_typeid = 
typeid;
 
  281            if ((
typeid = H5Tcopy(H5T_C_S1)) < 0)
 
  283            if (H5Tset_size(
typeid, H5T_VARIABLE) < 0)
 
  285            if(H5Tset_cset(
typeid, H5T_CSET_UTF8) < 0)
 
  289            *hdf_typeid = 
typeid;
 
  300                typeid = H5T_STD_I8LE;
 
  302                typeid = H5T_STD_I8BE;
 
  304                typeid = H5T_NATIVE_SCHAR;
 
  309                typeid = H5T_STD_I16LE;
 
  311                typeid = H5T_STD_I16BE;
 
  313                typeid = H5T_NATIVE_SHORT;
 
  318                typeid = H5T_STD_I32LE;
 
  320                typeid = H5T_STD_I32BE;
 
  322                typeid = H5T_NATIVE_INT;
 
  327                typeid = H5T_STD_U8LE;
 
  329                typeid = H5T_STD_U8BE;
 
  331                typeid = H5T_NATIVE_UCHAR;
 
  336                typeid = H5T_STD_U16LE;
 
  338                typeid = H5T_STD_U16BE;
 
  340                typeid = H5T_NATIVE_USHORT;
 
  345                typeid = H5T_STD_U32LE;
 
  347                typeid = H5T_STD_U32BE;
 
  349                typeid = H5T_NATIVE_UINT;
 
  354                typeid = H5T_STD_I64LE;
 
  356                typeid = H5T_STD_I64BE;
 
  358                typeid = H5T_NATIVE_LLONG;
 
  363                typeid = H5T_STD_U64LE;
 
  365                typeid = H5T_STD_U64BE;
 
  367                typeid = H5T_NATIVE_ULLONG;
 
  372                typeid = H5T_IEEE_F32LE;
 
  374                typeid = H5T_IEEE_F32BE;
 
  376                typeid = H5T_NATIVE_FLOAT;
 
  381                typeid = H5T_IEEE_F64LE;
 
  383                typeid = H5T_IEEE_F64BE;
 
  385                typeid = H5T_NATIVE_DOUBLE;
 
  390            if (nc4_find_type(h5, xtype, &type))
 
  394            typeid = ((NC_HDF5_TYPE_INFO_T *)type->format_type_info)->hdf_typeid;
 
  400        if ((*hdf_typeid = H5Tcopy(
typeid)) < 0)
 
  404    assert(*hdf_typeid != -1);
 
  407    if (
typeid > 0 && H5Tclose(
typeid) < 0)
 
  427put_att_grpa(NC_GRP_INFO_T *grp, 
int varid, NC_ATT_INFO_T *att)
 
  429    NC_HDF5_GRP_INFO_T *hdf5_grp;
 
  430    hid_t datasetid = 0, locid;
 
  431    hid_t attid = 0, spaceid = 0, file_typeid = 0;
 
  432    hid_t existing_att_typeid = 0, existing_attid = 0, existing_spaceid = 0;
 
  436    int phoney_data = 99;
 
  439    assert(att->hdr.name && grp && grp->format_grp_info);
 
  440    LOG((3, 
"%s: varid %d att->hdr.id %d att->hdr.name %s att->nc_typeid %d " 
  441         "att->len %d", __func__, varid, att->hdr.id, att->hdr.name,
 
  442         att->nc_typeid, att->len));
 
  445    hdf5_grp = (NC_HDF5_GRP_INFO_T *)grp->format_grp_info;
 
  448    if (grp->nc4_info->no_write)
 
  453        locid = hdf5_grp->hdf_grpid;
 
  456        if ((retval = nc4_open_var_grp2(grp, varid, &datasetid)))
 
  463    dims[0] = (hsize_t)att->len;
 
  464    if ((retval = nc4_get_hdf_typeid(grp->nc4_info, att->nc_typeid,
 
  483        size_t string_size = dims[0];
 
  487            if ((spaceid = H5Screate(H5S_NULL)) < 0)
 
  492            if ((spaceid = H5Screate(H5S_SCALAR)) < 0)
 
  495        if (H5Tset_size(file_typeid, string_size) < 0)
 
  497        if (H5Tset_strpad(file_typeid, H5T_STR_NULLTERM) < 0)
 
  504            if ((spaceid = H5Screate(H5S_NULL)) < 0)
 
  509            if ((spaceid = H5Screate_simple(1, dims, NULL)) < 0)
 
  515    if ((attr_exists = H5Aexists(locid, att->hdr.name)) < 0)
 
  522        if ((existing_attid = H5Aopen(locid, att->hdr.name, H5P_DEFAULT)) < 0)
 
  526        if ((existing_att_typeid = H5Aget_type(existing_attid)) < 0)
 
  530        if ((existing_spaceid = H5Aget_space(existing_attid)) < 0)
 
  532        if ((npoints = H5Sget_simple_extent_npoints(existing_spaceid)) < 0)
 
  537        if (!H5Tequal(file_typeid, existing_att_typeid) ||
 
  538            (att->nc_typeid != 
NC_CHAR && npoints != att->len))
 
  543            if (H5Adelete(locid, att->hdr.name) < 0)
 
  548            if ((attid = H5Acreate1(locid, att->hdr.name, file_typeid, spaceid,
 
  553            if (H5Awrite(attid, file_typeid, data) < 0)
 
  561            if (H5Awrite(existing_attid, file_typeid, data) < 0)
 
  570        if ((attid = H5Acreate1(locid, att->hdr.name, file_typeid, spaceid,
 
  575        if (H5Awrite(attid, file_typeid, data) < 0)
 
  580    if (file_typeid && H5Tclose(file_typeid))
 
  582    if (attid > 0 && H5Aclose(attid) < 0)
 
  584    if (existing_att_typeid && H5Tclose(existing_att_typeid))
 
  586    if (existing_attid > 0 && H5Aclose(existing_attid) < 0)
 
  588    if (spaceid > 0 && H5Sclose(spaceid) < 0)
 
  590    if (existing_spaceid > 0 && H5Sclose(existing_spaceid) < 0)
 
  607write_attlist(NCindex *attlist, 
int varid, NC_GRP_INFO_T *grp)
 
  612    for(
size_t i = 0; i < ncindexsize(attlist); i++)
 
  614        att = (NC_ATT_INFO_T *)ncindexith(attlist, i);
 
  618            LOG((4, 
"%s: writing att %s to varid %d", __func__, att->hdr.name, varid));
 
  619            if ((retval = put_att_grpa(grp, varid, att)))
 
  621            att->dirty = NC_FALSE;
 
  622            att->created = NC_TRUE;
 
  642write_coord_dimids(NC_VAR_INFO_T *var)
 
  644    NC_HDF5_VAR_INFO_T *hdf5_var;
 
  645    hsize_t coords_len[1];
 
  646    hid_t c_spaceid = -1, c_attid = -1;
 
  649    assert(var && var->format_var_info);
 
  652    hdf5_var = (NC_HDF5_VAR_INFO_T *)var->format_var_info;
 
  655    coords_len[0] = var->ndims;
 
  656    if ((c_spaceid = H5Screate_simple(1, coords_len, coords_len)) < 0)
 
  660    if ((c_attid = H5Acreate1(hdf5_var->hdf_datasetid, COORDINATES,
 
  661                             H5T_NATIVE_INT, c_spaceid, H5P_DEFAULT)) < 0)
 
  665    if (H5Awrite(c_attid, H5T_NATIVE_INT, var->dimids) < 0)
 
  669    if (c_spaceid >= 0 && H5Sclose(c_spaceid) < 0)
 
  671    if (c_attid >= 0 && H5Aclose(c_attid) < 0)
 
  687write_quantize_att(NC_VAR_INFO_T *var)
 
  689    NC_HDF5_VAR_INFO_T *hdf5_var;
 
  691    hid_t c_spaceid = -1, c_attid = -1;
 
  695    assert(var && var->format_var_info);
 
  698    hdf5_var = (NC_HDF5_VAR_INFO_T *)var->format_var_info;
 
  701    switch (var->quantize_mode)
 
  717    if ((c_spaceid = H5Screate_simple(1, &len, &len)) < 0)
 
  721    if ((c_attid = H5Acreate1(hdf5_var->hdf_datasetid, att_name,
 
  722                             H5T_NATIVE_INT, c_spaceid, H5P_DEFAULT)) < 0)
 
  726    if (H5Awrite(c_attid, H5T_NATIVE_INT, &var->nsd) < 0)
 
  730    if (c_spaceid >= 0 && H5Sclose(c_spaceid) < 0)
 
  732    if (c_attid >= 0 && H5Aclose(c_attid) < 0)
 
  748write_netcdf4_dimid(hid_t datasetid, 
int dimid)
 
  750    hid_t dimid_spaceid = -1, dimid_attid = -1;
 
  755    if ((dimid_spaceid = H5Screate(H5S_SCALAR)) < 0)
 
  759    if ((attr_exists = H5Aexists(datasetid, NC_DIMID_ATT_NAME)) < 0)
 
  762        dimid_attid = H5Aopen_by_name(datasetid, 
".", NC_DIMID_ATT_NAME,
 
  763                                      H5P_DEFAULT, H5P_DEFAULT);
 
  766        dimid_attid = H5Acreate1(datasetid, NC_DIMID_ATT_NAME,
 
  767                                H5T_NATIVE_INT, dimid_spaceid, H5P_DEFAULT);
 
  773    LOG((4, 
"%s: writing secret dimid %d", __func__, dimid));
 
  774    if (H5Awrite(dimid_attid, H5T_NATIVE_INT, &dimid) < 0)
 
  779    if (dimid_spaceid >= 0 && H5Sclose(dimid_spaceid) < 0)
 
  781    if (dimid_attid >= 0 && H5Aclose(dimid_attid) < 0)
 
  802var_create_dataset(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, nc_bool_t write_dimid)
 
  804    NC_HDF5_GRP_INFO_T *hdf5_grp;
 
  805    NC_HDF5_VAR_INFO_T *hdf5_var;
 
  806    hid_t plistid = 0, access_plistid = 0, 
typeid = 0, spaceid = 0;
 
  807    hsize_t chunksize[H5S_MAX_RANK], dimsize[H5S_MAX_RANK], maxdimsize[H5S_MAX_RANK];
 
  810    NC_DIM_INFO_T *dim = NULL;
 
  813    unsigned int* params = NULL;
 
  815    assert(grp && grp->format_grp_info && var && var->format_var_info);
 
  817    LOG((3, 
"%s:: name %s", __func__, var->hdr.name));
 
  820    hdf5_grp = (NC_HDF5_GRP_INFO_T *)grp->format_grp_info;
 
  821    hdf5_var = (NC_HDF5_VAR_INFO_T *)var->format_var_info;
 
  824    if ((plistid = H5Pcreate(H5P_DATASET_CREATE)) < 0)
 
  826    if ((access_plistid = H5Pcreate(H5P_DATASET_ACCESS)) < 0)
 
  830    if (H5Pset_obj_track_times(plistid, 0) < 0)
 
  834    if ((retval = nc4_get_hdf_typeid(grp->nc4_info, var->type_info->hdr.id, &
typeid,
 
  835                                     var->type_info->endianness)))
 
  842        if (H5Pset_fill_time(plistid, H5D_FILL_TIME_NEVER) < 0)
 
  847        if ((retval = nc4_get_fill_value(grp->nc4_info, var, &fillp)))
 
  853            if (var->type_info->nc_type_class == 
NC_STRING)
 
  855                if (H5Pset_fill_value(plistid, 
typeid, fillp) < 0)
 
  864                hid_t fill_typeid = 0;
 
  866                if ((retval = nc4_get_hdf_typeid(grp->nc4_info, var->type_info->hdr.id, &fill_typeid,
 
  869                if (H5Pset_fill_value(plistid, fill_typeid, fillp) < 0)
 
  871                    if (H5Tclose(fill_typeid) < 0)
 
  875                if (H5Tclose(fill_typeid) < 0)
 
  887    if(var->filters != NULL) {
 
  889    NClist* filters = (NClist*)var->filters;
 
  890    for(j=0;j<nclistlength(filters);j++) {
 
  891        struct NC_HDF5_Filter* fi = (
struct NC_HDF5_Filter*)nclistget(filters,j);
 
  892        if(fi->filterid == H5Z_FILTER_FLETCHER32) {
 
  893            if(H5Pset_fletcher32(plistid) < 0)
 
  895        } 
else if(fi->filterid == H5Z_FILTER_SHUFFLE) {
 
  896            if(H5Pset_shuffle(plistid) < 0)
 
  898            } 
else if(fi->filterid == H5Z_FILTER_DEFLATE) {
 
  901                unsigned int level = fi->params[0];
 
  902                if(H5Pset_deflate(plistid, level) < 0)
 
  904            } 
else if(fi->filterid == H5Z_FILTER_SZIP) {
 
  907                unsigned int options_mask = fi->params[0];
 
  908                unsigned int bits_per_pixel = fi->params[1];
 
  909                if(H5Pset_szip(plistid, options_mask, bits_per_pixel) < 0)
 
  912                herr_t code = H5Pset_filter(plistid, fi->filterid,
 
  914                                           fi->nparams, fi->params);
 
  930        for (d = 0; d < var->ndims; d++) {
 
  932            assert(dim && dim->hdr.id == var->dimids[d]);
 
  940        if (nclistlength((NClist*)var->filters) == 0 &&
 
  941            (var->chunksizes == NULL || !var->chunksizes[0]) && !unlimdim)
 
  946        for (d = 0; d < var->ndims; d++)
 
  949            assert(dim && dim->hdr.id == var->dimids[d]);
 
  950            dimsize[d] = dim->unlimited ? NC_HDF5_UNLIMITED_DIMSIZE : dim->len;
 
  951            maxdimsize[d] = dim->unlimited ? H5S_UNLIMITED : (hsize_t)dim->len;
 
  954                if (var->chunksizes[d])
 
  955                    chunksize[d] = var->chunksizes[d];
 
  959                    if (var->type_info->nc_type_class == 
NC_STRING)
 
  960                        type_size = 
sizeof(
char *);
 
  962                        type_size = var->type_info->size;
 
  968                        chunksize[d] = (hsize_t)pow(DEFAULT_CHUNK_SIZE/(
double)type_size,
 
  969                                                    1/(
double)((
int)var->ndims - unlimdim));
 
  973                    if (!dim->unlimited && chunksize[d] > dim->len)
 
  974                        chunksize[d] = dim->len;
 
  977                    var->chunksizes[d] = chunksize[d];
 
  983        if ((spaceid = H5Screate_simple((
int)var->ndims, dimsize, maxdimsize)) < 0)
 
  988        if ((spaceid = H5Screate(H5S_SCALAR)) < 0)
 
  997        if (H5Pset_layout(plistid, H5D_CONTIGUOUS) < 0)
 
 1002        if (H5Pset_layout(plistid, H5D_COMPACT) < 0)
 
 1005    else if (var->ndims)
 
 1007        if (H5Pset_chunk(plistid, (
int)var->ndims, chunksize) < 0)
 
 1012    if (!grp->nc4_info->no_attr_create_order) {
 
 1013      if (H5Pset_attr_creation_order(plistid, H5P_CRT_ORDER_TRACKED|
 
 1014                     H5P_CRT_ORDER_INDEXED) < 0)
 
 1019    if (var->storage == 
NC_CHUNKED && var->chunkcache.size)
 
 1020        if (H5Pset_chunk_cache(access_plistid, var->chunkcache.nelems,
 
 1021                               var->chunkcache.size, var->chunkcache.preemption) < 0)
 
 1025    name_to_use = var->alt_name ? var->alt_name : var->hdr.name;
 
 1026    LOG((4, 
"%s: about to H5Dcreate2 dataset %s of type 0x%x", __func__,
 
 1027         name_to_use, 
typeid));
 
 1028    if ((hdf5_var->hdf_datasetid = H5Dcreate2(hdf5_grp->hdf_grpid, name_to_use, 
typeid,
 
 1029                                              spaceid, H5P_DEFAULT, plistid, access_plistid)) < 0)
 
 1031    var->created = NC_TRUE;
 
 1032    var->is_new_var = NC_FALSE;
 
 1038        if ((retval = write_coord_dimids(var)))
 
 1044    if (hdf5_var->dimscale)
 
 1046        if (H5DSset_scale(hdf5_var->hdf_datasetid, var->hdr.name) < 0)
 
 1057            if ((retval = write_netcdf4_dimid(hdf5_var->hdf_datasetid, var->dimids[0])))
 
 1065    if (var->quantize_mode)
 
 1066    if ((retval = write_quantize_att(var)))
 
 1070    if ((retval = write_attlist(var->att, var->hdr.id, grp)))
 
 1074    var->attr_dirty = NC_FALSE;
 
 1078    if (
typeid > 0 && H5Tclose(
typeid) < 0)
 
 1080    if (plistid > 0 && H5Pclose(plistid) < 0)
 
 1082    if (access_plistid > 0 && H5Pclose(access_plistid) < 0)
 
 1084    if (spaceid > 0 && H5Sclose(spaceid) < 0)
 
 1088        if (var->type_info->nc_type_class == 
NC_VLEN)
 
 1090        else if (var->type_info->nc_type_class == 
NC_STRING && *(
char **)fillp)
 
 1091            free(*(
char **)fillp);
 
 1112nc4_adjust_var_cache(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
 
 1114    size_t chunk_size_bytes = 1;
 
 1124    if (grp->nc4_info->parallel)
 
 1129    for (d = 0; d < var->ndims; d++)
 
 1130        chunk_size_bytes *= var->chunksizes[d];
 
 1131    if (var->type_info->size)
 
 1132        chunk_size_bytes *= var->type_info->size;
 
 1134        chunk_size_bytes *= 
sizeof(
char *);
 
 1139    if (var->chunkcache.size == CHUNK_CACHE_SIZE)
 
 1140        if (chunk_size_bytes > var->chunkcache.size)
 
 1142            var->chunkcache.size = chunk_size_bytes * DEFAULT_CHUNKS_IN_CACHE;
 
 1143            if (var->chunkcache.size > DEFAULT_CHUNK_CACHE_SIZE)
 
 1144                var->chunkcache.size = DEFAULT_CHUNK_CACHE_SIZE;
 
 1145            if ((retval = nc4_reopen_dataset(grp, var)))
 
 1168commit_type(NC_GRP_INFO_T *grp, NC_TYPE_INFO_T *type)
 
 1170    NC_HDF5_GRP_INFO_T *hdf5_grp;
 
 1171    NC_HDF5_TYPE_INFO_T *hdf5_type;
 
 1172    hid_t base_hdf_typeid;
 
 1175    assert(grp && grp->format_grp_info && type && type->format_type_info);
 
 1178    hdf5_grp = (NC_HDF5_GRP_INFO_T *)grp->format_grp_info;
 
 1179    hdf5_type = (NC_HDF5_TYPE_INFO_T *)type->format_type_info;
 
 1182    if (type->committed)
 
 1188        NC_FIELD_INFO_T *field;
 
 1189        hid_t hdf_base_typeid, hdf_typeid;
 
 1192        if ((hdf5_type->hdf_typeid = H5Tcreate(H5T_COMPOUND, type->size)) < 0)
 
 1194        LOG((4, 
"creating compound type %s hdf_typeid 0x%x", type->hdr.name,
 
 1195             hdf5_type->hdf_typeid));
 
 1197        for(i=0;i<nclistlength(type->u.c.field);i++)
 
 1199            field = (NC_FIELD_INFO_T *)nclistget(type->u.c.field, i);
 
 1201            if ((retval = nc4_get_hdf_typeid(grp->nc4_info, field->nc_typeid,
 
 1202                                             &hdf_base_typeid, type->endianness)))
 
 1211                for (d = 0; d < field->ndims; d++)
 
 1212                    dims[d] = (hsize_t)field->dim_size[d];
 
 1213                if ((hdf_typeid = H5Tarray_create1(hdf_base_typeid, field->ndims,
 
 1216                    if (H5Tclose(hdf_base_typeid) < 0)
 
 1220                if (H5Tclose(hdf_base_typeid) < 0)
 
 1224                hdf_typeid = hdf_base_typeid;
 
 1225            LOG((4, 
"inserting field %s offset %d hdf_typeid 0x%x", field->hdr.name,
 
 1226                 field->offset, hdf_typeid));
 
 1227            if (H5Tinsert(hdf5_type->hdf_typeid, field->hdr.name, field->offset,
 
 1230            if (H5Tclose(hdf_typeid) < 0)
 
 1234    else if (type->nc_type_class == 
NC_VLEN)
 
 1237        if ((retval = nc4_get_hdf_typeid(grp->nc4_info, type->u.v.base_nc_typeid,
 
 1238                                         &base_hdf_typeid, type->endianness)))
 
 1242        if ((hdf5_type->hdf_typeid = H5Tvlen_create(base_hdf_typeid)) < 0)
 
 1245    else if (type->nc_type_class == 
NC_OPAQUE)
 
 1248        if ((hdf5_type->hdf_typeid = H5Tcreate(H5T_OPAQUE, type->size)) < 0)
 
 1251    else if (type->nc_type_class == 
NC_ENUM)
 
 1253        NC_ENUM_MEMBER_INFO_T *enum_m;
 
 1256        if (nclistlength(type->u.e.enum_member) == 0)
 
 1260        if ((retval = nc4_get_hdf_typeid(grp->nc4_info, type->u.e.base_nc_typeid,
 
 1261                                         &base_hdf_typeid, type->endianness)))
 
 1265        if ((hdf5_type->hdf_typeid =  H5Tenum_create(base_hdf_typeid)) < 0)
 
 1269        for(i=0;i<nclistlength(type->u.e.enum_member);i++) {
 
 1270            enum_m = (NC_ENUM_MEMBER_INFO_T*)nclistget(type->u.e.enum_member,i);
 
 1271            if (H5Tenum_insert(hdf5_type->hdf_typeid, enum_m->name, enum_m->value) < 0)
 
 1277        LOG((0, 
"Unknown class: %d", type->nc_type_class));
 
 1282    if (H5Tcommit1(hdf5_grp->hdf_grpid, type->hdr.name, hdf5_type->hdf_typeid) < 0)
 
 1284    type->committed = NC_TRUE;
 
 1285    LOG((4, 
"just committed type %s, HDF typeid: 0x%x", type->hdr.name,
 
 1286         hdf5_type->hdf_typeid));
 
 1291    if ((hdf5_type->native_hdf_typeid = H5Tget_native_type(hdf5_type->hdf_typeid,
 
 1292                                                           H5T_DIR_DEFAULT)) < 0)
 
 1309write_nc3_strict_att(hid_t hdf_grpid)
 
 1311    hid_t attid = 0, spaceid = 0;
 
 1318    if ((attr_exists = H5Aexists(hdf_grpid, NC3_STRICT_ATT_NAME)) < 0)
 
 1325    if ((spaceid = H5Screate(H5S_SCALAR)) < 0)
 
 1327    if ((attid = H5Acreate1(hdf_grpid, NC3_STRICT_ATT_NAME,
 
 1328                           H5T_NATIVE_INT, spaceid, H5P_DEFAULT)) < 0)
 
 1330    if (H5Awrite(attid, H5T_NATIVE_INT, &one) < 0)
 
 1334    if (spaceid > 0 && (H5Sclose(spaceid) < 0))
 
 1336    if (attid > 0 && (H5Aclose(attid) < 0))
 
 1354create_group(NC_GRP_INFO_T *grp)
 
 1356    NC_HDF5_GRP_INFO_T *hdf5_grp, *parent_hdf5_grp;
 
 1360    assert(grp && grp->format_grp_info && grp->parent &&
 
 1361           grp->parent->format_grp_info);
 
 1364    hdf5_grp = (NC_HDF5_GRP_INFO_T *)grp->format_grp_info;
 
 1365    parent_hdf5_grp = (NC_HDF5_GRP_INFO_T *)grp->parent->format_grp_info;
 
 1366    assert(parent_hdf5_grp->hdf_grpid);
 
 1370    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0)
 
 1374    if (H5Pset_obj_track_times(gcpl_id, 0) < 0)
 
 1378    if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED|H5P_CRT_ORDER_INDEXED) < 0)
 
 1382    if (!grp->nc4_info->no_attr_create_order) {
 
 1383      if (H5Pset_attr_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED|H5P_CRT_ORDER_INDEXED) < 0)
 
 1388    if ((hdf5_grp->hdf_grpid = H5Gcreate2(parent_hdf5_grp->hdf_grpid, grp->hdr.name,
 
 1389                                          H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0)
 
 1393    if (gcpl_id > -1 && H5Pclose(gcpl_id) < 0)
 
 1396        if (hdf5_grp->hdf_grpid > 0 && H5Gclose(hdf5_grp->hdf_grpid) < 0)
 
 1414attach_dimscales(NC_GRP_INFO_T *grp)
 
 1417    NC_HDF5_VAR_INFO_T *hdf5_var;
 
 1420    for (
size_t v = 0; v < ncindexsize(grp->vars); v++)
 
 1423        var = (NC_VAR_INFO_T *)ncindexith(grp->vars, v);
 
 1424        assert(var && var->format_var_info);
 
 1425        hdf5_var = (NC_HDF5_VAR_INFO_T *)var->format_var_info;
 
 1429        if (hdf5_var->dimscale)
 
 1433        for (
unsigned int d = 0; d < var->ndims; d++)
 
 1436            if (hdf5_var->dimscale_attached)
 
 1438                if (!hdf5_var->dimscale_attached[d])
 
 1441                    assert(var->dim[d] && var->dim[d]->hdr.id == var->dimids[d] &&
 
 1442                           var->dim[d]->format_dim_info);
 
 1444                    LOG((2, 
"%s: attaching scale for dimid %d to var %s",
 
 1445                         __func__, var->dimids[d], var->hdr.name));
 
 1448                    if (var->dim[d]->coord_var)
 
 1449                        dsid = ((NC_HDF5_VAR_INFO_T *)(var->dim[d]->coord_var->format_var_info))->hdf_datasetid;
 
 1451                        dsid = ((NC_HDF5_DIM_INFO_T *)var->dim[d]->format_dim_info)->hdf_dimscaleid;
 
 1457                    if (H5DSattach_scale(hdf5_var->hdf_datasetid, dsid, d) < 0)
 
 1459                    hdf5_var->dimscale_attached[d] = NC_TRUE;
 
 1479var_exists(hid_t grpid, 
char *name, nc_bool_t *exists)
 
 1487    if ((link_exists = H5Lexists(grpid, name, H5P_DEFAULT)) < 0)
 
 1494        if (H5Gget_objinfo(grpid, name, 1, &statbuf) < 0)
 
 1497        if (H5G_DATASET == statbuf.type)
 
 1520remove_coord_atts(hid_t hdf_datasetid)
 
 1526    if ((attr_exists = H5Aexists(hdf_datasetid, NC_DIMID_ATT_NAME)) < 0)
 
 1530        if (H5Adelete(hdf_datasetid, NC_DIMID_ATT_NAME) < 0)
 
 1535    if ((attr_exists = H5Aexists(hdf_datasetid,
 
 1536                                 HDF5_DIMSCALE_CLASS_ATT_NAME)) < 0)
 
 1540        if (H5Adelete(hdf_datasetid, HDF5_DIMSCALE_CLASS_ATT_NAME) < 0)
 
 1543    if ((attr_exists = H5Aexists(hdf_datasetid,
 
 1544                                 HDF5_DIMSCALE_NAME_ATT_NAME)) < 0)
 
 1548        if (H5Adelete(hdf_datasetid, HDF5_DIMSCALE_NAME_ATT_NAME) < 0)
 
 1569write_var(NC_VAR_INFO_T *var, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
 
 1571    NC_HDF5_GRP_INFO_T *hdf5_grp;
 
 1572    NC_HDF5_VAR_INFO_T *hdf5_var;
 
 1573    nc_bool_t replace_existing_var = NC_FALSE;
 
 1576    assert(var && var->format_var_info && grp && grp->format_grp_info);
 
 1578    LOG((4, 
"%s: writing var %s", __func__, var->hdr.name));
 
 1581    hdf5_grp = (NC_HDF5_GRP_INFO_T *)grp->format_grp_info;
 
 1582    hdf5_var = (NC_HDF5_VAR_INFO_T *)var->format_var_info;
 
 1586    if (var->created && var->fill_val_changed)
 
 1588        replace_existing_var = NC_TRUE;
 
 1589        var->fill_val_changed = NC_FALSE;
 
 1595        flag_atts_dirty(var->att);
 
 1602    if (var->became_coord_var)
 
 1604        if ((NC_DIM_INFO_T *)ncindexlookup(grp->dim, var->hdr.name))
 
 1608            if ((retval = var_exists(hdf5_grp->hdf_grpid, var->hdr.name, &exists)))
 
 1614                replace_existing_var = NC_TRUE;
 
 1615                flag_atts_dirty(var->att);
 
 1622    if (replace_existing_var)
 
 1627        if ((d1 = (NC_DIM_INFO_T *)ncindexlookup(grp->dim, var->hdr.name)))
 
 1630            assert(d1->format_dim_info && d1->hdr.name);
 
 1632            if ((retval = var_exists(hdf5_grp->hdf_grpid, var->hdr.name, &exists)))
 
 1640                    dsid = ((NC_HDF5_VAR_INFO_T *)d1->coord_var->format_var_info)->hdf_datasetid;
 
 1642                    dsid = ((NC_HDF5_DIM_INFO_T *)d1->format_dim_info)->hdf_dimscaleid;
 
 1648                if ((retval = rec_detach_scales(grp->nc4_info->root_grp,
 
 1649                                                var->dimids[0], dsid)))
 
 1657    if (var->was_coord_var && hdf5_var->dimscale_attached)
 
 1662            if ((retval = remove_coord_atts(hdf5_var->hdf_datasetid)))
 
 1666        for (
unsigned int d = 0; d < var->ndims; d++)
 
 1668            if (hdf5_var->dimscale_attached[d])
 
 1671                assert(var->dim[d] && var->dim[d]->hdr.id == var->dimids[d] &&
 
 1672                       var->dim[d]->format_dim_info);
 
 1675                if (var->dim[d]->coord_var)
 
 1676                    dsid = ((NC_HDF5_VAR_INFO_T *)var->dim[d]->coord_var->format_var_info)->hdf_datasetid;
 
 1678                    dsid = ((NC_HDF5_DIM_INFO_T *)var->dim[d]->format_dim_info)->hdf_dimscaleid;
 
 1682                if (H5DSdetach_scale(hdf5_var->hdf_datasetid, dsid, d) < 0)
 
 1684                hdf5_var->dimscale_attached[d] = NC_FALSE;
 
 1690    if (replace_existing_var)
 
 1693        if (hdf5_var->hdf_datasetid && H5Dclose(hdf5_var->hdf_datasetid) < 0)
 
 1695        hdf5_var->hdf_datasetid = 0;
 
 1698        if (H5Gunlink(hdf5_grp->hdf_grpid, var->hdr.name) < 0)
 
 1703    if (var->is_new_var || replace_existing_var)
 
 1705        if ((retval = var_create_dataset(grp, var, write_dimid)))
 
 1710        if (write_dimid && var->ndims)
 
 1711            if ((retval = write_netcdf4_dimid(hdf5_var->hdf_datasetid,
 
 1716    if (replace_existing_var)
 
 1720        if(hdf5_var->dimscale)
 
 1722            if ((retval = rec_reattach_scales(grp->nc4_info->root_grp,
 
 1723                                              var->dimids[0], hdf5_var->hdf_datasetid)))
 
 1730            if (hdf5_var->dimscale_attached)
 
 1731                memset(hdf5_var->dimscale_attached, 0, 
sizeof(nc_bool_t) * var->ndims);
 
 1736    var->was_coord_var = NC_FALSE;
 
 1737    var->became_coord_var = NC_FALSE;
 
 1740    if (var->attr_dirty)
 
 1743        if ((retval = write_attlist(var->att, var->hdr.id, grp)))
 
 1745        var->attr_dirty = NC_FALSE;
 
 1763nc4_create_dim_wo_var(NC_DIM_INFO_T *dim)
 
 1765    NC_HDF5_DIM_INFO_T *hdf5_dim;
 
 1766    NC_HDF5_GRP_INFO_T *hdf5_grp;
 
 1767    hid_t spaceid = -1, create_propid = -1;
 
 1768    hsize_t dims[1], max_dims[1], chunk_dims[1] = {1};
 
 1772    LOG((4, 
"%s: creating dim %s", __func__, dim->hdr.name));
 
 1775    assert(!dim->coord_var);
 
 1778    hdf5_grp = (NC_HDF5_GRP_INFO_T *)dim->container->format_grp_info;
 
 1779    hdf5_dim = (NC_HDF5_DIM_INFO_T *)dim->format_dim_info;
 
 1782    if ((create_propid = H5Pcreate(H5P_DATASET_CREATE)) < 0)
 
 1786    if (H5Pset_obj_track_times(create_propid, 0) < 0)
 
 1791    max_dims[0] = dim->len;
 
 1797        max_dims[0] = H5S_UNLIMITED;
 
 1798        if (H5Pset_chunk(create_propid, 1, chunk_dims) < 0)
 
 1803    if ((spaceid = H5Screate_simple(1, dims, max_dims)) < 0)
 
 1807    if (!dim->container->nc4_info->no_attr_create_order) {
 
 1808      if (H5Pset_attr_creation_order(create_propid, H5P_CRT_ORDER_TRACKED|
 
 1809                     H5P_CRT_ORDER_INDEXED) < 0)
 
 1813    LOG((4, 
"%s: about to H5Dcreate1 a dimscale dataset %s", __func__,
 
 1815    if ((hdf5_dim->hdf_dimscaleid = H5Dcreate2(hdf5_grp->hdf_grpid, dim->hdr.name,
 
 1816                                               H5T_IEEE_F32BE, spaceid,
 
 1817                                               H5P_DEFAULT, create_propid,
 
 1824    snprintf(dimscale_wo_var, 
sizeof(dimscale_wo_var), 
"%s%10d", DIM_WITHOUT_VARIABLE, (
int)dim->len);
 
 1825    if (H5DSset_scale(hdf5_dim->hdf_dimscaleid, dimscale_wo_var) < 0)
 
 1831    if ((retval = write_netcdf4_dimid(hdf5_dim->hdf_dimscaleid, dim->hdr.id)))
 
 1835    if (spaceid > 0 && H5Sclose(spaceid) < 0)
 
 1837    if (create_propid > 0 && H5Pclose(create_propid) < 0)
 
 1855write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
 
 1857    NC_HDF5_DIM_INFO_T *hdf5_dim;
 
 1860    assert(dim && dim->format_dim_info && grp && grp->format_grp_info);
 
 1863    hdf5_dim = (NC_HDF5_DIM_INFO_T *)dim->format_dim_info;
 
 1869    if (!hdf5_dim->hdf_dimscaleid)
 
 1870        if ((retval = nc4_create_dim_wo_var(dim)))
 
 1876        NC_VAR_INFO_T *v1 = NULL;
 
 1878        assert(dim->unlimited);
 
 1882        v1 = dim->coord_var;
 
 1885            NC_HDF5_VAR_INFO_T *hdf5_v1;
 
 1889            hdf5_v1 = (NC_HDF5_VAR_INFO_T *)v1->format_var_info;
 
 1893            if (!(new_size = malloc(v1->ndims * 
sizeof(hsize_t))))
 
 1895            for (d1 = 0; d1 < v1->ndims; d1++)
 
 1897                assert(v1->dim[d1] && v1->dim[d1]->hdr.id == v1->dimids[d1]);
 
 1898                new_size[d1] = v1->dim[d1]->len;
 
 1900            if (H5Dset_extent(hdf5_v1->hdf_datasetid, new_size) < 0)
 
 1910    if (write_dimid && hdf5_dim->hdf_dimscaleid)
 
 1911        if ((retval = write_netcdf4_dimid(hdf5_dim->hdf_dimscaleid, dim->hdr.id)))
 
 1932nc4_rec_write_metadata(NC_GRP_INFO_T *grp, nc_bool_t bad_coord_order)
 
 1934    NC_DIM_INFO_T *dim = NULL;
 
 1935    NC_VAR_INFO_T *var = NULL;
 
 1936    NC_GRP_INFO_T *child_grp = NULL;
 
 1937    int coord_varid = -1;
 
 1938    size_t var_index = 0;
 
 1939    size_t dim_index = 0;
 
 1942    assert(grp && grp->hdr.name &&
 
 1943           ((NC_HDF5_GRP_INFO_T *)(grp->format_grp_info))->hdf_grpid);
 
 1944    LOG((3, 
"%s: grp->hdr.name %s, bad_coord_order %d", __func__, grp->hdr.name,
 
 1948    if ((retval = write_attlist(grp->att, 
NC_GLOBAL, grp)))
 
 1953    dim = (NC_DIM_INFO_T *)ncindexith(grp->dim, dim_index);
 
 1954    var = (NC_VAR_INFO_T *)ncindexith(grp->vars, var_index);
 
 1961        nc_bool_t found_coord, wrote_coord;
 
 1965        for (found_coord = NC_FALSE; dim && !found_coord; )
 
 1967            if (!dim->coord_var)
 
 1969                if ((retval = write_dim(dim, grp, bad_coord_order)))
 
 1974                coord_varid = dim->coord_var->hdr.id;
 
 1975                found_coord = NC_TRUE;
 
 1977            dim = (NC_DIM_INFO_T *)ncindexith(grp->dim, ++dim_index);
 
 1982        for (wrote_coord = NC_FALSE; var && !wrote_coord; )
 
 1984            if ((retval = write_var(var, grp, bad_coord_order)))
 
 1986            if (found_coord && var->hdr.id == coord_varid)
 
 1987                wrote_coord = NC_TRUE;
 
 1988            var = (NC_VAR_INFO_T *)ncindexith(grp->vars, ++var_index);
 
 1993    if (!grp->nc4_info->no_dimscale_attach) {
 
 1994        if ((retval = attach_dimscales(grp)))
 
 1999    for (
size_t i = 0; i < ncindexsize(grp->children); i++)
 
 2001        child_grp = (NC_GRP_INFO_T *)ncindexith(grp->children, i);
 
 2003        if ((retval = nc4_rec_write_metadata(child_grp, bad_coord_order)))
 
 2019nc4_rec_write_groups_types(NC_GRP_INFO_T *grp)
 
 2021    NC_GRP_INFO_T *child_grp;
 
 2022    NC_HDF5_GRP_INFO_T *hdf5_grp;
 
 2023    NC_TYPE_INFO_T *type;
 
 2027    assert(grp && grp->hdr.name && grp->format_grp_info);
 
 2028    LOG((3, 
"%s: grp->hdr.name %s", __func__, grp->hdr.name));
 
 2031    hdf5_grp = (NC_HDF5_GRP_INFO_T *)grp->format_grp_info;
 
 2034    if (!hdf5_grp->hdf_grpid)
 
 2035        if ((retval = create_group(grp)))
 
 2041        if ((retval = write_nc3_strict_att(hdf5_grp->hdf_grpid)))
 
 2045    for(i=0;i<ncindexsize(grp->type);i++) {
 
 2046        type = (NC_TYPE_INFO_T *)ncindexith(grp->type, i);
 
 2048        if ((retval = commit_type(grp, type)))
 
 2053    for(i=0;i<ncindexsize(grp->children);i++) {
 
 2054        if((child_grp = (NC_GRP_INFO_T*)ncindexith(grp->children,i)) == NULL) 
continue;
 
 2055        if ((retval = nc4_rec_write_groups_types(child_grp)))
 
 2075nc4_rec_match_dimscales(NC_GRP_INFO_T *grp)
 
 2083    assert(grp && grp->hdr.name);
 
 2084    LOG((4, 
"%s: grp->hdr.name %s", __func__, grp->hdr.name));
 
 2087    for (i = 0; i < ncindexsize(grp->children); i++)
 
 2089        g = (NC_GRP_INFO_T*)ncindexith(grp->children, i);
 
 2091        if ((retval = nc4_rec_match_dimscales(g)))
 
 2097    for (i = 0; i < ncindexsize(grp->vars); i++)
 
 2099        NC_HDF5_VAR_INFO_T *hdf5_var;
 
 2103        var = (NC_VAR_INFO_T*)ncindexith(grp->vars, i);
 
 2104        assert(var && var->format_var_info);
 
 2105        hdf5_var = (NC_HDF5_VAR_INFO_T *)var->format_var_info;
 
 2122        const size_t ndims = var->ndims;
 
 2123        for (
size_t d = 0; d < ndims; d++)
 
 2125            if (var->dim[d] == NULL) {
 
 2126                nc4_find_dim(grp, var->dimids[d], &var->dim[d], NULL);
 
 2132        if (!hdf5_var->dimscale)
 
 2135            if (hdf5_var->dimscale_hdf5_objids)
 
 2137                for (
size_t d = 0; d < var->ndims; d++)
 
 2139                    nc_bool_t finished = NC_FALSE;
 
 2140                    LOG((5, 
"%s: var %s has dimscale info...", __func__, var->hdr.name));
 
 2143                    for (g = grp; g && !finished; g = g->parent)
 
 2146                        for (
size_t j = 0; j < ncindexsize(g->dim); j++)
 
 2149                            NC_HDF5_DIM_INFO_T *hdf5_dim;
 
 2150                            dim = (NC_DIM_INFO_T *)ncindexith(g->dim, j);
 
 2151                            assert(dim && dim->format_dim_info);
 
 2152                            hdf5_dim = (NC_HDF5_DIM_INFO_T *)dim->format_dim_info;
 
 2156#if H5_VERSION_GE(1,12,0) 
 2158                            if (H5Otoken_cmp(hdf5_var->hdf_datasetid, &hdf5_var->dimscale_hdf5_objids[d].token, &hdf5_dim->hdf5_objid.token, &token_cmp) < 0)
 
 2161                            if (hdf5_var->dimscale_hdf5_objids[d].fileno == hdf5_dim->hdf5_objid.fileno &&
 
 2164                            if (hdf5_var->dimscale_hdf5_objids[d].fileno[0] == hdf5_dim->hdf5_objid.fileno[0] &&
 
 2165                                hdf5_var->dimscale_hdf5_objids[d].objno[0] == hdf5_dim->hdf5_objid.objno[0] &&
 
 2166                                hdf5_var->dimscale_hdf5_objids[d].fileno[1] == hdf5_dim->hdf5_objid.fileno[1] &&
 
 2167                                hdf5_var->dimscale_hdf5_objids[d].objno[1] == hdf5_dim->hdf5_objid.objno[1])
 
 2170                                LOG((4, 
"%s: for dimension %d, found dim %s", __func__,
 
 2172                                var->dimids[d] = dim->hdr.id;
 
 2179                    LOG((5, 
"%s: dimid for this dimscale is %d", __func__,
 
 2180                         var->type_info->hdr.id));
 
 2187                hsize_t *h5dimlen = NULL, *h5dimlenmax = NULL;
 
 2191                if ((spaceid = H5Dget_space(hdf5_var->hdf_datasetid)) < 0)
 
 2197                    if (!(h5dimlen = malloc(var->ndims * 
sizeof(hsize_t))))
 
 2199                    if (!(h5dimlenmax = malloc(var->ndims * 
sizeof(hsize_t))))
 
 2204                    if ((dataset_ndims = H5Sget_simple_extent_dims(spaceid, h5dimlen,
 
 2205                                                                   h5dimlenmax)) < 0) {
 
 2210                    if (dataset_ndims != var->ndims) {
 
 2219                    if (H5Sget_simple_extent_type(spaceid) != H5S_SCALAR)
 
 2224                if (H5Sclose(spaceid) < 0) {
 
 2233                for (d = 0; d < var->ndims; d++)
 
 2235                    nc_bool_t match = NC_FALSE;
 
 2237                    for(
size_t k=0;k<ncindexsize(grp->dim);k++) {
 
 2238                        if((dim = (NC_DIM_INFO_T*)ncindexith(grp->dim,k)) == NULL) 
continue;
 
 2239                        if ((dim->len == h5dimlen[d]) &&
 
 2240                            ((h5dimlenmax[d] == H5S_UNLIMITED && dim->unlimited) ||
 
 2241                             (h5dimlenmax[d] != H5S_UNLIMITED && !dim->unlimited)))
 
 2242                        {match = NC_TRUE; 
break;}
 
 2246                    if (match == NC_FALSE)
 
 2249                        snprintf(phony_dim_name, 
sizeof(phony_dim_name), 
"phony_dim_%d", grp->nc4_info->next_dimid);
 
 2250                        LOG((3, 
"%s: creating phony dim for var %s", __func__, var->hdr.name));
 
 2251                        if ((retval = nc4_dim_list_add(grp, phony_dim_name, h5dimlen[d], -1, &dim)))
 
 2258                        if (!(dim->format_dim_info = calloc(1, 
sizeof(NC_HDF5_DIM_INFO_T))))
 
 2260                        if (h5dimlenmax[d] == H5S_UNLIMITED)
 
 2261                            dim->unlimited = NC_TRUE;
 
 2265                    var->dimids[d] = dim->hdr.id;
 
 2291reportobject(
int uselog, hid_t 
id, 
unsigned int type)
 
 2293    char name[NC_HDF5_MAX_NAME];
 
 2295    const char* 
typename = NULL;
 
 2296    long long printid = (
long long)
id;
 
 2298    len = H5Iget_name(
id, name, NC_HDF5_MAX_NAME);
 
 2303    case H5F_OBJ_FILE: 
typename = 
"File"; 
break;
 
 2304    case H5F_OBJ_DATASET: 
typename = 
"Dataset"; 
break;
 
 2305    case H5F_OBJ_GROUP: 
typename = 
"Group"; 
break;
 
 2306    case H5F_OBJ_DATATYPE: 
typename = 
"Datatype"; 
break;
 
 2308        typename = 
"Attribute";
 
 2309        len = H5Aget_name(
id, NC_HDF5_MAX_NAME, name);
 
 2310        if(len < 0) len = 0;
 
 2313    default: 
typename = 
"<unknown>"; 
break;
 
 2317        LOG((0,
"Type = %s(%lld) name='%s'",
typename,printid,name));
 
 2321        fprintf(stderr,
"Type = %s(%lld) name='%s'",
typename,printid,name);
 
 2337reportopenobjectsT(
int uselog, hid_t fid, 
int ntypes, 
unsigned int* otypes)
 
 2341    hid_t* idlist = NULL;
 
 2346        LOG((0,
"\nReport: open objects on %lld",(
long long)fid));
 
 2349        fprintf(stdout,
"\nReport: open objects on %lld\n",(
long long)fid);
 
 2350    size_t maxobjs = (size_t)H5Fget_obj_count(fid,H5F_OBJ_ALL);
 
 2351    if(idlist != NULL) free(idlist);
 
 2352    idlist = (hid_t*)malloc(
sizeof(hid_t)*maxobjs);
 
 2353    for(t=0;t<ntypes;t++) {
 
 2354        unsigned int ot = otypes[t];
 
 2355        ocount = H5Fget_obj_ids(fid,ot,maxobjs,idlist);
 
 2356        for(i=0;i<ocount;i++) {
 
 2357            hid_t o = idlist[i];
 
 2358            reportobject(uselog,o,ot);
 
 2361    if(idlist != NULL) free(idlist);
 
 2373reportopenobjects(
int uselog, hid_t fid)
 
 2375    unsigned int OTYPES[5] = {H5F_OBJ_FILE, H5F_OBJ_DATASET, H5F_OBJ_GROUP,
 
 2376                              H5F_OBJ_DATATYPE, H5F_OBJ_ATTR};
 
 2378    reportopenobjectsT(uselog, fid ,5, OTYPES);
 
 2389showopenobjects5(NC_FILE_INFO_T* h5)
 
 2391    NC_HDF5_FILE_INFO_T *hdf5_info;
 
 2393    assert(h5 && h5->format_file_info);
 
 2394    hdf5_info = (NC_HDF5_FILE_INFO_T *)h5->format_file_info;
 
 2396    fprintf(stderr,
"===== begin showopenobjects =====\n");
 
 2397    reportopenobjects(0,hdf5_info->hdfid);
 
 2398    fprintf(stderr,
"===== end showopenobjects =====\n");
 
 2411showopenobjects(
int ncid)
 
 2413    NC_FILE_INFO_T* h5 = NULL;
 
 2416    if (nc4_find_nc_grp_h5(ncid, NULL, NULL, &h5) != 
NC_NOERR)
 
 2417        fprintf(stderr,
"failed\n");
 
 2419        showopenobjects5(h5);
 
 2435NC4_hdf5get_libversion(
unsigned* major,
unsigned* minor,
unsigned* release)
 
 2437    if(H5get_libversion(major,minor,release) < 0)
 
 2453NC4_hdf5get_superblock(
struct NC_FILE_INFO* h5, 
int* idp)
 
 2455    NC_HDF5_FILE_INFO_T *hdf5_info;
 
 2460    assert(h5 && h5->format_file_info);
 
 2461    hdf5_info = (NC_HDF5_FILE_INFO_T *)h5->format_file_info;
 
 2463    if((plist = H5Fget_create_plist(hdf5_info->hdfid)) < 0)
 
 2465    if(H5Pget_version(plist, &super, NULL, NULL, NULL) < 0)
 
 2467    if(idp) *idp = (int)super;
 
 2469    if(plist >= 0) H5Pclose(plist);
 
 2473static int NC4_strict_att_exists(NC_FILE_INFO_T*);
 
 2474static int NC4_walk(hid_t, 
int*);
 
 2502NC4_isnetcdf4(
struct NC_FILE_INFO* h5)
 
 2510    exists = NC4_strict_att_exists(h5);
 
 2516    stat = NC4_walk(((NC_HDF5_GRP_INFO_T *)(h5->root_grp->format_grp_info))->hdf_grpid,
 
 2521        isnc4 = (count >= 2);
 
 2536NC4_strict_att_exists(NC_FILE_INFO_T *h5)
 
 2542    grpid = ((NC_HDF5_GRP_INFO_T *)(h5->root_grp->format_grp_info))->hdf_grpid;
 
 2545    if ((attr_exists = H5Aexists(grpid, NC3_STRICT_ATT_NAME)) < 0)
 
 2547    return (attr_exists?1:0);
 
 2560NC4_walk(hid_t gid, 
int* countp)
 
 2569    char name[NC_HDF5_MAX_NAME];
 
 2572    err = H5Gget_num_objs(gid, &nobj);
 
 2573    if(err < 0) 
return err;
 
 2575    for(hsize_t i = 0; i < nobj; i++) {
 
 2577        len = H5Gget_objname_by_idx(gid,i,name,(
size_t)NC_HDF5_MAX_NAME);
 
 2578        if(len < 0) 
return (
int)len;
 
 2580        otype =  H5Gget_objtype_by_idx(gid, i);
 
 2583        grpid = H5Gopen1(gid,name);
 
 2584            NC4_walk(grpid,countp);
 
 2589            if(strcmp(name,
"phony_dim")==0)
 
 2590                *countp = *countp + 1;
 
 2591            dsid = H5Dopen1(gid,name);
 
 2592            na = H5Aget_num_attrs(dsid);
 
 2593            for(j = 0; j < na; j++) {
 
 2594                hid_t aid =  H5Aopen_idx(dsid,(
unsigned int)    j);
 
 2596                    const NC_reservedatt* ra;
 
 2597                    ssize_t len = H5Aget_name(aid, NC_HDF5_MAX_NAME, name);
 
 2598                    if(len < 0) 
return (
int)len;
 
 2600                    ra = NC_findreserved(name);
 
 2602                        *countp = *countp + 1;
 
EXTERNL int nc_free_vlen(nc_vlen_t *vl)
Free memory in a single VLEN object.
Main header file for the C API.
#define NC_EBADTYPE
Not a netcdf data type.
#define NC_UINT
unsigned 4-byte int
#define NC_ENDIAN_NATIVE
In HDF5 files you can set the endianness of variables with nc_def_var_endian().
#define NC_EFILTER
Filter operation failed.
#define NC_QUANTIZE_GRANULARBR_ATT_NAME
When quantization is used for a variable, an attribute of the appropriate name is added.
#define NC_INT
signed 4 byte integer
#define NC_ENDIAN_BIG
In HDF5 files you can set the endianness of variables with nc_def_var_endian().
#define NC_MAX_VAR_DIMS
max per variable dimensions
#define NC_BYTE
signed 1 byte integer
#define NC_EPERM
Write to read only.
#define NC_QUANTIZE_BITROUND
Use BitRound quantization.
#define NC_EDIMSCALE
Problem with HDF5 dimscales.
#define NC_VLEN
vlen (variable-length) types
#define NC_NAT
Not A Type.
#define NC_DOUBLE
double precision floating point number
#define NC_UBYTE
unsigned 1 byte int
#define NC_FLOAT
single precision floating point number
#define NC_ENOMEM
Memory allocation (malloc) failure.
#define NC_COMPOUND
compound types
#define NC_CHUNKED
In HDF5 files you can set storage for each variable to be either contiguous or chunked,...
#define NC_SHORT
signed 2 byte integer
#define NC_QUANTIZE_GRANULARBR
Use Granular BitRound quantization.
#define NC_QUANTIZE_BITGROOM
Use BitGroom quantization.
#define NC_ENUM
enum types
#define NC_INT64
signed 8-byte int
#define NC_EATTMETA
Problem with attribute metadata.
#define NC_EHDFERR
Error at HDF5 layer.
#define NC_CONTIGUOUS
In HDF5 files you can set storage for each variable to be either contiguous or chunked,...
#define NC_GLOBAL
Attribute id to put/get a global attribute.
#define NC_UINT64
unsigned 8-byte int
#define NC_COMPACT
In HDF5 files you can set storage for each variable to be either contiguous or chunked,...
#define NC_EFILEMETA
Problem with file metadata.
#define NC_ENOTVAR
Variable not found.
#define NC_EINVAL
Invalid Argument.
#define NC_CLASSIC_MODEL
Enforce classic model on netCDF-4.
#define NC_ENDIAN_LITTLE
In HDF5 files you can set the endianness of variables with nc_def_var_endian().
#define NC_MAX_NAME
Maximum for classic library.
#define NC_NOERR
No Error.
#define NC_EDIMMETA
Problem with dimension metadata.
#define NC_USHORT
unsigned 2-byte int
#define NC_OPAQUE
opaque types
#define NC_QUANTIZE_BITGROOM_ATT_NAME
When quantization is used for a variable, an attribute of the appropriate name is added.
#define NC_CHAR
ISO/ASCII character.
#define NC_EVARMETA
Problem with variable metadata.
#define NC_QUANTIZE_BITROUND_ATT_NAME
When quantization is used for a variable, an attribute of the appropriate name is added.
int nc_type
The nc_type type is just an int.
This is the type of arrays of vlens.