1/*********************************************************************
2*    Copyright 2010, UCAR/Unidata
3*    See netcdf/COPYRIGHT file for copying and redistribution conditions.
4* ********************************************************************/
5
6#include "config.h"
7#include <stdlib.h>
8#include <string.h>
9#include <hdf5.h>
10#include "netcdf.h"
11#include "nc4internal.h"
12
13#define IGNORE 0
14
15#define HDF5_MAX_NAME 1024
16
17#define NCHECK(expr) {if((expr)!=NC_NOERR) {goto done;}}
18#define HCHECK(expr) {if((expr)<0) {ncstat = NC_EHDFERR; goto done;}}
19
20/* Global */
21struct NCPROPINFO globalpropinfo;
22
23int
24NC4_fileinfo_init(void)
25{
26    int stat = NC_NOERR;
27    unsigned major,minor,release;
28    int super;
29
30    /* Build nc properties */
31    memset((void*)&globalpropinfo,0,sizeof(globalpropinfo));
32    globalpropinfo.version = NCPROPS_VERSION;
33    globalpropinfo.netcdfver[0] = '\0';
34    globalpropinfo.hdf5ver[0] = '\0';
35
36    stat = NC4_hdf5get_libversion(&major,&minor,&release);
37    if(stat) goto done;
38    snprintf(globalpropinfo.hdf5ver,sizeof(globalpropinfo.hdf5ver),
39  "%1u.%1u.%1u",major,minor,release);
40    strncpy(globalpropinfo.netcdfver,PACKAGE_VERSION,sizeof(globalpropinfo.netcdfver));
41done:
42    return stat;
43}
44
45static int
46NC4_properties_parse(struct NCPROPINFOncprops, const char* text)
47{
48    int ret = NC_NOERR;
49    size_t len;
50    char* p;
51    char* propdata = NULL;
52
53    ncprops->version = 0;
54    ncprops->hdf5ver[0] = '\0';
55    ncprops->netcdfver[0] = '\0';
56
57    len = strlen(text);
58    if(len == 0) return NC_NOERR;
59    propdata = (char*)malloc(len+1);
60    if(propdata == NULL) return NC_ENOMEM;
61    memcpy(propdata,text,len+1);
62    propdata[len] = '\0'; /* guarantee */
63
64    /* Walk and fill in ncinfo */
65    p = propdata;
66    while(*p) {
67      char* name = p;
68      char* value = NULL;
69      char* q = strchr(p,'=');
70      if(q == NULL)
71     {ret = NC_EINVAL; goto done;}
72      *q++ = '\0';
73      value = p = q;
74      q = strchr(p,NCPROPSSEP);
75      if(q == NULLq = (p+strlen(p)); else* q++ = '\0';
76      p = q;
77      if(value != NULL) {
78     if(strcmp(name,NCPVERSION) == 0) {
79          int v = atoi(value);
80          if(v < 0) v = 0;
81          ncprops->version = v;
82     } else if(strcmp(name,NCPNCLIBVERSION) == 0)
83          strncpy(ncprops->netcdfver,value,sizeof(ncprops->netcdfver)-1);
84     else if(strcmp(name,NCPHDF5LIBVERSION) == 0)
85          strncpy(ncprops->hdf5ver,value,sizeof(ncprops->hdf5ver)-1);
86     /* else ignore */
87      }
88    }
89    /* Guarantee null term */
90    ncprops->netcdfver[sizeof(ncprops->netcdfver)-1] = '\0';
91    ncprops->hdf5ver[sizeof(ncprops->hdf5ver)-1] = '\0';
92done:
93    if(propdata != NULL) free(propdata);
94    return ret;
95}
96
97static int
98NC4_get_propattr(NC_HDF5_FILE_INFO_Th5)
99{
100    int ncstat = NC_NOERR;
101    size_t size;
102    H5T_class_t t_class;
103    hid_t grp = -1;
104    hid_t attid = -1;
105    hid_t aspace = -1;
106    hid_t atype = -1;
107    hid_t ntype = -1;
108    herr_t herr = 0;
109    char* text = NULL;
110
111    /* Get root group */
112    grp = h5->root_grp->hdf_grpid; /* get root group */
113    /* Try to extract the NCPROPS attribute */
114    if(H5Aexists(grp,NCPROPS) > 0) { /* Does exist */
115        attid = H5Aopen_name(grpNCPROPS);
116 herr = -1;
117 aspace = H5Aget_space(attid); /* dimensions of attribute data */
118        atype = H5Aget_type(attid);
119 /* Verify that atype and size */
120 t_class = H5Tget_class(atype);
121 if(t_class != H5T_STRING) {ncstat = NC_EATTMETA; goto done;}
122        size = H5Tget_size(atype);
123 if(size == 0) goto done;
124 text = (char*)malloc(size+1);
125 if(text == NULL)
126     {ncstat = NC_ENOMEM; goto done;}
127        HCHECK((ntype = H5Tget_native_type(atypeH5T_DIR_ASCEND)));
128        HCHECK((H5Aread(attidntypetext)));
129 /* Make sure its null terminated */
130 text[size] = '\0';
131 /* Try to parse text */
132 ncstat = NC4_properties_parse(&h5->fileinfo->propattr,text);
133 herr = 0;
134    }
135done:
136    if(attid >= 0) HCHECK((H5Aclose(attid)));
137    if(aspace >= 0) HCHECK((H5Sclose(aspace)));
138    if(ntype >= 0) HCHECK((H5Tclose(ntype)));
139    if(atype >= 0) HCHECK((H5Tclose(atype)));
140    if(text != NULL) free(text);
141    return ncstat;
142}
143
144int
145NC4_put_propattr(NC_HDF5_FILE_INFO_Th5)
146{
147    int ncstat = NC_NOERR;
148    H5T_class_t t_class;
149    size_t size;
150    hid_t grp = -1;
151    hid_t exists = -1;
152    hid_t attid = -1;
153    hid_t aspace = -1;
154    hid_t atype = -1;
155    herr_t herr = 0;
156    char* text = NULL;
157
158    /* Get root group */
159    grp = h5->root_grp->hdf_grpid; /* get root group */
160    /* See if the NCPROPS attribute exists */
161    if(H5Aexists(grp,NCPROPS) == 0) { /* Does not exist */
162      ncstat = NC4_buildpropinfo(&h5->fileinfo->propattr,&text);
163      if(text == NULL || ncstat != NC_NOERR) {
164        goto done;
165      }
166      herr = -1;
167      /* Create a datatype to refer to. */
168      HCHECK((atype = H5Tcopy(H5T_C_S1)));
169      HCHECK((H5Tset_cset(atypeH5T_CSET_ASCII)));
170      HCHECK((H5Tset_size(atype, strlen(text)+1))); /*keep nul term */
171      HCHECK((aspace = H5Screate(H5S_SCALAR)));
172      HCHECK((attid = H5Acreate(grpNCPROPSatypeaspaceH5P_DEFAULT)));
173      HCHECK((H5Awrite(attidatypetext)));
174      herr = 0;
175    }
176 done:
177    if(ncstat != NC_NOERR) {
178      if(text != NULL) {
179        free(text);
180        text = NULL;
181      }
182    }
183
184    if(attid >= 0) HCHECK((H5Aclose(attid)));
185    if(aspace >= 0) HCHECK((H5Sclose(aspace)));
186    if(atype >= 0) HCHECK((H5Tclose(atype)));
187    return ncstat;
188}
189
190int
191NC4_get_fileinfo(NC_HDF5_FILE_INFO_Th5, struct NCPROPINFOinit)
192{
193    int ncstat = NC_NOERR;
194
195    /* Allocate the fileinfo in h5 */
196    h5->fileinfo = (struct NCFILEINFO*)calloc(1,sizeof(struct NCFILEINFO));
197    if(h5->fileinfo == NULL)
198 {ncstat = NC_ENOMEM; goto done;}
199
200    /* Get superblock version */
201    NCHECK((ncstat = NC4_hdf5get_superblock(h5,&h5->fileinfo->superblockversion)));
202    /* Get properties attribute if not already defined */
203    if(init == NULL) {
204        NCHECK((ncstat = NC4_get_propattr(h5)));
205    } else { /*init != NULL*/
206       h5->fileinfo->propattr = *init; /* Initialize */
207    }
208done:
209    return ncstat;
210}
211
212int
213NC4_buildpropinfo(struct NCPROPINFOinfo,char** propdatap)
214{
215    size_t total;
216    char* propdata = NULL;
217
218    if(info == NULL || info->version == 0)  return NC_EINVAL;
219    if(propdatap == NULL)
220      return NC_NOERR;
221    *propdatap = NULL;
222
223    /* compute attribute length */
224    total = 0;
225    total += strlen(NCPVERSION);
226    total += strlen("=00000000");
227    if(strlen(info->netcdfver) > 0) {
228        total += 1; /*|NCPROPSEP|*/
229        total += strlen(NCPNCLIBVERSION);
230        total += strlen("=");
231        total += strlen(info->netcdfver);
232    }
233    if(strlen(info->hdf5ver) > 0) {
234        total += 1; /*|NCPROPSEP|*/
235        total += strlen(NCPHDF5LIBVERSION);
236        total += strlen("=");
237        total += strlen(info->hdf5ver);
238    }
239    propdata = (char*)malloc(total+1);
240    if(propdata == NULL)
241 return NC_ENOMEM;
242    snprintf(propdata,total+1,
243            "%s=%d|%s=%s|%s=%s",
244         NCPVERSION,info->version,
245         NCPNCLIBVERSION,info->netcdfver,
246         NCPHDF5LIBVERSION,info->hdf5ver);
247    /* Force null termination */
248    propdata[total] = '\0';
249    *propdatap = propdata;
250
251    /* propdatap is checked against being NULL above already. */
252    //if(propdatap) {
253    //  *propdatap = propdata;
254    //} else {
255    //  free(propdata);
256    //}
257
258    return NC_NOERR;
259}


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed