NetCDF  4.8.0
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
29 const char* nc4_atomic_name[NUM_ATOMIC_TYPES] = {"none", "byte", "char",
30  "short", "int", "float",
31  "double", "ubyte",
32  "ushort", "uint",
33  "int64", "uint64", "string"};
34 static const int nc4_atomic_size[NUM_ATOMIC_TYPES] = {0, NC_BYTE_LEN, NC_CHAR_LEN, NC_SHORT_LEN,
38 
52 int
53 NC4_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 
100 int
101 NC4_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 
125 int
126 NC4_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 
158 int
159 NC4_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 
218 int
219 NC4_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 
297 int
298 NC4_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 
348 int
349 NC4_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 
410 int
411 NC4_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 
500 int
501 NC4_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 
550 EXTERNL int
551 NC4_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 
626 int
627 nc4_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 
682 exit:
683  return retval;
684 }
nc4_rec_find_named_type
NC_TYPE_INFO_T * nc4_rec_find_named_type(NC_GRP_INFO_T *start_grp, char *name)
Definition: nc4internal.c:482
NC_USHORT
#define NC_USHORT
unsigned 2-byte int
Definition: netcdf.h:43
NC_NOERR
#define NC_NOERR
No Error.
Definition: netcdf.h:330
NC_EINVAL
#define NC_EINVAL
Invalid Argument.
Definition: netcdf.h:340
NC_EBADFIELD
#define NC_EBADFIELD
Bad field ID.
Definition: netcdf.h:461
EXTERNL
#define EXTERNL
Needed for DLL build.
Definition: netcdf.h:516
nc4_get_typeclass
int nc4_get_typeclass(const NC_FILE_INFO_T *h5, nc_type xtype, int *type_class)
Definition: nc4type.c:627
NC_CHAR_LEN
#define NC_CHAR_LEN
Definition: nc4type.c:19
nc_vlen_t
This is the type of arrays of vlens.
Definition: netcdf.h:698
NC_FLOAT
#define NC_FLOAT
single precision floating point number
Definition: netcdf.h:40
NC_DOUBLE_LEN
#define NC_DOUBLE_LEN
Definition: nc4type.c:25
NC_DOUBLE
#define NC_DOUBLE
double precision floating point number
Definition: netcdf.h:41
NC4_inq_typeids
int NC4_inq_typeids(int ncid, int *ntypes, int *typeids)
Definition: nc4type.c:53
NC4_inq_compound_field
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
NC_BYTE
#define NC_BYTE
signed 1 byte integer
Definition: netcdf.h:35
NC_VLEN
#define NC_VLEN
vlen (variable-length) types
Definition: netcdf.h:53
NC4_inq_typeid
EXTERNL int NC4_inq_typeid(int ncid, const char *name, nc_type *typeidp)
Definition: nc4type.c:551
NC_INT64_LEN
#define NC_INT64_LEN
Definition: nc4type.c:26
NC_INT
#define NC_INT
signed 4 byte integer
Definition: netcdf.h:38
NC_MAX_NAME
#define NC_MAX_NAME
Maximum for classic library.
Definition: netcdf.h:276
NC_BYTE_LEN
#define NC_BYTE_LEN
Definition: nc4type.c:21
NC_FLOAT_LEN
#define NC_FLOAT_LEN
Definition: nc4type.c:24
NC_UBYTE
#define NC_UBYTE
unsigned 1 byte int
Definition: netcdf.h:42
nc4_normalize_name
int nc4_normalize_name(const char *name, char *norm_name)
Definition: nc4internal.c:1580
NC4_inq_compound_fieldindex
int NC4_inq_compound_fieldindex(int ncid, nc_type typeid1, const char *name, int *fieldidp)
Definition: nc4type.c:349
NC4_inq_type
int NC4_inq_type(int ncid, nc_type typeid1, char *name, size_t *size)
Definition: nc4type.c:159
NC_SHORT_LEN
#define NC_SHORT_LEN
Definition: nc4type.c:22
NC_COMPOUND
#define NC_COMPOUND
compound types
Definition: netcdf.h:56
NC4_lookup_atomic_type
int NC4_lookup_atomic_type(const char *name, nc_type *idp, size_t *sizep)
Definition: nc4type.c:126
NC_SHORT
#define NC_SHORT
signed 2 byte integer
Definition: netcdf.h:37
NC_INT_LEN
#define NC_INT_LEN
Definition: nc4type.c:23
nc4_atomic_name
const char * nc4_atomic_name[NUM_ATOMIC_TYPES]
Definition: nc4type.c:29
nc_type
int nc_type
The nc_type type is just an int.
Definition: netcdf.h:25
nc4_find_grp_h5
int nc4_find_grp_h5(int ncid, NC_GRP_INFO_T **grp, NC_FILE_INFO_T **h5)
Definition: nc4internal.c:328
NC_EBADTYPE
#define NC_EBADTYPE
Not a netcdf data type.
Definition: netcdf.h:372
NC_ENUM
#define NC_ENUM
enum types
Definition: netcdf.h:55
NC4_inq_atomic_type
int NC4_inq_atomic_type(nc_type typeid1, char *name, size_t *size)
Definition: nc4type.c:101
NC4_inq_enum_ident
int NC4_inq_enum_ident(int ncid, nc_type xtype, long long value, char *identifier)
Definition: nc4type.c:411
NC_ENOMEM
#define NC_ENOMEM
Memory allocation (malloc) failure.
Definition: netcdf.h:410
NC_NAT
#define NC_NAT
Not A Type.
Definition: netcdf.h:34
NC_UINT64
#define NC_UINT64
unsigned 8-byte int
Definition: netcdf.h:46
NC_STRING_LEN
#define NC_STRING_LEN
Definition: nc4type.c:20
NC_UINT
#define NC_UINT
unsigned 4-byte int
Definition: netcdf.h:44
NC_STRING
#define NC_STRING
string
Definition: netcdf.h:47
nc4_find_nc4_grp
int nc4_find_nc4_grp(int ncid, NC_GRP_INFO_T **grp)
Definition: nc4internal.c:307
NC4_inq_user_type
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
NC_CHAR
#define NC_CHAR
ISO/ASCII character.
Definition: netcdf.h:36
nc4_find_type
int nc4_find_type(const NC_FILE_INFO_T *h5, nc_type typeid, NC_TYPE_INFO_T **type)
Definition: nc4internal.c:518
NC4_inq_enum_member
int NC4_inq_enum_member(int ncid, nc_type typeid1, int idx, char *identifier, void *value)
Definition: nc4type.c:501
NC_INT64
#define NC_INT64
signed 8-byte int
Definition: netcdf.h:45