source: XIOS/dev/dev_olga/src/extern/src_netcdf4/ocdump.c @ 1022

Last change on this file since 1022 was 1022, checked in by mhnguyen, 7 years ago
File size: 11.4 KB
Line 
1/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
2   See the COPYRIGHT file for more information.
3*/
4
5#include "config.h"
6#include <sys/stat.h>
7
8#ifdef NETINET_IN_H
9#include <netinet/in.h>
10#endif
11
12#include "ocinternal.h"
13#include "ocdata.h"
14#include "ocdebug.h"
15
16#define MAXLEVEL 1
17
18/*Forward*/
19static void dumpocnode1(OCnode* node, int depth);
20static void dumpdimensions(OCnode* node);
21static void dumpattvalue(OCtype nctype, char** aset, int index);
22
23static char* sindent = NULL;
24
25static char*
26dent(int n)
27{
28    if(sindent == NULL) {
29        sindent = (char*)ocmalloc(102);
30        MEMCHECK(sindent,NULL);
31        memset((void*)sindent,(int)' ',(size_t)101);
32        sindent[101] = '\0';
33    }
34    if(n > 100) n = 100;
35    return sindent+(100-n);
36}
37
38/* support [dd] leader*/
39static char*
40dent2(int n) {return dent(n+4);}
41
42void
43ocdumpnode(OCnode* node)
44{
45    if(node != NULL) {
46        dumpocnode1(node,0);
47    } else {
48        fprintf(stdout,"<NULL>\n");
49    }
50    fflush(stdout);
51}
52
53static void
54dumpskip(OCnode* node)
55{
56    char tmpc[64];
57    char tmpi[64];
58    char tmpt[64];
59    char tmpo[64];
60    if(node->skip.count == OCINDETERMINATE)
61        strcpy(tmpc,"?");
62    else
63        snprintf(tmpc,sizeof(tmpc),"%lu",(unsigned long)node->skip.count);
64    if(node->skip.instancesize == OCINDETERMINATE)
65        strcpy(tmpi,"?");
66    else
67        snprintf(tmpi,sizeof(tmpi),"%lu",(unsigned long)node->skip.instancesize);
68    if(node->skip.totalsize == OCINDETERMINATE)
69        strcpy(tmpt,"?");
70    else
71        snprintf(tmpt,sizeof(tmpt),"%lu",(unsigned long)node->skip.totalsize);
72    if(node->skip.offset == OCINDETERMINATE)
73        strcpy(tmpo,"?");
74    else
75        snprintf(tmpo,sizeof(tmpo),"%lu",(unsigned long)node->skip.offset);
76
77    fprintf(stdout," [(%s*%s)/%s@%s]",tmpi,tmpc,tmpt,tmpo);
78}
79
80static void
81dumpocnode1(OCnode* node, int depth)
82{
83    unsigned int n;
84    switch (node->octype) {
85    case OC_Primitive: {
86        fprintf(stdout,"[%2d]%s ",depth,dent(depth));
87        if(node->name == NULL) OCPANIC("prim without name");
88        fprintf(stdout,"%s %s",octypetostring(node->etype),node->name);
89        dumpdimensions(node);
90#ifdef OCIGNORE
91        if(node->cache.cacheable) fprintf(stdout," [cached]");
92#endif
93        dumpskip(node);
94        fprintf(stdout," &%lx",(unsigned long)node);
95        fprintf(stdout,"\n");
96    } break;
97
98    case OC_Dataset: {
99        fprintf(stdout,"[%2d]%s ",depth,dent(depth));
100        fprintf(stdout,"dataset %s\n",
101                (node->name?node->name:""));
102        for(n=0;n<oclistlength(node->subnodes);n++) {
103            dumpocnode1((OCnode*)oclistget(node->subnodes,n),depth+1);
104        }
105    } break;
106
107    case OC_Structure: {
108        fprintf(stdout,"[%2d]%s ",depth,dent(depth));
109        fprintf(stdout,"struct %s",
110                (node->name?node->name:""));
111        dumpdimensions(node);
112        dumpskip(node);
113        fprintf(stdout," &%lx",(unsigned long)node);
114        fprintf(stdout,"\n");
115        for(n=0;n<oclistlength(node->subnodes);n++) {
116            dumpocnode1((OCnode*)oclistget(node->subnodes,n),depth+1);
117        }
118    } break;
119
120    case OC_Sequence: {
121        fprintf(stdout,"[%2d]%s ",depth,dent(depth));
122        fprintf(stdout,"sequence %s",
123                (node->name?node->name:""));
124        dumpdimensions(node);
125        dumpskip(node);
126        fprintf(stdout," &%lx",(unsigned long)node);
127        fprintf(stdout,"\n");
128        for(n=0;n<oclistlength(node->subnodes);n++) {
129            dumpocnode1((OCnode*)oclistget(node->subnodes,n),depth+1);
130        }
131    } break;
132
133    case OC_Grid: {
134        unsigned int i;
135        fprintf(stdout,"[%2d]%s ",depth,dent(depth));
136        fprintf(stdout,"grid %s",
137                (node->name?node->name:""));
138        dumpdimensions(node);
139        dumpskip(node);
140        fprintf(stdout," &%lx",(unsigned long)node);
141        fprintf(stdout,"\n");
142        fprintf(stdout,"%sarray:\n",dent2(depth+1));
143        dumpocnode1((OCnode*)oclistget(node->subnodes,0),depth+2);
144        fprintf(stdout,"%smaps:\n",dent2(depth+1));
145        for(i=1;i<oclistlength(node->subnodes);i++) {
146            dumpocnode1((OCnode*)oclistget(node->subnodes,i),depth+2);
147        }
148    } break;
149
150    case OC_Attribute: {
151        fprintf(stdout,"[%2d]%s ",depth,dent(depth));
152        if(node->name == NULL) OCPANIC("Attribute without name");
153        fprintf(stdout,"%s %s",octypetostring(node->etype),node->name);
154        for(n=0;n<oclistlength(node->att.values);n++) {
155            char* value = (char*)oclistget(node->att.values,n);
156            if(n > 0) fprintf(stdout,",");
157            fprintf(stdout," %s",value);
158        }
159        fprintf(stdout," &%lx",(unsigned long)node);
160        fprintf(stdout,"\n");
161    } break;
162
163    case OC_Attributeset: {
164        fprintf(stdout,"[%2d]%s ",depth,dent(depth));
165        fprintf(stdout,"%s:\n",node->name?node->name:"Attributes");
166        for(n=0;n<oclistlength(node->subnodes);n++) {
167            dumpocnode1((OCnode*)oclistget(node->subnodes,n),depth+1);
168        }
169    } break;
170
171    default:
172        OCPANIC1("encountered unexpected node type: %x",node->octype);
173    }
174
175    if(node->attributes != NULL) {
176        unsigned int i;
177        for(i=0;i<oclistlength(node->attributes);i++) {
178            OCattribute* att = (OCattribute*)oclistget(node->attributes,i);
179            fprintf(stdout,"%s[%s=",dent2(depth+2),att->name);
180            if(att->nvalues == 0)
181                OCPANIC("Attribute.nvalues == 0");
182            if(att->nvalues == 1) {
183                dumpattvalue(att->etype,att->values,0);
184            } else {
185                unsigned int j;
186                fprintf(stdout,"{");
187                for(j=0;j<att->nvalues;j++) {
188                    if(j>0) fprintf(stdout,", ");
189                    dumpattvalue(att->etype,att->values,j);
190                }
191                fprintf(stdout,"}");
192            }
193            fprintf(stdout,"]\n");
194        }
195    }
196}
197
198static void
199dumpdimensions(OCnode* node)
200{
201    unsigned int i;
202    for(i=0;i<node->array.rank;i++) {
203        OCnode* dim = (OCnode*)oclistget(node->array.dimensions,i);
204        fprintf(stdout,"[%s=%lu]",
205                        (dim->name?dim->name:"?"),
206                        (unsigned long)dim->dim.declsize);
207    }
208}
209
210static void
211dumpattvalue(OCtype nctype, char** strings, int index)
212{
213    if(nctype == OC_String || nctype == OC_URL) {
214        fprintf(stdout,"\"%s\"",strings[index]);
215    } else {
216        fprintf(stdout,"%s",strings[index]);
217    }
218}
219
220void
221ocdumpslice(OCslice* slice)
222{
223    fprintf(stdout,"[");
224    fprintf(stdout,"%lu",(unsigned long)slice->first);
225    if(slice->stride > 1) fprintf(stdout,":%lu",(unsigned long)slice->stride);
226    fprintf(stdout,":%lu",(unsigned long)(slice->first+slice->count)-1);
227    fprintf(stdout,"]");
228}
229
230void
231ocdumpclause(OCprojectionclause* ref)
232{
233    unsigned int i;
234    OClist* path = oclistnew();
235    occollectpathtonode(ref->node,path);
236    for(i=0;i<oclistlength(path);i++) {
237        OClist* sliceset;
238        OCnode* node = (OCnode*)oclistget(path,i);
239        if(node->tree != NULL) continue; /* leave off the root node*/
240        fprintf(stdout,"%s%s",(i>0?PATHSEPARATOR:""),node->name);
241        sliceset = (OClist*)oclistget(ref->indexsets,i);
242        if(sliceset != NULL) {
243            unsigned int j;
244            for(j=0;j<oclistlength(sliceset);j++) {
245                OCslice* slice = (OCslice*)oclistget(sliceset,j);
246                ocdumpslice(slice);
247            }
248        }
249    }
250}
251
252
253static void
254addfield(char* field, char* line, int align)
255{
256    int len,rem;
257    strcat(line,"|");
258    strcat(line,field);
259    len = strlen(field);
260    rem = (align - len);
261    while(rem-- > 0) strcat(line," ");
262}
263
264static void
265dumpfield(int index, char* n8, int isxdr)
266{
267    char line[1024];
268    char tmp[32];
269
270    union {
271        unsigned int uv;
272        int sv;
273        char cv[4];
274        float fv;
275    } form;
276    union {
277        char cv[8];
278        unsigned long long ll;
279        double d;
280    } dform;
281
282    line[0] = '\0';
283
284    /* offset */
285    sprintf(tmp,"%6d",index);
286    addfield(tmp,line,5);
287
288    memcpy(form.cv,n8,4);
289
290    /* straight hex*/
291    sprintf(tmp,"%08x",form.uv);
292    addfield(tmp,line,8);
293
294    if(isxdr) {swapinline32(&form.uv);}
295
296    /* unsigned integer */
297    sprintf(tmp,"%12u",form.uv);
298    addfield(tmp,line,12);
299
300    /* signed integer */
301    sprintf(tmp,"%12d",form.sv);
302    addfield(tmp,line,12);
303
304    /* float */
305    sprintf(tmp,"%#g",form.fv);
306    addfield(tmp,line,12);
307
308    /* char[4] */
309    {
310        /* use raw form (i.e. n8)*/
311        int i;
312        tmp[0] = '\0';
313        for(i=0;i<4;i++) {
314            char stmp[64];
315            unsigned int c = (n8[i] & 0xff);
316            if(c < ' ' || c > 126)
317                sprintf(stmp,"\\%02x",c);
318            else
319                sprintf(stmp,"%c",c);
320            strcat(tmp,stmp);
321        }
322    }
323
324    addfield(tmp,line,16);
325
326    /* double */
327    memcpy(dform.cv,n8,2*XDRUNIT);
328    if(isxdr) xxdrntohdouble(dform.cv,&dform.d);
329    sprintf(tmp,"%#g",dform.d);
330    addfield(tmp,line,12);
331
332    fprintf(stdout,"%s\n",line);
333}
334
335static void
336typedmemorydump(char* memory, size_t len, int fromxdr)
337{
338    unsigned int i,count,rem;
339    char line[1024];
340    char* pmem;
341    char mem[8];
342
343    assert(memory[len] == 0);
344
345    /* build the header*/
346    line[0] = '\0';
347    addfield("offset",line,6);
348    addfield("hex",line,8);
349    addfield("uint",line,12);
350    addfield("int",line,12);
351    addfield("float",line,12);
352    addfield("char[4]",line,16);
353    addfield("double",line,12);
354    strcat(line,"\n");
355    fprintf(stdout,"%s",line);
356
357    count = (len / sizeof(int));
358    rem = (len % sizeof(int));
359
360    for(pmem=memory,i=0;i<count;i++,pmem+=4) {
361        memset(mem,0,8);
362        if(i<(count-1))
363            memcpy(mem,pmem,8);
364        else
365            memcpy(mem,pmem,4);
366        dumpfield(i*sizeof(unsigned int),mem,fromxdr);
367    }
368    if(rem > 0) {
369        memset(mem,0,8);
370        memcpy(mem,pmem,4);
371        dumpfield(i*sizeof(unsigned int),mem,fromxdr);
372    }
373    fflush(stdout);
374}
375
376static void
377simplememorydump(char* memory, size_t len, int fromxdr)
378{
379    unsigned int i,count,rem;
380    int* imemory;
381    char tmp[32];
382    char line[1024];
383
384    assert(memory[len] == 0);
385
386    /* build the header*/
387    line[0] = '\0';
388    addfield("offset",line,6);
389    addfield("XDR (hex)",line,9);
390    addfield("!XDR (hex)",line,10);
391    fprintf(stdout,"%s\n",line);
392
393    count = (len / sizeof(int));
394    rem = (len % sizeof(int));
395    if(rem != 0)
396        fprintf(stderr,"ocdump: |mem|%%4 != 0\n");
397    imemory = (int*)memory;
398
399    for(i=0;i<count;i++) {
400        unsigned int vx = (unsigned int)imemory[i];
401        unsigned int v = vx;
402        if(!xxdr_network_order) swapinline32(&v);
403        line[0] = '\0';
404        sprintf(tmp,"%6d",i);
405        addfield(tmp,line,6);
406        sprintf(tmp,"%08x",vx);
407        addfield(tmp,line,9);
408        sprintf(tmp,"%08x",v);
409        addfield(tmp,line,10);
410        fprintf(stdout,"%s\n",line);
411    }
412    fflush(stdout);
413}
414
415void
416ocdumpmemory(char* memory, size_t len, int xdrencoded, int level)
417{
418    if(level > MAXLEVEL) level = MAXLEVEL;
419    switch (level) {
420    case 1: /* Do a multi-type dump */
421        typedmemorydump(memory,len,xdrencoded);
422        break;
423    case 0: /* Dump a simple linear list of the contents of the memory as 32-bit hex and decimal */
424    default:
425        simplememorydump(memory,len,xdrencoded);
426        break;
427    }
428}
429
430static int
431ocreadfile(FILE* file, int datastart, char** memp, size_t* lenp)
432{
433    char* mem;
434    size_t len;
435    size_t pos;
436    size_t red;
437    struct stat stats;
438
439    pos = ftell(file);
440    fseek(file,0,SEEK_SET);
441    fseek(file,datastart,SEEK_SET);
442
443    fstat(fileno(file),&stats);
444    len = stats.st_size;
445    len -= datastart;
446   
447    mem = (char*)calloc(len+1,1);
448    if(mem == NULL) return 0;
449
450    /* Read only the data part */
451    red = fread(mem,1,len,file);
452    if(red < len) {
453        fprintf(stderr,"ocreadfile: short file\n");
454        return 0;
455    }   
456    fseek(file,pos,SEEK_SET); /* leave it as we found it*/
457    if(memp) *memp = mem;
458    if(lenp) *lenp = len;
459    return 1;
460}
461
462void
463ocdd(OCstate* state, OCnode* root, int xdrencoded, int level)
464{
465    char* mem;
466    size_t len;
467    if(root->tree->data.file != NULL) {
468        if(!ocreadfile(root->tree->data.file,root->tree->data.bod,&mem,&len)) {
469            fprintf(stderr,"ocdd could not read data file\n");
470            return;
471        }
472        ocdumpmemory(mem,len,xdrencoded,level);
473        free(mem);
474    } else {
475        mem = root->tree->data.memory;
476        mem += root->tree->data.bod;
477        len = root->tree->data.datasize;
478        len -= root->tree->data.bod;
479        ocdumpmemory(mem,len,xdrencoded,level);
480    }
481}
482
Note: See TracBrowser for help on using the repository browser.