mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-03-19 17:30:27 +08:00
[NCF-284]/ ZQX-155900
Some servers do not properly implement the current DAP2 spec. It turns out that this server is one of those: http://nomads.ncep.noaa.gov:9090/ When a reference such as this is made: http://nomads.ncep.noaa.gov:9090/dods/gens/gens20140123/gep_all_12z?prmslmsl[0][0][0][0:359] tt is returning this: Dataset { float prmslmsl[ens=1][time=1][lat=1][lon=360]; } gens%2fgens20140123%2fgep_all_12z; when it should be returning this: Dataset { Structure { float prmslmsl[ens=1][time=1][lat=1][lon=360]; } prmslmsl; } gens%2fgens20140123%2fgep_all_12z; The reason is that when picking fields out of a grid, one must maintain the fully qualified name, so the grid is converted to an enclosing structure. It turns out that the problem was that when I create the new structure node, I was improperly linking it into the existing graph. This caused a null pointer failure. Fix is to make sure the relevant field (node->root) is set.
This commit is contained in:
parent
75adeae78b
commit
8541a32175
@ -227,7 +227,7 @@ buildcachenode34(NCDAPCOMMON* nccomm,
|
||||
|
||||
/* re-struct*/
|
||||
if(!FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE)) {
|
||||
ncstat = restruct3(dxdroot,nccomm->cdf.ddsroot,constraint->projections);
|
||||
ncstat = restruct3(nccomm, dxdroot,nccomm->cdf.ddsroot,constraint->projections);
|
||||
if(ncstat) {THROWCHK(ncstat); goto done;}
|
||||
}
|
||||
|
||||
|
@ -16,11 +16,11 @@ CDFnode* v4node = NULL;
|
||||
|
||||
/* Forward*/
|
||||
static NCerror sequencecheck3r(CDFnode* node, NClist* vars, CDFnode* topseq);
|
||||
static NCerror restruct3r(CDFnode*, CDFnode*, NClist*);
|
||||
static NCerror repairgrids(NClist*);
|
||||
static NCerror structwrap3(CDFnode*, CDFnode*, int, CDFnode*, int);
|
||||
static NCerror restruct3r(NCDAPCOMMON*, CDFnode*, CDFnode*, NClist*);
|
||||
static NCerror repairgrids(NCDAPCOMMON*, NClist*);
|
||||
static NCerror structwrap3(NCDAPCOMMON*, CDFnode*, CDFnode*, int, CDFnode*, int);
|
||||
static int findin(CDFnode* parent, CDFnode* child);
|
||||
static CDFnode* makenewstruct3(CDFnode* node, CDFnode* template);
|
||||
static CDFnode* makenewstruct3(NCDAPCOMMON*, CDFnode*, CDFnode*);
|
||||
static NCerror mapnodes3r(CDFnode*, CDFnode*, int depth);
|
||||
static NCerror mapfcn(CDFnode* dstnode, CDFnode* srcnode);
|
||||
static NCerror definedimsetplus3(NCDAPCOMMON* nccomm, CDFnode* node);
|
||||
@ -315,7 +315,7 @@ Input is
|
||||
*/
|
||||
|
||||
NCerror
|
||||
restruct3(CDFnode* ddsroot, CDFnode* template, NClist* projections)
|
||||
restruct3(NCDAPCOMMON* ncc, CDFnode* ddsroot, CDFnode* template, NClist* projections)
|
||||
{
|
||||
NCerror ncstat = NC_NOERR;
|
||||
NClist* repairs = nclistnew();
|
||||
@ -338,11 +338,11 @@ fprintf(stderr,"restruct: template=%s\n",dumptree(template));
|
||||
/* Match roots */
|
||||
if(!simplenodematch34(ddsroot,template))
|
||||
ncstat = NC_EDATADDS;
|
||||
else if(!restruct3r(ddsroot,template,repairs))
|
||||
else if(!restruct3r(ncc, ddsroot,template,repairs))
|
||||
ncstat = NC_EDATADDS;
|
||||
else if(nclistlength(repairs) > 0) {
|
||||
/* Do the repairs */
|
||||
ncstat = repairgrids(repairs);
|
||||
ncstat = repairgrids(ncc, repairs);
|
||||
}
|
||||
|
||||
if(repairs)
|
||||
@ -364,7 +364,7 @@ we expected a grid.
|
||||
*/
|
||||
|
||||
static int
|
||||
restruct3r(CDFnode* parentnode, CDFnode* templateparent, NClist* repairlist)
|
||||
restruct3r(NCDAPCOMMON* ncc, CDFnode* parentnode, CDFnode* templateparent, NClist* repairlist)
|
||||
{
|
||||
int index, i, j, match;
|
||||
|
||||
@ -399,7 +399,7 @@ ocfqn(subnode->ocnode),ocfqn(matchnode->ocnode));
|
||||
node of the template, so it is ok =>
|
||||
recurse looking for nested mis-matches
|
||||
*/
|
||||
if(!restruct3r(subnode,matchnode,repairlist))
|
||||
if(!restruct3r(ncc,subnode,matchnode,repairlist))
|
||||
return 0;
|
||||
} else {
|
||||
/* If we do not have a direct match, then we need to look
|
||||
@ -430,7 +430,7 @@ ocfqn(subnode->ocnode),ocfqn(matchnode->ocnode));
|
||||
/* Wrap the node wrt the template grid or template struct */
|
||||
|
||||
static NCerror
|
||||
repairgrids(NClist* repairlist)
|
||||
repairgrids(NCDAPCOMMON* ncc, NClist* repairlist)
|
||||
{
|
||||
NCerror ncstat = NC_NOERR;
|
||||
int i;
|
||||
@ -440,7 +440,7 @@ repairgrids(NClist* repairlist)
|
||||
CDFnode* template = (CDFnode*)nclistget(repairlist,i+1);
|
||||
int index = findin(node->container,node);
|
||||
int tindex = findin(template->container,template);
|
||||
ncstat = structwrap3(node,node->container,index,
|
||||
ncstat = structwrap3(ncc, node,node->container,index,
|
||||
template->container,tindex);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,"repairgrids: %s -> %s\n",
|
||||
@ -452,14 +452,13 @@ ocfqn(node->ocnode),ocfqn(template->ocnode));
|
||||
}
|
||||
|
||||
static NCerror
|
||||
structwrap3(CDFnode* node, CDFnode* parent, int parentindex,
|
||||
structwrap3(NCDAPCOMMON* ncc, CDFnode* node, CDFnode* parent, int parentindex,
|
||||
CDFnode* templategrid, int gridindex)
|
||||
{
|
||||
CDFnode* newstruct;
|
||||
|
||||
ASSERT((templategrid->nctype == NC_Grid));
|
||||
|
||||
newstruct = makenewstruct3(node,templategrid);
|
||||
newstruct = makenewstruct3(ncc, node,templategrid);
|
||||
if(newstruct == NULL) {return THROW(NC_ENOMEM);}
|
||||
|
||||
/* replace the node with the new structure
|
||||
@ -489,17 +488,14 @@ findin(CDFnode* parent, CDFnode* child)
|
||||
*/
|
||||
|
||||
static CDFnode*
|
||||
makenewstruct3(CDFnode* node, CDFnode* templatenode)
|
||||
makenewstruct3(NCDAPCOMMON* ncc, CDFnode* node, CDFnode* templatenode)
|
||||
{
|
||||
CDFnode* newstruct = (CDFnode*)calloc(1,sizeof(CDFnode));
|
||||
CDFnode* newstruct = makecdfnode34(ncc,templatenode->ocname,OC_Structure,
|
||||
templatenode->ocnode, node->container);
|
||||
if(newstruct == NULL) return NULL;
|
||||
newstruct->nctype = NC_Structure;
|
||||
newstruct->nc_virtual = 1;
|
||||
newstruct->ocname = nulldup(templatenode->ocname);
|
||||
newstruct->ocnode = templatenode->ocnode;
|
||||
newstruct->ncbasename = nulldup(templatenode->ncbasename);
|
||||
newstruct->subnodes = nclistnew();
|
||||
newstruct->container = node->container;
|
||||
newstruct->template = templatenode;
|
||||
node->container = newstruct;
|
||||
nclistpush(newstruct->subnodes,(void*)node);
|
||||
|
@ -358,7 +358,6 @@ makegetvar34(NCDAPCOMMON* nccomm, CDFnode* var, void* data, nc_type dsttype, Get
|
||||
getvar->target = var;
|
||||
getvar->memory = data;
|
||||
getvar->dsttype = dsttype;
|
||||
getvar->target = var;
|
||||
if(ncstat) nullfree(getvar);
|
||||
return ncstat;
|
||||
}
|
||||
@ -400,6 +399,10 @@ makecdfnode34(NCDAPCOMMON* nccomm, char* ocname, OCtype octype,
|
||||
oc_dds_atomictype(nccomm->oc.conn,ocnode,&octype);
|
||||
node->etype = octypetonc(octype);
|
||||
}
|
||||
if(container != NULL)
|
||||
node->root = container->root;
|
||||
else if(node->nctype == NC_Dataset)
|
||||
node->root = node;
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -456,32 +459,45 @@ buildcdftree34r(NCDAPCOMMON* nccomm, OCddsnode ocnode, CDFnode* container,
|
||||
|
||||
switch (octype) {
|
||||
case OC_Dataset:
|
||||
cdfnode = makecdfnode34(nccomm,ocname,octype,ocnode,container);
|
||||
nclistpush(tree->nodes,(void*)cdfnode);
|
||||
tree->root = cdfnode;
|
||||
cdfnode->tree = tree;
|
||||
break;
|
||||
|
||||
case OC_Grid:
|
||||
case OC_Structure:
|
||||
case OC_Sequence:
|
||||
cdfnode = makecdfnode34(nccomm,ocname,octype,ocnode,container);
|
||||
nclistpush(tree->nodes,(void*)cdfnode);
|
||||
#if 0
|
||||
if(tree->root == NULL) {
|
||||
tree->root = cdfnode;
|
||||
cdfnode->tree = tree;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case OC_Atomic:
|
||||
cdfnode = makecdfnode34(nccomm,ocname,octype,ocnode,container);
|
||||
nclistpush(tree->nodes,(void*)cdfnode);
|
||||
#if 0
|
||||
if(tree->root == NULL) {
|
||||
tree->root = cdfnode;
|
||||
cdfnode->tree = tree;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case OC_Dimension:
|
||||
default: PANIC1("buildcdftree: unexpect OC node type: %d",(int)octype);
|
||||
|
||||
}
|
||||
#if 0
|
||||
/* cross link */
|
||||
assert(tree->root != NULL);
|
||||
cdfnode->root = tree->root;
|
||||
#endif
|
||||
|
||||
if(ocrank > 0) defdimensions(ocnode,cdfnode,nccomm,tree);
|
||||
for(i=0;i<ocnsubnodes;i++) {
|
||||
@ -726,6 +742,7 @@ simplenodematch34(CDFnode* node1, CDFnode* node2)
|
||||
which returns different Dataset {...} names
|
||||
depending on the constraint.
|
||||
*/
|
||||
|
||||
if(FLAGSET(node1->root->tree->owner->controls,NCF_COLUMBIA)
|
||||
&& node1->nctype == NC_Dataset) return 1;
|
||||
|
||||
|
@ -9,7 +9,8 @@ TOP="/home/dmh/mach/netcdf-c"
|
||||
#TOP="/cygdrive/c/Users/dmh/svn/trunk"
|
||||
|
||||
#F="http://ticket:ticket1@utmea.enea.it:8080/thredds/dodsC/UNIDATA_passwd/head_out.nc"
|
||||
F="http://motherlode.ucar.edu"
|
||||
F="http://nomads.ncep.noaa.gov:9090/dods/gens/gens20140123/gep_all_12z"
|
||||
VAR=prmslmsl
|
||||
|
||||
#PROG=./ncd
|
||||
PROG="$TOP/ncdump/ncdump"
|
||||
|
@ -130,7 +130,7 @@ extern size_t dap_zero[NC_MAX_VAR_DIMS];
|
||||
|
||||
extern NCerror nc3d_open(const char* path, int mode, int* ncidp);
|
||||
extern int nc3d_close(int ncid);
|
||||
extern NCerror restruct3(CDFnode* ddsroot, CDFnode* template, NClist*);
|
||||
extern NCerror restruct3(NCDAPCOMMON*, CDFnode* ddsroot, CDFnode* template, NClist*);
|
||||
extern void setvisible(CDFnode* root, int visible);
|
||||
extern NCerror mapnodes3(CDFnode* dstroot, CDFnode* srcroot);
|
||||
extern void unmap3(CDFnode* root);
|
||||
|
@ -680,7 +680,7 @@ fetchconstrainedmetadata3(NCDAPCOMMON* dapcomm)
|
||||
|
||||
if(!FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) {
|
||||
/* fix DAP server problem by adding back any inserting needed structure nodes */
|
||||
ncstat = restruct3(dapcomm->cdf.ddsroot,dapcomm->cdf.fullddsroot,dapcomm->oc.dapconstraint->projections);
|
||||
ncstat = restruct3(dapcomm, dapcomm->cdf.ddsroot,dapcomm->cdf.fullddsroot,dapcomm->oc.dapconstraint->projections);
|
||||
if(ncstat) goto fail;
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef OCDEBUG
|
||||
#define OCDEBUG
|
||||
#undef OCDEBUG
|
||||
#endif
|
||||
|
||||
/* OCCATCHERROR is used to detect errors as close
|
||||
|
@ -124,9 +124,6 @@ readpacket(OCstate* state, OCURI* url,OCbytes* packet,OCdxd dxd,long* lastmodifi
|
||||
{
|
||||
fprintf(stderr,"readpacket: packet.size=%lu\n",
|
||||
(unsigned long)ocbyteslength(packet));
|
||||
int count = ocbyteslength(packet);
|
||||
if(count > 20) count = 20;
|
||||
fprintf(stderr,"packet[0..20]=|%20s|",ocbytescontents(packet));
|
||||
}
|
||||
#endif
|
||||
return OCTHROW(stat);
|
||||
|
Loading…
x
Reference in New Issue
Block a user