1/*********************************************************************
2 *   Copyright 1993, UCAR/Unidata
3 *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
4 *   $Header: /upc/share/CVS/netcdf-3/ncgen/getfill.c,v 1.8 2010/04/14 22:04:56 dmh Exp $
5 *********************************************************************/
6
7#include "includes.h"
8#include "dump.h"
9
10/* mnemonic*/
11#define TOPLEVEL 1
12
13/*Forward*/
14static void fill(SymboltsymDatalist*);
15static void fillarray(SymboltsymDimsetdimset, int indexDatalist*);
16static void filllist(SymboltvsymDatalistdl);
17
18/* Construct a Datalist representing a complete fill value*/
19/* for a specified variable */
20/* Cache if needed later*/
21
22Datalist*
23getfiller(Symboltvsym)
24{
25    Datalistfiller = NULL;
26    Symboltsym = tvsym;
27    ASSERT(tvsym->objectclass == NC_VAR || tvsym->objectclass == NC_TYPE);
28    if(tvsym->objectclass == NC_VAR) {
29 tsym = tvsym->typ.basetype;
30        filler = tvsym->var.special._Fillvalue; /* get cached value (if any)*/
31    }
32    if(filler == NULL || tvsym->objectclass == NC_TYPE) {
33        filler = tvsym->typ._Fillvalue; /* get cached value (if any)*/
34    }
35    if(filler == NULL) { /* need to compute it*/
36        filler = builddatalist(0);
37 fill(tsym,filler);
38    }
39#ifdef GENDEBUG2
40    dumpdatalist(filler,"getfiller");
41#endif
42    if(tvsym->objectclass == NC_VAR) {
43        tvsym->var.special._Fillvalue = filler;
44    } else if(tvsym->objectclass == NC_TYPE) {
45        tvsym->typ._Fillvalue = filler; /* cache value*/
46    }
47    return filler;
48}
49
50static void
51fill(SymboltsymDatalistfiller)
52{
53    unsigned long i;
54    NCConstant con = nullconstant;
55    Datalistsublist;
56
57    ASSERT(tsym->objectclass == NC_TYPE);
58    switch (tsym->subclass) {
59    case NC_ENUM: case NC_OPAQUE: case NC_PRIM:
60        con.nctype = tsym->typ.typecode;
61        nc_getfill(&con);
62 break;
63    case NC_COMPOUND:
64 sublist = builddatalist(listlength(tsym->subnodes));
65        for(i=0;i<listlength(tsym->subnodes);i++) {
66     Symbolfield = (Symbol*)listget(tsym->subnodes,i);
67     if(field->typ.dimset.ndims > 0) {
68                fillarray(field->typ.basetype,&field->typ.dimset,0,filler);
69     } else
70 filllist(field->typ.basetype,sublist);
71        }
72 con = builddatasublist(sublist);
73 break;
74    case NC_VLEN:
75 sublist = builddatalist(0);
76 filllist(tsym->typ.basetype,sublist); /* generate a single instance*/
77 con = builddatasublist(sublist);
78 break;
79    default: PANIC1("fill: unexpected subclass %d",tsym->subclass);
80    }
81    dlappend(filler,&con);
82}
83
84static void
85filllist(SymboltsymDatalistdl)
86{
87    int i;
88    Datalistsublist;
89    NCConstant con = nullconstant;
90
91    ASSERT(tsym->objectclass == NC_TYPE);
92    switch (tsym->subclass) {
93    case NC_ENUM: case NC_OPAQUE: case NC_PRIM:
94        con.nctype = tsym->typ.typecode;
95        nc_getfill(&con);
96 dlappend(dl,&con);
97 break;
98    case NC_COMPOUND:
99 sublist = builddatalist(listlength(tsym->subnodes));
100        for(i=0;i<listlength(tsym->subnodes);i++) {
101     Symbolfield = (Symbol*)listget(tsym->subnodes,i);
102     filllist(field->typ.basetype,sublist);
103        }
104 con = builddatasublist(sublist);
105 dlappend(dl,&con);
106 break;
107    case NC_VLEN:
108 sublist = builddatalist(0);
109 filllist(tsym->typ.basetype,sublist); /* generate a single instance*/
110 con = builddatasublist(sublist);
111 dlappend(dl,&con);
112 break;
113    default: PANIC1("fill: unexpected subclass %d",tsym->subclass);
114    }
115}
116
117static void
118fillarray(SymbolbasetypeDimsetdimset, int indexDatalistarraylist)
119{
120    int i;
121    Symboldim = dimset->dimsyms[index];
122    unsigned int size = dim->dim.declsize;
123    int isunlimited = (size == 0);
124    int lastdim = (index == (dimset->ndims - 1));
125    int firstdim = (index == 0);
126    Datalistsublist;
127
128    sublist = (firstdim?builddatalist(0):arraylist);
129    if(isunlimited) {
130 /* do a single entry to satisfy*/
131        if(lastdim) {
132     filllist(basetype,sublist);
133 } else {
134     fillarray(basetype->typ.basetype,dimset,index+1,sublist);
135 }
136    } else { /* bounded*/
137        if(lastdim) {
138     for(i=0;i<size;i++) filllist(basetype,sublist);
139 } else {
140     for(i=0;i<size;i++) {
141         fillarray(basetype->typ.basetype,dimset,index+1,sublist);
142     }
143 }
144    }
145}
146
147/*
148 * Given primitive netCDF type, return a default fill_value appropriate for
149 * that type.
150 */
151void
152nc_getfill(NCConstantvalue)
153{
154    switch(value->nctype) {
155      case NC_CHARvalue->value.charv = NC_FILL_CHAR; break;
156      case NC_BYTEvalue->value.int8v = NC_FILL_BYTE; break;
157      case NC_SHORTvalue->value.int16v = NC_FILL_SHORT; break;
158      case NC_INTvalue->value.int32v = NC_FILL_INT; break;
159      case NC_FLOATvalue->value.floatv = NC_FILL_FLOAT; break;
160      case NC_DOUBLEvalue->value.doublev = NC_FILL_DOUBLE; break;
161      case NC_UBYTEvalue->value.uint8v = NC_FILL_UBYTE; break;
162      case NC_USHORTvalue->value.uint16v = NC_FILL_USHORT; break;
163      case NC_UINTvalue->value.uint32v = NC_FILL_UINT; break;
164      case NC_INT64value->value.int64v = NC_FILL_INT64; break;
165      case NC_UINT64value->value.uint64v = NC_FILL_UINT64; break;
166      case NC_STRING:
167        value->value.stringv.stringv = nulldup(NC_FILL_STRING);
168        value->value.stringv.len = (int)strlen(NC_FILL_STRING);
169 /* Exception: if string is null, then make it's length be 1 */
170 if(value->value.stringv.len == 0)
171     value->value.stringv.len = 1;
172 break;
173      case NC_OPAQUE:
174        value->value.opaquev.len = 2;
175        value->value.opaquev.stringv = nulldup("00");
176 break;
177      default:
178 derror("nc_getfill: unrecognized type: %d",value->nctype);
179    }
180}
181
182char*
183nc_dfaltfillname(nc_type nctype)
184{
185    switch (nctype) {
186    case NC_BYTE: return "NC_FILL_BYTE";
187    case NC_CHAR: return "NC_FILL_CHAR";
188    case NC_SHORT: return "NC_FILL_SHORT";
189    case NC_INT: return "NC_FILL_INT";
190    case NC_FLOAT: return "NC_FILL_FLOAT";
191    case NC_DOUBLE: return "NC_FILL_DOUBLE";
192    case NC_UBYTE: return "NC_FILL_UBYTE";
193    case NC_USHORT: return "NC_FILL_USHORT";
194    case NC_UINT: return "NC_FILL_UINT";
195    case NC_INT64: return "NC_FILL_INT64";
196    case NC_UINT64: return "NC_FILL_UINT64";
197    case NC_STRING: return "NC_FILL_STRING";
198    default: PANIC("unexpected default fill name");
199    }
200    return NULL;
201}
202


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