1/*********************************************************************
2 *   Copyright 1993, UCAR/Unidata
3 *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
4 *********************************************************************/
5
6#include "config.h"
7#ifdef USE_PARALLEL
8#include "netcdf_par.h"
9#endif
10#include "ncdap.h"
11#include "dapdump.h"
12#include "dceconstraints.h"
13
14#define CHECK(n) if((n) != NC_NOERR) {return (n);} else {}
15
16static void dumptreer(CDFnoderootNCbytesbuf, int indent, int visible);
17
18int
19dumpmetadata(int ncidNChdr** hdrp)
20{
21    int stat,i,j,k;
22    NChdrhdr = (NChdr*)calloc(1,sizeof(NChdr));
23    MEMCHECK(hdr,NC_ENOMEM);
24    hdr->ncid = ncid;
25    hdr->content = ncbytesnew();
26    if(hdrp) *hdrp = hdr;
27
28    stat = nc_inq(hdr->ncid,
29   &hdr->ndims,
30   &hdr->nvars,
31   &hdr->ngatts,
32   &hdr->unlimid);
33    CHECK(stat);
34    if(ncdap3debug > 0) {
35        fprintf(stdout,"ncid=%d ngatts=%d ndims=%d nvars=%d unlimid=%d\n",
36 hdr->ncid,hdr->ngatts,hdr->ndims,hdr->nvars,hdr->unlimid);
37    }
38    hdr->gatts = (NCattribute*)calloc(1,hdr->ngatts*sizeof(NCattribute));
39    MEMCHECK(hdr->gatts,NC_ENOMEM);
40    if(hdr->ngatts > 0)
41 fprintf(stdout,"global attributes:\n");
42    for(i=0;i<hdr->ngatts;i++) {
43 NCattributeatt = &hdr->gatts[i];
44        char attname[NC_MAX_NAME];
45 nc_type nctype;
46 size_t typesize;
47        size_t nvalues;
48
49        stat = nc_inq_attname(hdr->ncid,NC_GLOBAL,i,attname);
50        CHECK(stat);
51 att->name = nulldup(attname);
52 stat = nc_inq_att(hdr->ncid,NC_GLOBAL,att->name,&nctype,&nvalues);
53        CHECK(stat);
54 att->etype = nctypetodap(nctype);
55  typesize = nctypesizeof(att->etype);
56 fprintf(stdout,"\t[%d]: name=%s type=%s values(%lu)=",
57 i,att->name,nctypetostring(octypetonc(att->etype)),
58                        (unsigned long)nvalues);
59 if(nctype == NC_CHAR) {
60     size_t len = typesize*nvalues;
61     char* values = (char*)malloc(len+1);/* for null terminate*/
62     MEMCHECK(values,NC_ENOMEM);
63     stat = nc_get_att(hdr->ncid,NC_GLOBAL,att->name,values);
64            CHECK(stat);
65     values[len] = '\0';
66     fprintf(stdout," '%s'",values);
67 } else {
68     size_t len = typesize*nvalues;
69     char* values = (char*)malloc(len);
70     MEMCHECK(values,NC_ENOMEM);
71     stat = nc_get_att(hdr->ncid,NC_GLOBAL,att->name,values);
72            CHECK(stat);
73     for(k=0;k<nvalues;k++) {
74 fprintf(stdout," ");
75 dumpdata1(octypetonc(att->etype),k,values);
76     }
77 }
78 fprintf(stdout,"\n");
79    }
80
81    hdr->dims = (Dim*)malloc(hdr->ndims*sizeof(Dim));
82    MEMCHECK(hdr->dims,NC_ENOMEM);
83    for(i=0;i<hdr->ndims;i++) {
84 hdr->dims[i].dimid = i;
85        stat = nc_inq_dim(hdr->ncid,
86                   hdr->dims[i].dimid,
87                   hdr->dims[i].name,
88                   &hdr->dims[i].size);
89        CHECK(stat);
90 fprintf(stdout,"dim[%d]: name=%s size=%lu\n",
91 i,hdr->dims[i].name,(unsigned long)hdr->dims[i].size);
92    }
93    hdr->vars = (Var*)malloc(hdr->nvars*sizeof(Var));
94    MEMCHECK(hdr->vars,NC_ENOMEM);
95    for(i=0;i<hdr->nvars;i++) {
96 Varvar = &hdr->vars[i];
97 nc_type nctype;
98 var->varid = i;
99        stat = nc_inq_var(hdr->ncid,
100                   var->varid,
101                   var->name,
102   &nctype,
103   &var->ndims,
104   var->dimids,
105                   &var->natts);
106        CHECK(stat);
107 var->nctype = (nctype);
108 fprintf(stdout,"var[%d]: name=%s type=%s |dims|=%d",
109 i,
110 var->name,
111 nctypetostring(var->nctype),
112 var->ndims);
113 fprintf(stdout," dims={");
114 for(j=0;j<var->ndims;j++) {
115     fprintf(stdout," %d",var->dimids[j]);
116 }
117 fprintf(stdout,"}\n");
118 var->atts = (NCattribute*)malloc(var->natts*sizeof(NCattribute));
119        MEMCHECK(var->atts,NC_ENOMEM);
120        for(j=0;j<var->natts;j++) {
121     NCattributeatt = &var->atts[j];
122     char attname[NC_MAX_NAME];
123     size_t typesize;
124     char* values;
125     nc_type nctype;
126     size_t nvalues;
127            stat = nc_inq_attname(hdr->ncid,var->varid,j,attname);
128     CHECK(stat);
129     att->name = nulldup(attname);
130     stat = nc_inq_att(hdr->ncid,var->varid,att->name,&nctype,&nvalues);
131     CHECK(stat);
132     att->etype = nctypetodap(nctype);
133     typesize = nctypesizeof(att->etype);
134     values = (char*)malloc(typesize*nvalues);
135     MEMCHECK(values,NC_ENOMEM);
136     stat = nc_get_att(hdr->ncid,var->varid,att->name,values);
137            CHECK(stat);
138     fprintf(stdout,"\tattr[%d]: name=%s type=%s values(%lu)=",
139 j,att->name,nctypetostring(octypetonc(att->etype)),(unsigned long)nvalues);
140     for(k=0;k<nvalues;k++) {
141 fprintf(stdout," ");
142 dumpdata1(octypetonc(att->etype),k,values);
143     }
144     fprintf(stdout,"\n");
145 }
146    }
147    fflush(stdout);
148    return NC_NOERR;
149}
150
151void
152dumpdata1(nc_type nctype, size_t index, char* data)
153{
154    switch (nctype) {
155    case NC_CHAR:
156 fprintf(stdout,"'%c' %hhd",data[index],data[index]);
157 break;
158    case NC_BYTE:
159 fprintf(stdout,"%hdB",((signed char*)data)[index]);
160 break;
161    case NC_UBYTE:
162 fprintf(stdout,"%huB",((unsigned char*)data)[index]);
163 break;
164    case NC_SHORT:
165 fprintf(stdout,"%hdS",((short*)data)[index]);
166 break;
167    case NC_USHORT:
168 fprintf(stdout,"%hdUS",((unsigned short*)data)[index]);
169 break;
170    case NC_INT:
171 fprintf(stdout,"%d",((int*)data)[index]);
172 break;
173    case NC_UINT:
174 fprintf(stdout,"%uU",((unsigned int*)data)[index]);
175 break;
176    case NC_FLOAT:
177 fprintf(stdout,"%#gF",((float*)data)[index]);
178 break;
179    case NC_DOUBLE:
180 fprintf(stdout,"%#gD",((double*)data)[index]);
181 break;
182    case NC_STRING:
183 fprintf(stdout,"\"%s\"",((char**)data)[index]);
184 break;
185    default:
186 fprintf(stdout,"Unknown type: %i",nctype);
187 break;
188    }
189    fflush(stdout);
190}
191
192/* Following should be kept consistent with
193   the makeXXXstring3 routines in constraints3.c
194*/
195
196/* Convert an NCprojection instance into a string
197   that can be used with the url
198*/
199char*
200dumpprojections(NClistprojections)
201{
202    char* tmp;
203    int v = dceverbose;
204    dceverbose = 1;
205    tmp = dcelisttostring(projections,",");
206    dceverbose = v;
207    return tmp;
208}
209
210char*
211dumpprojection(DCEprojectionproj)
212{
213    char* tmp;
214    int v = dceverbose;
215    dceverbose = 1;
216    tmp = dcetostring((DCEnode*)proj);
217    dceverbose = v;
218    return tmp;
219}
220
221char*
222dumpselections(NClistselections)
223{
224    return dcelisttostring(selections,"&");
225}
226
227char*
228dumpselection(DCEselectionsel)
229{
230    return dcetostring((DCEnode*)sel);
231}
232
233char*
234dumpconstraint(DCEconstraintcon)
235{
236    char* tmp;
237    int v = dceverbose;
238    dceverbose = 1;
239    tmp = dcetostring((DCEnode*)con);
240    dceverbose = v;
241    return tmp;
242}
243
244char*
245dumpsegments(NClistsegments)
246{
247    return dcelisttostring(segments,".");
248}
249
250char*
251dumppath(CDFnodeleaf)
252{
253    NClistpath = nclistnew();
254    NCbytesbuf = ncbytesnew();
255    char* result;
256    int i;
257
258    if(leaf == NULL) return nulldup("");
259    collectnodepath(leaf,path,!WITHDATASET);
260    for(i=0;i<nclistlength(path);i++) {
261 CDFnodenode = (CDFnode*)nclistget(path,i);
262 if(i > 0) ncbytescat(buf,".");
263 ncbytescat(buf,node->ncbasename);
264    }
265    result = ncbytesdup(buf);
266    ncbytesfree(buf);
267    nclistfree(path);
268    return result;
269}
270
271static void
272dumpindent(int indentNCbytesbuf)
273{
274    static char* indentstr = "  ";
275    int i;
276    for(i=0;i<indent;i++) ncbytescat(buf,indentstr);
277}
278
279static void
280dumptreer1(CDFnoderootNCbytesbuf, int indent, char* tag, int visible)
281{
282    int i;
283    dumpindent(indent,buf);
284    ncbytescat(buf,tag);
285    ncbytescat(buf," {\n");
286    for(i=0;i<nclistlength(root->subnodes);i++) {
287 CDFnodenode = (CDFnode*)nclistget(root->subnodes,i);
288 if(visible && root->invisible) continue;
289 if(root->nctype == NC_Grid) {
290     if(i==0) {
291 dumpindent(indent+1,buf);
292         ncbytescat(buf,"Array:\n");
293     } else if(i==1) {
294 dumpindent(indent+1,buf);
295         ncbytescat(buf,"Maps:\n");
296     }
297     dumptreer(node,buf,indent+2,visible);
298 } else {
299     dumptreer(node,buf,indent+1,visible);
300 }
301    }
302    dumpindent(indent,buf);
303    ncbytescat(buf,"} ");
304    ncbytescat(buf,(root->ncbasename?root->ncbasename:"<?>"));
305}
306
307static void
308dumptreer(CDFnoderootNCbytesbuf, int indent, int visible)
309{
310    int i;
311    char* primtype = NULL;
312    NClistdimset = NULL;
313
314    if(visible && root->invisible) return;
315    switch (root->nctype) {
316    case NC_Dataset:
317 dumptreer1(root,buf,indent,"Dataset",visible);
318 break;
319    case NC_Sequence:
320 dumptreer1(root,buf,indent,"Sequence",visible);
321 break;
322    case NC_Structure:
323 dumptreer1(root,buf,indent,"Structure",visible);
324 break;
325    case NC_Grid:
326 dumptreer1(root,buf,indent,"Grid",visible);
327 break;
328    case NC_Atomic:
329 switch (root->etype) {
330 case NC_BYTEprimtype = "byte"; break;
331 case NC_CHARprimtype = "char"; break;
332 case NC_SHORTprimtype = "short"; break;
333 case NC_INTprimtype = "int"; break;
334 case NC_FLOATprimtype = "float"; break;
335 case NC_DOUBLEprimtype = "double"; break;
336 case NC_UBYTEprimtype = "ubyte"; break;
337 case NC_USHORTprimtype = "ushort"; break;
338 case NC_UINTprimtype = "uint"; break;
339 case NC_INT64primtype = "int64"; break;
340 case NC_UINT64primtype = "uint64"; break;
341 case NC_STRINGprimtype = "string"; break;
342 default: break;
343 }
344 dumpindent(indent,buf);
345 ncbytescat(buf,primtype);
346 ncbytescat(buf," ");
347        ncbytescat(buf,(root->ncbasename?root->ncbasename:"<?>"));
348 break;
349    default: break;
350    }
351
352    if(nclistlength(root->array.dimsetplus) > 0) dimset = root->array.dimsetplus;
353    else if(nclistlength(root->array.dimset0) > 0) dimset = root->array.dimset0;
354    if(dimset != NULL) {
355 for(i=0;i<nclistlength(dimset);i++) {
356     CDFnodedim = (CDFnode*)nclistget(dimset,i);
357     char tmp[64];
358     ncbytescat(buf,"[");
359     if(dim->ncbasename != NULL) {
360 ncbytescat(buf,dim->ncbasename);
361         ncbytescat(buf,"=");
362     }
363     snprintf(tmp,sizeof(tmp),"%lu",(unsigned long)dim->dim.declsize);
364     ncbytescat(buf,tmp);
365     ncbytescat(buf,"]");
366 }
367    }
368    ncbytescat(buf,";\n");
369}
370
371char*
372dumptree(CDFnoderoot)
373{
374    NCbytesbuf = ncbytesnew();
375    char* result;
376    dumptreer(root,buf,0,0);
377    result = ncbytesdup(buf);
378    ncbytesfree(buf);
379    return result;
380}
381
382char*
383dumpvisible(CDFnoderoot)
384{
385    NCbytesbuf = ncbytesnew();
386    char* result;
387    dumptreer(root,buf,0,1);
388    result = ncbytesdup(buf);
389    ncbytesfree(buf);
390    return result;
391}
392
393/* Provide detailed data on a CDFnode */
394char*
395dumpnode(CDFnodenode)
396{
397    NCbytesbuf = ncbytesnew();
398    char* result;
399    int i;
400    char* nctype = NULL;
401    char* primtype = NULL;
402    char tmp[1024];
403
404    switch (node->nctype) {
405    case NC_Datasetnctype = "Dataset"; break;
406    case NC_Sequencenctype = "Sequence"; break;
407    case NC_Structurenctype = "Structure"; break;
408    case NC_Gridnctype = "Grid"; break;
409    case NC_Atomic:
410 switch (node->etype) {
411 case NC_BYTEprimtype = "byte"; break;
412 case NC_CHARprimtype = "char"; break;
413 case NC_SHORTprimtype = "short"; break;
414 case NC_INTprimtype = "int"; break;
415 case NC_FLOATprimtype = "float"; break;
416 case NC_DOUBLEprimtype = "double"; break;
417 case NC_UBYTEprimtype = "ubyte"; break;
418 case NC_USHORTprimtype = "ushort"; break;
419 case NC_UINTprimtype = "uint"; break;
420 case NC_INT64primtype = "int64"; break;
421 case NC_UINT64primtype = "uint64"; break;
422 case NC_STRINGprimtype = "string"; break;
423 default: break;
424 }
425 break;
426    default: break;
427    }
428    snprintf(tmp,sizeof(tmp),"%s %s {\n",
429 (nctype?nctype:primtype),node->ocname);
430    ncbytescat(buf,tmp);
431    snprintf(tmp,sizeof(tmp),"ocnode=%lx\n",(unsigned long)node->ocnode);
432    ncbytescat(buf,tmp);
433    snprintf(tmp,sizeof(tmp),"container=%s\n",
434 (node->container?node->container->ocname:"null"));
435    ncbytescat(buf,tmp);
436    snprintf(tmp,sizeof(tmp),"root=%s\n",
437 (node->root?node->root->ocname:"null"));
438    ncbytescat(buf,tmp);
439    snprintf(tmp,sizeof(tmp),"ncbasename=%s\n",node->ncbasename);
440    ncbytescat(buf,tmp);
441    snprintf(tmp,sizeof(tmp),"ncfullname=%s\n",node->ncfullname);
442    ncbytescat(buf,tmp);
443    snprintf(tmp,sizeof(tmp),"|subnodes|=%ld\n",nclistlength(node->subnodes));
444    ncbytescat(buf,tmp);
445    snprintf(tmp,sizeof(tmp),"externaltype=%d\n",node->externaltype);
446    ncbytescat(buf,tmp);
447    snprintf(tmp,sizeof(tmp),"ncid=%d\n",node->ncid);
448    ncbytescat(buf,tmp);
449    snprintf(tmp,sizeof(tmp),"maxstringlength=%ld\n",node->maxstringlength);
450    ncbytescat(buf,tmp);
451    snprintf(tmp,sizeof(tmp),"sequencelimit=%ld\n",node->sequencelimit);
452    ncbytescat(buf,tmp);
453    snprintf(tmp,sizeof(tmp),"usesequence=%d\n",node->usesequence);
454    ncbytescat(buf,tmp);
455    snprintf(tmp,sizeof(tmp),"elided=%d\n",node->elided);
456    ncbytescat(buf,tmp);
457    snprintf(tmp,sizeof(tmp),"invisible=%d\n",node->invisible);
458    ncbytescat(buf,tmp);
459    snprintf(tmp,sizeof(tmp),"attachment=%s\n",
460 (node->attachment?node->attachment->ocname:"null"));
461    ncbytescat(buf,tmp);
462    snprintf(tmp,sizeof(tmp),"rank=%lu\n",nclistlength(node->array.dimset0));
463    ncbytescat(buf,tmp);
464    for(i=0;i<nclistlength(node->array.dimset0);i++) {
465 CDFnodedim = (CDFnode*)nclistget(node->array.dimset0,i);
466        snprintf(tmp,sizeof(tmp),"dims[%d]={\n",i);
467        ncbytescat(buf,tmp);
468 snprintf(tmp,sizeof(tmp),"    ocname=%s\n",dim->ocname);
469        ncbytescat(buf,tmp);
470 snprintf(tmp,sizeof(tmp),"    ncbasename=%s\n",dim->ncbasename);
471        ncbytescat(buf,tmp);
472 snprintf(tmp,sizeof(tmp),"    dimflags=%u\n",
473 (unsigned int)dim->dim.dimflags);
474        ncbytescat(buf,tmp);
475 snprintf(tmp,sizeof(tmp),"    declsize=%lu\n",
476     (unsigned long)dim->dim.declsize);
477        ncbytescat(buf,tmp);
478        snprintf(tmp,sizeof(tmp),"    }\n");
479        ncbytescat(buf,tmp);
480    }
481
482    result = ncbytesdup(buf);
483    ncbytesfree(buf);
484    return result;
485}
486
487char*
488dumpalign(NCalignmentncalign)
489{
490    char* result;
491    char tmp[1024];
492    if(ncalign == NULL)
493 result = nulldup("NCalignment{size=-- alignment=-- offset=--}");
494    else {
495        snprintf(tmp,sizeof(tmp),"NCalignment{size=%lu alignment=%lu offset=%lu}",
496  ncalign->size,ncalign->alignment,ncalign->offset);
497        result = nulldup(tmp);
498    }
499    return result;
500}
501
502char*
503dumpcachenode(NCcachenodenode)
504{
505    char* result = NULL;
506    char tmp[8192];
507    int i;
508    NCbytesbuf;
509
510    if(node == NULL) return strdup("cachenode{null}");
511    buf = ncbytesnew();
512    result = dcebuildconstraintstring(node->constraint);
513    snprintf(tmp,sizeof(tmp),"cachenode%s(%lx){size=%lu; constraint=%s; vars=",
514 node->isprefetch?"*":"",
515 (unsigned long)node,
516 (unsigned long)node->xdrsize,
517         result);
518    ncbytescat(buf,tmp);
519    if(nclistlength(node->vars)==0)
520 ncbytescat(buf,"null");
521    else for(i=0;i<nclistlength(node->vars);i++) {
522 CDFnodevar = (CDFnode*)nclistget(node->vars,i);
523 if(i > 0) ncbytescat(buf,",");
524 ncbytescat(buf,makecdfpathstring(var,"."));
525    }
526    ncbytescat(buf,"}");
527    result = ncbytesdup(buf);
528    ncbytesfree(buf);
529    return result;
530}
531
532char*
533dumpcache(NCcachecache)
534{
535    char* result = NULL;
536    char tmp[8192];
537    int i;
538    NCbytesbuf;
539
540    if(cache == NULL) return strdup("cache{null}");
541    buf = ncbytesnew();
542    snprintf(tmp,sizeof(tmp),"cache{limit=%lu; size=%lu;\n",
543 (unsigned long)cache->cachelimit,
544 (unsigned long)cache->cachesize);
545    ncbytescat(buf,tmp);
546    if(cache->prefetch) {
547 ncbytescat(buf,"\tprefetch=");
548 ncbytescat(buf,dumpcachenode(cache->prefetch));
549 ncbytescat(buf,"\n");
550    }
551    if(nclistlength(cache->nodes) > 0) {
552        for(i=0;i<nclistlength(cache->nodes);i++) {
553        NCcachenodenode = (NCcachenode*)nclistget(cache->nodes,i);
554     ncbytescat(buf,"\t");
555     ncbytescat(buf,dumpcachenode(node));
556     ncbytescat(buf,"\n");
557 }
558    }
559    ncbytescat(buf,"}");
560    result = ncbytesdup(buf);
561    ncbytesfree(buf);
562    return result;
563}
564
565/* This should be consistent with makeslicestring3 in constraints3.c */
566char*
567dumpslice(DCEsliceslice)
568{
569    char buf[8192];
570    char tmp[8192];
571    buf[0] = '\0';
572    if(slice->last > slice->declsize && slice->declsize > 0)
573        slice->last = slice->declsize - 1;
574    if(slice->count == 1) {
575        snprintf(tmp,sizeof(tmp),"[%lu]",
576            (unsigned long)slice->first);
577    } else if(slice->stride == 1) {
578        snprintf(tmp,sizeof(tmp),"[%lu:%lu]",
579                (unsigned long)slice->first,
580                (unsigned long)slice->last);
581    } else {
582       snprintf(tmp,sizeof(tmp),"[%lu:%lu:%lu]",
583                (unsigned long)slice->first,
584                (unsigned long)slice->stride,
585                (unsigned long)slice->last);
586    }
587    strcat(buf,tmp);
588    return strdup(tmp);
589}
590
591char*
592dumpslices(DCEsliceslice, unsigned int rank)
593{
594    int i;
595    NCbytesbuf;
596    char* result = NULL;
597
598    buf = ncbytesnew();
599    for(i=0;i<rank;i++,slice++) {
600 char* sslice = dumpslice(slice);
601 if(sslice != NULL) {
602     ncbytescat(buf,sslice);
603     free(sslice);
604 }
605    }
606    result = ncbytesdup(buf);
607    ncbytesfree(buf);
608    return result;
609}
610
611void
612dumpraw(void* o)
613{
614    fprintf(stderr,"%s\n",dcerawtostring(o));
615    fflush(stderr);
616}
617
618void
619dumplistraw(NClistl)
620{
621    fprintf(stderr,"%s\n",dcerawlisttostring(l));
622    fflush(stderr);
623}
624
625/* For debugging */
626void
627dumpstringlist(NClistl)
628{
629    int i;
630    for(i=0;i<nclistlength(l);i++) {
631 const char* s = (const char*)nclistget(l,i);
632 fprintf(stderr,"[%d]: |%s|\n",i,s);
633    }
634    fflush(stderr);
635}


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