Coverage Report

Created: 2025-06-09 07:43

/src/gdal/netcdf-c-4.7.4/libdispatch/doffsets.c
Line
Count
Source (jump to first uncovered line)
1
/*********************************************************************
2
 *   Copyright 2018, UCAR/Unidata
3
 *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
4
 *   $Header: /upc/share/CVS/netcdf-3/ncgen/offsets.c,v 1.1 2009/09/25 18:22:40 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
27
#include "config.h"
28
#include        <stdlib.h>
29
#include        <stdio.h>
30
#include        <string.h>
31
#include        <assert.h>
32
#include        "nclog.h"
33
34
#ifdef OFFSETTEST
35
36
static void* emalloc(size_t);
37
38
typedef int nc_type;
39
typedef struct nc_vlen_t {
40
    size_t len;
41
    void* p;
42
} nc_vlen_t;
43
44
#define NC_NAT          0 /* NAT = 'Not A Type' (c.f. NaN) */
45
#define NC_BYTE         1 /* signed 1 byte integer */
46
#define NC_CHAR   2 /* ISO/ASCII character */
47
#define NC_SHORT  3 /* signed 2 byte integer */
48
#define NC_INT          4 /* signed 4 byte integer */
49
#define NC_FLOAT  5 /* single precision floating point number */
50
#define NC_DOUBLE   6 /* double precision floating point number */
51
#define NC_UBYTE  7 /* unsigned 1 byte int */
52
#define NC_USHORT   8 /* unsigned 2-byte int */
53
#define NC_UINT   9 /* unsigned 4-byte int */
54
#define NC_INT64  10  /* signed 8-byte int */
55
#define NC_UINT64   11  /* unsigned 8-byte int */
56
#define NC_STRING   12  /* string */
57
#define NC_STRING   12  /* string */
58
#define NC_VLEN   13  
59
#define NC_OPAQUE   14  
60
#define NC_ENUM   15  
61
#define NC_COMPOUND   16  
62
#endif
63
64
#include        "netcdf.h"
65
#include        "ncoffsets.h"
66
67
68
/*
69
The heart of this is the following macro,
70
which computes the offset of a field x
71
when preceded by a char field.
72
The assumptions appear to be as follows:
73
1. the offset produced in this situation indicates
74
   the alignment for x relative in such a way that it
75
   depends only on the types that precede it in the struct.
76
2. the compiler does not reorder fields.
77
3. arrays are tightly packed.
78
4. nested structs are alignd according to their first member
79
   (this actually follows from C language requirement that
80
    a struct can legally be cast to an instance of its first member).
81
Given the alignments for the various common primitive types,
82
it is assumed that one can use them anywhere to construct
83
the layout of a struct of such types.
84
It seems to work for HDF5 for a wide variety of machines.
85
Note that technically, this is compiler dependent, but in practice
86
all compilers seem to mimic the gcc rules.
87
*/
88
89
24
#define COMP_ALIGNMENT(DST,TYPE)  {\
90
24
    struct {char f1; TYPE x;} tmp; \
91
24
    DST.type_name = #TYPE ;        \
92
24
    DST.alignment = (size_t)((char*)(&(tmp.x)) - (char*)(&tmp));}
