Coverage Report

Created: 2025-10-28 07:06

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