1 /*! \file dvarput.c
2 Functions for writing data to variables.
3 
4 Copyright 2018 University Corporation for Atmospheric
5 Research/Unidata. See COPYRIGHT file for more info.
6 */
7 
8 #include "ncdispatch.h"
9 
10 struct PUTodometer {
11     int            rank;
12     size_t         index[NC_MAX_VAR_DIMS];
13     size_t         start[NC_MAX_VAR_DIMS];
14     size_t         edges[NC_MAX_VAR_DIMS];
15     ptrdiff_t      stride[NC_MAX_VAR_DIMS];
16     size_t         stop[NC_MAX_VAR_DIMS];
17 };
18 
19 /**
20  * @internal Initialize odometer.
21  *
22  * @param odom Pointer to odometer.
23  * @param rank
24  * @param start Start indices.
25  * @param edges Counts.
26  * @param stride Strides.
27  *
28  */
29 static void
odom_init(struct PUTodometer * odom,int rank,const size_t * start,const size_t * edges,const ptrdiff_t * stride)30 odom_init(struct PUTodometer* odom, int rank, const size_t* start,
31           const size_t* edges, const ptrdiff_t* stride)
32 {
33     int i;
34     memset(odom,0,sizeof(struct PUTodometer));
35     odom->rank = rank;
36     assert(odom->rank <= NC_MAX_VAR_DIMS);
37     for(i=0;i<odom->rank;i++) {
38 	odom->start[i] = (start != NULL ? start[i] : 0);
39 	odom->edges[i] = (edges != NULL ? edges[i] : 1);
40 	odom->stride[i] = (stride != NULL ? stride[i] : 1);
41 	odom->stop[i] = odom->start[i] + (odom->edges[i]*(size_t)odom->stride[i]);
42 	odom->index[i] = odom->start[i];
43     }
44 }
45 
46 /**
47  * @internal Return true if there is more.
48  *
49  * @param odom Pointer to odometer.
50  *
51  * @return True if there is more, 0 otherwise.
52  */
53 static int
odom_more(struct PUTodometer * odom)54 odom_more(struct PUTodometer* odom)
55 {
56     return (odom->index[0] < odom->stop[0]);
57 }
58 
59 /**
60  * @internal Return true if there is more.
61  *
62  * @param odom Pointer to odometer.
63  *
64  * @return True if there is more, 0 otherwise.
65  */
66 static int
odom_next(struct PUTodometer * odom)67 odom_next(struct PUTodometer* odom)
68 {
69     int i;
70     if(odom->rank == 0) return 0;
71     for(i=odom->rank-1;i>=0;i--) {
72         odom->index[i] += (size_t)odom->stride[i];
73         if(odom->index[i] < odom->stop[i]) break;
74 	if(i == 0) return 0; /* leave the 0th entry if it overflows*/
75 	odom->index[i] = odom->start[i]; /* reset this position*/
76     }
77     return 1;
78 }
79 
80 /** \internal
81 \ingroup variables
82 */
83 static int
NC_put_vara(int ncid,int varid,const size_t * start,const size_t * edges,const void * value,nc_type memtype)84 NC_put_vara(int ncid, int varid, const size_t *start,
85 	    const size_t *edges, const void *value, nc_type memtype)
86 {
87    NC* ncp;
88    size_t *my_count = (size_t *)edges;
89 
90    int stat = NC_check_id(ncid, &ncp);
91    if(stat != NC_NOERR) return stat;
92 
93    if(start == NULL || edges == NULL) {
94       stat = NC_check_nulls(ncid, varid, start, &my_count, NULL);
95       if(stat != NC_NOERR) return stat;
96    }
97    stat = ncp->dispatch->put_vara(ncid, varid, start, my_count, value, memtype);
98    if(edges == NULL) free(my_count);
99    return stat;
100 }
101 
102 /** \internal
103 \ingroup variables
104 */
105 static int
NC_put_var(int ncid,int varid,const void * value,nc_type memtype)106 NC_put_var(int ncid, int varid, const void *value, nc_type memtype)
107 {
108    int ndims;
109    size_t shape[NC_MAX_VAR_DIMS];
110    int stat = nc_inq_varndims(ncid,varid, &ndims);
111    if(stat) return stat;
112    stat = NC_getshape(ncid,varid, ndims, shape);
113    if(stat) return stat;
114    return NC_put_vara(ncid, varid, NC_coord_zero, shape, value, memtype);
115 }
116 
117 /** \internal
118 \ingroup variables
119 */
120 static int
NC_put_var1(int ncid,int varid,const size_t * coord,const void * value,nc_type memtype)121 NC_put_var1(int ncid, int varid, const size_t *coord, const void* value,
122 	    nc_type memtype)
123 {
124    return NC_put_vara(ncid, varid, coord, NC_coord_one, value, memtype);
125 }
126 
127 /** \internal
128 \ingroup variables
129 */
130 int
NCDEFAULT_put_vars(int ncid,int varid,const size_t * start,const size_t * edges,const ptrdiff_t * stride,const void * value0,nc_type memtype)131 NCDEFAULT_put_vars(int ncid, int varid, const size_t * start,
132 	    const size_t * edges, const ptrdiff_t * stride,
133 	    const void *value0, nc_type memtype)
134 {
135   /* Rebuilt put_vars code to simplify and avoid use of put_varm */
136 
137    int status = NC_NOERR;
138    int i,isstride1,isrecvar;
139    int rank;
140    struct PUTodometer odom;
141    nc_type vartype = NC_NAT;
142    NC* ncp;
143    size_t vartypelen;
144    size_t nels;
145    int memtypelen;
146    const char* value = (const char*)value0;
147    int nrecdims;                /* number of record dims for a variable */
148    int is_recdim[NC_MAX_VAR_DIMS]; /* for variable's dimensions */
149    size_t varshape[NC_MAX_VAR_DIMS];
150    size_t mystart[NC_MAX_VAR_DIMS];
151    size_t myedges[NC_MAX_VAR_DIMS];
152    ptrdiff_t mystride[NC_MAX_VAR_DIMS];
153    const char* memptr = value;
154 
155    status = NC_check_id (ncid, &ncp);
156    if(status != NC_NOERR) return status;
157 
158    status = nc_inq_vartype(ncid, varid, &vartype);
159    if(status != NC_NOERR) return status;
160 
161    if(memtype == NC_NAT) memtype = vartype;
162 
163    /* compute the variable type size */
164    status = nc_inq_type(ncid,vartype,NULL,&vartypelen);
165    if(status != NC_NOERR) return status;
166 
167    if(memtype > NC_MAX_ATOMIC_TYPE)
168 	memtypelen = (int)vartypelen;
169     else
170 	memtypelen = nctypelen(memtype);
171 
172    /* Check gross internal/external type compatibility */
173    if(vartype != memtype) {
174       /* If !atomic, the two types must be the same */
175       if(vartype > NC_MAX_ATOMIC_TYPE
176          || memtype > NC_MAX_ATOMIC_TYPE)
177 	 return NC_EBADTYPE;
178       /* ok, the types differ but both are atomic */
179       if(memtype == NC_CHAR || vartype == NC_CHAR)
180 	 return NC_ECHAR;
181    }
182 
183    /* Get the variable rank */
184    status = nc_inq_varndims(ncid, varid, &rank);
185    if(status != NC_NOERR) return status;
186 
187    /* Start array is always required for non-scalar vars. */
188    if(rank > 0 && start == NULL)
189       return NC_EINVALCOORDS;
190 
191    /* Get variable dimension sizes */
192    status = NC_inq_recvar(ncid,varid,&nrecdims,is_recdim);
193    if(status != NC_NOERR) return status;
194    isrecvar = (nrecdims > 0);
195    NC_getshape(ncid,varid,rank,varshape);
196 
197    /* Optimize out using various checks */
198    if (rank == 0) {
199       /*
200        * The variable is a scalar; consequently,
201        * there is only one thing to get and only one place to put it.
202        * (Why was I called?)
203        */
204       size_t edge1[1] = {1};
205       return NC_put_vara(ncid, varid, start, edge1, value0, memtype);
206    }
207 
208    /* Do various checks and fixups on start/edges/stride */
209    isstride1 = 1; /* assume so */
210    nels = 1;
211    for(i=0;i<rank;i++) {
212 	size_t dimlen;
213 	mystart[i] = (start == NULL ? 0 : start[i]);
214 #if 0
215 	dimlen = (i == 0 && isrecvar ? numrecs : varshape[i]);
216 	if(i == 0 && isrecvar) {/*do nothing*/}
217 #else
218         /* illegal value checks */
219 	dimlen = varshape[i];
220 	if(is_recdim[i]) {/*do nothing*/}
221 #endif
222         else {
223 	  /* mystart is unsigned, will never be < 0 */
224 	  if (mystart[i] > dimlen) return NC_EINVALCOORDS;
225        }
226 	if(edges == NULL) {
227 #if 0
228 	   if(i == 0 && isrecvar)
229   	      myedges[i] = numrecs - start[i];
230 #else
231 	   if(is_recdim[i] && isrecvar)
232   	      myedges[i] = varshape[i] - start[i];
233 #endif
234 	   else
235 	      myedges[i] = varshape[i] - mystart[i];
236 	} else
237 	    myedges[i] = edges[i];
238 
239 	if(!is_recdim[i]) {
240 	  if (mystart[i] == dimlen && myedges[i] > 0)
241               return NC_EINVALCOORDS;
242         }
243 
244 	if(!is_recdim[i]) {
245           /* myediges is unsigned, will never be < 0 */
246 	  if(mystart[i] + myedges[i] > dimlen)
247 	    return NC_EEDGE;
248         }
249 	mystride[i] = (stride == NULL ? 1 : stride[i]);
250 	if(mystride[i] <= 0
251 	   /* cast needed for braindead systems with signed size_t */
252            || ((unsigned long) mystride[i] >= X_INT_MAX))
253            return NC_ESTRIDE;
254   	if(mystride[i] != 1) isstride1 = 0;
255         nels *= myedges[i];
256    }
257 
258    if(isstride1) {
259       return NC_put_vara(ncid, varid, mystart, myedges, value, memtype);
260    }
261 
262    if(nels == 0) {
263       /* This should be here instead of before NC_put_vara call to
264        * avoid hang in parallel write for single stride.
265        * Still issue with parallel hang if stride > 1
266        */
267       return NC_NOERR; /* cannot write anything */
268    }
269 
270    /* Initial version uses and odometer to walk the variable
271       and read each value one at a time. This can later be optimized
272       to read larger chunks at a time.
273     */
274 
275 
276    odom_init(&odom,rank,mystart,myedges,mystride);
277 
278    /* walk the odometer to extract values */
279    while(odom_more(&odom)) {
280       int localstatus = NC_NOERR;
281       /* Write a single value */
282       localstatus = NC_put_vara(ncid,varid,odom.index,NC_coord_one,memptr,memtype);
283       /* So it turns out that when get_varm is used, all errors are
284          delayed and ERANGE will be overwritten by more serious errors.
285       */
286       if(localstatus != NC_NOERR) {
287 	    if(status == NC_NOERR || localstatus != NC_ERANGE)
288 	       status = localstatus;
289       }
290       memptr += memtypelen;
291       odom_next(&odom);
292    }
293    return status;
294 }
295 
296 /** \internal
297 \ingroup variables
298 */
299 int
NCDEFAULT_put_varm(int ncid,int varid,const size_t * start,const size_t * edges,const ptrdiff_t * stride,const ptrdiff_t * imapp,const void * value0,nc_type memtype)300 NCDEFAULT_put_varm(
301    int ncid,
302    int varid,
303    const size_t * start,
304    const size_t * edges,
305    const ptrdiff_t * stride,
306    const ptrdiff_t * imapp,
307    const void *value0,
308    nc_type memtype)
309 {
310    int status = NC_NOERR;
311    nc_type vartype = NC_NAT;
312    int varndims = 0;
313    int maxidim = 0;
314    NC* ncp;
315    int memtypelen;
316    const char* value = (char*)value0;
317 
318    status = NC_check_id (ncid, &ncp);
319    if(status != NC_NOERR) return status;
320 
321 /*
322   if(NC_indef(ncp)) return NC_EINDEFINE;
323   if(NC_readonly (ncp)) return NC_EPERM;
324 */
325 
326    /* mid body */
327    status = nc_inq_vartype(ncid, varid, &vartype);
328    if(status != NC_NOERR) return status;
329    /* Check that this is an atomic type */
330    if(vartype > NC_MAX_ATOMIC_TYPE)
331 	return NC_EMAPTYPE;
332 
333    status = nc_inq_varndims(ncid, varid, &varndims);
334    if(status != NC_NOERR) return status;
335 
336    if(memtype == NC_NAT) {
337       memtype = vartype;
338    }
339 
340    if(memtype == NC_CHAR && vartype != NC_CHAR)
341       return NC_ECHAR;
342    else if(memtype != NC_CHAR && vartype == NC_CHAR)
343       return NC_ECHAR;
344 
345    memtypelen = nctypelen(memtype);
346 
347    maxidim = (int) varndims - 1;
348 
349    if (maxidim < 0)
350    {
351       /*
352        * The variable is a scalar; consequently,
353        * there s only one thing to get and only one place to put it.
354        * (Why was I called?)
355        */
356       size_t edge1[1] = {1};
357       return NC_put_vara(ncid, varid, start, edge1, value, memtype);
358    }
359 
360    /*
361     * else
362     * The variable is an array.
363     */
364    {
365       int idim;
366       size_t *mystart = NULL;
367       size_t *myedges = 0;
368       size_t *iocount= 0;    /* count vector */
369       size_t *stop = 0;   /* stop indexes */
370       size_t *length = 0; /* edge lengths in bytes */
371       ptrdiff_t *mystride = 0;
372       ptrdiff_t *mymap= 0;
373       size_t varshape[NC_MAX_VAR_DIMS];
374       int isrecvar;
375       size_t numrecs;
376       int stride1; /* is stride all ones? */
377 
378       /*
379        * Verify stride argument.
380        */
381       stride1 = 1;		/*  assume ok; */
382       if(stride != NULL) {
383 	 for (idim = 0; idim <= maxidim; ++idim) {
384             if ((stride[idim] == 0)
385 		/* cast needed for braindead systems with signed size_t */
386                 || ((unsigned long) stride[idim] >= X_INT_MAX))
387 	    {
388 	       return NC_ESTRIDE;
389             }
390 	    if(stride[idim] != 1) stride1 = 0;
391 	 }
392       }
393 
394       /* If stride1 is true, and there is no imap, then call get_vara
395          directly
396       */
397       if(stride1 && imapp == NULL) {
398 	 return NC_put_vara(ncid, varid, start, edges, value, memtype);
399       }
400 
401       /* Compute some dimension related values */
402       isrecvar = NC_is_recvar(ncid,varid,&numrecs);
403       NC_getshape(ncid,varid,varndims,varshape);
404 
405       /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
406       mystart = (size_t *)calloc((size_t)(varndims * 7), sizeof(ptrdiff_t));
407       if(mystart == NULL) return NC_ENOMEM;
408       myedges = mystart + varndims;
409       iocount = myedges + varndims;
410       stop = iocount + varndims;
411       length = stop + varndims;
412       mystride = (ptrdiff_t *)(length + varndims);
413       mymap = mystride + varndims;
414 
415       /*
416        * Check start, edges
417        */
418       for (idim = maxidim; idim >= 0; --idim)
419       {
420 	 mystart[idim] = start != NULL
421 	    ? start[idim]
422 	    : 0;
423 
424 	 myedges[idim] = edges != NULL
425 	    ? edges[idim]
426 	    : idim == 0 && isrecvar
427     	        ? numrecs - mystart[idim]
428 	        : varshape[idim] - mystart[idim];
429       }
430 
431       for (idim = isrecvar; idim <= maxidim; ++idim)
432       {
433 	 if (mystart[idim] > varshape[idim] ||
434 	    (mystart[idim] == varshape[idim] && myedges[idim] > 0))
435 	 {
436 	    status = NC_EINVALCOORDS;
437 	    goto done;
438 	 }
439 
440 	 if (mystart[idim] + myedges[idim] > varshape[idim])
441 	 {
442 	    status = NC_EEDGE;
443 	    goto done;
444 	 }
445       }
446 
447       /*
448        * Initialize I/O parameters.
449        */
450       for (idim = maxidim; idim >= 0; --idim)
451       {
452 	 if (edges != NULL && edges[idim] == 0)
453 	 {
454 	    status = NC_NOERR;    /* read/write no data */
455 	    goto done;
456 	 }
457 
458 	 mystride[idim] = stride != NULL
459 	    ? stride[idim]
460 	    : 1;
461 	 mymap[idim] = imapp != NULL
462 	    ? imapp[idim]
463 	    : idim == maxidim
464 	        ? 1
465 	        : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
466 
467 	 iocount[idim] = 1;
468 	 length[idim] = ((size_t)mymap[idim]) * myedges[idim];
469 	 stop[idim] = mystart[idim] + myedges[idim] * (size_t)mystride[idim];
470       }
471 
472       /* Lower body */
473       /*
474        * As an optimization, adjust I/O parameters when the fastest
475        * dimension has unity stride both externally and internally.
476        * In this case, the user could have called a simpler routine
477        * (i.e. ncvar$1()
478        */
479       if (mystride[maxidim] == 1
480 	  && mymap[maxidim] == 1)
481       {
482 	 iocount[maxidim] = myedges[maxidim];
483 	 mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
484 	 mymap[maxidim] = (ptrdiff_t) length[maxidim];
485       }
486 
487       /*
488        * Perform I/O.  Exit when done.
489        */
490       for (;;)
491       {
492 	 /* TODO: */
493 	 int lstatus = NC_put_vara(ncid, varid, mystart, iocount,
494 				   value, memtype);
495 	 if (lstatus != NC_NOERR) {
496 	    if(status == NC_NOERR || lstatus != NC_ERANGE)
497 	       status = lstatus;
498 	 }
499 
500 	 /*
501 	  * The following code permutes through the variable s
502 	  * external start-index space and it s internal address
503 	  * space.  At the UPC, this algorithm is commonly
504 	  * called "odometer code".
505 	  */
506 	 idim = maxidim;
507         carry:
508 	 value += (mymap[idim] * memtypelen);
509 	 mystart[idim] += (size_t)mystride[idim];
510 	 if (mystart[idim] == stop[idim])
511 	 {
512 	    size_t l = (length[idim] * (size_t)memtypelen);
513 	    value -= l;
514 	    mystart[idim] = start[idim];
515 	    if (--idim < 0)
516 	       break; /* normal return */
517 	    goto carry;
518 	 }
519       } /* I/O loop */
520      done:
521       free(mystart);
522    } /* variable is array */
523    return status;
524 }
525 
526 /** \internal
527 \ingroup variables
528 */
529 static int
NC_put_vars(int ncid,int varid,const size_t * start,const size_t * edges,const ptrdiff_t * stride,const void * value,nc_type memtype)530 NC_put_vars(int ncid, int varid, const size_t *start,
531 	    const size_t *edges, const ptrdiff_t *stride,
532 	    const void *value, nc_type memtype)
533 {
534    NC* ncp;
535    size_t *my_count = (size_t *)edges;
536    ptrdiff_t *my_stride = (ptrdiff_t *)stride;
537    int stat;
538 
539    stat = NC_check_id(ncid, &ncp);
540    if(stat != NC_NOERR) return stat;
541 
542    /* Handle any NULL parameters. */
543    if(start == NULL || edges == NULL || stride == NULL) {
544       stat = NC_check_nulls(ncid, varid, start, &my_count, &my_stride);
545       if(stat != NC_NOERR) return stat;
546    }
547 
548    stat = ncp->dispatch->put_vars(ncid, varid, start, my_count, my_stride,
549                                   value, memtype);
550    if(edges == NULL) free(my_count);
551    if(stride == NULL) free(my_stride);
552    return stat;
553 }
554 
555 /** \internal
556 \ingroup variables
557 */
558 static int
NC_put_varm(int ncid,int varid,const size_t * start,const size_t * edges,const ptrdiff_t * stride,const ptrdiff_t * map,const void * value,nc_type memtype)559 NC_put_varm(int ncid, int varid, const size_t *start,
560 	    const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t* map,
561 	    const void *value, nc_type memtype)
562 {
563    NC* ncp;
564    size_t *my_count = (size_t *)edges;
565    ptrdiff_t *my_stride = (ptrdiff_t *)stride;
566    int stat;
567 
568    stat = NC_check_id(ncid, &ncp);
569    if(stat != NC_NOERR) return stat;
570 
571    /* Handle any NULL parameters. */
572    if(start == NULL || edges == NULL || stride == NULL) {
573       stat = NC_check_nulls(ncid, varid, start, &my_count, &my_stride);
574       if(stat != NC_NOERR) return stat;
575    }
576 
577    stat = ncp->dispatch->put_varm(ncid, varid, start, my_count, my_stride,
578                                   map, value, memtype);
579    if(edges == NULL) free(my_count);
580    if(stride == NULL) free(my_stride);
581    return stat;
582 }
583 
584 /** \name Writing Data to Variables
585 
586 Functions to write data from variables. */
587 /*! \{ */ /* All these functions are part of this named group... */
588 
589 /** \ingroup variables
590 Write an array of values to a variable.
591 
592 The values to be written are associated with the netCDF variable by
593 assuming that the last dimension of the netCDF variable varies fastest
594 in the C interface. The netCDF dataset must be in data mode. The array
595 to be written is specified by giving a corner and a vector of edge
596 lengths to \ref specify_hyperslab.
597 
598 The functions for types ubyte, ushort, uint, longlong, ulonglong, and
599 string are only available for netCDF-4/HDF5 files.
600 
601 The nc_put_var() function will write a variable of any type, including
602 user defined type. For this function, the type of the data in memory
603 must match the type of the variable - no data conversion is done.
604 
605 \param ncid NetCDF or group ID, from a previous call to nc_open(),
606 nc_create(), nc_def_grp(), or associated inquiry functions such as
607 nc_inq_ncid().
608 
609 \param varid Variable ID
610 
611 \param startp Start vector with one element for each dimension to \ref
612 specify_hyperslab.
613 
614 \param countp Count vector with one element for each dimension to \ref
615 specify_hyperslab.
616 
617 \param op Pointer where the data will be copied. Memory must be
618 allocated by the user before this function is called.
619 
620 \returns ::NC_NOERR No error.
621 \returns ::NC_ENOTVAR Variable not found.
622 \returns ::NC_EINVALCOORDS Index exceeds dimension bound.
623 \returns ::NC_EEDGE Start+count exceeds dimension bound.
624 \returns ::NC_ERANGE One or more of the values are out of range.
625 \returns ::NC_EINDEFINE Operation not allowed in define mode.
626 \returns ::NC_EBADID Bad ncid.
627 \author Glenn Davis, Russ Rew, Ed Hartnett, Dennis Heimbigner, Ward Fisher
628  */
629 /**@{*/
630 int
nc_put_vara(int ncid,int varid,const size_t * startp,const size_t * countp,const void * op)631 nc_put_vara(int ncid, int varid, const size_t *startp,
632 	    const size_t *countp, const void *op)
633 {
634    NC* ncp;
635    int stat = NC_check_id(ncid, &ncp);
636    nc_type xtype;
637    if(stat != NC_NOERR) return stat;
638    stat = nc_inq_vartype(ncid, varid, &xtype);
639    if(stat != NC_NOERR) return stat;
640    return NC_put_vara(ncid, varid, startp, countp, op, xtype);
641 }
642 
643 int
nc_put_vara_text(int ncid,int varid,const size_t * startp,const size_t * countp,const char * op)644 nc_put_vara_text(int ncid, int varid, const size_t *startp,
645 		 const size_t *countp, const char *op)
646 {
647    return NC_put_vara(ncid, varid, startp, countp,
648 		      (void*)op, NC_CHAR);
649 }
650 
651 int
nc_put_vara_schar(int ncid,int varid,const size_t * startp,const size_t * countp,const signed char * op)652 nc_put_vara_schar(int ncid, int varid, const size_t *startp,
653 		  const size_t *countp, const signed char *op)
654 {
655    return NC_put_vara(ncid, varid, startp, countp, (void *)op,
656 		      NC_BYTE);
657 }
658 
659 int
nc_put_vara_uchar(int ncid,int varid,const size_t * startp,const size_t * countp,const unsigned char * op)660 nc_put_vara_uchar(int ncid, int varid, const size_t *startp,
661 		  const size_t *countp, const unsigned char *op)
662 {
663    return NC_put_vara(ncid, varid, startp, countp, (void *)op,
664 		      T_uchar);
665 }
666 
667 int
nc_put_vara_short(int ncid,int varid,const size_t * startp,const size_t * countp,const short * op)668 nc_put_vara_short(int ncid, int varid, const size_t *startp,
669 		  const size_t *countp, const short *op)
670 {
671    return NC_put_vara(ncid, varid, startp, countp, (void *)op,
672 		      NC_SHORT);
673 }
674 
675 int
nc_put_vara_int(int ncid,int varid,const size_t * startp,const size_t * countp,const int * op)676 nc_put_vara_int(int ncid, int varid, const size_t *startp,
677 		const size_t *countp, const int *op)
678 {
679    return NC_put_vara(ncid, varid, startp, countp, (void *)op,
680 		      NC_INT);
681 }
682 
683 int
nc_put_vara_long(int ncid,int varid,const size_t * startp,const size_t * countp,const long * op)684 nc_put_vara_long(int ncid, int varid, const size_t *startp,
685 		 const size_t *countp, const long *op)
686 {
687    return NC_put_vara(ncid, varid, startp, countp, (void *)op,
688 		      T_long);
689 }
690 
691 int
nc_put_vara_float(int ncid,int varid,const size_t * startp,const size_t * countp,const float * op)692 nc_put_vara_float(int ncid, int varid, const size_t *startp,
693 		  const size_t *countp, const float *op)
694 {
695    return NC_put_vara(ncid, varid, startp, countp, (void *)op,
696 		      T_float);
697 }
698 
699 int
nc_put_vara_double(int ncid,int varid,const size_t * startp,const size_t * countp,const double * op)700 nc_put_vara_double(int ncid, int varid, const size_t *startp,
701 		   const size_t *countp, const double *op)
702 {
703    return NC_put_vara(ncid, varid, startp, countp, (void *)op,
704 		      T_double);
705 }
706 
707 int
nc_put_vara_ubyte(int ncid,int varid,const size_t * startp,const size_t * countp,const unsigned char * op)708 nc_put_vara_ubyte(int ncid, int varid, const size_t *startp,
709 		  const size_t *countp, const unsigned char *op)
710 {
711    return NC_put_vara(ncid, varid, startp, countp, (void *)op,
712 		      T_ubyte);
713 }
714 
715 int
nc_put_vara_ushort(int ncid,int varid,const size_t * startp,const size_t * countp,const unsigned short * op)716 nc_put_vara_ushort(int ncid, int varid, const size_t *startp,
717 		   const size_t *countp, const unsigned short *op)
718 {
719    return NC_put_vara(ncid, varid, startp, countp, (void *)op,
720 		      T_ushort);
721 }
722 
723 int
nc_put_vara_uint(int ncid,int varid,const size_t * startp,const size_t * countp,const unsigned int * op)724 nc_put_vara_uint(int ncid, int varid, const size_t *startp,
725 		 const size_t *countp, const unsigned int *op)
726 {
727    return NC_put_vara(ncid, varid, startp, countp, (void *)op,
728 		      T_uint);
729 }
730 
731 int
nc_put_vara_longlong(int ncid,int varid,const size_t * startp,const size_t * countp,const long long * op)732 nc_put_vara_longlong(int ncid, int varid, const size_t *startp,
733 		     const size_t *countp, const long long *op)
734 {
735    return NC_put_vara(ncid, varid, startp, countp, (void *)op,
736 		      T_longlong);
737 }
738 
739 int
nc_put_vara_ulonglong(int ncid,int varid,const size_t * startp,const size_t * countp,const unsigned long long * op)740 nc_put_vara_ulonglong(int ncid, int varid, const size_t *startp,
741 		      const size_t *countp, const unsigned long long *op)
742 {
743    return NC_put_vara(ncid, varid, startp, countp, (void *)op,
744 		      NC_UINT64);
745 }
746 
747 int
nc_put_vara_string(int ncid,int varid,const size_t * startp,const size_t * countp,const char ** op)748 nc_put_vara_string(int ncid, int varid, const size_t *startp,
749 		   const size_t *countp, const char* *op)
750 {
751    return NC_put_vara(ncid, varid, startp, countp, (void *)op,
752 		      NC_STRING);
753 }
754 
755 /**@}*/
756 
757 /** \ingroup variables
758 Write one datum.
759 
760 \param ncid NetCDF or group ID, from a previous call to nc_open(),
761 nc_create(), nc_def_grp(), or associated inquiry functions such as
762 nc_inq_ncid().
763 
764 \param varid Variable ID
765 
766 \param indexp Index vector with one element for each dimension.
767 
768 \param op Pointer from where the data will be copied.
769 
770 \returns ::NC_NOERR No error.
771 \returns ::NC_ENOTVAR Variable not found.
772 \returns ::NC_EINVALCOORDS Index exceeds dimension bound.
773 \returns ::NC_EEDGE Start+count exceeds dimension bound.
774 \returns ::NC_ERANGE One or more of the values are out of range.
775 \returns ::NC_EINDEFINE Operation not allowed in define mode.
776 \returns ::NC_EBADID Bad ncid.
777 \author Glenn Davis, Russ Rew, Ed Hartnett, Dennis Heimbigner, Ward Fisher
778  */
779 /**@{*/
780 int
nc_put_var1(int ncid,int varid,const size_t * indexp,const void * op)781 nc_put_var1(int ncid, int varid, const size_t *indexp, const void *op)
782 {
783    return NC_put_var1(ncid, varid, indexp, op, NC_NAT);
784 }
785 
786 int
nc_put_var1_text(int ncid,int varid,const size_t * indexp,const char * op)787 nc_put_var1_text(int ncid, int varid, const size_t *indexp, const char *op)
788 {
789    return NC_put_var1(ncid, varid, indexp, (void *)op, NC_CHAR);
790 }
791 
792 int
nc_put_var1_schar(int ncid,int varid,const size_t * indexp,const signed char * op)793 nc_put_var1_schar(int ncid, int varid, const size_t *indexp, const signed char *op)
794 {
795    return NC_put_var1(ncid, varid, indexp, (void *)op, NC_BYTE);
796 }
797 
798 int
nc_put_var1_uchar(int ncid,int varid,const size_t * indexp,const unsigned char * op)799 nc_put_var1_uchar(int ncid, int varid, const size_t *indexp, const unsigned char *op)
800 {
801    return NC_put_var1(ncid, varid, indexp, (void *)op, NC_UBYTE);
802 }
803 
804 int
nc_put_var1_short(int ncid,int varid,const size_t * indexp,const short * op)805 nc_put_var1_short(int ncid, int varid, const size_t *indexp, const short *op)
806 {
807    return NC_put_var1(ncid, varid, indexp, (void *)op, NC_SHORT);
808 }
809 
810 int
nc_put_var1_int(int ncid,int varid,const size_t * indexp,const int * op)811 nc_put_var1_int(int ncid, int varid, const size_t *indexp, const int *op)
812 {
813    return NC_put_var1(ncid, varid, indexp, (void *)op, NC_INT);
814 }
815 
816 int
nc_put_var1_long(int ncid,int varid,const size_t * indexp,const long * op)817 nc_put_var1_long(int ncid, int varid, const size_t *indexp, const long *op)
818 {
819    return NC_put_var1(ncid, varid, indexp, (void*)op, longtype);
820 }
821 
822 int
nc_put_var1_float(int ncid,int varid,const size_t * indexp,const float * op)823 nc_put_var1_float(int ncid, int varid, const size_t *indexp, const float *op)
824 {
825    return NC_put_var1(ncid, varid, indexp, (void*)op, NC_FLOAT);
826 }
827 
828 int
nc_put_var1_double(int ncid,int varid,const size_t * indexp,const double * op)829 nc_put_var1_double(int ncid, int varid, const size_t *indexp, const double *op)
830 {
831    return NC_put_var1(ncid, varid, indexp, (void *)op, NC_DOUBLE);
832 }
833 
834 int
nc_put_var1_ubyte(int ncid,int varid,const size_t * indexp,const unsigned char * op)835 nc_put_var1_ubyte(int ncid, int varid, const size_t *indexp, const unsigned char *op)
836 {
837    return NC_put_var1(ncid, varid, indexp, (void *)op, NC_UBYTE);
838 }
839 
840 int
nc_put_var1_ushort(int ncid,int varid,const size_t * indexp,const unsigned short * op)841 nc_put_var1_ushort(int ncid, int varid, const size_t *indexp, const unsigned short *op)
842 {
843    return NC_put_var1(ncid, varid, indexp, (void *)op, NC_USHORT);
844 }
845 
846 int
nc_put_var1_uint(int ncid,int varid,const size_t * indexp,const unsigned int * op)847 nc_put_var1_uint(int ncid, int varid, const size_t *indexp, const unsigned int *op)
848 {
849    return NC_put_var1(ncid, varid, indexp, (void *)op, NC_UINT);
850 }
851 
852 int
nc_put_var1_longlong(int ncid,int varid,const size_t * indexp,const long long * op)853 nc_put_var1_longlong(int ncid, int varid, const size_t *indexp, const long long *op)
854 {
855    return NC_put_var1(ncid, varid, indexp, (void *)op, NC_INT64);
856 }
857 
858 int
nc_put_var1_ulonglong(int ncid,int varid,const size_t * indexp,const unsigned long long * op)859 nc_put_var1_ulonglong(int ncid, int varid, const size_t *indexp, const unsigned long long *op)
860 {
861    return NC_put_var1(ncid, varid, indexp, (void *)op, NC_UINT64);
862 }
863 
864 int
nc_put_var1_string(int ncid,int varid,const size_t * indexp,const char ** op)865 nc_put_var1_string(int ncid, int varid, const size_t *indexp, const char* *op)
866 {
867    return NC_put_var1(ncid, varid, indexp, (void*)op, NC_STRING);
868 }
869 
870 /**@}*/
871 
872 /** \ingroup variables
873 Write an entire variable with one call.
874 
875 The nc_put_var_ type family of functions write all the values of a
876 variable into a netCDF variable of an open netCDF dataset. This is the
877 simplest interface to use for writing a value in a scalar variable or
878 whenever all the values of a multidimensional variable can all be
879 written at once. The values to be written are associated with the
880 netCDF variable by assuming that the last dimension of the netCDF
881 variable varies fastest in the C interface. The values are converted
882 to the external data type of the variable, if necessary.
883 
884 Take care when using this function with record variables (variables
885 that use the ::NC_UNLIMITED dimension). If you try to write all the
886 values of a record variable into a netCDF file that has no record data
887 yet (hence has 0 records), nothing will be written. Similarly, if you
888 try to write all the values of a record variable but there are more
889 records in the file than you assume, more in-memory data will be
890 accessed than you supply, which may result in a segmentation
891 violation. To avoid such problems, it is better to use the nc_put_vara
892 interfaces for variables that use the ::NC_UNLIMITED dimension.
893 
894 The functions for types ubyte, ushort, uint, longlong, ulonglong, and
895 string are only available for netCDF-4/HDF5 files.
896 
897 The nc_put_var() function will write a variable of any type, including
898 user defined type. For this function, the type of the data in memory
899 must match the type of the variable - no data conversion is done.
900 
901 \param ncid NetCDF or group ID, from a previous call to nc_open(),
902 nc_create(), nc_def_grp(), or associated inquiry functions such as
903 nc_inq_ncid().
904 
905 \param varid Variable ID
906 
907 \param op Pointer from where the data will be copied.
908 
909 \returns ::NC_NOERR No error.
910 \returns ::NC_ENOTVAR Variable not found.
911 \returns ::NC_EINVALCOORDS Index exceeds dimension bound.
912 \returns ::NC_EEDGE Start+count exceeds dimension bound.
913 \returns ::NC_ERANGE One or more of the values are out of range.
914 \returns ::NC_EINDEFINE Operation not allowed in define mode.
915 \returns ::NC_EBADID Bad ncid.
916 \author Glenn Davis, Russ Rew, Ed Hartnett, Dennis Heimbigner, Ward Fisher
917  */
918 /**@{*/
919 int
nc_put_var(int ncid,int varid,const void * op)920 nc_put_var(int ncid, int varid, const void *op)
921 {
922    return NC_put_var(ncid, varid, op, NC_NAT);
923 }
924 
925 int
nc_put_var_text(int ncid,int varid,const char * op)926 nc_put_var_text(int ncid, int varid, const char *op)
927 {
928    return NC_put_var(ncid,varid,(void*)op,NC_CHAR);
929 }
930 
931 int
nc_put_var_schar(int ncid,int varid,const signed char * op)932 nc_put_var_schar(int ncid, int varid, const signed char *op)
933 {
934    return NC_put_var(ncid,varid,(void*)op,NC_BYTE);
935 }
936 
937 int
nc_put_var_uchar(int ncid,int varid,const unsigned char * op)938 nc_put_var_uchar(int ncid, int varid, const unsigned char *op)
939 {
940    return NC_put_var(ncid,varid,(void*)op,T_uchar);
941 }
942 
943 int
nc_put_var_short(int ncid,int varid,const short * op)944 nc_put_var_short(int ncid, int varid, const short *op)
945 {
946    return NC_put_var(ncid,varid,(void*)op,NC_SHORT);
947 }
948 
949 int
nc_put_var_int(int ncid,int varid,const int * op)950 nc_put_var_int(int ncid, int varid, const int *op)
951 {
952    return NC_put_var(ncid,varid,(void*)op,NC_INT);
953 }
954 
955 int
nc_put_var_long(int ncid,int varid,const long * op)956 nc_put_var_long(int ncid, int varid, const long *op)
957 {
958    return NC_put_var(ncid,varid,(void*)op,T_long);
959 }
960 
961 int
nc_put_var_float(int ncid,int varid,const float * op)962 nc_put_var_float(int ncid, int varid, const float *op)
963 {
964    return NC_put_var(ncid,varid,(void*)op,T_float);
965 }
966 
967 int
nc_put_var_double(int ncid,int varid,const double * op)968 nc_put_var_double(int ncid, int varid, const double *op)
969 {
970    return NC_put_var(ncid,varid,(void*)op,T_double);
971 }
972 
973 int
nc_put_var_ubyte(int ncid,int varid,const unsigned char * op)974 nc_put_var_ubyte(int ncid, int varid, const unsigned char *op)
975 {
976    return NC_put_var(ncid,varid,(void*)op,T_ubyte);
977 }
978 
979 int
nc_put_var_ushort(int ncid,int varid,const unsigned short * op)980 nc_put_var_ushort(int ncid, int varid, const unsigned short *op)
981 {
982    return NC_put_var(ncid,varid,(void*)op,T_ushort);
983 }
984 
985 int
nc_put_var_uint(int ncid,int varid,const unsigned int * op)986 nc_put_var_uint(int ncid, int varid, const unsigned int *op)
987 {
988    return NC_put_var(ncid,varid,(void*)op,T_uint);
989 }
990 
991 int
nc_put_var_longlong(int ncid,int varid,const long long * op)992 nc_put_var_longlong(int ncid, int varid, const long long *op)
993 {
994    return NC_put_var(ncid,varid,(void*)op,T_longlong);
995 }
996 
997 int
nc_put_var_ulonglong(int ncid,int varid,const unsigned long long * op)998 nc_put_var_ulonglong(int ncid, int varid, const unsigned long long *op)
999 {
1000    return NC_put_var(ncid,varid,(void*)op,NC_UINT64);
1001 }
1002 
1003 int
nc_put_var_string(int ncid,int varid,const char ** op)1004 nc_put_var_string(int ncid, int varid, const char* *op)
1005 {
1006    return NC_put_var(ncid,varid,(void*)op,NC_STRING);
1007 }
1008 
1009 /**\} */
1010 
1011 /** \ingroup variables
1012 Write a strided array of values to a variable.
1013 
1014 \param ncid NetCDF or group ID, from a previous call to nc_open(),
1015 nc_create(), nc_def_grp(), or associated inquiry functions such as
1016 nc_inq_ncid().
1017 
1018 \param varid Variable ID
1019 
1020 \param startp Start vector with one element for each dimension to \ref
1021 specify_hyperslab.
1022 
1023 \param countp Count vector with one element for each dimension to \ref
1024 specify_hyperslab.
1025 
1026 \param stridep Stride vector with one element for each dimension to
1027 \ref specify_hyperslab.
1028 
1029 \param op Pointer where the data will be copied. Memory must be
1030 allocated by the user before this function is called.
1031 
1032 \returns ::NC_NOERR No error.
1033 \returns ::NC_ENOTVAR Variable not found.
1034 \returns ::NC_EINVALCOORDS Index exceeds dimension bound.
1035 \returns ::NC_EEDGE Start+count exceeds dimension bound.
1036 \returns ::NC_ERANGE One or more of the values are out of range.
1037 \returns ::NC_EINDEFINE Operation not allowed in define mode.
1038 \returns ::NC_EBADID Bad ncid.
1039 \author Glenn Davis, Russ Rew, Ed Hartnett, Dennis Heimbigner, Ward Fisher
1040  */
1041 /**@{*/
1042 int
nc_put_vars(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const void * op)1043 nc_put_vars(int ncid, int varid, const size_t *startp,
1044 	     const size_t *countp, const ptrdiff_t *stridep,
1045 	     const void *op)
1046 {
1047    return NC_put_vars(ncid, varid, startp, countp, stridep, op, NC_NAT);
1048 }
1049 
1050 int
nc_put_vars_text(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const char * op)1051 nc_put_vars_text(int ncid, int varid, const size_t *startp,
1052 		 const size_t *countp, const ptrdiff_t *stridep,
1053 		 const char *op)
1054 {
1055    return NC_put_vars(ncid, varid, startp, countp,
1056 		      stridep,(void*)op,NC_CHAR);
1057 }
1058 
1059 int
nc_put_vars_schar(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const signed char * op)1060 nc_put_vars_schar(int ncid, int varid, const size_t *startp,
1061 		  const size_t *countp, const ptrdiff_t *stridep,
1062 		  const signed char *op)
1063 {
1064    return NC_put_vars(ncid, varid, startp, countp,
1065 		      stridep,(void*)op,NC_BYTE);
1066 }
1067 
1068 int
nc_put_vars_uchar(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const unsigned char * op)1069 nc_put_vars_uchar(int ncid, int varid,
1070 		  const size_t *startp, const size_t *countp,
1071 		  const ptrdiff_t *stridep,
1072 		  const unsigned char *op)
1073 {
1074    return NC_put_vars(ncid, varid, startp, countp,
1075 		      stridep, (void *)op, T_uchar);
1076 }
1077 
1078 int
nc_put_vars_short(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const short * op)1079 nc_put_vars_short(int ncid, int varid,
1080 		  const size_t *startp, const size_t *countp,
1081 		  const ptrdiff_t *stridep,
1082 		  const short *op)
1083 {
1084    return NC_put_vars(ncid, varid, startp, countp,
1085 		      stridep, (void *)op, NC_SHORT);
1086 }
1087 
1088 int
nc_put_vars_int(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const int * op)1089 nc_put_vars_int(int ncid, int varid,
1090 		const size_t *startp, const size_t *countp,
1091 		const ptrdiff_t *stridep,
1092 		const int *op)
1093 {
1094    return NC_put_vars(ncid, varid, startp, countp,
1095 		      stridep, (void *)op, NC_INT);
1096 }
1097 
1098 int
nc_put_vars_long(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const long * op)1099 nc_put_vars_long(int ncid, int varid,
1100 		 const size_t *startp, const size_t *countp,
1101 		 const ptrdiff_t *stridep,
1102 		 const long *op)
1103 {
1104    return NC_put_vars(ncid, varid, startp, countp,
1105 		      stridep, (void *)op, T_long);
1106 }
1107 
1108 int
nc_put_vars_float(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const float * op)1109 nc_put_vars_float(int ncid, int varid,
1110 		  const size_t *startp, const size_t *countp,
1111 		  const ptrdiff_t *stridep,
1112 		  const float *op)
1113 {
1114    return NC_put_vars(ncid, varid, startp, countp,
1115 		      stridep, (void *)op, T_float);
1116 }
1117 
1118 int
nc_put_vars_double(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const double * op)1119 nc_put_vars_double(int ncid, int varid,
1120 		   const size_t *startp, const size_t *countp,
1121 		   const ptrdiff_t *stridep,
1122 		   const double *op)
1123 {
1124    return NC_put_vars(ncid, varid, startp, countp,
1125 		      stridep, (void *)op, T_double);
1126 }
1127 
1128 int
nc_put_vars_ubyte(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const unsigned char * op)1129 nc_put_vars_ubyte(int ncid, int varid,
1130 		  const size_t *startp, const size_t *countp,
1131 		  const ptrdiff_t *stridep,
1132 		  const unsigned char *op)
1133 {
1134    return NC_put_vars(ncid, varid, startp, countp,
1135 		      stridep, (void *)op, T_ubyte);
1136 }
1137 
1138 int
nc_put_vars_ushort(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const unsigned short * op)1139 nc_put_vars_ushort(int ncid, int varid,
1140 		   const size_t *startp, const size_t *countp,
1141 		   const ptrdiff_t *stridep,
1142 		   const unsigned short *op)
1143 {
1144    return NC_put_vars(ncid, varid, startp, countp,
1145 		      stridep, (void *)op, T_ushort);
1146 }
1147 
1148 int
nc_put_vars_uint(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const unsigned int * op)1149 nc_put_vars_uint(int ncid, int varid,
1150 		 const size_t *startp, const size_t *countp,
1151 		 const ptrdiff_t *stridep,
1152 		 const unsigned int *op)
1153 {
1154    return NC_put_vars(ncid, varid, startp, countp,
1155 		      stridep, (void *)op, T_uint);
1156 }
1157 
1158 int
nc_put_vars_longlong(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const long long * op)1159 nc_put_vars_longlong(int ncid, int varid,
1160 		     const size_t *startp, const size_t *countp,
1161 		     const ptrdiff_t *stridep,
1162 		     const long long *op)
1163 {
1164    return NC_put_vars(ncid, varid, startp, countp,
1165 		      stridep, (void *)op, T_longlong);
1166 }
1167 
1168 int
nc_put_vars_ulonglong(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const unsigned long long * op)1169 nc_put_vars_ulonglong(int ncid, int varid,
1170 		      const size_t *startp, const size_t *countp,
1171 		      const ptrdiff_t *stridep,
1172 		      const unsigned long long *op)
1173 {
1174    return NC_put_vars(ncid, varid, startp, countp,
1175 		      stridep, (void *)op, NC_UINT64);
1176 }
1177 
1178 int
nc_put_vars_string(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const char ** op)1179 nc_put_vars_string(int ncid, int varid,
1180 		   const size_t *startp, const size_t *countp,
1181 		   const ptrdiff_t *stridep,
1182 		   const char**op)
1183 {
1184    return NC_put_vars(ncid, varid, startp, countp, stridep,
1185 		      (void *)op, NC_STRING);
1186 }
1187 
1188 /**\} */
1189 
1190 /** \ingroup variables
1191 Write a mapped array of values to a variable.
1192 
1193 The nc_put_varm() function will only write a variable of an
1194 atomic type; it will not write user defined types. For this
1195 function, the type of the data in memory must match the type
1196 of the variable - no data conversion is done.
1197 
1198 @deprecated Use of this family of functions is discouraged,
1199 although it will continue to be supported.
1200 The reason is the complexity of the
1201 algorithm makes its use difficult for users to properly use.
1202 
1203 \param ncid NetCDF or group ID, from a previous call to nc_open(),
1204 nc_create(), nc_def_grp(), or associated inquiry functions such as
1205 nc_inq_ncid().
1206 
1207 \param varid Variable ID
1208 
1209 \param startp Start vector with one element for each dimension to \ref
1210 specify_hyperslab.
1211 
1212 \param countp Count vector with one element for each dimension to \ref
1213 specify_hyperslab.
1214 
1215 \param stridep Stride vector with one element for each dimension to
1216 \ref specify_hyperslab.
1217 
1218 \param imapp Mapping vector with one element for each dimension to
1219 \ref specify_hyperslab.
1220 
1221 \param op Pointer where the data will be copied. Memory must be
1222 allocated by the user before this function is called.
1223 
1224 \returns ::NC_NOERR No error.
1225 \returns ::NC_ENOTVAR Variable not found.
1226 \returns ::NC_EINVALCOORDS Index exceeds dimension bound.
1227 \returns ::NC_EEDGE Start+count exceeds dimension bound.
1228 \returns ::NC_ERANGE One or more of the values are out of range.
1229 \returns ::NC_EINDEFINE Operation not allowed in define mode.
1230 \returns ::NC_EBADID Bad ncid.
1231 \author Glenn Davis, Russ Rew, Ed Hartnett, Dennis Heimbigner, Ward Fisher
1232  */
1233 /**@{*/
1234 int
nc_put_varm(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,const void * op)1235 nc_put_varm(int ncid, int varid, const size_t *startp,
1236 	     const size_t *countp, const ptrdiff_t *stridep,
1237 	     const ptrdiff_t *imapp, const void *op)
1238 {
1239    return NC_put_varm(ncid, varid, startp, countp, stridep, imapp, op, NC_NAT);
1240 }
1241 
1242 int
nc_put_varm_text(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,const char * op)1243 nc_put_varm_text(int ncid, int varid, const size_t *startp,
1244 		 const size_t *countp, const ptrdiff_t *stridep,
1245 		 const ptrdiff_t *imapp, const char *op)
1246 {
1247    return NC_put_varm(ncid, varid, startp, countp, stridep, imapp,
1248 		      (void *)op, NC_CHAR);
1249 }
1250 
1251 int
nc_put_varm_schar(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,const signed char * op)1252 nc_put_varm_schar(int ncid, int varid,
1253 		  const size_t *startp, const size_t *countp,
1254 		  const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1255 		  const signed char *op)
1256 {
1257    return NC_put_varm(ncid, varid, startp, countp, stridep, imapp,
1258 		      (void *)op, NC_BYTE);
1259 }
1260 
1261 int
nc_put_varm_uchar(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,const unsigned char * op)1262 nc_put_varm_uchar(int ncid, int varid,
1263 		  const size_t *startp, const size_t *countp,
1264 		  const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1265 		  const unsigned char *op)
1266 {
1267    return NC_put_varm(ncid, varid, startp, countp, stridep, imapp,
1268 		      (void *)op, T_uchar);
1269 }
1270 
1271 int
nc_put_varm_short(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,const short * op)1272 nc_put_varm_short(int ncid, int varid,
1273 		  const size_t *startp, const size_t *countp,
1274 		  const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1275 		  const short *op)
1276 {
1277    return NC_put_varm(ncid, varid, startp, countp, stridep, imapp,
1278 		      (void *)op, NC_SHORT);
1279 }
1280 
1281 int
nc_put_varm_int(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,const int * op)1282 nc_put_varm_int(int ncid, int varid,
1283 		const size_t *startp, const size_t *countp,
1284 		const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1285 		const int *op)
1286 {
1287    return NC_put_varm(ncid, varid, startp, countp, stridep, imapp,
1288 		      (void *)op, NC_INT);
1289 }
1290 
1291 int
nc_put_varm_long(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,const long * op)1292 nc_put_varm_long(int ncid, int varid,
1293 		 const size_t *startp, const size_t *countp,
1294 		 const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1295 		 const long *op)
1296 {
1297    return NC_put_varm(ncid, varid, startp, countp, stridep, imapp,
1298 		      (void *)op, T_long);
1299 }
1300 
1301 int
nc_put_varm_float(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,const float * op)1302 nc_put_varm_float(int ncid, int varid,
1303 		  const size_t *startp, const size_t *countp,
1304 		  const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1305 		  const float *op)
1306 {
1307    return NC_put_varm(ncid, varid, startp, countp, stridep, imapp,
1308 		      (void *)op, T_float);
1309 }
1310 
1311 int
nc_put_varm_double(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,const double * op)1312 nc_put_varm_double(int ncid, int varid,
1313 		   const size_t *startp, const size_t *countp,
1314 		   const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1315 		   const double *op)
1316 {
1317    return NC_put_varm(ncid, varid, startp, countp, stridep, imapp,
1318 		      (void *)op, T_double);
1319 }
1320 
1321 int
nc_put_varm_ubyte(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,const unsigned char * op)1322 nc_put_varm_ubyte(int ncid, int varid,
1323 		  const size_t *startp, const size_t *countp,
1324 		  const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1325 		  const unsigned char *op)
1326 {
1327    return NC_put_varm(ncid, varid, startp, countp, stridep, imapp,
1328 		      (void *)op, T_ubyte);
1329 }
1330 
1331 int
nc_put_varm_ushort(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,const unsigned short * op)1332 nc_put_varm_ushort(int ncid, int varid,
1333 		   const size_t *startp, const size_t *countp,
1334 		   const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1335 		   const unsigned short *op)
1336 {
1337    return NC_put_varm(ncid, varid, startp, countp, stridep, imapp,
1338 		      (void *)op, T_ushort);
1339 }
1340 
1341 int
nc_put_varm_uint(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,const unsigned int * op)1342 nc_put_varm_uint(int ncid, int varid,
1343 		 const size_t *startp, const size_t *countp,
1344 		 const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1345 		 const unsigned int *op)
1346 {
1347    return NC_put_varm(ncid, varid, startp, countp, stridep, imapp,
1348 		      (void *)op, T_uint);
1349 }
1350 
1351 int
nc_put_varm_longlong(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,const long long * op)1352 nc_put_varm_longlong(int ncid, int varid,
1353 		     const size_t *startp, const size_t *countp,
1354 		     const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1355 		     const long long *op)
1356 {
1357    return NC_put_varm(ncid, varid, startp, countp, stridep, imapp,
1358 		      (void *)op, T_longlong);
1359 }
1360 
1361 int
nc_put_varm_ulonglong(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,const unsigned long long * op)1362 nc_put_varm_ulonglong(int ncid, int varid,
1363 		      const size_t *startp, const size_t *countp,
1364 		      const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1365 		      const unsigned long long *op)
1366 {
1367    return NC_put_varm(ncid, varid, startp, countp, stridep, imapp,
1368 		      (void *)op, NC_UINT64);
1369 }
1370 
1371 int
nc_put_varm_string(int ncid,int varid,const size_t * startp,const size_t * countp,const ptrdiff_t * stridep,const ptrdiff_t * imapp,const char ** op)1372 nc_put_varm_string(int ncid, int varid,
1373 		   const size_t *startp, const size_t *countp,
1374 		   const ptrdiff_t *stridep, const ptrdiff_t *imapp,
1375 		   const char**op)
1376 {
1377    return NC_put_varm(ncid, varid, startp, countp, stridep, imapp,
1378 		      (void *)op, NC_STRING);
1379 }
1380 
1381 /**\} */
1382 
1383 /*! \} */ /*End of named group... */
1384