1 | /********************************************************************* |
---|
2 | * Copyright 1993, UCAR/Unidata |
---|
3 | * See netcdf/COPYRIGHT file for copying and redistribution conditions. |
---|
4 | * $Header: /upc/share/CVS/netcdf-3/libncdap3/dapalign.c,v 1.5 2009/09/23 22:26:00 dmh Exp $ |
---|
5 | *********************************************************************/ |
---|
6 | |
---|
7 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
---|
8 | * Copyright by The HDF Group. * |
---|
9 | * Copyright by the Board of Trustees of the University of Illinois. * |
---|
10 | * All rights reserved. * |
---|
11 | * * |
---|
12 | * This file is part of HDF5. The full HDF5 copyright notice, including * |
---|
13 | * terms governing use, modification, and redistribution, is contained in * |
---|
14 | * the files COPYING and Copyright.html. COPYING can be found at the root * |
---|
15 | * of the source code distribution tree; Copyright.html can be found at the * |
---|
16 | * root level of an installed copy of the electronic HDF5 document set and * |
---|
17 | * is linked from the top-level documents page. It can also be found at * |
---|
18 | * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * |
---|
19 | * access to either file, you may request a copy from help@hdfgroup.org. * |
---|
20 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
---|
21 | |
---|
22 | /* |
---|
23 | This code is a variantion of the H5detect.c code from HDF5. |
---|
24 | Author: D. Heimbigner 10/7/2008 |
---|
25 | */ |
---|
26 | #include "config.h" |
---|
27 | #ifndef OFFSETTEST |
---|
28 | #include "ncdap3.h" |
---|
29 | #else |
---|
30 | #include <stdlib.h> |
---|
31 | #include <string.h> |
---|
32 | #include <assert.h> |
---|
33 | #endif |
---|
34 | |
---|
35 | #include "dapnc.h" |
---|
36 | #include "dapdebug.h" |
---|
37 | #include "dapalign.h" |
---|
38 | |
---|
39 | typedef struct nccalignvlen_t { |
---|
40 | size_t len; |
---|
41 | void* p; |
---|
42 | } nccalignvlen_t; |
---|
43 | |
---|
44 | #ifdef OFFSETTEST |
---|
45 | typedef int nc_type; |
---|
46 | #define NC_NAT 0 /* NAT = 'Not A Type' (c.f. NaN) */ |
---|
47 | #define NC_BYTE 1 /* signed 1 byte integer */ |
---|
48 | #define NC_CHAR 2 /* ISO/ASCII character */ |
---|
49 | #define NC_SHORT 3 /* signed 2 byte integer */ |
---|
50 | #define NC_INT 4 /* signed 4 byte integer */ |
---|
51 | #define NC_FLOAT 5 /* single precision floating point number */ |
---|
52 | #define NC_DOUBLE 6 /* double precision floating point number */ |
---|
53 | #define NC_UBYTE 7 /* unsigned 1 byte int */ |
---|
54 | #define NC_USHORT 8 /* unsigned 2-byte int */ |
---|
55 | #define NC_UINT 9 /* unsigned 4-byte int */ |
---|
56 | #define NC_INT64 10 /* signed 8-byte int */ |
---|
57 | #define NC_UINT64 11 /* unsigned 8-byte int */ |
---|
58 | #define NC_STRING 12 /* string */ |
---|
59 | #define NC_VLEN 13 |
---|
60 | #define NC_OPAQUE 14 |
---|
61 | #endif |
---|
62 | |
---|
63 | /* |
---|
64 | The heart of this is the following macro, |
---|
65 | which computes the offset of a field x |
---|
66 | when preceded by a char field. |
---|
67 | The assumptions appear to be as follows: |
---|
68 | 1. the offset produced in this situation indicates |
---|
69 | the alignment for x relative in such a way that it |
---|
70 | depends only on the types that precede it in the struct. |
---|
71 | 2. the compiler does not reorder fields. |
---|
72 | 3. arrays are tightly packed. |
---|
73 | 4. nested structs are alignd according to their first member |
---|
74 | (this actually follows from C language requirement that |
---|
75 | a struct can legally be cast to an instance of its first member). |
---|
76 | Given the alignments for the various common primitive types, |
---|
77 | it is assumed that one can use them anywhere to construct |
---|
78 | the layout of a struct of such types. |
---|
79 | It seems to work for HDF5 for a wide variety of machines. |
---|
80 | */ |
---|
81 | |
---|
82 | #define COMP_ALIGNMENT(DST,TYPE) {\ |
---|
83 | struct {char f1; TYPE x;} tmp; \ |
---|
84 | DST.typename = #TYPE ; \ |
---|
85 | DST.alignment = (size_t)((char*)(&(tmp.x)) - (char*)(&tmp));} |
---|
86 | |
---|
87 | |
---|
88 | #define NCCTYPECOUNT (NCCTYPENCVLEN+1) |
---|
89 | |
---|
90 | static NCtypealignvec vec[NCCTYPECOUNT]; |
---|
91 | static NCtypealignset set; |
---|
92 | static int dapaligninit = 0; |
---|
93 | |
---|
94 | unsigned int |
---|
95 | ncctypealignment(int nctype) |
---|
96 | { |
---|
97 | NCtypealignment* align = NULL; |
---|
98 | int index = 0; |
---|
99 | if(!dapaligninit) compute_nccalignments(); |
---|
100 | switch (nctype) { |
---|
101 | case NC_BYTE: index = NCCTYPEUCHAR; break; |
---|
102 | case NC_CHAR: index = NCCTYPECHAR; break; |
---|
103 | case NC_SHORT: index = NCCTYPESHORT; break; |
---|
104 | case NC_INT: index = NCCTYPEINT; break; |
---|
105 | case NC_FLOAT: index = NCCTYPEFLOAT; break; |
---|
106 | case NC_DOUBLE: index = NCCTYPEDOUBLE; break; |
---|
107 | case NC_UBYTE: index = NCCTYPEUCHAR; break; |
---|
108 | case NC_USHORT: index = NCCTYPEUSHORT; break; |
---|
109 | case NC_UINT: index = NCCTYPEUINT; break; |
---|
110 | case NC_INT64: index = NCCTYPELONGLONG; break; |
---|
111 | case NC_UINT64: index = NCCTYPEULONGLONG; break; |
---|
112 | case NC_STRING: index = NCCTYPEPTR; break; |
---|
113 | case NC_VLEN: index = NCCTYPENCVLEN; break; |
---|
114 | case NC_OPAQUE: index = NCCTYPEUCHAR; break; |
---|
115 | default: |
---|
116 | #ifndef OFFSETTEST |
---|
117 | PANIC1("nctypealignment: bad type code: %d",nctype); |
---|
118 | #else |
---|
119 | return 0; |
---|
120 | #endif |
---|
121 | } |
---|
122 | align = &vec[index]; |
---|
123 | return align->alignment; |
---|
124 | } |
---|
125 | |
---|
126 | |
---|
127 | void |
---|
128 | compute_nccalignments(void) |
---|
129 | { |
---|
130 | /* Compute the alignments for all the common C data types*/ |
---|
131 | /* First for the struct*/ |
---|
132 | /* initialize*/ |
---|
133 | memset((void*)&set,0,sizeof(set)); |
---|
134 | memset((void*)vec,0,sizeof(vec)); |
---|
135 | |
---|
136 | COMP_ALIGNMENT(set.charalign,char); |
---|
137 | COMP_ALIGNMENT(set.ucharalign,unsigned char); |
---|
138 | COMP_ALIGNMENT(set.shortalign,short); |
---|
139 | COMP_ALIGNMENT(set.ushortalign,unsigned short); |
---|
140 | COMP_ALIGNMENT(set.intalign,int); |
---|
141 | COMP_ALIGNMENT(set.uintalign,unsigned int); |
---|
142 | COMP_ALIGNMENT(set.longalign,long); |
---|
143 | COMP_ALIGNMENT(set.ulongalign,unsigned long); |
---|
144 | COMP_ALIGNMENT(set.longlongalign,long long); |
---|
145 | COMP_ALIGNMENT(set.ulonglongalign,unsigned long long); |
---|
146 | COMP_ALIGNMENT(set.floatalign,float); |
---|
147 | COMP_ALIGNMENT(set.doublealign,double); |
---|
148 | COMP_ALIGNMENT(set.ptralign,void*); |
---|
149 | COMP_ALIGNMENT(set.ncvlenalign,nccalignvlen_t); |
---|
150 | |
---|
151 | /* Then the vector*/ |
---|
152 | COMP_ALIGNMENT(vec[NCCTYPECHAR],char); |
---|
153 | COMP_ALIGNMENT(vec[NCCTYPEUCHAR],unsigned char); |
---|
154 | COMP_ALIGNMENT(vec[NCCTYPESHORT],short); |
---|
155 | COMP_ALIGNMENT(vec[NCCTYPEUSHORT],unsigned short); |
---|
156 | COMP_ALIGNMENT(vec[NCCTYPEINT],int); |
---|
157 | COMP_ALIGNMENT(vec[NCCTYPEUINT],unsigned int); |
---|
158 | COMP_ALIGNMENT(vec[NCCTYPELONG],long); |
---|
159 | COMP_ALIGNMENT(vec[NCCTYPEULONG],unsigned long); |
---|
160 | COMP_ALIGNMENT(vec[NCCTYPELONGLONG],long long); |
---|
161 | COMP_ALIGNMENT(vec[NCCTYPEULONGLONG],unsigned long long); |
---|
162 | COMP_ALIGNMENT(vec[NCCTYPEFLOAT],float); |
---|
163 | COMP_ALIGNMENT(vec[NCCTYPEDOUBLE],double); |
---|
164 | COMP_ALIGNMENT(vec[NCCTYPEPTR],void*); |
---|
165 | COMP_ALIGNMENT(vec[NCCTYPENCVLEN],nccalignvlen_t); |
---|
166 | |
---|
167 | dapaligninit = 1; |
---|
168 | } |
---|
169 | |
---|
170 | /* Compute padding */ |
---|
171 | int |
---|
172 | nccpadding(unsigned long offset, int alignment) |
---|
173 | { |
---|
174 | int pad,rem; |
---|
175 | rem = (alignment==0?0:(offset % alignment)); |
---|
176 | pad = (rem==0?0:(alignment - rem)); |
---|
177 | return pad; |
---|
178 | } |
---|
179 | |
---|
180 | #ifdef OFFSETTEST |
---|
181 | |
---|
182 | #define COMP_ALIGNMENT1(DST,TYPE1,TYPE) {\ |
---|
183 | struct {TYPE1 f1; TYPE x;} tmp; \ |
---|
184 | DST.typename = #TYPE ; \ |
---|
185 | DST.alignment = (size_t)((char*)(&(tmp.x)) - (char*)(&tmp));} |
---|
186 | |
---|
187 | #define COMP_ALIGNMENT2(DST,TYPE1,TYPE2,TYPE) {\ |
---|
188 | struct {TYPE1 f1, TYPE2 f2; TYPE x;} tmp; \ |
---|
189 | DST.typename = #TYPE ; \ |
---|
190 | DST.alignment = (size_t)((char*)(&(tmp.x)) - (char*)(&tmp));} |
---|
191 | |
---|
192 | #define COMP_SIZE0(DST,TYPE1,TYPE2) {\ |
---|
193 | struct {TYPE1 c; TYPE2 x;} tmp; \ |
---|
194 | DST = sizeof(tmp); } |
---|
195 | |
---|
196 | static char* |
---|
197 | padname(char* name) |
---|
198 | { |
---|
199 | #define MAX 20 |
---|
200 | if(name == NULL) name = "null"; |
---|
201 | int len = strlen(name); |
---|
202 | if(len > MAX) len = MAX; |
---|
203 | char* s = (char*)malloc(MAX+1); |
---|
204 | memset(s,' ',MAX); |
---|
205 | s[MAX+1] = '\0'; |
---|
206 | strncpy(s,name,len); |
---|
207 | return s; |
---|
208 | } |
---|
209 | |
---|
210 | static void |
---|
211 | verify(NCtypealignvec* vec) |
---|
212 | { |
---|
213 | int i,j; |
---|
214 | NCtypealignvec* vec16; |
---|
215 | NCtypealignvec* vec32; |
---|
216 | int* sizes8; |
---|
217 | int* sizes16; |
---|
218 | int* sizes32; |
---|
219 | |
---|
220 | vec16 = (NCtypealignvec*)malloc(sizeof(NCtypealignvec)*NCCTYPECOUNT); |
---|
221 | vec32 = (NCtypealignvec*)malloc(sizeof(NCtypealignvec)*NCCTYPECOUNT); |
---|
222 | sizes8 = (int*)malloc(sizeof(int)*NCCTYPECOUNT); |
---|
223 | sizes16 = (int*)malloc(sizeof(int)*NCCTYPECOUNT); |
---|
224 | sizes32 = (int*)malloc(sizeof(int)*NCCTYPECOUNT); |
---|
225 | |
---|
226 | COMP_SIZE0(sizes8[1],char,char); |
---|
227 | COMP_SIZE0(sizes8[2],unsigned char,char); |
---|
228 | COMP_SIZE0(sizes8[3],short,char); |
---|
229 | COMP_SIZE0(sizes8[4],unsigned short,char); |
---|
230 | COMP_SIZE0(sizes8[5],int,char); |
---|
231 | COMP_SIZE0(sizes8[6],unsigned int,char); |
---|
232 | COMP_SIZE0(sizes8[7],long,char); |
---|
233 | COMP_SIZE0(sizes8[8],unsigned long,char); |
---|
234 | COMP_SIZE0(sizes8[9],long long,char); |
---|
235 | COMP_SIZE0(sizes8[10],unsigned long long,char); |
---|
236 | COMP_SIZE0(sizes8[11],float,char); |
---|
237 | COMP_SIZE0(sizes8[12],double,char) ; |
---|
238 | COMP_SIZE0(sizes8[13],void*,char); |
---|
239 | COMP_SIZE0(sizes8[14],alignvlen_t,char); |
---|
240 | |
---|
241 | COMP_SIZE0(sizes16[1],char,short); |
---|
242 | COMP_SIZE0(sizes16[2],unsigned char,short); |
---|
243 | COMP_SIZE0(sizes16[3],short,short); |
---|
244 | COMP_SIZE0(sizes16[4],unsigned short,short); |
---|
245 | COMP_SIZE0(sizes16[5],int,short); |
---|
246 | COMP_SIZE0(sizes16[6],unsigned int,short); |
---|
247 | COMP_SIZE0(sizes16[7],long,short); |
---|
248 | COMP_SIZE0(sizes16[8],unsigned long,short); |
---|
249 | COMP_SIZE0(sizes16[9],long long,short); |
---|
250 | COMP_SIZE0(sizes16[10],unsigned long long,short); |
---|
251 | COMP_SIZE0(sizes16[11],float,short); |
---|
252 | COMP_SIZE0(sizes16[12],double,short) ; |
---|
253 | COMP_SIZE0(sizes16[13],void*,short); |
---|
254 | COMP_SIZE0(sizes16[14],alignvlen_t*,short); |
---|
255 | |
---|
256 | COMP_SIZE0(sizes32[1],char,int); |
---|
257 | COMP_SIZE0(sizes32[2],unsigned char,int); |
---|
258 | COMP_SIZE0(sizes32[3],short,int); |
---|
259 | COMP_SIZE0(sizes32[4],unsigned short,int); |
---|
260 | COMP_SIZE0(sizes32[5],int,int); |
---|
261 | COMP_SIZE0(sizes32[6],unsigned int,int); |
---|
262 | COMP_SIZE0(sizes32[7],long,int); |
---|
263 | COMP_SIZE0(sizes32[8],unsigned long,int); |
---|
264 | COMP_SIZE0(sizes32[9],long long,int); |
---|
265 | COMP_SIZE0(sizes32[10],unsigned long long,int); |
---|
266 | COMP_SIZE0(sizes32[11],float,int); |
---|
267 | COMP_SIZE0(sizes32[12],double,int) ; |
---|
268 | COMP_SIZE0(sizes32[13],void*,int); |
---|
269 | COMP_SIZE0(sizes32[14],alignvlen_t*,int); |
---|
270 | |
---|
271 | COMP_ALIGNMENT1(vec16[1],char,short); |
---|
272 | COMP_ALIGNMENT1(vec16[2],unsigned char,short); |
---|
273 | COMP_ALIGNMENT1(vec16[3],short,short); |
---|
274 | COMP_ALIGNMENT1(vec16[4],unsigned short,short); |
---|
275 | COMP_ALIGNMENT1(vec16[5],int,short); |
---|
276 | COMP_ALIGNMENT1(vec16[6],unsigned int,short); |
---|
277 | COMP_ALIGNMENT1(vec32[7],long,short); |
---|
278 | COMP_ALIGNMENT1(vec32[8],unsigned long,short); |
---|
279 | COMP_ALIGNMENT1(vec32[9],long long,short); |
---|
280 | COMP_ALIGNMENT1(vec32[10],unsigned long long,short); |
---|
281 | COMP_ALIGNMENT1(vec16[11],float,short); |
---|
282 | COMP_ALIGNMENT1(vec16[12],double,short); |
---|
283 | COMP_ALIGNMENT1(vec16[13],void*,short); |
---|
284 | COMP_ALIGNMENT1(vec16[14],alignvlen_t*,short); |
---|
285 | |
---|
286 | COMP_ALIGNMENT1(vec32[1],char,short); |
---|
287 | COMP_ALIGNMENT1(vec32[2],unsigned char,short); |
---|
288 | COMP_ALIGNMENT1(vec32[3],char,short); |
---|
289 | COMP_ALIGNMENT1(vec32[4],unsigned short,short); |
---|
290 | COMP_ALIGNMENT1(vec32[5],int,int); |
---|
291 | COMP_ALIGNMENT1(vec32[6],unsigned int,int); |
---|
292 | COMP_ALIGNMENT1(vec32[7],long,int); |
---|
293 | COMP_ALIGNMENT1(vec32[8],unsigned long,int); |
---|
294 | COMP_ALIGNMENT1(vec32[9],long long,int); |
---|
295 | COMP_ALIGNMENT1(vec32[10],unsigned long long,int); |
---|
296 | COMP_ALIGNMENT1(vec32[11],float,int); |
---|
297 | COMP_ALIGNMENT1(vec32[12],double,int); |
---|
298 | COMP_ALIGNMENT1(vec32[13],void*,int); |
---|
299 | COMP_ALIGNMENT1(vec32[14],alignvlen_t*,int); |
---|
300 | |
---|
301 | for(i=0;i<NCCTYPECOUNT;i++) { |
---|
302 | printf("%s: size=%2d alignment=%2d\n", |
---|
303 | padname(vec[i].typename),sizes8[i],vec[i].alignment); |
---|
304 | } |
---|
305 | for(i=0;i<NCCTYPECOUNT;i++) { |
---|
306 | printf("short vs %s: size=%2d alignment=%2d\n", |
---|
307 | padname(vec[i].typename),sizes16[i],vec16[i].alignment); |
---|
308 | } |
---|
309 | for(i=0;i<NCCTYPECOUNT;i++) { |
---|
310 | printf("int vs %s: size=%2d alignment=%2d\n", |
---|
311 | padname(vec[i].typename),sizes32[i],vec32[i].alignment); |
---|
312 | } |
---|
313 | |
---|
314 | } |
---|
315 | |
---|
316 | int |
---|
317 | main(int argc, char** argv) |
---|
318 | { |
---|
319 | int i; |
---|
320 | |
---|
321 | compute_nccalignments(); |
---|
322 | |
---|
323 | verify(vec); |
---|
324 | |
---|
325 | /* |
---|
326 | for(i=0;i<NCCTYPECOUNT;i++) { |
---|
327 | printf("%s:\talignment=%d\n",vec[i].typename,vec[i].alignment); |
---|
328 | } |
---|
329 | */ |
---|
330 | exit(0); |
---|
331 | } |
---|
332 | #endif /*OFFSETTEST*/ |
---|