1 /*! \file
2   Functions for Compound Types
3 
4   Copyright 2011 University Corporation for Atmospheric
5   Research/Unidata. See \ref copyright file for more info. */
6 
7 #include "ncdispatch.h"
8 
9 /** \name Compound Types
10     Functions to create and learn about compound types. */
11 /*! \{ */ /* All these functions are part of this named group... */
12 
13 
14 /** \ingroup user_types
15 
16 Create a compound type. Provide an ncid, a name, and a total size (in
17 bytes) of one element of the completed compound type.
18 
19 After calling this function, fill out the type with repeated calls to
20 nc_insert_compound(). Call nc_insert_compound() once for each field
21 you wish to insert into the compound type.
22 
23 \param ncid \ref ncid
24 \param size The size, in bytes, of the compound type.
25 \param name \ref object_name of the created type.
26 \param typeidp The type ID of the new type is copied here.
27 
28 \returns ::NC_NOERR No error.
29 \returns ::NC_EBADID Bad \ref ncid.
30 \returns ::NC_EBADTYPE Bad type id.
31 \returns ::NC_ENAMEINUSE That name is in use.
32 \returns ::NC_EMAXNAME Name exceeds max length NC_MAX_NAME.
33 \returns ::NC_EBADNAME Name contains illegal characters.
34 \returns ::NC_ESTRICTNC3 Attempting a netCDF-4 operation on a netCDF-3 file.
35 \returns ::NC_ENOTNC4 This file was created with the strict netcdf-3 flag, therefore netcdf-4 operations are not allowed. (see nc_open).
36 \returns ::NC_EHDFERR An error was reported by the HDF5 layer.
37 \returns ::NC_EPERM Attempt to write to a read-only file.
38 \returns ::NC_ENOTINDEFINE Not in define mode.
39 
40 \section nc_def_compound_example Example
41 
42 \code
43 struct s1
44 {
45 int i1;
46 int i2;
47 };
48 struct s1 data[DIM_LEN], data_in[DIM_LEN];
49 
50 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
51 if (nc_def_compound(ncid, sizeof(struct s1), SVC_REC, &typeid)) ERR;
52 if (nc_insert_compound(ncid, typeid, BATTLES_WITH_KLINGONS,
53 HOFFSET(struct s1, i1), NC_INT)) ERR;
54 if (nc_insert_compound(ncid, typeid, DATES_WITH_ALIENS,
55 HOFFSET(struct s1, i2), NC_INT)) ERR;
56 if (nc_def_dim(ncid, STARDATE, DIM_LEN, &dimid)) ERR;
57 if (nc_def_var(ncid, SERVICE_RECORD, typeid, 1, dimids, &varid)) ERR;
58 if (nc_put_var(ncid, varid, data)) ERR;
59 if (nc_close(ncid)) ERR;
60 \endcode
61 */
62 int
nc_def_compound(int ncid,size_t size,const char * name,nc_type * typeidp)63 nc_def_compound(int ncid, size_t size, const char *name,
64 		nc_type *typeidp)
65 {
66    NC* ncp;
67    int stat = NC_check_id(ncid,&ncp);
68    if(stat != NC_NOERR) return stat;
69    return ncp->dispatch->def_compound(ncid,size,name,typeidp);
70 }
71 
72 /** \ingroup user_types
73 Insert a named field into a compound type.
74 
75 \param ncid \ref ncid
76 
77 \param xtype The typeid for this compound type, as returned by
78 nc_def_compound(), or nc_inq_var().
79 
80 \param name The \ref object_name of the new field.
81 
82 \param offset Offset in byte from the beginning of the compound type
83 for this field.
84 
85 \param field_typeid The type of the field to be inserted.
86 
87 \returns ::NC_NOERR No error.
88 \returns ::NC_EBADID Bad \ref ncid.
89 \returns ::NC_EBADTYPE Bad type id.
90 \returns ::NC_ENAMEINUSE That name is in use.
91 \returns ::NC_EMAXNAME Name exceeds max length NC_MAX_NAME.
92 \returns ::NC_EBADNAME Name contains illegal characters.
93 \returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled.
94 \returns ::NC_EHDFERR An error was reported by the HDF5 layer.
95 \returns ::NC_EPERM Attempt to write to a read-only file.
96 \returns ::NC_ENOTINDEFINE Not in define mode.
97 */
98 int
nc_insert_compound(int ncid,nc_type xtype,const char * name,size_t offset,nc_type field_typeid)99 nc_insert_compound(int ncid, nc_type xtype, const char *name,
100 		   size_t offset, nc_type field_typeid)
101 {
102    NC *ncp;
103    int stat = NC_check_id(ncid, &ncp);
104    if(stat != NC_NOERR) return stat;
105    return ncp->dispatch->insert_compound(ncid, xtype, name,
106 					 offset, field_typeid);
107 }
108 
109 /** \ingroup user_types
110 Insert a named array field into a compound type.
111 
112 \param ncid \ref ncid
113 
114 \param xtype The typeid for this compound type, as returned by
115 nc_def_compound(), or nc_inq_var().
116 
117 \param name The \ref object_name of the new field.
118 
119 \param offset Offset in byte from the beginning of the compound type
120 for this field.
121 
122 \param field_typeid The type of the field to be inserted.
123 
124  \param ndims Number of dimensions in array.
125 
126  \param dim_sizes Array of dimension sizes.
127 
128 \returns ::NC_NOERR No error.
129 \returns ::NC_EBADID Bad \ref ncid.
130 \returns ::NC_EBADTYPE Bad type id.
131 \returns ::NC_ENAMEINUSE That name is in use.
132 \returns ::NC_EMAXNAME Name exceeds max length NC_MAX_NAME.
133 \returns ::NC_EBADNAME Name contains illegal characters.
134 \returns ::NC_ESTRICTNC3 Attempting a netCDF-4 operation on a netCDF-3 file.
135 \returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled.
136 \returns ::NC_EHDFERR An error was reported by the HDF5 layer.
137 \returns ::NC_EPERM Attempt to write to a read-only file.
138 \returns ::NC_ENOTINDEFINE Not in define mode.
139 */
140 int
nc_insert_array_compound(int ncid,nc_type xtype,const char * name,size_t offset,nc_type field_typeid,int ndims,const int * dim_sizes)141 nc_insert_array_compound(int ncid, nc_type xtype, const char *name,
142 			 size_t offset, nc_type field_typeid,
143 			 int ndims, const int *dim_sizes)
144 {
145    NC* ncp;
146    int stat = NC_check_id(ncid,&ncp);
147    if(stat != NC_NOERR) return stat;
148    return ncp->dispatch->insert_array_compound(ncid,xtype,name,offset,field_typeid,ndims,dim_sizes);
149 }
150 
151 /**  \ingroup user_types
152 Learn about a compound type. Get the number of fields, len, and
153 name of a compound type.
154 
155 \param ncid \ref ncid
156 
157 \param xtype The typeid for this compound type, as returned by
158 nc_def_compound(), or nc_inq_var().
159 
160 \param name Returned \ref object_name of compound type. \ref
161 ignored_if_null.
162 
163 \param sizep Returned size of compound type in bytes. \ref ignored_if_null.
164 
165 \param nfieldsp The number of fields in the compound type will be
166 placed here. \ref ignored_if_null.
167 
168 \returns ::NC_NOERR No error.
169 \returns ::NC_EBADID Bad \ref ncid.
170 \returns ::NC_EBADTYPE Bad type id.
171 \returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled.
172 \returns ::NC_EHDFERR An error was reported by the HDF5 layer.
173  */
174 int
nc_inq_compound(int ncid,nc_type xtype,char * name,size_t * sizep,size_t * nfieldsp)175 nc_inq_compound(int ncid, nc_type xtype, char *name,
176 		size_t *sizep, size_t *nfieldsp)
177 {
178    int class = 0;
179    int stat = nc_inq_user_type(ncid,xtype,name,sizep,NULL,nfieldsp,&class);
180    if(stat != NC_NOERR) return stat;
181    if(class != NC_COMPOUND) stat = NC_EBADTYPE;
182    return stat;
183 }
184 
185 /**  \ingroup user_types
186 Learn the name of a compound type.
187 
188 \param ncid \ref ncid
189 
190 \param xtype The typeid for this compound type, as returned by
191 nc_def_compound(), or nc_inq_var().
192 
193 \param name Returned \ref object_name of compound type. \ref
194 ignored_if_null.
195 
196 \returns ::NC_NOERR No error.
197 \returns ::NC_EBADID Bad \ref ncid.
198 \returns ::NC_EBADTYPE Bad type id.
199 \returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled.
200 \returns ::NC_EHDFERR An error was reported by the HDF5 layer.
201  */
202 int
nc_inq_compound_name(int ncid,nc_type xtype,char * name)203 nc_inq_compound_name(int ncid, nc_type xtype, char *name)
204 {
205    return nc_inq_compound(ncid,xtype,name,NULL,NULL);
206 }
207 
208 /**  \ingroup user_types
209 Learn the size of a compound type.
210 
211 \param ncid \ref ncid
212 
213 \param xtype The typeid for this compound type, as returned by
214 nc_def_compound(), or nc_inq_var().
215 
216 \param sizep Returned size of compound type in bytes. \ref
217 ignored_if_null.
218 
219 \returns ::NC_NOERR No error.
220 \returns ::NC_EBADID Bad \ref ncid.
221 \returns ::NC_EBADTYPE Bad type id.
222 \returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled.
223 \returns ::NC_EHDFERR An error was reported by the HDF5 layer.
224  */
225 int
nc_inq_compound_size(int ncid,nc_type xtype,size_t * sizep)226 nc_inq_compound_size(int ncid, nc_type xtype, size_t *sizep)
227 {
228    return nc_inq_compound(ncid,xtype,NULL,sizep,NULL);
229 }
230 
231 /**  \ingroup user_types
232 Learn the number of fields in a compound type.
233 
234 \param ncid \ref ncid
235 
236 \param xtype The typeid for this compound type, as returned by
237 nc_def_compound(), or nc_inq_var().
238 
239 \param nfieldsp The number of fields in the compound type will be
240 placed here. \ref ignored_if_null.
241 
242 \returns ::NC_NOERR No error.
243 \returns ::NC_EBADID Bad \ref ncid.
244 \returns ::NC_EBADTYPE Bad type id.
245 \returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled.
246 \returns ::NC_EHDFERR An error was reported by the HDF5 layer.
247  */
248 int
nc_inq_compound_nfields(int ncid,nc_type xtype,size_t * nfieldsp)249 nc_inq_compound_nfields(int ncid, nc_type xtype, size_t *nfieldsp)
250 {
251    return nc_inq_compound(ncid,xtype,NULL,NULL,nfieldsp);
252 }
253 
254 /**  \ingroup user_types
255 Get information about one of the fields of a compound type.
256 
257 \param ncid \ref ncid
258 
259 \param xtype The typeid for this compound type, as returned by
260 nc_def_compound(), or nc_inq_var().
261 
262 \param fieldid A zero-based index number specifying a field in the
263 compound type.
264 
265 \param name Returned \ref object_name of the field. \ref
266 ignored_if_null.
267 
268 \param offsetp A pointer which will get the offset of the field. \ref
269 ignored_if_null.
270 
271 \param field_typeidp A pointer which will get the typeid of the
272 field. \ref ignored_if_null.
273 
274 \param ndimsp A pointer which will get the number of dimensions of the
275 field. \ref ignored_if_null.
276 
277 \param dim_sizesp A pointer which will get the dimension sizes of the
278 field. \ref ignored_if_null.
279 
280 \returns ::NC_NOERR No error.
281 \returns ::NC_EBADID Bad \ref ncid.
282 \returns ::NC_EBADTYPE Bad type id.
283 \returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled.
284 \returns ::NC_EHDFERR An error was reported by the HDF5 layer.
285  */
286 int
nc_inq_compound_field(int ncid,nc_type xtype,int fieldid,char * name,size_t * offsetp,nc_type * field_typeidp,int * ndimsp,int * dim_sizesp)287 nc_inq_compound_field(int ncid, nc_type xtype, int fieldid,
288 		      char *name, size_t *offsetp,
289 		      nc_type *field_typeidp, int *ndimsp,
290 		      int *dim_sizesp)
291 {
292    NC* ncp;
293    int stat = NC_check_id(ncid,&ncp);
294    if(stat != NC_NOERR) return stat;
295    return ncp->dispatch->inq_compound_field(ncid, xtype, fieldid,
296 					    name, offsetp, field_typeidp,
297 					    ndimsp, dim_sizesp);
298 }
299 
300 /**  \ingroup user_types
301 Get information about one of the fields of a compound type.
302 
303 \param ncid \ref ncid
304 
305 \param xtype The typeid for this compound type, as returned by
306 nc_def_compound(), or nc_inq_var().
307 
308 \param fieldid A zero-based index number specifying a field in the
309 compound type.
310 
311 \param name Returned \ref object_name of the field. \ref
312 ignored_if_null.
313 
314 \returns ::NC_NOERR No error.
315 \returns ::NC_EBADID Bad \ref ncid.
316 \returns ::NC_EBADTYPE Bad type id.
317 \returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled.
318 \returns ::NC_EHDFERR An error was reported by the HDF5 layer.
319  */
320 int
nc_inq_compound_fieldname(int ncid,nc_type xtype,int fieldid,char * name)321 nc_inq_compound_fieldname(int ncid, nc_type xtype, int fieldid,
322 			  char *name)
323 {
324    NC* ncp;
325    int stat = NC_check_id(ncid,&ncp);
326    if(stat != NC_NOERR) return stat;
327    return ncp->dispatch->inq_compound_field(ncid, xtype, fieldid,
328 					    name, NULL, NULL, NULL,
329 					    NULL);
330 }
331 
332 /**  \ingroup user_types
333 Get information about one of the fields of a compound type.
334 
335 \param ncid \ref ncid
336 
337 \param xtype The typeid for this compound type, as returned by
338 nc_def_compound(), or nc_inq_var().
339 
340 \param fieldid A zero-based index number specifying a field in the
341 compound type.
342 
343 \param offsetp A pointer which will get the offset of the field. \ref
344 ignored_if_null.
345 
346 \returns ::NC_NOERR No error.
347 \returns ::NC_EBADID Bad \ref ncid.
348 \returns ::NC_EBADTYPE Bad type id.
349 \returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled.
350 \returns ::NC_EHDFERR An error was reported by the HDF5 layer.
351  */
352 int
nc_inq_compound_fieldoffset(int ncid,nc_type xtype,int fieldid,size_t * offsetp)353 nc_inq_compound_fieldoffset(int ncid, nc_type xtype, int fieldid,
354 			    size_t *offsetp)
355 {
356    NC* ncp;
357    int stat = NC_check_id(ncid,&ncp);
358    if(stat != NC_NOERR) return stat;
359    return ncp->dispatch->inq_compound_field(ncid,xtype,fieldid,NULL,offsetp,NULL,NULL,NULL);
360 }
361 
362 /**  \ingroup user_types
363 Get information about one of the fields of a compound type.
364 
365 \param ncid \ref ncid
366 
367 \param xtype The typeid for this compound type, as returned by
368 nc_def_compound(), or nc_inq_var().
369 
370 \param fieldid A zero-based index number specifying a field in the
371 compound type.
372 
373 \param field_typeidp A pointer which will get the typeid of the
374 field. \ref ignored_if_null.
375 
376 \returns ::NC_NOERR No error.
377 \returns ::NC_EBADID Bad \ref ncid.
378 \returns ::NC_EBADTYPE Bad type id.
379 \returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled.
380 \returns ::NC_EHDFERR An error was reported by the HDF5 layer.
381  */
382 int
nc_inq_compound_fieldtype(int ncid,nc_type xtype,int fieldid,nc_type * field_typeidp)383 nc_inq_compound_fieldtype(int ncid, nc_type xtype, int fieldid,
384 			  nc_type *field_typeidp)
385 {
386    NC* ncp;
387    int stat = NC_check_id(ncid,&ncp);
388    if(stat != NC_NOERR) return stat;
389    return ncp->dispatch->inq_compound_field(ncid,xtype,fieldid,NULL,NULL,field_typeidp,NULL,NULL);
390 }
391 
392 /**  \ingroup user_types
393 Get information about one of the fields of a compound type.
394 
395 \param ncid \ref ncid
396 
397 \param xtype The typeid for this compound type, as returned by
398 nc_def_compound(), or nc_inq_var().
399 
400 \param fieldid A zero-based index number specifying a field in the
401 compound type.
402 
403 \param ndimsp A pointer which will get the number of dimensions of the
404 field. \ref ignored_if_null.
405 
406 \returns ::NC_NOERR No error.
407 \returns ::NC_EBADID Bad \ref ncid.
408 \returns ::NC_EBADTYPE Bad type id.
409 \returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled.
410 \returns ::NC_EHDFERR An error was reported by the HDF5 layer.
411  */
412 int
nc_inq_compound_fieldndims(int ncid,nc_type xtype,int fieldid,int * ndimsp)413 nc_inq_compound_fieldndims(int ncid, nc_type xtype, int fieldid,
414 			   int *ndimsp)
415 {
416    NC* ncp;
417    int stat = NC_check_id(ncid,&ncp);
418    if(stat != NC_NOERR) return stat;
419    return ncp->dispatch->inq_compound_field(ncid,xtype,fieldid,NULL,NULL,NULL,ndimsp,NULL);
420 }
421 
422 /**  \ingroup user_types
423 Get information about one of the fields of a compound type.
424 
425 \param ncid \ref ncid
426 
427 \param xtype The typeid for this compound type, as returned by
428 nc_def_compound(), or nc_inq_var().
429 
430 \param fieldid A zero-based index number specifying a field in the
431 compound type.
432 
433 \param dim_sizesp A pointer which will get the dimension sizes of the
434 field. \ref ignored_if_null.
435 
436 \returns ::NC_NOERR No error.
437 \returns ::NC_EBADID Bad \ref ncid.
438 \returns ::NC_EBADTYPE Bad type id.
439 \returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled.
440 \returns ::NC_EHDFERR An error was reported by the HDF5 layer.
441  */
442 int
nc_inq_compound_fielddim_sizes(int ncid,nc_type xtype,int fieldid,int * dim_sizesp)443 nc_inq_compound_fielddim_sizes(int ncid, nc_type xtype, int fieldid,
444 			       int *dim_sizesp)
445 {
446    NC *ncp;
447    int stat = NC_check_id(ncid, &ncp);
448    if(stat != NC_NOERR) return stat;
449    return ncp->dispatch->inq_compound_field(ncid, xtype, fieldid,
450 					    NULL, NULL, NULL, NULL,
451 					    dim_sizesp);
452 }
453 
454 /**  \ingroup user_types
455 Learn the Index of a Named Field in a Compound Type. Get the index
456  * of a field in a compound type from the name.
457 
458 \param ncid \ref ncid
459 
460 \param xtype The typeid for this compound type, as returned by
461 nc_def_compound(), or nc_inq_var().
462 
463 \param name \ref object_name of the field. \ref ignored_if_null.
464 
465 \param fieldidp A pointer which will get the index of the named
466 field. \ref ignored_if_null.
467 
468 \returns ::NC_NOERR No error.
469 \returns ::NC_EBADID Bad \ref ncid.
470 \returns ::NC_EBADTYPE Bad type id.
471 \returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled.
472 \returns ::NC_EHDFERR An error was reported by the HDF5 layer.
473  */
474 int
nc_inq_compound_fieldindex(int ncid,nc_type xtype,const char * name,int * fieldidp)475 nc_inq_compound_fieldindex(int ncid, nc_type xtype, const char *name,
476 			   int *fieldidp)
477 {
478    NC* ncp;
479    int stat = NC_check_id(ncid,&ncp);
480    if(stat != NC_NOERR) return stat;
481    return ncp->dispatch->inq_compound_fieldindex(ncid,xtype,name,fieldidp);
482 }
483 /*! \} */  /* End of named group ...*/
484 
485 
486 
487 
488 
489 
490