93
94
#if 0
95
char* ctypenames[NCTYPES] = {
96
(char*)NULL,
97
"char","unsigned char",
98
"short","unsigned short",
99
"int","unsigned int",
100
"long long","unsigned long long",
101
"float","double",
102
"void*","nc_vlen_t"
103
};
104
#endif
105
106
static NCtypealignvec vec[NC_NCTYPES];
107
static NCtypealignset set;
108
static int NC_alignments_computed = 0;
109
110
/* Argument is a netcdf type class, except compound|ENUM  */
111
size_t
112
NC_class_alignment(int ncclass)
113
0
{
114
0
    NCalignment* align = NULL;
115
0
    int index = 0;
116
0
    if(!NC_alignments_computed)
117
0
  NC_compute_alignments();
118
0
    switch (ncclass) {
119
0
      case NC_BYTE: index = NC_UCHARINDEX; break;
120
0
      case NC_CHAR: index = NC_CHARINDEX; break;
121
0
      case NC_SHORT: index = NC_SHORTINDEX; break;
122
0
      case NC_INT: index = NC_INTINDEX; break;
123
0
      case NC_FLOAT: index = NC_FLOATINDEX; break;
124
0
      case NC_DOUBLE: index = NC_DOUBLEINDEX; break;
125
0
      case NC_UBYTE: index = NC_UCHARINDEX; break;
126
0
      case NC_USHORT: index = NC_USHORTINDEX; break;
127
0
      case NC_UINT: index = NC_UINTINDEX; break;
128
0
      case NC_INT64: index = NC_LONGLONGINDEX; break;
129
0
      case NC_UINT64: index = NC_ULONGLONGINDEX; break;
130
0
      case NC_STRING: index = NC_PTRINDEX; break;
131
      /* Here class matters */
132
0
      case NC_VLEN: index = NC_NCVLENINDEX; break;
133
0
      case NC_OPAQUE: index = NC_UCHARINDEX; break;
134
0
      case NC_ENUM: /* fall thru */
135
0
      case NC_COMPOUND: /* fall thru */
136
0
      default:
137
0
  nclog(NCLOGERR,"nc_class_alignment: class code %d cannot be aligned",ncclass);
138
0
  return 0;
139
0
    }
140
0
    align = &vec[index];
141
0
    return align->alignment;
142
0
}
143
144
void
145
NC_compute_alignments(void)
146
1
{
147
1
    if(NC_alignments_computed) return;
148
    /* Compute the alignments for all the common C data types*/
149
    /* First for the struct*/
150
    /* initialize*/
151
1
    memset((void*)&set,0,sizeof(set));
152
1
    memset((void*)vec,0,sizeof(vec));
153
154
1
    COMP_ALIGNMENT(set.charalign,char);
155
1
    COMP_ALIGNMENT(set.ucharalign,unsigned char);
156
1
    COMP_ALIGNMENT(set.shortalign,short);
157
1
    COMP_ALIGNMENT(set.ushortalign,unsigned short);
158
1
    COMP_ALIGNMENT(set.intalign,int);
159
1
    COMP_ALIGNMENT(set.uintalign,unsigned int);
160
1
    COMP_ALIGNMENT(set.longlongalign,long long);
161
1
    COMP_ALIGNMENT(set.ulonglongalign,unsigned long long);
162
1
    COMP_ALIGNMENT(set.floatalign,float);
163
1
    COMP_ALIGNMENT(set.doublealign,double);
164
1
    COMP_ALIGNMENT(set.ptralign,void*);
165
1
    COMP_ALIGNMENT(set.ncvlenalign,nc_vlen_t);
166
167
    /* Then the vector*/
168
1
    COMP_ALIGNMENT(vec[NC_CHARINDEX],char);
169
1
    COMP_ALIGNMENT(vec[NC_UCHARINDEX],unsigned char); 
170
1
    COMP_ALIGNMENT(vec[NC_SHORTINDEX],short);
171
1
    COMP_ALIGNMENT(vec[NC_USHORTINDEX],unsigned short);
172
1
    COMP_ALIGNMENT(vec[NC_INTINDEX],int);
173
1
    COMP_ALIGNMENT(vec[NC_UINTINDEX],unsigned int);
174
1
    COMP_ALIGNMENT(vec[NC_LONGLONGINDEX],long long);
175
1
    COMP_ALIGNMENT(vec[NC_ULONGLONGINDEX],unsigned long long);
176
1
    COMP_ALIGNMENT(vec[NC_FLOATINDEX],float);
177
1
    COMP_ALIGNMENT(vec[NC_DOUBLEINDEX],double);
178
1
    COMP_ALIGNMENT(vec[NC_PTRINDEX],void*);
179
1
    COMP_ALIGNMENT(vec[NC_NCVLENINDEX],nc_vlen_t);
180
1
    NC_alignments_computed = 1;
181
1
}
182
183
#ifdef OFFSETTEST
184
185
/* Compute the alignment of TYPE when it is preceded
186
   by a field of type TYPE1
187
*/
188
#define COMP_ALIGNMENT1(DST,TYPE1,TYPE)  {\
189
    struct {TYPE1 f1; TYPE x;} tmp; \
