1 /******************************************************************************
2 *
3 *  NSSDC/CDF			CDF C interface for non-macro'ed functions
4 *				of the Standard Interface.
5 *
6 *  Version 2.4a, 8-Mar-97, Hughes STX.
7 *
8 *  Modification history:
9 *
10 *   V1.0   1-Jun-91, J Love	Original version (for CDF V2.1).  This is a
11 *				combination of cdf.c, cdfattr.c and cdfvar.c.
12 *				Most of these functions can be replaced by
13 *				the macros in 'cdf.h'.
14 *   V1.1  30-Jul-91, J Love	Use 'CDFlib'.
15 *   V2.0  10-Feb-92, J Love	IBM PC port.
16 *   V2.1  21-Aug-92, J Love	CDF V2.3 (shareable/NeXT/zVar).
17 *   V2.2  18-Oct-93, J Love	CDF V2.4.
18 *   V2.3   9-Nov-94, J Love	CDF V2.5.
19 *   V2.4  14-Feb-96, J Love	CDF V2.6 (renamed - previously `cdf_c_if.c').
20 *   V2.4a  8-Mar-97, J Love	Windows NT for Visual C++ 4 on an IBM PC.
21 *   V3.0  28-Aug-01, M Liu      Add CDFgetrVarsRecordData, CDFgetzVarsRecordData,
22 *                               CDFputrVarsRecordData, CDFputzVarsRecordData.
23 *   V3.1  31-May-05, M Liu      Replaced CDFgetrVarsRecordData and
24 *                               CDFgetzVarsRecordData with a general function.
25 *                               So, are the CDFputrVarsRecordData and
26 *                               CDFputzVarsRecordData.
27 *   V3.2  13-Apr-07, D. Han     Modified CDFattrInquire not to select CDF id
28 *                               twice (performance improvement).
29 *   V3.3  22-Oct-08, M. Liu     Modified CDFgetVarsRecordDatabyNames and
30 *                               CDFputVarsRecordDatabyNames allocate buffers
31 *                               based on the number of variables involved.
32 *
33 ******************************************************************************/
34 
35 #include "cdflib.h"
36 #include "cdflib64.h"
37 
38 static int backward = 0;
39 static int setFileBackwardFlag = 0;
40 
41 static long checksum = 0;
42 static int setChecksumFlag = 0;
43 
44 /******************************************************************************
45 * CDFcreateCDF.
46 ******************************************************************************/
47 
CDFcreateCDF(cdfName,id)48 VISIBLE_PREFIX CDFstatus CDFcreateCDF (cdfName, id)
49 char    *cdfName;	/* In -- CDF name. */
50 CDFid   *id;            /* Out -- CDF id. */
51 {
52   CDFstatus pStatus = CDF_OK;
53   long dimSizes[1] = {0};
54   if (!sX(CDFlib(CREATE_, CDF_, cdfName, 0L, dimSizes, id,
55                  NULL_), &pStatus)) return pStatus;
56   return pStatus;
57 }
58 
59 /******************************************************************************
60 * CDFattrInquire.
61 * Can't implement with macro because the attribute's scope determines which
62 * item(s) to use.
63 ******************************************************************************/
64 
CDFattrInquire(id,attrNum,attrName,attrScope,maxEntry)65 VISIBLE_PREFIX CDFstatus CDFattrInquire (id, attrNum, attrName, attrScope,
66                                          maxEntry)
67 CDFid   id;             /* In -- CDF id. */
68 long    attrNum;        /* In -- Attribute number. */
69 char    *attrName;      /* Out -- Attribute name. */
70 long    *attrScope;     /* Out -- Attribute scope. */
71 long    *maxEntry;      /* Out -- Maximum gEntry/rEntry number used. */
72 {
73   CDFstatus pStatus = CDF_OK;
74   if (!sX(CDFlib(SELECT_, CDF_, id,
75                           ATTR_, attrNum,
76                  GET_, ATTR_SCOPE_, attrScope,
77                  NULL_), &pStatus)) return pStatus;
78   if (!sX(CDFlib(GET_, ATTR_NAME_, attrName,
79                        BOO(GLOBALscope(*attrScope),ATTR_MAXgENTRY_,
80                                                    ATTR_MAXrENTRY_), maxEntry,
81                  NULL_), &pStatus)) return pStatus;
82   return pStatus;
83 }
84 
85 /******************************************************************************
86 * CDFinquireAttr.
87 * Can't implement with macro because the attribute's scope determines which
88 * item(s) to use.
89 ******************************************************************************/
90 
CDFinquireAttr(id,attrNum,attrName,scope,maxgEntry,maxrEntry,maxzEntry)91 VISIBLE_PREFIX CDFstatus CDFinquireAttr (id, attrNum, attrName, scope,
92 					 maxgEntry, maxrEntry, maxzEntry)
93 CDFid   id;             /* In -- CDF id. */
94 long    attrNum;        /* In -- Attribute number. */
95 char    *attrName;      /* Out -- Attribute name. */
96 long    *scope;         /* Out -- Attribute scope. */
97 long    *maxgEntry;     /* Out -- Maximum gEntry number used for gAttribute. */
98 long    *maxrEntry;     /* Out -- Maximum rEntry number used for vAttribute. */
99 long    *maxzEntry;     /* Out -- Maximum zEntry number used for vAttribute. */
100 {
101 
102   CDFstatus pStatus = CDF_OK;
103 
104   *maxgEntry = -1L;
105   *maxrEntry = -1L;
106   *maxzEntry = -1L;
107 
108   if (!sX(CDFlib(SELECT_, CDF_, id,
109                           ATTR_, attrNum,
110                  GET_, ATTR_SCOPE_, scope,
111                  NULL_), &pStatus)) return pStatus;
112   if (!sX(CDFlib(GET_, ATTR_NAME_, attrName,
113                        (BOO(GLOBALscope(*scope),ATTR_MAXgENTRY_,
114                                 		ATTR_MAXrENTRY_)),
115                        (BOO(GLOBALscope(*scope),maxgEntry,maxrEntry)),
116                  NULL_), &pStatus)) return pStatus;
117   if (!GLOBALscope(*scope)) {
118     if (!sX(CDFlib(GET_, ATTR_MAXzENTRY_, maxzEntry,
119 		   NULL_), &pStatus)) return pStatus;
120   }
121 
122   return pStatus;
123 }
124 
125 /******************************************************************************
126 * CDFinquireAttrEntry.
127 * Can't implement with macro because the attribute's scope determines which
128 * item(s) to use.
129 ******************************************************************************/
130 
CDFinquireAttrEntry(id,grzEntry,attrNum,entryNum,dataType,numElems)131 VISIBLE_PREFIX CDFstatus CDFinquireAttrEntry (id, grzEntry, attrNum,
132                                               entryNum, dataType, numElems)
133 CDFid   id;             /* In -- CDF id. */
134 int     grzEntry;       /* In -- Flag for g/r/zEntry. */
135 long    attrNum;        /* In -- Attribute number. */
136 long    entryNum;       /* In -- gEntry/rEntry/zEntry number. */
137 long    *dataType;      /* Out -- gEntry/rEntry/zEntry data type. */
138 long    *numElems;      /* Out -- gEntry/rEntry/zEntry number of elements. */
139 {
140   long scope;
141   CDFstatus pStatus = CDF_OK;
142   if (!sX(CDFlib(SELECT_, CDF_, id,
143                           ATTR_, attrNum,
144                  GET_, ATTR_SCOPE_, &scope,
145                  NULL_), &pStatus)) return pStatus;
146   if (GLOBALscope(scope) && (grzEntry != 0) && (grzEntry != 1))
147     return ILLEGAL_FOR_SCOPE;
148   if (!GLOBALscope(scope) && (grzEntry == 1)) return ILLEGAL_FOR_SCOPE;
149 
150   if (!sX(CDFlib(SELECT_, BOO((grzEntry == 3),zENTRY_,
151                               (BOO(GLOBALscope(scope),gENTRY_,
152                                    rENTRY_))), entryNum,
153                  GET_, BOO((grzEntry == 3),zENTRY_DATATYPE_,
154                            (BOO(GLOBALscope(scope),gENTRY_DATATYPE_,
155                                 rENTRY_DATATYPE_))), dataType,
156                        BOO((grzEntry == 3),zENTRY_NUMELEMS_,
157                            (BOO(GLOBALscope(scope),gENTRY_NUMELEMS_,
158                                 rENTRY_NUMELEMS_))), numElems,
159                  NULL_), &pStatus)) return pStatus;
160   return pStatus;
161 }
162 
163 /******************************************************************************
164 * CDFputAttrEntry.
165 * Can't implement with macro because the attribute's scope determines which
166 * item(s) to use.
167 ******************************************************************************/
168 
CDFputAttrEntry(id,grzEntry,attrNum,entryNum,dataType,numElems,value)169 VISIBLE_PREFIX CDFstatus CDFputAttrEntry (id, grzEntry, attrNum, entryNum,
170                                           dataType, numElems, value)
171 CDFid	id;		/* In -- CDF id. */
172 int     grzEntry;       /* In -- Flag for g/r/zEntry. */
173 long	attrNum;	/* In -- Attribute number. */
174 long	entryNum;	/* In -- gEntry/rEntry/zEntry number. */
175 long	dataType;	/* In -- gEntry/rEntry/zEntry data type. */
176 long	numElems;	/* In -- gEntry/rEntry/zEntry number of elements. */
177 void	*value;		/* In -- Value. */
178 {
179   long scope;
180   CDFstatus pStatus = CDF_OK;
181   if (!sX(CDFlib(SELECT_, CDF_, id,
182 			  ATTR_, attrNum,
183 		 GET_, ATTR_SCOPE_, &scope,
184 		 NULL_), &pStatus)) return pStatus;
185   if (GLOBALscope(scope) && (grzEntry != 0) && (grzEntry != 1))
186     return ILLEGAL_FOR_SCOPE;
187   if (!GLOBALscope(scope) && (grzEntry != 2) && (grzEntry != 3))
188     return ILLEGAL_FOR_SCOPE;
189 
190   if (!sX(CDFlib(SELECT_, BOO((grzEntry == 3),zENTRY_,
191                               (BOO(GLOBALscope(scope),gENTRY_,
192                                rENTRY_))), entryNum,
193 		 PUT_, BOO((grzEntry == 3),zENTRY_DATA_,
194                            (BOO(GLOBALscope(scope),gENTRY_DATA_,
195                                 rENTRY_DATA_))), dataType, numElems, value,
196 		 NULL_), &pStatus)) return pStatus;
197   return pStatus;
198 }
199 
200 /******************************************************************************
201 * CDFgetAttrEntry.
202 * Can't implement with macro because the attribute's scope determines which
203 * item(s) to use.
204 ******************************************************************************/
205 
CDFgetAttrEntry(id,grzEntry,attrNum,entryNum,value)206 VISIBLE_PREFIX CDFstatus CDFgetAttrEntry (id, grzEntry, attrNum, entryNum,
207                                           value)
208 CDFid   id;             /* In -- CDF id. */
209 int     grzEntry;       /* In -- Flag for g/r/zEntry. */
210 long    attrNum;        /* In -- Attribute number. */
211 long    entryNum;       /* In -- gEntry/rEntry/zEntry number. */
212 void    *value;         /* Out -- Value. */
213 {
214   long scope;
215   CDFstatus pStatus = CDF_OK;
216   if (!sX(CDFlib(SELECT_, CDF_, id,
217                           ATTR_, attrNum,
218                  GET_, ATTR_SCOPE_, &scope,
219                  NULL_), &pStatus)) return pStatus;
220   if (GLOBALscope(scope) && (grzEntry != 0) && (grzEntry != 1))
221     return ILLEGAL_FOR_SCOPE;
222   if (!GLOBALscope(scope) && (grzEntry != 2) && (grzEntry != 3))
223     return ILLEGAL_FOR_SCOPE;
224 
225   if (!sX(CDFlib(SELECT_, BOO((grzEntry == 3),zENTRY_,
226                               (BOO(GLOBALscope(scope),gENTRY_,
227                                rENTRY_))), entryNum,
228                  GET_, BOO((grzEntry == 3),zENTRY_DATA_,
229                            (BOO(GLOBALscope(scope),gENTRY_DATA_,
230                                 rENTRY_DATA_))), value,
231                  NULL_), &pStatus)) return pStatus;
232   return pStatus;
233 }
234 
235 /******************************************************************************
236 * CDFdeleteAttrEntry.
237 * Can't implement with macro because the attribute's scope determines which
238 * item(s) to use.
239 ******************************************************************************/
240 
CDFdeleteAttrEntry(id,grzEntry,attrNum,entryNum)241 VISIBLE_PREFIX CDFstatus CDFdeleteAttrEntry (id, grzEntry, attrNum, entryNum)
242 CDFid   id;             /* In -- CDF id. */
243 int     grzEntry;       /* In -- Flag for g/r/zEntry. */
244 long    attrNum;        /* In -- Attribute number. */
245 long    entryNum;       /* In -- gEntry/rEntry/zEntry number. */
246 {
247   long scope;
248   CDFstatus pStatus = CDF_OK;
249   if (!sX(CDFlib(SELECT_, CDF_, id,
250                           ATTR_, attrNum,
251                  GET_, ATTR_SCOPE_, &scope,
252                  NULL_), &pStatus)) return pStatus;
253   if (GLOBALscope(scope) && (grzEntry != 1)) return ILLEGAL_FOR_SCOPE;
254   if (!GLOBALscope(scope) && (grzEntry != 2) && (grzEntry != 3))
255     return ILLEGAL_FOR_SCOPE;
256 
257   if (!sX(CDFlib(SELECT_, BOO((grzEntry == 3),zENTRY_,
258                               (BOO(GLOBALscope(scope),gENTRY_,
259                                rENTRY_))), entryNum,
260                  DELETE_, BOO((grzEntry == 3),zENTRY_,
261                               (BOO(GLOBALscope(scope),gENTRY_, rENTRY_))),
262                  NULL_), &pStatus)) return pStatus;
263   return pStatus;
264 }
265 
266 /******************************************************************************
267 * CDFsetAttrEntryDataSpec.
268 * Can't implement with macro because the attribute's scope determines which
269 * item(s) to use.
270 ******************************************************************************/
271 
CDFsetAttrEntryDataSpec(id,grzEntry,attrNum,entryNum,dataType,numElems)272 VISIBLE_PREFIX CDFstatus CDFsetAttrEntryDataSpec (id, grzEntry, attrNum,
273                                                   entryNum, dataType, numElems)
274 CDFid   id;             /* In -- CDF id. */
275 int     grzEntry;       /* In -- Flag for g/r/zEntry. */
276 long    attrNum;        /* In -- Attribute number. */
277 long    entryNum;       /* In -- gEntry/rEntry/zEntry number. */
278 long    dataType;       /* In -- Data type. */
279 long    numElems;       /* In -- Number of elements. */
280 {
281   long scope;
282   CDFstatus pStatus = CDF_OK;
283   if (!sX(CDFlib(SELECT_, CDF_, id,
284                           ATTR_, attrNum,
285                  GET_, ATTR_SCOPE_, &scope,
286                  NULL_), &pStatus)) return pStatus;
287   if (GLOBALscope(scope) && (grzEntry != 1)) return ILLEGAL_FOR_SCOPE;
288   if (!GLOBALscope(scope) && (grzEntry != 2) && (grzEntry != 3))
289     return ILLEGAL_FOR_SCOPE;
290 
291   if (!sX(CDFlib(SELECT_, BOO((grzEntry == 3),zENTRY_,
292                               (BOO(GLOBALscope(scope),gENTRY_,
293                                rENTRY_))), entryNum,
294                  PUT_, BOO((grzEntry == 3),zENTRY_DATASPEC_,
295                            (BOO(GLOBALscope(scope),gENTRY_DATASPEC_,
296                                                    rENTRY_DATASPEC_))),
297                        dataType, numElems,
298                  NULL_), &pStatus)) return pStatus;
299   return pStatus;
300 }
301 
302 /******************************************************************************
303 * CDFgetAttrNum.
304 * Can't implement with macro since it is the attribute number which is to be
305 * returned (unless an error).
306 ******************************************************************************/
307 
CDFgetAttrNum(id,attrName)308 VISIBLE_PREFIX long CDFgetAttrNum (id,attrName)
309 CDFid	id;		/* In -- CDF id. */
310 char	*attrName;	/* In -- attribute name. */
311 {
312   CDFstatus status;
313   long attrNum;
314   status = CDFlib (SELECT_, CDF_, id,
315 		   GET_, ATTR_NUMBER_, attrName, &attrNum,
316 		   NULL_);
317   if (StatusOK(status))
318     return attrNum;
319   else
320     return status;
321 }
322 
323 /******************************************************************************
324 * CDFgetVarNum.
325 * Can't implement with macro since it is the variable number which is to be
326 * returned (unless an error).
327 ******************************************************************************/
328 
CDFgetVarNum(id,varName)329 VISIBLE_PREFIX long CDFgetVarNum (id,varName)
330 CDFid	id;		/* In -- CDF id. */
331 char	*varName;	/* In -- variable name. */
332 {
333   CDFstatus status;
334   long varNum;
335   status = CDFlib (SELECT_, CDF_, id,
336 		   GET_, rVAR_NUMBER_, varName, &varNum,
337 		   NULL_);
338   if (StatusOK(status))
339     return varNum;
340   else {
341     status = CDFlib (SELECT_, CDF_, id,
342 	             GET_, zVAR_NUMBER_, varName, &varNum,
343 		     NULL_);
344     if (StatusOK(status))
345       return varNum;
346   }
347     return status;
348 }
349 
350 /******************************************************************************
351 * CDFgetNumAttrEntries.
352 * Can't implement with macro because the attribute's scope determines which
353 * item(s) to use.
354 ******************************************************************************/
355 
CDFgetNumAttrEntries(id,grzEntry,attrNum,numEntries)356 VISIBLE_PREFIX CDFstatus CDFgetNumAttrEntries (id, grzEntry, attrNum,
357                                                numEntries)
358 CDFid   id;             /* In -- CDF id. */
359 int     grzEntry;       /* In -- Flag for g/r/zEntry. */
360 long    attrNum;        /* In -- Attribute number. */
361 long    *numEntries;    /* Out -- number of gEntries/rEntries/zEntries. */
362 {
363   long scope;
364   CDFstatus pStatus = CDF_OK;
365   if (!sX(CDFlib(SELECT_, CDF_, id,
366                           ATTR_, attrNum,
367                  GET_, ATTR_SCOPE_, &scope,
368                  NULL_), &pStatus)) return pStatus;
369   if (GLOBALscope(scope) && (grzEntry != 1)) return ILLEGAL_FOR_SCOPE;
370   if (!GLOBALscope(scope) && (grzEntry != 2) && (grzEntry != 3))
371     return ILLEGAL_FOR_SCOPE;
372 
373   if (!sX(CDFlib(GET_, BOO((grzEntry == 3), ATTR_NUMzENTRIES_,
374                            (BOO(GLOBALscope(scope), ATTR_NUMgENTRIES_,
375                                 ATTR_NUMrENTRIES_))), numEntries,
376                  NULL_), &pStatus)) return pStatus;
377   return pStatus;
378 }
379 
380 /******************************************************************************
381 * CDFgetAttrMaxEntry.
382 * Can't implement with macro because the attribute's scope determines which
383 * item(s) to use.
384 ******************************************************************************/
385 
CDFgetAttrMaxEntry(id,grzEntry,attrNum,maxEntry)386 VISIBLE_PREFIX CDFstatus CDFgetAttrMaxEntry (id, grzEntry, attrNum, maxEntry)
387 CDFid   id;             /* In -- CDF id. */
388 int     grzEntry;       /* In -- Flag for g/r/zEntry. */
389 long    attrNum;        /* In -- Attribute number. */
390 long    *maxEntry;      /* Out -- Max. number of gEntry/rEntry/zEntry. */
391 {
392   long scope;
393   CDFstatus pStatus = CDF_OK;
394   if (!sX(CDFlib(SELECT_, CDF_, id,
395                           ATTR_, attrNum,
396                  GET_, ATTR_SCOPE_, &scope,
397                  NULL_), &pStatus)) return pStatus;
398   if (GLOBALscope(scope) && (grzEntry != 1)) return ILLEGAL_FOR_SCOPE;
399   if (!GLOBALscope(scope) && (grzEntry != 2) && (grzEntry != 3))
400     return ILLEGAL_FOR_SCOPE;
401 
402   if (!sX(CDFlib(GET_, BOO((grzEntry == 3), ATTR_MAXzENTRY_,
403                            (BOO(GLOBALscope(scope), ATTR_MAXgENTRY_,
404                             ATTR_MAXrENTRY_))), maxEntry,
405                  NULL_), &pStatus)) return pStatus;
406   return pStatus;
407 }
408 
409 /******************************************************************************
410 * CDFgetAttrEntryDataType.
411 * Can't implement with macro because the attribute's scope determines which
412 * item(s) to use.
413 ******************************************************************************/
414 
CDFgetAttrEntryDataType(id,grzEntry,attrNum,entryNum,dataType)415 VISIBLE_PREFIX CDFstatus CDFgetAttrEntryDataType (id, grzEntry, attrNum,
416                                                   entryNum, dataType)
417 CDFid   id;             /* In -- CDF id. */
418 int     grzEntry;       /* In -- Flag for g/r/zEntry. */
419 long    attrNum;        /* In -- Attribute number. */
420 long    entryNum;       /* In -- gEntry/rEntry/zEntry number. */
421 long    *dataType;      /* Out -- gEntry/rEntry/zEntry dataType. */
422 {
423   long scope;
424   CDFstatus pStatus = CDF_OK;
425   if (!sX(CDFlib(SELECT_, CDF_, id,
426                           ATTR_, attrNum,
427                  GET_, ATTR_SCOPE_, &scope,
428                  NULL_), &pStatus)) return pStatus;
429   if (GLOBALscope(scope) && (grzEntry != 1)) return ILLEGAL_FOR_SCOPE;
430   if (!GLOBALscope(scope) && (grzEntry != 2) && (grzEntry != 3))
431     return ILLEGAL_FOR_SCOPE;
432 
433   if (!sX(CDFlib(SELECT_, BOO((grzEntry == 3), zENTRY_,
434                               BOO(GLOBALscope(scope), gENTRY_,
435                                   rENTRY_)), entryNum,
436                  GET_, BOO((grzEntry == 3), zENTRY_DATATYPE_,
437                            BOO(GLOBALscope(scope), gENTRY_DATATYPE_,
438                                rENTRY_DATATYPE_)), dataType,
439                  NULL_), &pStatus)) return pStatus;
440   return pStatus;
441 }
442 
443 /******************************************************************************
444 * CDFgetAttrEntryNumElements.
445 * Can't implement with macro because the attribute's scope determines which
446 * item(s) to use.
447 ******************************************************************************/
448 
CDFgetAttrEntryNumElements(id,grzEntry,attrNum,entryNum,numElements)449 VISIBLE_PREFIX CDFstatus CDFgetAttrEntryNumElements (id, grzEntry, attrNum,
450                                                      entryNum, numElements)
451 CDFid   id;             /* In -- CDF id. */
452 int     grzEntry;       /* Flag for g/r/zEntry. */
453 long    attrNum;        /* In -- Attribute number. */
454 long    entryNum;       /* In -- gEntry/rEntry/zEntry number. */
455 long    *numElements;   /* Out -- gEntry/rEntry/zEntry numElements. */
456 {
457   long scope;
458   CDFstatus pStatus = CDF_OK;
459   if (!sX(CDFlib(SELECT_, CDF_, id,
460                           ATTR_, attrNum,
461                  GET_, ATTR_SCOPE_, &scope,
462                  NULL_), &pStatus)) return pStatus;
463   if (GLOBALscope(scope) && (grzEntry != 1)) return ILLEGAL_FOR_SCOPE;
464   if (!GLOBALscope(scope) && (grzEntry != 2) && (grzEntry != 3))
465     return ILLEGAL_FOR_SCOPE;
466 
467   if (!sX(CDFlib(SELECT_, BOO((grzEntry == 3), zENTRY_,
468                               BOO(GLOBALscope(scope), gENTRY_,
469                                   rENTRY_)), entryNum,
470                  GET_, BOO((grzEntry == 3), zENTRY_NUMELEMS_,
471                            BOO(GLOBALscope(scope), gENTRY_NUMELEMS_,
472                                rENTRY_NUMELEMS_)), numElements,
473                  NULL_), &pStatus)) return pStatus;
474   return pStatus;
475 }
476 
477 /******************************************************************************
478 * CDFgetVarRecordData.
479 * Acquire a full record data from a given record of a variable.
480 * Retrieved data are filled into the buffer.
481 ******************************************************************************/
482 
CDFgetVarRecordData(id,zVar,varNum,recNum,buffer)483 VISIBLE_PREFIX CDFstatus CDFgetVarRecordData (id, zVar, varNum, recNum, buffer)
484 CDFid   id;             /* In -- CDF id. */
485 int     zVar;           /* In -- Flag for zVariable. */
486 long    varNum;         /* In -- Variable number. */
487 long    recNum;         /* In -- Record number to read. */
488 void    *buffer;        /* Out -- Buffer for holding data. */
489 
490 {
491   CDFstatus pStatus = CDF_OK;
492   long numVars, varNums[CDF_MAX_DIMS];
493 
494   numVars = 1;
495   varNums[0] = varNum;
496 
497   if (!sX(CDFlib(SELECT_, CDF_, id,
498                           BOO((zVar == 1),zVARs_RECNUMBER_,rVARs_RECNUMBER_),
499                           recNum,
500                  GET_, BOO((zVar == 1),zVARs_RECDATA_,rVARs_RECDATA_), numVars,
501                        varNums, buffer,
502                  NULL_), &pStatus)) return pStatus;
503   return pStatus;
504 }
505 
506 /******************************************************************************
507 * CDFputVarRecordData.
508 * Write a full record data for a given record of a variable.
509 ******************************************************************************/
510 
CDFputVarRecordData(id,zVar,varNum,recNum,buffer)511 VISIBLE_PREFIX CDFstatus CDFputVarRecordData (id, zVar, varNum, recNum, buffer)
512 CDFid   id;             /* In -- CDF id. */
513 int     zVar;           /* In -- Flag for zVariable. */
514 long    varNum;         /* In -- Variable number. */
515 long    recNum;         /* In -- Record number to read. */
516 void    *buffer;        /* In -- Buffer for holding data. */
517 
518 {
519   CDFstatus pStatus = CDF_OK;
520   long numVars, varNums[CDF_MAX_DIMS];
521 
522   numVars = 1;
523   varNums[0] = varNum;
524 
525   if (!sX(CDFlib(SELECT_, CDF_, id,
526                           BOO((zVar == 1),zVARs_RECNUMBER_,rVARs_RECNUMBER_),
527                           recNum,
528                  PUT_, BOO((zVar == 1),zVARs_RECDATA_,rVARs_RECDATA_), numVars,
529                        varNums, buffer,
530                  NULL_), &pStatus)) return pStatus;
531   return pStatus;
532 }
533 
534 /******************************************************************************
535 * CDFgetVarsRecordDatabyNames.
536 * Acquire a full record data for a given record for a set of the selected
537 * r/zVariables. Retrieved data are filled into the buffers that are pointed to
538 * by the passed array of pointers. The selected variables are identified by
539 * their names.
540 ******************************************************************************/
541 
CDFgetVarsRecordDatabyNames(id,zVar,numVars,varNames,recNum,buffptr)542 VISIBLE_PREFIX CDFstatus CDFgetVarsRecordDatabyNames (id, zVar, numVars,
543                                                       varNames, recNum,
544                                                       buffptr)
545 CDFid   id;             /* In -- CDF id. */
546 int     zVar;           /* In -- Flag for zVariable. */
547 long    numVars;        /* In -- Number of variables. */
548 char    *varNames[];    /* In -- Array of variable names. */
549 long    recNum;         /* In -- Record number to read. */
550 void    *buffptr[];     /* Out -- Array of buffer pointers for holding data. */
551 
552 {
553   CDFstatus pStatus = CDF_OK;
554   long dataType, numElems, numDims;
555   long dimSizes[CDF_MAX_DIMS], dimVarys[CDF_MAX_DIMS];
556   long dataTypeSize, recNumValues, *phyRecSize;
557   long totalSize, offset, *varNums;
558   int i, j;
559   void *buffer;
560 
561   if (numVars <= 0) return pStatus;
562 
563   if (!sX(CDFlib(SELECT_, CDF_, id,
564                  NULL_), &pStatus)) return pStatus;
565 
566   totalSize = 0;
567   phyRecSize = cdf_AllocateMemory (numVars*sizeof(long)*2, NULL);
568   if (phyRecSize == NULL) return BAD_MALLOC;
569   varNums = phyRecSize+numVars;
570 
571   for (i = 0; i < numVars; i++) {
572     if (!sX(CDFlib(GET_, BOO((zVar == 1),zVAR_NUMBER_,rVAR_NUMBER_),
573                          varNames[i], &varNums[i],
574                    NULL_), &pStatus)) return pStatus;
575     if (!sX(CDFlib(SELECT_, BOO((zVar == 1),zVAR_,rVAR_), varNums[i],
576                    GET_, BOO((zVar == 1),zVAR_DATATYPE_,rVAR_DATATYPE_),
577                          &dataType,
578                          BOO((zVar == 1),zVAR_NUMELEMS_,rVAR_NUMELEMS_),
579                          &numElems,
580                          BOO((zVar == 1),zVAR_NUMDIMS_,rVARs_NUMDIMS_),
581                          &numDims,
582                          BOO((zVar == 1),zVAR_DIMSIZES_,rVARs_DIMSIZES_),
583                          dimSizes,
584                          BOO((zVar == 1),zVAR_DIMVARYS_,rVAR_DIMVARYS_),
585                          dimVarys,
586                    NULL_), &pStatus)) return pStatus;
587     if (!sX(CDFlib(GET_, DATATYPE_SIZE_, dataType, &dataTypeSize,
588                    NULL_), &pStatus)) return pStatus;
589 
590     if (numDims == 0) {
591       numDims = 1;
592       dimSizes[0] = 1;
593       dimVarys[0] = 0;
594     }
595 
596     recNumValues = 1;
597     for (j = 0; j < numDims; j++)
598       if (dimVarys[j]) recNumValues *= dimSizes[j];
599     phyRecSize[i] = recNumValues * dataTypeSize * numElems;
600     totalSize += phyRecSize[i];
601   }
602 
603   buffer = cdf_AllocateMemory (totalSize, NULL);
604   if (buffer == NULL) return BAD_MALLOC;
605 
606   if (!sX(CDFlib(SELECT_, BOO((zVar == 1),zVARs_RECNUMBER_,rVARs_RECNUMBER_),
607                          recNum,
608                  GET_, BOO((zVar == 1),zVARs_RECDATA_,rVARs_RECDATA_), numVars,
609                        varNums, buffer,
610                  NULL_), &pStatus)) return pStatus;
611 
612   offset = 0;
613   for (i = 0; i < numVars; i++) {
614     memcpy((char *) buffptr[i], (char *) buffer+offset, phyRecSize[i]);
615     offset += phyRecSize[i];
616   }
617   cdf_FreeMemory (buffer, NULL);
618   cdf_FreeMemory (phyRecSize, NULL);
619   return CDF_OK;
620 
621 }
622 
623 /******************************************************************************
624 * CDFputVarsRecordDatabyNames.
625 * Write a full record data for a given record for a set of the selected
626 * r/zVariables. Input data are pointed to by the passed array of pointers.
627 ******************************************************************************/
628 
CDFputVarsRecordDatabyNames(id,zVar,numVars,varNames,recNum,buffptr)629 VISIBLE_PREFIX CDFstatus CDFputVarsRecordDatabyNames (id, zVar, numVars,
630                                                       varNames, recNum,
631                                                       buffptr)
632 CDFid   id;             /* In -- CDF id. */
633 int     zVar;           /* In -- Flag for zVariable. */
634 long    numVars;        /* In -- Number of variables. */
635 char    *varNames[];    /* In -- Array of variable names. */
636 long    recNum;         /* In -- Record number to read. */
637 void    *buffptr[];     /* In -- Array of buffer pointers for holding data. */
638 
639 {
640   CDFstatus pStatus = CDF_OK;
641   long dataType, numElems, numDims;
642   long dimSizes[CDF_MAX_DIMS], dimVarys[CDF_MAX_DIMS];
643   long dataTypeSize, recNumValues, *phyRecSize;
644   long totalSize, offset, *varNums;
645   int i, j;
646   void *buffer;
647 
648   if (numVars <= 0) return pStatus;
649 
650   if (!sX(CDFlib(SELECT_, CDF_, id,
651                  NULL_), &pStatus)) return pStatus;
652 
653   phyRecSize = cdf_AllocateMemory (numVars*sizeof(long)*2, NULL);
654   if (phyRecSize == NULL) return BAD_MALLOC;
655   varNums = phyRecSize+numVars;
656 
657   totalSize = 0;
658   for (i = 0; i < numVars; i++) {
659     if (!sX(CDFlib(GET_, BOO((zVar == 1),zVAR_NUMBER_,rVAR_NUMBER_),
660                          varNames[i], &varNums[i],
661                    NULL_), &pStatus)) return pStatus;
662     if (!sX(CDFlib(SELECT_, BOO((zVar == 1),zVAR_,rVAR_), varNums[i],
663                    GET_, BOO((zVar == 1),zVAR_DATATYPE_,rVAR_DATATYPE_),
664                          &dataType,
665                          BOO((zVar == 1),zVAR_NUMELEMS_,rVAR_NUMELEMS_),
666                          &numElems,
667                          BOO((zVar == 1),zVAR_NUMDIMS_,rVARs_NUMDIMS_),
668                          &numDims,
669                          BOO((zVar == 1),zVAR_DIMSIZES_,rVARs_DIMSIZES_),
670                          dimSizes,
671                          BOO((zVar == 1),zVAR_DIMVARYS_,rVAR_DIMVARYS_),
672                          dimVarys,
673                    NULL_), &pStatus)) return pStatus;
674     if (!sX(CDFlib(GET_, DATATYPE_SIZE_, dataType, &dataTypeSize,
675                    NULL_), &pStatus)) return pStatus;
676 
677     if (numDims == 0) {
678       numDims = 1;
679       dimSizes[0] = 1;
680       dimVarys[0] = 0;
681     }
682 
683     recNumValues = 1;
684     for (j = 0; j < numDims; j++)
685       if (dimVarys[j]) recNumValues *= dimSizes[j];
686     phyRecSize[i] = recNumValues * dataTypeSize * numElems;
687     totalSize += phyRecSize[i];
688   }
689 
690   buffer = cdf_AllocateMemory (totalSize, NULL);
691   if (buffer == NULL) return BAD_MALLOC;
692 
693   offset = 0;
694   for (i = 0; i < numVars; i++) {
695     memcpy((char *) buffer+offset, (char *) buffptr[i], phyRecSize[i]);
696     offset += phyRecSize[i];
697   }
698 
699   if (!sX(CDFlib(SELECT_, BOO((zVar == 1),zVARs_RECNUMBER_,rVARs_RECNUMBER_),
700                          recNum,
701                  PUT_, BOO((zVar == 1),zVARs_RECDATA_,rVARs_RECDATA_), numVars,
702                        varNums, buffer,
703                  NULL_), &pStatus)) return pStatus;
704 
705   cdf_FreeMemory (buffer, NULL);
706   cdf_FreeMemory (phyRecSize, NULL);
707   return CDF_OK;
708 
709 }
710 
711 /******************************************************************************
712 * CDFinquireAttrInfo. (Holding for backward version -- should not use)
713 * Can't implement with macro because the attribute's scope determines which
714 * item(s) to use.
715 ******************************************************************************/
716 
CDFinquireAttrInfo(id,zEntry,attrNum,attrName,scope,maxEntry)717 VISIBLE_PREFIX CDFstatus CDFinquireAttrInfo (id, zEntry, attrNum, attrName,
718                                              scope, maxEntry)
719 CDFid   id;             /* In -- CDF id. */
720 int     zEntry;         /* In -- Flag for zEntry. */
721 long    attrNum;        /* In -- Attribute number. */
722 char    *attrName;      /* Out -- Attribute name. */
723 long    *scope;         /* Out -- Attribute scope. */
724 long    *maxEntry;      /* Out -- Maximum g/r/zEntry number used. */
725 {
726   CDFstatus pStatus = CDF_OK;
727   if (!sX(CDFlib(SELECT_, CDF_, id,
728                           ATTR_, attrNum,
729                  GET_, ATTR_SCOPE_, scope,
730                  NULL_), &pStatus)) return pStatus;
731   if (GLOBALscope(*scope) && (zEntry == 1)) return ILLEGAL_FOR_SCOPE;
732   if (!sX(CDFlib(GET_, ATTR_NAME_, attrName,
733                        BOO((zEntry == 1),ATTR_MAXzENTRY_,
734                            (BOO(GLOBALscope(*scope),ATTR_MAXgENTRY_,
735                                 ATTR_MAXrENTRY_))), maxEntry,
736                  NULL_), &pStatus)) return pStatus;
737   return pStatus;
738 }
739 
740 /******************************************************************************
741 * CDFsetFileBackward. This function has precedence over the environment
742 * variable in determining whether a backward file is to be created.
743 ******************************************************************************/
744 
CDFsetFileBackward(flag)745 VISIBLE_PREFIX void CDFsetFileBackward (flag)
746 int flag;
747 {
748   if (flag != 0) backward = 1;
749   else backward = 0;
750   /*
751    * Set setFileBackward flag. So, if the environment variable is also
752    * set, we can ignore that as calling CDFsetFileBackward function has
753    * precedence over the environment variable approach.
754    */
755   setFileBackwardFlag = 1;
756 }
757 
758 /******************************************************************************
759 * CDFsetFileBackward2. This function is called if the environment variable
760 * is set to create the backward file. However, if CDFsetFileBackward
761 * function has been called and as it has precedence over the environment
762 * variable, calling this function will have no effect at all.
763 ******************************************************************************/
764 
CDFsetFileBackward2(flag)765 VISIBLE_PREFIX void CDFsetFileBackward2 (flag)
766 int flag;
767 {
768   if (setFileBackwardFlag == 0) { /* True if CDFsetFileBackward is not */
769                                   /* called.                           */
770     if (flag != 0) backward = 1;
771     else backward = 0;
772   }
773 }
774 
775 /******************************************************************************
776 * CDFsetChecksumMode. This function has precedence over the environment
777 * variable in determining whether a checksum is to be used.
778 ******************************************************************************/
779 
CDFsetChecksumMode(flag)780 VISIBLE_PREFIX void CDFsetChecksumMode (flag)
781 long flag;
782 {
783   checksum = flag;
784   /*
785    * Set setChecksum flag. So, if the environment variable is also
786    * set, we can ignore that as calling CDFsetChecksum function has
787    * precedence over the environment variable approach.
788    */
789   setChecksumFlag = 1;
790 }
791 
792 /******************************************************************************
793 * CDFgetFileBackward.
794 *   Acquires the backward flag defined from CDFsetFileBackward function or
795 *   the environment variable.
796 ******************************************************************************/
797 
CDFgetFileBackward()798 VISIBLE_PREFIX int CDFgetFileBackward ()
799 {
800   return backward;
801 }
802 
803 /******************************************************************************
804 * CDFgetChecksumMode.
805 *   Acquires the checksum flag defined from CDFsetChecksum function or
806 *   the environment variable.
807 ******************************************************************************/
808 
CDFgetChecksumMode()809 VISIBLE_PREFIX long CDFgetChecksumMode ()
810 {
811   return checksum;
812 }
813 
814 /******************************************************************************
815 * CDFsetFileBackwardFlag. (Holding for backward version -- should not use.)
816 ******************************************************************************/
817 
CDFsetFileBackwardFlag(flag)818 VISIBLE_PREFIX void CDFsetFileBackwardFlag (flag)
819 int flag;
820 {
821 /*
822   long version;
823   CDFstatus status;
824   status = CDFlib (GET_, LIB_VERSION_, &version,
825                    NULL_);
826   if (version == 3) backward = flag;
827 */
828   backward = flag;
829 }
830 
831 /******************************************************************************
832 * CDFgetFileBackwardFlag. (Holding for backward version -- should not use.)
833 ******************************************************************************/
834 
CDFgetFileBackwardFlag()835 VISIBLE_PREFIX int CDFgetFileBackwardFlag ()
836 {
837   if (backward == 0) return 0;
838   else return 1;
839 }
840 
841