NetCDF 4.8.0
Loading...
Searching...
No Matches
nc4type.c
Go to the documentation of this file.
1/* Copyright 2005, University Corporation for Atmospheric Research. See
2 * the COPYRIGHT file for copying and redistribution conditions. */
14#include "nc4internal.h"
15#include "nc4dispatch.h"
16
17/* The sizes of types may vary from platform to platform, but within
18 * netCDF files, type sizes are fixed. */
19#define NC_CHAR_LEN sizeof(char)
20#define NC_STRING_LEN sizeof(char *)
21#define NC_BYTE_LEN 1
22#define NC_SHORT_LEN 2
23#define NC_INT_LEN 4
24#define NC_FLOAT_LEN 4
25#define NC_DOUBLE_LEN 8
26#define NC_INT64_LEN 8
29const char* nc4_atomic_name[NUM_ATOMIC_TYPES] = {"none", "byte", "char",
30 "short", "int", "float",
31 "double", "ubyte",
32 "ushort", "uint",
33 "int64", "uint64", "string"};
34static const int nc4_atomic_size[NUM_ATOMIC_TYPES] = {0, NC_BYTE_LEN, NC_CHAR_LEN, NC_SHORT_LEN,
38
52int
53NC4_inq_typeids(int ncid, int *ntypes, int *typeids)
54{
55 NC_GRP_INFO_T *grp;
56 NC_FILE_INFO_T *h5;
57 NC_TYPE_INFO_T *type;
58 int num = 0;
59 int retval;
60
61 LOG((2, "nc_inq_typeids: ncid 0x%x", ncid));
62
63 /* Find info for this file and group, and set pointer to each. */
64 if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
65 return retval;
66 assert(h5 && grp);
67
68 /* Count types. */
69 if (grp->type) {
70 int i;
71 for(i=0;i<ncindexsize(grp->type);i++)
72 {
73 if((type = (NC_TYPE_INFO_T*)ncindexith(grp->type,i)) == NULL) continue;
74 if (typeids)
75 typeids[num] = type->hdr.id;
76 num++;
77 }
78 }
79
80 /* Give the count to the user. */
81 if (ntypes)
82 *ntypes = num;
83
84 return NC_NOERR;
85}
86
100int
101NC4_inq_atomic_type(nc_type typeid1, char *name, size_t *size)
102{
103 LOG((2, "nc_inq_atomic_type: typeid %d", typeid1));
104
105 if (typeid1 >= NUM_ATOMIC_TYPES)
106 return NC_EBADTYPE;
107 if (name)
108 strcpy(name, nc4_atomic_name[typeid1]);
109 if (size)
110 *size = nc4_atomic_size[typeid1];
111 return NC_NOERR;
112}
113
125int
126NC4_lookup_atomic_type(const char *name, nc_type* idp, size_t *sizep)
127{
128 int i;
129
130 LOG((2, "nc_lookup_atomic_type: name %s ", name));
131
132 if (name == NULL || strlen(name) == 0)
133 return NC_EBADTYPE;
134 for(i=0;i<NUM_ATOMIC_TYPES;i++) {
135 if(strcasecmp(name,nc4_atomic_name[i])==0) {
136 if(idp) *idp = i;
137 if(sizep) *sizep = nc4_atomic_size[i];
138 return NC_NOERR;
139 }
140 }
141 return NC_EBADTYPE;
142}
143
158int
159NC4_inq_type(int ncid, nc_type typeid1, char *name, size_t *size)
160{
161 NC_GRP_INFO_T *grp;
162 NC_TYPE_INFO_T *type;
163
164 int retval;
165
166 LOG((2, "nc_inq_type: ncid 0x%x typeid %d", ncid, typeid1));
167
168 /* If this is an atomic type, the answer is easy. */
169 if (typeid1 < NUM_ATOMIC_TYPES)
170 {
171 if (name)
172 strcpy(name, nc4_atomic_name[typeid1]);
173 if (size)
174 *size = nc4_atomic_size[typeid1];
175 return NC_NOERR;
176 }
177
178 /* Not an atomic type - so find group. */
179 if ((retval = nc4_find_nc4_grp(ncid, &grp)))
180 return retval;
181
182 /* Find this type. */
183 if (!(type = nclistget(grp->nc4_info->alltypes, typeid1)))
184 return NC_EBADTYPE;
185
186 if (name)
187 strcpy(name, type->hdr.name);
188
189 if (size)
190 {
191 if (type->nc_type_class == NC_VLEN)
192 *size = sizeof(nc_vlen_t);
193 else if (type->nc_type_class == NC_STRING)
194 *size = NC_STRING_LEN;
195 else
196 *size = type->size;
197 }
198
199 return NC_NOERR;
200}
201
218int
219NC4_inq_user_type(int ncid, nc_type typeid1, char *name, size_t *size,
220 nc_type *base_nc_typep, size_t *nfieldsp, int *classp)
221{
222 NC_GRP_INFO_T *grp;
223 NC_TYPE_INFO_T *type;
224 int retval;
225
226 LOG((2, "nc_inq_user_type: ncid 0x%x typeid %d", ncid, typeid1));
227
228 /* Find group metadata. */
229 if ((retval = nc4_find_nc4_grp(ncid, &grp)))
230 return retval;
231
232 /* Find this type. */
233 if (!(type = nclistget(grp->nc4_info->alltypes, typeid1)))
234 return NC_EBADTYPE;
235
236 /* Count the number of fields. */
237 if (nfieldsp)
238 {
239 if (type->nc_type_class == NC_COMPOUND)
240 *nfieldsp = nclistlength(type->u.c.field);
241 else if (type->nc_type_class == NC_ENUM)
242 *nfieldsp = nclistlength(type->u.e.enum_member);
243 else
244 *nfieldsp = 0;
245 }
246
247 /* Fill in size and name info, if desired. */
248 if (size)
249 {
250 if (type->nc_type_class == NC_VLEN)
251 *size = sizeof(nc_vlen_t);
252 else if (type->nc_type_class == NC_STRING)
253 *size = NC_STRING_LEN;
254 else
255 *size = type->size;
256 }
257 if (name)
258 strcpy(name, type->hdr.name);
259
260 /* VLENS and ENUMs have a base type - that is, they type they are
261 * arrays of or enums of. */
262 if (base_nc_typep)
263 {
264 if (type->nc_type_class == NC_ENUM)
265 *base_nc_typep = type->u.e.base_nc_typeid;
266 else if (type->nc_type_class == NC_VLEN)
267 *base_nc_typep = type->u.v.base_nc_typeid;
268 else
269 *base_nc_typep = NC_NAT;
270 }
271
272 /* If the user wants it, tell whether this is a compound, opaque,
273 * vlen, enum, or string class of type. */
274 if (classp)
275 *classp = type->nc_type_class;
276
277 return NC_NOERR;
278}
279
297int
298NC4_inq_compound_field(int ncid, nc_type typeid1, int fieldid, char *name,
299 size_t *offsetp, nc_type *field_typeidp, int *ndimsp,
300 int *dim_sizesp)
301{
302 NC_GRP_INFO_T *grp;
303 NC_TYPE_INFO_T *type;
304 NC_FIELD_INFO_T *field;
305 int d, retval;
306
307 /* Find file metadata. */
308 if ((retval = nc4_find_nc4_grp(ncid, &grp)))
309 return retval;
310
311 /* Find this type. */
312 if (!(type = nclistget(grp->nc4_info->alltypes, typeid1)))
313 return NC_EBADTYPE;
314
315 /* Find the field. */
316 if (!(field = nclistget(type->u.c.field,fieldid)))
317 return NC_EBADFIELD;
318
319 if (name)
320 strcpy(name, field->hdr.name);
321 if (offsetp)
322 *offsetp = field->offset;
323 if (field_typeidp)
324 *field_typeidp = field->nc_typeid;
325 if (ndimsp)
326 *ndimsp = field->ndims;
327 if (dim_sizesp)
328 for (d = 0; d < field->ndims; d++)
329 dim_sizesp[d] = field->dim_size[d];
330
331 return NC_NOERR;
332}
333
348int
349NC4_inq_compound_fieldindex(int ncid, nc_type typeid1, const char *name, int *fieldidp)
350{
351 NC_FILE_INFO_T *h5;
352 NC_TYPE_INFO_T *type;
353 NC_FIELD_INFO_T *field;
354 char norm_name[NC_MAX_NAME + 1];
355 int retval;
356 int i;
357
358 LOG((2, "nc_inq_compound_fieldindex: ncid 0x%x typeid %d name %s",
359 ncid, typeid1, name));
360
361 /* Find file metadata. */
362 if ((retval = nc4_find_grp_h5(ncid, NULL, &h5)))
363 return retval;
364
365 /* Find the type. */
366 if ((retval = nc4_find_type(h5, typeid1, &type)))
367 return retval;
368
369 /* Did the user give us a good compound type typeid? */
370 if (!type || type->nc_type_class != NC_COMPOUND)
371 return NC_EBADTYPE;
372
373 /* Normalize name. */
374 if ((retval = nc4_normalize_name(name, norm_name)))
375 return retval;
376
377 /* Find the field with this name. */
378 for (i = 0; i < nclistlength(type->u.c.field); i++)
379 {
380 field = nclistget(type->u.c.field, i);
381 assert(field);
382 if (!strcmp(field->hdr.name, norm_name))
383 break;
384 field = NULL; /* because this is the indicator of not found */
385 }
386
387 if (!field)
388 return NC_EBADFIELD;
389
390 if (fieldidp)
391 *fieldidp = field->hdr.id;
392 return NC_NOERR;
393}
394
410int
411NC4_inq_enum_ident(int ncid, nc_type xtype, long long value, char *identifier)
412{
413 NC_GRP_INFO_T *grp;
414 NC_TYPE_INFO_T *type;
415 NC_ENUM_MEMBER_INFO_T *enum_member;
416 long long ll_val;
417 int i;
418 int retval;
419 int found;
420
421 LOG((3, "nc_inq_enum_ident: xtype %d value %d\n", xtype, value));
422
423 /* Find group metadata. */
424 if ((retval = nc4_find_nc4_grp(ncid, &grp)))
425 return retval;
426
427 /* Find this type. */
428 if (!(type = nclistget(grp->nc4_info->alltypes, xtype)))
429 return NC_EBADTYPE;
430
431 /* Complain if they are confused about the type. */
432 if (type->nc_type_class != NC_ENUM)
433 return NC_EBADTYPE;
434
435 /* Move to the desired enum member in the list. */
436 for (found = 0, i = 0; i < nclistlength(type->u.e.enum_member); i++)
437 {
438 enum_member = nclistget(type->u.e.enum_member, i);
439 assert(enum_member);
440 switch (type->u.e.base_nc_typeid)
441 {
442 case NC_BYTE:
443 ll_val = *(char *)enum_member->value;
444 break;
445 case NC_UBYTE:
446 ll_val = *(unsigned char *)enum_member->value;
447 break;
448 case NC_SHORT:
449 ll_val = *(short *)enum_member->value;
450 break;
451 case NC_USHORT:
452 ll_val = *(unsigned short *)enum_member->value;
453 break;
454 case NC_INT:
455 ll_val = *(int *)enum_member->value;
456 break;
457 case NC_UINT:
458 ll_val = *(unsigned int *)enum_member->value;
459 break;
460 case NC_INT64:
461 case NC_UINT64:
462 ll_val = *(long long *)enum_member->value;
463 break;
464 default:
465 return NC_EINVAL;
466 }
467 LOG((4, "ll_val=%d", ll_val));
468 if (ll_val == value)
469 {
470 if (identifier)
471 strcpy(identifier, enum_member->name);
472 found = 1;
473 break;
474 }
475 }
476
477 /* If we didn't find it, life sucks for us. :-( */
478 if (!found)
479 return NC_EINVAL;
480
481 return NC_NOERR;
482}
483
500int
501NC4_inq_enum_member(int ncid, nc_type typeid1, int idx, char *identifier,
502 void *value)
503{
504 NC_GRP_INFO_T *grp;
505 NC_TYPE_INFO_T *type;
506 NC_ENUM_MEMBER_INFO_T *enum_member;
507 int retval;
508
509 LOG((2, "nc_inq_enum_member: ncid 0x%x typeid %d", ncid, typeid1));
510
511 /* Find group metadata. */
512 if ((retval = nc4_find_nc4_grp(ncid, &grp)))
513 return retval;
514
515 /* Find this type. */
516 if (!(type = nclistget(grp->nc4_info->alltypes, typeid1)))
517 return NC_EBADTYPE;
518
519 /* Complain if they are confused about the type. */
520 if (type->nc_type_class != NC_ENUM)
521 return NC_EBADTYPE;
522
523 /* Move to the desired enum member in the list. */
524 if (!(enum_member = nclistget(type->u.e.enum_member, idx)))
525 return NC_EINVAL;
526
527 /* Give the people what they want. */
528 if (identifier)
529 strcpy(identifier, enum_member->name);
530 if (value)
531 memcpy(value, enum_member->value, type->size);
532
533 return NC_NOERR;
534}
535
550EXTERNL int
551NC4_inq_typeid(int ncid, const char *name, nc_type *typeidp)
552{
553 NC_GRP_INFO_T *grp;
554 NC_GRP_INFO_T *grptwo;
555 NC_FILE_INFO_T *h5;
556 NC_TYPE_INFO_T *type = NULL;
557 char *norm_name;
558 int i, retval;
559
560 /* Handle atomic types. */
561 for (i = 0; i < NUM_ATOMIC_TYPES; i++)
562 if (!strcmp(name, nc4_atomic_name[i]))
563 {
564 if (typeidp)
565 *typeidp = i;
566 return NC_NOERR;
567 }
568
569 /* Find info for this file and group, and set pointer to each. */
570 if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
571 return retval;
572 assert(h5 && grp);
573
574 /* If the first char is a /, this is a fully-qualified
575 * name. Otherwise, this had better be a local name (i.e. no / in
576 * the middle). */
577 if (name[0] != '/' && strstr(name, "/"))
578 return NC_EINVAL;
579
580 /* Normalize name. */
581 if (!(norm_name = (char*)malloc(strlen(name) + 1)))
582 return NC_ENOMEM;
583 if ((retval = nc4_normalize_name(name, norm_name))) {
584 free(norm_name);
585 return retval;
586 }
587 /* Is the type in this group? If not, search parents. */
588 for (grptwo = grp; grptwo; grptwo = grptwo->parent) {
589 type = (NC_TYPE_INFO_T*)ncindexlookup(grptwo->type,norm_name);
590 if(type)
591 {
592 if (typeidp)
593 *typeidp = type->hdr.id;
594 break;
595 }
596 }
597
598 /* Still didn't find type? Search file recursively, starting at the
599 * root group. */
600 if (!type)
601 if ((type = nc4_rec_find_named_type(grp->nc4_info->root_grp, norm_name)))
602 if (typeidp)
603 *typeidp = type->hdr.id;
604
605 free(norm_name);
606
607 /* OK, I give up already! */
608 if (!type)
609 return NC_EBADTYPE;
610
611 return NC_NOERR;
612}
613
626int
627nc4_get_typeclass(const NC_FILE_INFO_T *h5, nc_type xtype, int *type_class)
628{
629 int retval = NC_NOERR;
630
631 LOG((4, "%s xtype: %d", __func__, xtype));
632 assert(type_class);
633
634 /* If this is an atomic type, the answer is easy. */
635 if (xtype <= NC_STRING)
636 {
637 switch (xtype)
638 {
639 case NC_BYTE:
640 case NC_UBYTE:
641 case NC_SHORT:
642 case NC_USHORT:
643 case NC_INT:
644 case NC_UINT:
645 case NC_INT64:
646 case NC_UINT64:
647 /* NC_INT is class used for all integral types */
648 *type_class = NC_INT;
649 break;
650
651 case NC_FLOAT:
652 case NC_DOUBLE:
653 /* NC_FLOAT is class used for all floating-point types */
654 *type_class = NC_FLOAT;
655 break;
656
657 case NC_CHAR:
658 *type_class = NC_CHAR;
659 break;
660
661 case NC_STRING:
662 *type_class = NC_STRING;
663 break;
664
665 default:
666 BAIL(NC_EBADTYPE);
667 }
668 }
669 else
670 {
671 NC_TYPE_INFO_T *type;
672
673 /* See if it's a used-defined type */
674 if ((retval = nc4_find_type(h5, xtype, &type)))
675 BAIL(retval);
676 if (!type)
677 BAIL(NC_EBADTYPE);
678
679 *type_class = type->nc_type_class;
680 }
681
682exit:
683 return retval;
684}
NC_TYPE_INFO_T * nc4_rec_find_named_type(NC_GRP_INFO_T *start_grp, char *name)
int nc4_find_nc4_grp(int ncid, NC_GRP_INFO_T **grp)
int nc4_find_grp_h5(int ncid, NC_GRP_INFO_T **grp, NC_FILE_INFO_T **h5)
int nc4_normalize_name(const char *name, char *norm_name)
int nc4_find_type(const NC_FILE_INFO_T *h5, nc_type typeid, NC_TYPE_INFO_T **type)
#define NC_INT_LEN
Definition nc4type.c:23
int NC4_inq_compound_fieldindex(int ncid, nc_type typeid1, const char *name, int *fieldidp)
Definition nc4type.c:349
int NC4_inq_user_type(int ncid, nc_type typeid1, char *name, size_t *size, nc_type *base_nc_typep, size_t *nfieldsp, int *classp)
Definition nc4type.c:219
#define NC_FLOAT_LEN
Definition nc4type.c:24
#define NC_BYTE_LEN
Definition nc4type.c:21
int NC4_lookup_atomic_type(const char *name, nc_type *idp, size_t *sizep)
Definition nc4type.c:126
const char * nc4_atomic_name[NUM_ATOMIC_TYPES]
Definition nc4type.c:29
int NC4_inq_compound_field(int ncid, nc_type typeid1, int fieldid, char *name, size_t *offsetp, nc_type *field_typeidp, int *ndimsp, int *dim_sizesp)
Definition nc4type.c:298
int NC4_inq_atomic_type(nc_type typeid1, char *name, size_t *size)
Definition nc4type.c:101
#define NC_INT64_LEN
Definition nc4type.c:26
EXTERNL int NC4_inq_typeid(int ncid, const char *name, nc_type *typeidp)
Definition nc4type.c:551
int NC4_inq_enum_member(int ncid, nc_type typeid1, int idx, char *identifier, void *value)
Definition nc4type.c:501
int NC4_inq_type(int ncid, nc_type typeid1, char *name, size_t *size)
Definition nc4type.c:159
int NC4_inq_typeids(int ncid, int *ntypes, int *typeids)
Definition nc4type.c:53
#define NC_DOUBLE_LEN
Definition nc4type.c:25
int NC4_inq_enum_ident(int ncid, nc_type xtype, long long value, char *identifier)
Definition nc4type.c:411
int nc4_get_typeclass(const NC_FILE_INFO_T *h5, nc_type xtype, int *type_class)
Definition nc4type.c:627
#define NC_STRING_LEN
Definition nc4type.c:20
#define NC_SHORT_LEN
Definition nc4type.c:22
#define NC_CHAR_LEN
Definition nc4type.c:19
#define NC_EBADTYPE
Not a netcdf data type.
Definition netcdf.h:372
#define NC_EBADFIELD
Bad field ID.
Definition netcdf.h:461
#define NC_UINT
unsigned 4-byte int
Definition netcdf.h:44
#define NC_INT
signed 4 byte integer
Definition netcdf.h:38
#define NC_BYTE
signed 1 byte integer
Definition netcdf.h:35
#define NC_VLEN
vlen (variable-length) types
Definition netcdf.h:53
#define NC_NAT
Not A Type.
Definition netcdf.h:34
#define NC_DOUBLE
double precision floating point number
Definition netcdf.h:41
#define NC_UBYTE
unsigned 1 byte int
Definition netcdf.h:42
#define NC_FLOAT
single precision floating point number
Definition netcdf.h:40
#define NC_ENOMEM
Memory allocation (malloc) failure.
Definition netcdf.h:410
#define EXTERNL
Needed for DLL build.
Definition netcdf.h:516
#define NC_COMPOUND
compound types
Definition netcdf.h:56
#define NC_SHORT
signed 2 byte integer
Definition netcdf.h:37
#define NC_ENUM
enum types
Definition netcdf.h:55
#define NC_INT64
signed 8-byte int
Definition netcdf.h:45
#define NC_UINT64
unsigned 8-byte int
Definition netcdf.h:46
#define NC_EINVAL
Invalid Argument.
Definition netcdf.h:340
#define NC_MAX_NAME
Maximum for classic library.
Definition netcdf.h:276
#define NC_NOERR
No Error.
Definition netcdf.h:330
#define NC_USHORT
unsigned 2-byte int
Definition netcdf.h:43
#define NC_STRING
string
Definition netcdf.h:47
#define NC_CHAR
ISO/ASCII character.
Definition netcdf.h:36
int nc_type
The nc_type type is just an int.
Definition netcdf.h:25
This is the type of arrays of vlens.
Definition netcdf.h:698