1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
/*********************************************************************
* Copyright 2018, UCAR/Unidata
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
*********************************************************************/
#include "dapincludes.h"
#define OCCHECK(exp) if((ocstat = (exp))) {THROWCHK(ocstat); goto done;}
/* Forward */
static NCerror buildattribute(char*,nc_type,size_t,char**,NCattribute**);
/*
Invoke oc_merge_das and then extract special
attributes such as "strlen" and "dimname"
and stuff from DODS_EXTRA.
*/
int
dapmerge(NCDAPCOMMON* nccomm, CDFnode* ddsroot, OCddsnode dasroot)
{
int i,j;
NCerror ncstat = NC_NOERR;
OCerror ocstat = OC_NOERR;
NClist* allnodes;
OClink conn;
char* ocname = NULL;
char** values = NULL;
conn = nccomm->oc.conn;
if(ddsroot == NULL || dasroot == NULL)
return NC_NOERR;
/* Merge the das tree onto the dds tree */
ocstat = oc_merge_das(nccomm->oc.conn,dasroot,ddsroot->ocnode);
if(ocstat != OC_NOERR) goto done;
/* Create attributes on CDFnodes */
allnodes = ddsroot->tree->nodes;
for(i=0;i<nclistlength(allnodes);i++) {
CDFnode* node = (CDFnode*)nclistget(allnodes,i);
OCddsnode ocnode = node->ocnode;
size_t attrcount;
OCtype ocetype;
OCCHECK(oc_dds_attr_count(conn,ocnode,&attrcount));
for(j=0;j<attrcount;j++) {
size_t nvalues;
NCattribute* att = NULL;
if(ocname != NULL) {
free(ocname); ocname = NULL;
} /* from last loop */
OCCHECK(oc_dds_attr(conn,ocnode,j,&ocname,&ocetype,&nvalues,NULL));
if(nvalues > 0) {
values = (char**)malloc(sizeof(char*)*nvalues);
if(values == NULL) {ncstat = NC_ENOMEM; goto done;}
OCCHECK(oc_dds_attr(conn,ocnode,j,NULL,NULL,NULL,values));
}
ncstat = buildattribute(ocname,octypetonc(ocetype),nvalues,values,&att);
if(ncstat != NC_NOERR) goto done;
if(node->attributes == NULL)
node->attributes = nclistnew();
nclistpush(node->attributes,(void*)att);
if(strncmp(ocname,"DODS",strlen("DODS"))==0) {
att->invisible = 1;
/* Define extra semantics associated with
DODS and DODS_EXTRA attributes */
if(strcmp(ocname,"DODS.strlen")==0
|| strcmp(ocname,"DODS_EXTRA.strlen")==0) {
unsigned int maxstrlen = 0;
if(values != NULL) {
if(0==sscanf(values[0],"%u",&maxstrlen))
maxstrlen = 0;
}
node->dodsspecial.maxstrlen = maxstrlen;
#ifdef DEBUG
fprintf(stderr,"%s.maxstrlen=%d\n",node->ocname,(int)node->dodsspecial.maxstrlen);
#endif
} else if(strcmp(ocname,"DODS.dimName")==0
|| strcmp(ocname,"DODS_EXTRA.dimName")==0) {
if(values != NULL) {
node->dodsspecial.dimname = nulldup(values[0]);
#ifdef DEBUG
fprintf(stderr,"%s.dimname=%s\n",node->ocname,node->dodsspecial.dimname);
#endif
} else node->dodsspecial.dimname = NULL;
} else if(strcmp(ocname,"DODS.Unlimited_Dimension")==0
|| strcmp(ocname,"DODS_EXTRA.Unlimited_Dimension")==0) {
char* val0 = NULL;
if(values != NULL)
val0 = values[0];
if(val0 != NULL) {
if(nccomm->cdf.recorddimname != NULL) {
if(strcmp(nccomm->cdf.recorddimname,val0)!=0)
nclog(NCLOGWARN,"Duplicate DODS_EXTRA:Unlimited_Dimension specifications");
} else {
nccomm->cdf.recorddimname = nulldup(values[0]);
#ifdef DEBUG
fprintf(stderr,"%s.Unlimited_Dimension=%s\n",node->ocname,nccomm->cdf.recorddimname);
#endif
}
}
}
}
/* clean up */
if(values) {
oc_reclaim_strings(nvalues,values);
free(values);
values = NULL;
}
}
}
done:
if(values != NULL) free(values);
if(ocname != NULL) free(ocname);
if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat);
return THROW(ncstat);
}
/*
Build an NCattribute
from a DAP attribute.
As of Jun 27, 2017, we modify
to suppress nul characters and terminate
the name at the first nul.
*/
static NCerror
buildattribute(char* name, nc_type ptype,
size_t nvalues, char** values, NCattribute** attp)
{
int i;
NCerror ncstat = NC_NOERR;
NCattribute* att = NULL;
att = (NCattribute*)calloc(1,sizeof(NCattribute));
MEMCHECK(att,NC_ENOMEM);
att->name = nulldup(name);
att->etype = ptype;
att->values = nclistnew();
for(i=0;i<nvalues;i++) {
char* copy = nulldup(values[i]);
nclistpush(att->values,(void*)copy);
}
if(attp) *attp = att;
else
free(att);
return THROW(ncstat);
}
|