[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:
dmh 2014-01-24 13:26:00 -07:00
parent 75adeae78b
commit 8541a32175
8 changed files with 40 additions and 29 deletions

View File

@ -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;}
}

View File

@ -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);

View File

@ -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;

View File

@ -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"

View File

@ -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);

View File

@ -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;
}

View File

@ -9,7 +9,7 @@
#endif
#ifndef OCDEBUG
#define OCDEBUG
#undef OCDEBUG
#endif
/* OCCATCHERROR is used to detect errors as close

View File

@ -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);