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


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