190
    DST.type_name = #TYPE ;        \
191
    DST.alignment = (size_t)((char*)(&(tmp.x)) - (char*)(&tmp));}
192
193
/* Compute the alignment of TYPE when it is preceded
194
   by a field of type TYPE1 and a field of type TYPE2
195
*/
196
#define COMP_ALIGNMENT2(DST,TYPE1,TYPE2,TYPE)  {\
197
    struct {TYPE1 f1, TYPE2 f2; TYPE x;} tmp;   \
198
    DST.type_name = #TYPE ;                      \
199
    DST.alignment = (size_t)((char*)(&(tmp.x)) - (char*)(&tmp));}
200
201
/* Compute the alignment of TYPE when it is preceded
202
   by a field of type TYPE1 and a field of type TYPE2
203
*/
204
#define COMP_SIZE0(DST,TYPE1,TYPE2)  {\
205
    struct {TYPE1 c; TYPE2 x;} tmp; \
206
    DST = sizeof(tmp); }
207
208
static char*
209
padname(char* name)
210
{
211
#define MAX 20
212
    if(name == NULL) name = "null";
213
    int len = strlen(name);
214
    if(len > MAX) len = MAX;
215
    char* s = (char*)emalloc(MAX+1);
216
    memset(s,' ',MAX);
217
    s[MAX+1] = '\0';
218
    strncpy(s,name,len);
219
    return s;
220
}
221
222
static void
223
verify(NCtypealignvec* vec)
224
{
225
    int i,j;
226
    NCtypealignvec* vec16;
227
    NCtypealignvec* vec32;
228
    int* sizes8;
229
    int* sizes16;
230
    int* sizes32;
231
232
    vec16 = (NCtypealignvec*)emalloc(sizeof(NCtypealignvec)*NCTYPES);
233
    vec32 = (NCtypealignvec*)emalloc(sizeof(NCtypealignvec)*NCTYPES);
234
    sizes8 = (int*)emalloc(sizeof(int)*NCTYPES);
235
    sizes16 = (int*)emalloc(sizeof(int)*NCTYPES);
236
    sizes32 = (int*)emalloc(sizeof(int)*NCTYPES);
237
238
    COMP_SIZE0(sizes8[1],char,char);
239
    COMP_SIZE0(sizes8[2],unsigned char,char);
240
    COMP_SIZE0(sizes8[3],short,char);
241
    COMP_SIZE0(sizes8[4],unsigned short,char);
242
    COMP_SIZE0(sizes8[5],int,char);
243
    COMP_SIZE0(sizes8[6],unsigned int,char);
244
    COMP_SIZE0(sizes8[7],long long,char);
245
    COMP_SIZE0(sizes8[8],unsigned long long,char);
246
    COMP_SIZE0(sizes8[9],float,char);
247
    COMP_SIZE0(sizes8[10],double,char) ;
248
    COMP_SIZE0(sizes8[11],void*,char);
249
    COMP_SIZE0(sizes8[12],nc_vlen_t,char);
250
251
    COMP_SIZE0(sizes16[1],char,short);
252
    COMP_SIZE0(sizes16[2],unsigned char,short);
253
    COMP_SIZE0(sizes16[3],short,short);
254
    COMP_SIZE0(sizes16[4],unsigned short,short);
255
    COMP_SIZE0(sizes16[5],int,short);
256
    COMP_SIZE0(sizes16[6],unsigned int,short);
257
    COMP_SIZE0(sizes16[7],long long,short);
258
    COMP_SIZE0(sizes16[8],unsigned long long,short);
259
    COMP_SIZE0(sizes16[9],float,short);
260
    COMP_SIZE0(sizes16[10],double,short) ;
261
    COMP_SIZE0(sizes16[11],void*,short);
262
    COMP_SIZE0(sizes16[12],nc_vlen_t*,short);
263
264
    COMP_SIZE0(sizes32[1],char,int);
265
    COMP_SIZE0(sizes32[2],unsigned char,int);
266
    COMP_SIZE0(sizes32[3],short,int);
267
    COMP_SIZE0(sizes32[4],unsigned short,int);
268
    COMP_SIZE0(sizes32[5],int,int);
269
    COMP_SIZE0(sizes32[6],unsigned int,int);
270
    COMP_SIZE0(sizes32[7],long long,int);
271
    COMP_SIZE0(sizes32[8],unsigned long long,int);
272
    COMP_SIZE0(sizes32[9],float,int);
273
    COMP_SIZE0(sizes32[10],double,int) ;
274
    COMP_SIZE0(sizes32[11],void*,int);
275
    COMP_SIZE0(sizes32[12],nc_vlen_t*,int);
276
277
    COMP_ALIGNMENT1(vec16[1],char,short);
278
    COMP_ALIGNMENT1(vec16[2],unsigned char,short);
279
    COMP_ALIGNMENT1(vec16[3],short,short);
280
    COMP_ALIGNMENT1(vec16[4],unsigned short,short);
281
    COMP_ALIGNMENT1(vec16[5],int,short);
282
    COMP_ALIGNMENT1(vec16[6],unsigned int,short);
283
    COMP_ALIGNMENT1(vec32[7],long long,short);
284
    COMP_ALIGNMENT1(vec32[8],unsigned long long,short);
285
    COMP_ALIGNMENT1(vec16[9],float,short);
286
    COMP_ALIGNMENT1(vec16[10],double,short);
287
    COMP_ALIGNMENT1(vec16[11],void*,short);
288
    COMP_ALIGNMENT1(vec16[12],nc_vlen_t*,short);
289
290
    COMP_ALIGNMENT1(vec32[1],char,short);
291
    COMP_ALIGNMENT1(vec32[2],unsigned char,short);
292
    COMP_ALIGNMENT1(vec32[3],char,short);
293
    COMP_ALIGNMENT1(vec32[4],unsigned short,short);
294
    COMP_ALIGNMENT1(vec32[5],int,int);
295
    COMP_ALIGNMENT1(vec32[6],unsigned int,int);
296
    COMP_ALIGNMENT1(vec32[7],long long,int);
297
    COMP_ALIGNMENT1(vec32[8],unsigned long long,int);
298
    COMP_ALIGNMENT1(vec32[9],float,int);
299
    COMP_ALIGNMENT1(vec32[10],double,int);
300
    COMP_ALIGNMENT1(vec32[11],void*,int);
301
    COMP_ALIGNMENT1(vec32[12],nc_vlen_t*,int);
302
303
    for(i=0;i<NCTYPES;i++) {
304
  printf("%s: size=%2d  alignment=%2d\n",
305
    padname(vec[i].type_name),sizes8[i],vec[i].alignment);
306
    }
307
    for(i=0;i<NCTYPES;i++) {
308
  printf("short vs %s: size=%2d  alignment=%2d\n",
309
    padname(vec[i].type_name),sizes16[i],vec16[i].alignment);
310
    }
311
    for(i=0;i<NCTYPES;i++) {
312
  printf("int vs %s: size=%2d  alignment=%2d\n",
313
    padname(vec[i].type_name),sizes32[i],vec32[i].alignment);
314
    }
315
316
}
317
318
void *
319
emalloc(size_t bytes) {
320
    size_t *memory;
321
    memory = malloc(bytes);
322
    if(memory == 0) {
323
  printf("malloc failed\n");
324
  exit(2);
325
    }
326
    return memory;
327
}
328
329
int
330
main(int argc, char** argv)
331
{
332
    int i;
333
334
    compute_alignments();
335
336
    verify(vec);
337
338
/*
339
    for(i=0;i<NCTYPES;i++) {
340
  printf("%s:\talignment=%d\n",vec[i].type_name,vec[i].alignment);
341
    }
342
*/
343
    exit(0);
344
}
345
#endif /*OFFSETTEST*/