source: XIOS/trunk/extern/src_netcdf4/dapalign.c @ 409

Last change on this file since 409 was 409, checked in by ymipsl, 11 years ago

Add improved nectdf internal library src

YM

  • Property svn:eol-style set to native
File size: 11.4 KB
Line 
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/*
23This code is a variantion of the H5detect.c code from HDF5.
24Author: 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
39typedef struct nccalignvlen_t {
40    size_t len;
41    void* p;
42} nccalignvlen_t;
43
44#ifdef OFFSETTEST
45typedef 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/*
64The heart of this is the following macro,
65which computes the offset of a field x
66when preceded by a char field.
67The assumptions appear to be as follows:
681. 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.
712. the compiler does not reorder fields.
723. arrays are tightly packed.
734. 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).
76Given the alignments for the various common primitive types,
77it is assumed that one can use them anywhere to construct
78the layout of a struct of such types.
79It 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
90static NCtypealignvec vec[NCCTYPECOUNT];
91static NCtypealignset set;
92static int dapaligninit = 0;
93
94unsigned int
95ncctypealignment(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
127void
128compute_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 */
171int
172nccpadding(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
196static char*
197padname(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
210static void
211verify(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
316int
317main(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*/
Note: See TracBrowser for help on using the repository browser.