1/*********************************************************************
2 *   Copyright 2009, UCAR/Unidata
3 *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
4 *********************************************************************/
5
6#include "includes.h"
7#include "nc_iter.h"
8
9#ifdef ENABLE_BINARY
10
11static void alignto(int alignmentBytebufferbuf, int base);
12
13static int bin_uid = 0;
14
15static int
16bin_charconstant(GeneratorgeneratorSymbolsymBytebufferbuf, ...)
17{
18    /* Just transfer charbuf to codebuf */
19    Bytebuffercharbuf;
20    va_list ap;
21    vastart(ap,buf);
22    charbuf = va_arg(apBytebuffer*);
23    va_end(ap);
24    bbNull(charbuf);
25    bbCatbuf(buf,charbuf);
26    return 1;
27}
28
29static int
30bin_constant(GeneratorgeneratorSymbolsymNCConstantconBytebufferbuf,...)
31{
32    if(con->nctype != NC_ECONST) {
33        alignbuffer(con,buf);
34    }
35    switch (con->nctype) {
36    case NC_OPAQUE: {
37        unsigned char* bytes = NULL;
38        size_t len;
39 /* Assume the opaque string has been normalized */
40        bytes=makebytestring(con->value.opaquev.stringv,&len);
41        bbAppendn(buf,(void*)bytes,len);
42 free(bytes);
43    } break;
44    case NC_CHAR:
45        bbAppendn(buf,&con->value.charv,sizeof(con->value.charv));
46        break;
47    case NC_BYTE:
48        bbAppendn(buf,(void*)&con->value.int8v,sizeof(con->value.int8v));
49        break;
50    case NC_SHORT:
51        bbAppendn(buf,(void*)&con->value.int16v,sizeof(con->value.int16v));
52        break;
53    case NC_INT:
54        bbAppendn(buf,(void*)&con->value.int32v,sizeof(con->value.int32v));
55        break;
56    case NC_FLOAT:
57        bbAppendn(buf,(void*)&con->value.floatv,sizeof(con->value.floatv));
58        break;
59    case NC_DOUBLE:
60        bbAppendn(buf,(void*)&con->value.doublev,sizeof(con->value.doublev));
61        break;
62    case NC_UBYTE:
63        bbAppendn(buf,(void*)&con->value.uint8v,sizeof(con->value.uint8v));
64        break;
65    case NC_USHORT:
66        bbAppendn(buf,(void*)&con->value.uint16v,sizeof(con->value.uint16v));
67        break;
68    case NC_UINT:
69        bbAppendn(buf,(void*)&con->value.uint32v,sizeof(con->value.uint32v));
70        break;
71    case NC_INT64: {
72        union SI64 { char ch[8]; long long i64;} si64;
73        si64.i64 = con->value.int64v;
74        bbAppendn(buf,(void*)si64.ch,sizeof(si64.ch));
75        } break;
76    case NC_UINT64: {
77        union SU64 { char ch[8]; unsigned long long i64;} su64;
78        su64.i64 = con->value.uint64v;
79        bbAppendn(buf,(void*)su64.ch,sizeof(su64.ch));
80        } break;
81    case NC_NIL:
82    case NC_STRING: {
83        char* ptr;
84        int len = (size_t)con->value.stringv.len;
85 if(len == 0 && con->value.stringv.stringv == NULL) {
86     char* nil = NULL;
87            bbAppendn(buf,(void*)&nil,sizeof(nil));
88 } else {
89     ptr = (char*)malloc(len+1);
90     memcpy(ptr,con->value.stringv.stringv,len);
91     ptr[len] = '\0';
92            bbAppendn(buf,(void*)&ptr,sizeof(ptr));
93        }
94 } break;
95
96    default: PANIC1("bin_constant: unexpected type: %d",con->nctype);
97    }
98    return 1;
99}
100
101static int
102bin_listbegin(GeneratorgeneratorSymboltsym, void* liststateListClass lc, size_t sizeBytebufferbuf, int* uidp, ...)
103{
104    if(uidp) *uidp = ++bin_uid;
105    if(lc == LISTCOMPOUND)
106        *((int*)liststate) = bbLength(buf);
107    return 1;
108}
109
110static int
111bin_list(GeneratorgeneratorSymboltsym, void* liststateListClass lc, int uid, size_t countBytebufferbuf, ...)
112{
113    if(lc == LISTCOMPOUND) {
114        int offsetbase = *((int*)liststate);
115        /* Pad for the alignment */
116 alignto(tsym->typ.alignment,buf,offsetbase);
117    }
118    return 1;
119}
120
121static int
122bin_listend(GeneratorgeneratorSymboltsym, void* liststateListClass lc, int uid, size_t countBytebufferbuf, ...)
123{
124    if(lc == LISTCOMPOUND) {
125        int offsetbase = *((int*)liststate);
126        /* Pad out the whole instance */
127 alignto(tsym->typ.cmpdalign,buf,offsetbase);
128    }
129    return 1;
130}
131
132
133static int
134bin_vlendecl(GeneratorgeneratorSymboltsymBytebufferbuf, int uid, size_t count,...)
135{
136    va_list ap;
137    Bytebuffervlenmem;
138    nc_vlen_t ptr;
139    vastart(ap,count);
140    vlenmem = va_arg(apBytebuffer*);
141    va_end(ap);
142    ptr.len = count;
143    ptr.p = bbDup(vlenmem);
144    bbAppendn(buf,(char*)&ptr,sizeof(ptr));
145    return 1;
146}
147
148static int
149bin_vlenstring(GeneratorgeneratorSymbolsymBytebuffercodebuf, int* uidp, size_t* sizep,...)
150{
151    Bytebuffervlenmem;
152    nc_vlen_t ptr;
153    va_list ap;
154    if(uidp) *uidp = ++bin_uid;
155    vastart(ap,sizep);
156    vlenmem = va_arg(apBytebuffer*);
157    va_end(ap);
158    ptr.len = bbLength(vlenmem);
159    ptr.p = bbDup(vlenmem);
160    bbAppendn(codebuf,(char*)&ptr,sizeof(ptr));
161    return 1;
162}
163
164static const char zeros[] =
165    "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
166
167static void
168alignto(int alignmentBytebufferbuf, int base)
169{
170    int pad = 0;
171    int offset = bbLength(buf);
172    offset -= base; /* Need to actually align wrt to the base */
173    pad = getpadding(offset,alignment);
174    if(pad > 0) {
175 bbAppendn(buf,(void*)zeros,pad);
176    }
177}
178
179/* Define the single static bin data generator  */
180static Generator bin_generator_singleton = {
181    NULL,
182    bin_charconstant,
183    bin_constant,
184    bin_listbegin,
185    bin_list,
186    bin_listend,
187    bin_vlendecl,
188    bin_vlenstring
189};
190Generatorbin_generator = &bin_generator_singleton;
191
192#endif /*ENABLE_BINARY*/
193


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