1 /******************************************************************************
2 *
3 * NSSDC/CDF CDF `get' operations.
4 *
5 * Version 1.4, 9-Sep-96, Hughes STX.
6 *
7 * Modification history:
8 *
9 * V1.0 20-May-92, J Love Original version (was part of `cdflib.c').
10 * V1.1 16-Sep-92, J Love CDF V2.3 (shareable/NeXT/zVar).
11 * V1.2 13-Dec-93, J Love CDF V2.4.
12 * V1.3 15-Dec-94, J Love CDF V2.5.
13 * V1.3a 9-Jan-95, J Love Encode/decode changes. More cache-residency.
14 * V1.3b 24-Feb-95, J Love Solaris 2.3 IDL i/f.
15 * V1.3c 4-Aug-95, J Love CDFexport-related changes.
16 * V1.4 9-Sep-96, J Love CDF V2.6.
17 * V2.0 08-Apr-04, M Liu Removed call to LocateCurrentVar function as
18 * its offset becomes avilable when it is
19 * selected.
20 * V2.1 21-Jun-04, M Liu Modified the error message for NOT_A_CDF.
21 * V3.2 16-Oct-07, D Han The length of the pad value for a CDF_CHAR
22 * variable is the length of the variable (i.e.
23 * CHAR/162, etc.). If the length of the pad
24 * value is greater than 16, it causes
25 * segmentation fault for the IDL CDF interface
26 * routine.
27 ******************************************************************************/
28
29 #include "cdflib.h"
30 #include "cdfrev.h"
31
32 /******************************************************************************
33 * CDFget.
34 ******************************************************************************/
35
CDFget(Va,Cur)36 STATICforIDL CDFstatus CDFget (Va, Cur)
37 struct VAstruct *Va;
38 struct CurStruct *Cur;
39 {
40 CDFstatus tStatus, pStatus = CDF_OK;
41
42 switch (Va->item) {
43 /****************************************************************************
44 * CDF_INFO_
45 ****************************************************************************/
46 case CDF_INFO_: {
47 char CDFpathX[DU_MAX_PATH_LEN+1], CDFpathT[CDF_PATHNAME_LEN+1], *CDFpathP;
48 vFILE *dotFp; Logical upper_case_ext, version_numbers, no_append;
49 Int32 magicNumber1, magicNumber2; int i;
50 long *cType, *cParms, *cFileSize, *uFileSize;
51 CDFpathP = va_arg (Va->ap, char *);
52 cType = va_arg (Va->ap, long *);
53 cParms = va_arg (Va->ap, long *);
54 cFileSize = va_arg (Va->ap, long *);
55 uFileSize = va_arg (Va->ap, long *);
56 if (strlen(CDFpathP) > (size_t) CDF_PATHNAME_LEN) {
57 if (!sX(CDF_NAME_TRUNC,&pStatus)) return pStatus;
58 }
59 strcpyX (CDFpathT, CDFpathP, CDF_PATHNAME_LEN);
60 #if STRIP_TRAILING_BLANKS_FROM_CDFPATH
61 StripTrailingBlanks (CDFpathT);
62 #endif
63 #if defined(vms) || defined(dos)
64 MakeUpperString (CDFpathT);
65 #endif
66 if (!ValidCDFname(CDFpathT)) return BAD_CDF_NAME;
67 if (!sX(FindCDF(CDFpathT,&no_append,
68 &upper_case_ext,
69 &version_numbers),&pStatus)) return pStatus;
70 BuildFilePath (CDFt, CDFpathT, no_append, upper_case_ext, version_numbers,
71 INT32_ZERO, CDFpathX);
72 dotFp = V_open (CDFpathX, READ_ONLY_a_mode);
73 if (dotFp == NULL) return CDF_OPEN_ERROR;
74 if (!Read32(dotFp,&magicNumber1)) {
75 V_close (dotFp, NULL, NULL);
76 return CDF_READ_ERROR;
77 }
78 if (!Read32(dotFp,&magicNumber2)) {
79 V_close (dotFp, NULL, NULL);
80 return CDF_READ_ERROR;
81 }
82 switch (magicNumber1) {
83 case V1magicNUMBER_flip:
84 V_close (dotFp, NULL, NULL);
85 return ILLEGAL_ON_V1_CDF;
86 case V2magicNUMBER_1pre:
87 *cType = NO_COMPRESSION;
88 *cFileSize = 0;
89 if (!SEEKv(dotFp,0L,vSEEK_END)) {
90 V_close (dotFp, NULL, NULL);
91 return CDF_READ_ERROR;
92 }
93 *uFileSize = V_tell (dotFp);
94 break;
95 case V2magicNUMBER_1:
96 switch (magicNumber2) {
97 case V2magicNUMBER_2u:
98 *cType = NO_COMPRESSION;
99 *cFileSize = 0;
100 if (!SEEKv(dotFp,0L,vSEEK_END)) {
101 V_close (dotFp, NULL, NULL);
102 return CDF_READ_ERROR;
103 }
104 *uFileSize = V_tell (dotFp);
105 break;
106 case V2magicNUMBER_2c: {
107 struct CCRstruct CCR; struct CPRstruct CPR;
108 if (!sX(ReadCCR(dotFp,V2_CCR_OFFSET,
109 CCR_RECORD,&CCR,
110 CCR_NULL),&pStatus)) {
111 V_close (dotFp, NULL, NULL);
112 return pStatus;
113 }
114 if (CCR.uSize == 0) {
115 V_close (dotFp, NULL, NULL);
116 return EMPTY_COMPRESSED_CDF;
117 }
118 if (!sX(ReadCPR(dotFp,CCR.CPRoffset,
119 CPR_RECORD,&CPR,
120 CPR_NULL),&pStatus)) {
121 V_close (dotFp, NULL, NULL);
122 return pStatus;
123 }
124 *cType = (long) CPR.cType;
125 if (CPR.pCount > CDF_MAX_PARMS) {
126 V_close (dotFp, NULL, NULL);
127 return TOO_MANY_PARMS;
128 }
129 for (i = 0; i < CPR.pCount; i++) cParms[i] = (long) CPR.cParms[i];
130 if (!SEEKv(dotFp,0L,vSEEK_END)) {
131 V_close (dotFp, NULL, NULL);
132 return CDF_READ_ERROR;
133 }
134 *cFileSize = V_tell (dotFp);
135 *uFileSize = (long) CCR.uSize + MAGIC_NUMBERS_SIZE;
136 break;
137 }
138 default:
139 V_close (dotFp, NULL, NULL);
140 return NOT_A_CDF;
141 }
142 break;
143 default:
144 V_close (dotFp, NULL, NULL);
145 return NOT_A_CDF_OR_NOT_SUPPORTED;
146 }
147 V_close (dotFp, NULL, NULL);
148 break;
149 }
150 /****************************************************************************
151 * STATUS_TEXT_,
152 ****************************************************************************/
153 case STATUS_TEXT_: {
154 char *textPtr;
155 textPtr = va_arg (Va->ap, char *);
156 CDFstatusText (Cur->status, textPtr);
157 break;
158 }
159 /****************************************************************************
160 * DATATYPE_SIZE_,
161 ****************************************************************************/
162 case DATATYPE_SIZE_: {
163 long dataType = va_arg (Va->ap, long);
164 long *numBytes = va_arg (Va->ap, long *);
165 if (!ValidDataType((Int32)dataType)) return BAD_DATA_TYPE;
166 *numBytes = (long) CDFelemSize (dataType);
167 break;
168 }
169 /****************************************************************************
170 * rVARs_NUMDIMS_/zVAR_NUMDIMS_
171 * Note that inquiring the number of rVariable dimensions is allowed while
172 * in zMode.
173 ****************************************************************************/
174 case rVARs_NUMDIMS_: {
175 struct CDFstruct *CDF;
176 long *numDims = va_arg (Va->ap, long *);
177 SelectCDF (Cur->cdf, CDF)
178 *numDims = CDF->rNumDims;
179 break;
180 }
181 case zVAR_NUMDIMS_: {
182 struct CDFstruct *CDF;
183 long *numDimsP = va_arg (Va->ap, long *);
184 Logical zVar; Int32 offset, numDims;
185 SelectCDF (Cur->cdf, CDF)
186 if (!CURRENTvarSELECTED(CDF,TRUE)) return NO_VAR_SELECTED;
187
188 zVar = CurrentVarMode(CDF,TRUE);
189 if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
190 else offset = CDF->CURrVarOffset;
191
192 if (!sX(CalcDimParms(CDF,offset,zVar,&numDims,NULL,NULL),&pStatus)) {
193 AbortAccess (CDF, UPDATE, noDELETE);
194 return pStatus;
195 }
196 ASSIGNnotNULL (numDimsP, numDims)
197 break;
198 }
199 /****************************************************************************
200 * rVARs_DIMSIZES_/zVAR_DIMSIZES_
201 * Note that inquiring the rVariable dimension sizes is allowed while in
202 * zMode.
203 ****************************************************************************/
204 case rVARs_DIMSIZES_: {
205 struct CDFstruct *CDF;
206 int dimN;
207 long *dimsize = va_arg (Va->ap, long *);
208 SelectCDF (Cur->cdf, CDF)
209 for (dimN = 0; dimN < CDF->rNumDims; dimN++) {
210 dimsize[dimN] = CDF->rDimSizes[dimN];
211 }
212 break;
213 }
214 case zVAR_DIMSIZES_: {
215 struct CDFstruct *CDF; Logical zVar;
216 Int32 offset, numDims, dimSizes[CDF_MAX_DIMS];
217 long *dimSizesP = va_arg (Va->ap, long *);
218 SelectCDF (Cur->cdf, CDF)
219 if (!CURRENTvarSELECTED(CDF,TRUE)) return NO_VAR_SELECTED;
220
221 zVar = CurrentVarMode(CDF,TRUE);
222 if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
223 else offset = CDF->CURrVarOffset;
224
225 if (!sX(CalcDimParms(CDF,offset,zVar,&numDims,dimSizes,NULL),&pStatus)) {
226 AbortAccess (CDF, UPDATE, noDELETE);
227 return pStatus;
228 }
229 ASSIGNnotNULLarray (dimSizesP, numDims, dimSizes)
230 break;
231 }
232 /****************************************************************************
233 * CDF_ENCODING_,
234 ****************************************************************************/
235 case CDF_ENCODING_: {
236 struct CDFstruct *CDF;
237 long *encoding = va_arg (Va->ap, long *);
238 SelectCDF (Cur->cdf, CDF)
239 *encoding = (long) CDF->encoding;
240 break;
241 }
242 /****************************************************************************
243 * CDF_MAJORITY_,
244 ****************************************************************************/
245 case CDF_MAJORITY_: {
246 struct CDFstruct *CDF;
247 long *majority = va_arg (Va->ap, long *);
248 SelectCDF (Cur->cdf, CDF)
249 *majority = BOO(CDF->rowMajor,ROW_MAJOR,COLUMN_MAJOR);
250 break;
251 }
252 /****************************************************************************
253 * CDF_FORMAT_,
254 ****************************************************************************/
255 case CDF_FORMAT_: {
256 struct CDFstruct *CDF;
257 long *format = va_arg (Va->ap, long *);
258 SelectCDF (Cur->cdf, CDF)
259 *format = BOO(CDF->singleFile,SINGLE_FILE,MULTI_FILE);
260 break;
261 }
262 /****************************************************************************
263 * CDF_CHECKSUM_,
264 ****************************************************************************/
265 case CDF_CHECKSUM_: {
266 struct CDFstruct *CDF;
267 long *checksum = va_arg (Va->ap, long *);
268 SelectCDF (Cur->cdf, CDF)
269 *checksum = CDF->checksum;
270 break;
271 }
272 /****************************************************************************
273 * CDF_COMPRESSION_
274 ****************************************************************************/
275 case CDF_COMPRESSION_: {
276 long *cType = va_arg (Va->ap, long *); /* Compression type. */
277 long *cParms = va_arg (Va->ap, long *); /* Compression parameters. */
278 long *cPct = va_arg (Va->ap, long *); /* Compression percentage. */
279 struct CDFstruct *CDF; struct CCRstruct CCR; struct CPRstruct CPR;
280 int i; long cTotal, uTotal;
281 SelectCDF (Cur->cdf, CDF)
282 /**************************************************************************
283 * If multi-file or uncompressed...
284 **************************************************************************/
285 if (!CDF->singleFile || CDF->uDotFp == NULL) {
286 *cType = NO_COMPRESSION;
287 *cPct = 100;
288 break;
289 }
290 /**************************************************************************
291 * ...otherwise, read the CCR and CPR.
292 **************************************************************************/
293 if (!sX(ReadCCR(CDF->dotFp,V2_CCR_OFFSET,
294 CCR_RECORD,&CCR,
295 CCR_NULL),&pStatus)) return pStatus;
296 if (!sX(ReadCPR(CDF->dotFp,CCR.CPRoffset,
297 CPR_RECORD,&CPR,
298 CPR_NULL),&pStatus)) return pStatus;
299 *cType = CPR.cType;
300 if (CPR.pCount > CDF_MAX_PARMS) return TOO_MANY_PARMS;
301 for (i = 0; i < CPR.pCount; i++) cParms[i] = CPR.cParms[i];
302 /**************************************************************************
303 * Calculate the percentage. If the `uSize' field of the CCR is zero,
304 * then the compressed CDF is empty (and the percentage is unknown).
305 **************************************************************************/
306 if (CCR.uSize == 0)
307 *cPct = 0;
308 else {
309 cTotal = MAGIC_NUMBERS_SIZE + CCR.RecordSize + CPR.RecordSize;
310 uTotal = MAGIC_NUMBERS_SIZE + CCR.uSize;
311 *cPct = (100L * cTotal) / uTotal;
312 }
313 break;
314 }
315 /****************************************************************************
316 * CDF_COPYRIGHT_
317 ****************************************************************************/
318 case CDF_COPYRIGHT_: {
319 struct CDFstruct *CDF;
320 char *copyRight = va_arg (Va->ap, char *);
321 SelectCDF (Cur->cdf, CDF)
322 if (!sX(ReadCDR(CDF->fp,CDF->CDRoffset,
323 CDR_COPYRIGHT,copyRight,
324 CDR_NULL),&pStatus)) {
325 AbortAccess (CDF, UPDATE, noDELETE);
326 return pStatus;
327 }
328 copyRight[CDF_COPYRIGHT_LEN] = NUL;
329 break;
330 }
331 /****************************************************************************
332 * LIB_COPYRIGHT_
333 ****************************************************************************/
334 case LIB_COPYRIGHT_: {
335 char *copyRight = va_arg (Va->ap, char *);
336 CDFcopyRight (copyRight);
337 break;
338 }
339 /****************************************************************************
340 * CDF_NUMrVARS_/CDF_NUMzVARS_
341 * Inquire number of r/z variables. When in zMode, the number of
342 * rVariables is always zero (0). (Inquiring the number of rVariables
343 * while in zMode is one of the few legal rVariable operations).
344 ****************************************************************************/
345 case CDF_NUMrVARS_:
346 case CDF_NUMzVARS_: {
347 Logical zOp = (Va->item == CDF_NUMzVARS_);
348 struct CDFstruct *CDF;
349 long *numVars = va_arg (Va->ap, long *);
350 SelectCDF (Cur->cdf, CDF)
351 if (zModeON(CDF))
352 *numVars = BOO(zOp,CDF->NrVars + CDF->NzVars,0);
353 else
354 *numVars = BOO(zOp,CDF->NzVars,CDF->NrVars);
355 break;
356 }
357 /****************************************************************************
358 * CDF_NUMATTRS_,
359 ****************************************************************************/
360 case CDF_NUMATTRS_: {
361 struct CDFstruct *CDF;
362 long *numAttrs = va_arg (Va->ap, long *);
363 Int32 tNumAttrs;
364 SelectCDF (Cur->cdf, CDF)
365 if (!sX(ReadGDR(CDF->fp,CDF->GDRoffset,
366 GDR_NUMATTR,&tNumAttrs,
367 GDR_NULL),&pStatus)) {
368 AbortAccess (CDF, UPDATE, noDELETE);
369 return pStatus;
370 }
371 *numAttrs = tNumAttrs;
372 break;
373 }
374 /****************************************************************************
375 * CDF_NUMgATTRS_/CDF_NUMvATTRS_
376 ****************************************************************************/
377 case CDF_NUMvATTRS_:
378 case CDF_NUMgATTRS_: {
379 Logical gOp = (Va->item == CDF_NUMgATTRS_);
380 struct CDFstruct *CDF;
381 long *numAttrs = va_arg (Va->ap, long *);
382 Int32 totalAttrs, offset, scope;
383 int attrX;
384 SelectCDF (Cur->cdf, CDF)
385 *numAttrs = 0;
386 if (!sX(ReadGDR(CDF->fp,CDF->GDRoffset,
387 GDR_NUMATTR,&totalAttrs,
388 GDR_ADRHEAD,&offset,
389 GDR_NULL),&pStatus)) {
390 AbortAccess (CDF, UPDATE, noDELETE);
391 return pStatus;
392 }
393 for (attrX = 0; attrX < totalAttrs; attrX++) {
394 CDF->fp->CurADRIndex = attrX;
395 if (!sX(ReadADR(CDF->fp,offset,
396 ADR_SCOPE,&scope,
397 ADR_NULL),&pStatus)) {
398 AbortAccess (CDF, UPDATE, noDELETE);
399 return pStatus;
400 }
401 if ((gOp && GLOBALscope(scope)) ||
402 (!gOp && VARIABLEscope(scope))) (*numAttrs)++;
403 if (!sX(ReadADR(CDF->fp,offset,
404 ADR_ADRNEXT,&offset,
405 ADR_NULL),&pStatus)) {
406 AbortAccess (CDF, UPDATE, noDELETE);
407 return pStatus;
408 }
409 }
410 break;
411 }
412 /****************************************************************************
413 * rVARs_MAXREC_/zVARs_MAXREC_
414 * Maximum record number of all of the rVariables/zVariables. Note that
415 * inquiring the maximum rVariable record number is allowed while in zMode.
416 ****************************************************************************/
417 case rVARs_MAXREC_: {
418 struct CDFstruct *CDF;
419 long *maxRec = va_arg (Va->ap, long *);
420 SelectCDF (Cur->cdf, CDF)
421 if (zModeON(CDF))
422 *maxRec = NO_RECORD;
423 else
424 *maxRec = CDF->rMaxRec;
425 break;
426 }
427 case zVARs_MAXREC_: {
428 struct CDFstruct *CDF;
429 long *maxRec = va_arg (Va->ap, long *);
430 Int32 offset, tMaxRec;
431 SelectCDF (Cur->cdf, CDF)
432 /**************************************************************************
433 * If zMode is on, consider both rVariables and zVariables. If zMode is
434 * not on, only consider the zVariables. Because zVariables did not exist
435 * in CDF V2.0, the problem with the `VDRnext' offset in the last VDR does
436 * not have to be considered here.
437 **************************************************************************/
438 *maxRec = BOO(zModeON(CDF),CDF->rMaxRec,NO_RECORD);
439 if (!sX(ReadGDR(CDF->fp,CDF->GDRoffset,
440 GDR_zVDRHEAD,&offset,
441 GDR_NULL),&pStatus)) {
442 AbortAccess (CDF, UPDATE, noDELETE);
443 return pStatus;
444 }
445 while (offset != ZERO_OFFSET) {
446 if (!sX(ReadVDR(CDF,CDF->fp,offset,TRUE,
447 VDR_MAXREC,&tMaxRec,
448 VDR_VDRNEXT,&offset,
449 VDR_NULL),&pStatus)) {
450 AbortAccess (CDF, UPDATE, noDELETE);
451 return pStatus;
452 }
453 *maxRec = MAXIMUM (*maxRec, tMaxRec);
454 }
455 break;
456 }
457 /****************************************************************************
458 * CDF_VERSION_,
459 ****************************************************************************/
460 case CDF_VERSION_: {
461 struct CDFstruct *CDF;
462 long *version = va_arg (Va->ap, long *);
463 Int32 tVersion;
464 SelectCDF (Cur->cdf, CDF)
465 if (!sX(ReadCDR(CDF->fp,CDF->CDRoffset,
466 CDR_VERSION,&tVersion,
467 CDR_NULL),&pStatus)) {
468 AbortAccess (CDF, UPDATE, noDELETE);
469 return pStatus;
470 }
471 *version = tVersion;
472 break;
473 }
474 /****************************************************************************
475 * CDF_RELEASE_,
476 ****************************************************************************/
477 case CDF_RELEASE_: {
478 struct CDFstruct *CDF;
479 long *release = va_arg (Va->ap, long *);
480 Int32 tRelease;
481 SelectCDF (Cur->cdf, CDF)
482 if (!sX(ReadCDR(CDF->fp,CDF->CDRoffset,
483 CDR_RELEASE,&tRelease,
484 CDR_NULL),&pStatus)) {
485 AbortAccess (CDF, UPDATE, noDELETE);
486 return pStatus;
487 }
488 *release = tRelease;
489 break;
490 }
491 /****************************************************************************
492 * CDF_INCREMENT_,
493 ****************************************************************************/
494 case CDF_INCREMENT_: {
495 struct CDFstruct *CDF;
496 long *increment = va_arg (Va->ap, long *);
497 Int32 tIncrement;
498 SelectCDF (Cur->cdf, CDF)
499 if (!sX(ReadCDR(CDF->fp,CDF->CDRoffset,
500 CDR_INCREMENT,&tIncrement,
501 CDR_NULL),&pStatus)) {
502 AbortAccess (CDF, UPDATE, noDELETE);
503 return pStatus;
504 }
505 *increment = tIncrement;
506 break;
507 }
508 /****************************************************************************
509 * LIB_VERSION_,
510 ****************************************************************************/
511 case LIB_VERSION_: {
512 long *version = va_arg (Va->ap, long *);
513 *version = CDF_LIBRARY_VERSION;
514 break;
515 }
516 /****************************************************************************
517 * LIB_RELEASE_,
518 ****************************************************************************/
519 case LIB_RELEASE_: {
520 long *release = va_arg (Va->ap, long *);
521 *release = CDF_LIBRARY_RELEASE;
522 break;
523 }
524 /****************************************************************************
525 * LIB_INCREMENT_,
526 ****************************************************************************/
527 case LIB_INCREMENT_: {
528 long *increment = va_arg (Va->ap, long *);
529 *increment = CDF_LIBRARY_INCREMENT;
530 break;
531 }
532 /****************************************************************************
533 * LIB_subINCREMENT_,
534 ****************************************************************************/
535 case LIB_subINCREMENT_: {
536 char *subincrement = va_arg (Va->ap, char *);
537 *subincrement = CDF_LIBRARY_subINCREMENT;
538 break;
539 }
540 /****************************************************************************
541 * rVAR_NAME_/zVAR_NAME_
542 * Note that a temporary variable is used when reading the variable name.
543 * This is because the caller may have only allocated enough memory for the
544 * size name they expect (ie., less than CDF_VAR_NAME_LEN characters). Since
545 * the variable name is NUL-terminated in the CDF, only the actual characters
546 * of the name will be copied to the caller's buffer.
547 ****************************************************************************/
548 case rVAR_NAME_:
549 case zVAR_NAME_: {
550 Logical zOp = (Va->item == zVAR_NAME_), zVar;
551 struct CDFstruct *CDF;
552 char *varName = va_arg (Va->ap, char *), tName[CDF_VAR_NAME_LEN+1];
553 Int32 offset;
554 SelectCDF (Cur->cdf, CDF)
555 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
556 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
557
558 zVar = CurrentVarMode(CDF,zOp);
559 if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
560 else offset = CDF->CURrVarOffset;
561
562 if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
563 VDR_NAME,tName,
564 VDR_NULL),&pStatus)) {
565 AbortAccess (CDF, UPDATE, noDELETE);
566 return pStatus;
567 }
568 strcpyX (varName, tName, CDF_VAR_NAME_LEN);
569 break;
570 }
571 /****************************************************************************
572 * rVAR_DATATYPE_/zVAR_DATATYPE_
573 * If this for an rVarible named "EPOCH" in a CDF prior to CDF V2.1.1,
574 * then return the CDF_EPOCH data type if the actual data type is CDF_REAL8
575 * or CDF_DOUBLE. (The CDF_EPOCH data type was not introduced until CDF
576 * V2.1.1). Note that only rVariables were supported prior to CDF V2.3.
577 ****************************************************************************/
578 case rVAR_DATATYPE_:
579 case zVAR_DATATYPE_: {
580 Logical zOp = (Va->item == zVAR_DATATYPE_), zVar;
581 struct CDFstruct *CDF;
582 long *dataType = va_arg (Va->ap, long *);
583 Int32 tDataType, offset;
584 SelectCDF (Cur->cdf, CDF)
585 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
586 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
587
588 zVar = CurrentVarMode(CDF,zOp);
589 if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
590 else offset = CDF->CURrVarOffset;
591
592 if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
593 VDR_DATATYPE,&tDataType,
594 VDR_NULL),&pStatus)) {
595 AbortAccess (CDF, UPDATE, noDELETE);
596 return pStatus;
597 }
598 if (!zVar && CDF->fakeEPOCH) {
599 char varName[CDF_VAR_NAME_LEN+1];
600 if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
601 VDR_NAME,varName,
602 VDR_NULL),&pStatus)) {
603 AbortAccess (CDF, UPDATE, noDELETE);
604 return pStatus;
605 }
606 if (!strcmpITB(varName,"EPOCH") && FLOAT8dataType(tDataType)) {
607 tDataType = CDF_EPOCH;
608 } else if (!strcmpITB(varName,"EPOCH") && FLOAT16dataType(tDataType)) {
609 tDataType = CDF_EPOCH16;
610 }
611 }
612 *dataType = tDataType;
613 break;
614 }
615 /****************************************************************************
616 * rVAR_NUMELEMS_/zVAR_NUMELEMS_,
617 ****************************************************************************/
618 case rVAR_NUMELEMS_:
619 case zVAR_NUMELEMS_: {
620 Logical zOp = (Va->item == zVAR_NUMELEMS_), zVar;
621 struct CDFstruct *CDF;
622 long *numElements = va_arg (Va->ap, long *);
623 Int32 offset, tNumElems;
624 SelectCDF (Cur->cdf, CDF)
625 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
626 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
627
628 zVar = CurrentVarMode(CDF,zOp);
629 if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
630 else offset = CDF->CURrVarOffset;
631
632 if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
633 VDR_NUMELEMS,&tNumElems,
634 VDR_NULL),&pStatus)) {
635 AbortAccess (CDF, UPDATE, noDELETE);
636 return pStatus;
637 }
638 *numElements = tNumElems;
639 break;
640 }
641 /****************************************************************************
642 * rVAR_RECVARY_/zVAR_RECVARY_,
643 ****************************************************************************/
644 case rVAR_RECVARY_:
645 case zVAR_RECVARY_: {
646 Logical zOp = (Va->item == zVAR_RECVARY_), zVar;
647 struct CDFstruct *CDF;
648 long *recVary = va_arg (Va->ap, long *);
649 Int32 flags, offset;
650 SelectCDF (Cur->cdf, CDF)
651 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
652 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
653
654 zVar = CurrentVarMode(CDF,zOp);
655 if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
656 else offset = CDF->CURrVarOffset;
657
658 if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
659 VDR_FLAGS,&flags,
660 VDR_NULL),&pStatus)) {
661 AbortAccess (CDF, UPDATE, noDELETE);
662 return pStatus;
663 }
664 *recVary = BOO(RECvaryBITset(flags),VARY,NOVARY);
665 break;
666 }
667 /****************************************************************************
668 * rVAR_DIMVARYS_/zVAR_DIMVARYS_,
669 ****************************************************************************/
670 case rVAR_DIMVARYS_:
671 case zVAR_DIMVARYS_: {
672 Logical zOp = (Va->item == zVAR_DIMVARYS_), zVar;
673 struct CDFstruct *CDF; Int32 offset, numDims, dimVarys[CDF_MAX_DIMS];
674 long *dimVarysP = va_arg (Va->ap, long *);
675 SelectCDF (Cur->cdf, CDF)
676 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
677 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
678
679 zVar = CurrentVarMode(CDF,zOp);
680 if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
681 else offset = CDF->CURrVarOffset;
682
683 if (!sX(CalcDimParms(CDF,offset,zVar,&numDims,NULL,dimVarys),&pStatus)) {
684 AbortAccess (CDF, UPDATE, noDELETE);
685 return pStatus;
686 }
687 ASSIGNnotNULLarray (dimVarysP, numDims, dimVarys)
688 break;
689 }
690 /****************************************************************************
691 * rVAR_MAXREC_/zVAR_MAXREC_,
692 ****************************************************************************/
693 case rVAR_MAXREC_:
694 case zVAR_MAXREC_: {
695 Logical zOp = (Va->item == zVAR_MAXREC_), zVar;
696 struct CDFstruct *CDF; Int32 offset, tMaxRec;
697 long *maxRec = va_arg (Va->ap, long *);
698 SelectCDF (Cur->cdf, CDF)
699 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
700 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
701
702 zVar = CurrentVarMode(CDF,zOp);
703 if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
704 else offset = CDF->CURrVarOffset;
705
706 if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
707 VDR_MAXREC,&tMaxRec,
708 VDR_NULL),&pStatus)) {
709 AbortAccess (CDF, UPDATE, noDELETE);
710 return pStatus;
711 }
712 *maxRec = (long) tMaxRec;
713 break;
714 }
715 /****************************************************************************
716 * rVAR_MAXallocREC_/zVAR_MAXallocREC_,
717 ****************************************************************************/
718 case rVAR_MAXallocREC_:
719 case zVAR_MAXallocREC_: {
720 Logical zOp = (Va->item == zVAR_MAXallocREC_), zVar;
721 struct CDFstruct *CDF;
722 Int32 offset, maxRec, lastAllocatedRecN;
723 long *maxAllocated = va_arg (Va->ap, long *);
724 SelectCDF (Cur->cdf, CDF)
725 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
726 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
727
728 zVar = CurrentVarMode(CDF,zOp);
729 if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
730 else offset = CDF->CURrVarOffset;
731
732 /**************************************************************************
733 * If a single-file CDF, pass back the maximum record number allocated.
734 * If a multi-file CDF, pass back the maximum record number written (which
735 * will always be the maximum record allocated).
736 **************************************************************************/
737 if (CDF->singleFile) {
738 if (!sX(LastRecord(CDF,offset,zVar,&lastAllocatedRecN),&pStatus)) {
739 AbortAccess (CDF, UPDATE, noDELETE);
740 return pStatus;
741 }
742 *maxAllocated = lastAllocatedRecN;
743 }
744 else {
745 if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
746 VDR_MAXREC,&maxRec,
747 VDR_NULL),&pStatus)) {
748 AbortAccess (CDF, UPDATE, noDELETE);
749 return pStatus;
750 }
751 *maxAllocated = (long) maxRec;
752 }
753 break;
754 }
755 /****************************************************************************
756 * rVAR_NUMRECS_/zVAR_NUMRECS_,
757 ****************************************************************************/
758 case rVAR_NUMRECS_:
759 case zVAR_NUMRECS_: {
760 Logical zOp = (Va->item == zVAR_NUMRECS_), zVar; struct VarStruct *Var;
761 struct CDFstruct *CDF; Int32 vdrOffset, nRecords; int vType;
762 Int32 tMaxRec;
763 long *nRecordsP = va_arg (Va->ap, long *);
764 SelectCDF (Cur->cdf, CDF)
765 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
766 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
767
768 zVar = CurrentVarMode(CDF,zOp);
769 if (zModeON(CDF) || zVar) vdrOffset = CDF->CURzVarOffset;
770 else vdrOffset = CDF->CURrVarOffset;
771
772 if (zModeON(CDF))
773 if (CDF->CURzVarNum < CDF->NrVars)
774 Var = CDF->rVars[(int)CDF->CURzVarNum];
775 else
776 Var = CDF->zVars[(int)(CDF->CURzVarNum - CDF->NrVars)];
777 else
778 Var = BOO(zOp,CDF->zVars[(int)CDF->CURzVarNum],
779 CDF->rVars[(int)CDF->CURrVarNum]);
780
781 if (!sX(ReadVDR(CDF,CDF->fp,vdrOffset,zVar,
782 VDR_MAXREC,&tMaxRec,
783 VDR_NULL),&pStatus)) {
784 AbortAccess (CDF, UPDATE, noDELETE);
785 return pStatus;
786 }
787 if (!sX(VariableType(CDF,vdrOffset,zVar,&vType),&pStatus)) {
788 AbortAccess (CDF, UPDATE, noDELETE);
789 return pStatus;
790 }
791 /**************************************************************************
792 * Depending on the variable type...
793 **************************************************************************/
794 switch (vType) {
795 case SPARSE_RECORDS_:
796 if (!sX(IndexingStatistics(CDF,vdrOffset,zVar,
797 NULL,NULL,NULL,
798 &nRecords,NULL),&pStatus)) return pStatus;
799 if (Var != NULL) {
800 if (Var->stage.areaOffset != NO_OFFSET &&
801 Var->stage.firstRec != NO_RECORD) {
802 Int32 tmp = (Var->stage.lastRec > tMaxRec ? tMaxRec : Var->stage.lastRec);
803 nRecords += (tmp - Var->stage.firstRec + 1);
804 }
805 }
806 break;
807 case COMPRESSED_:
808 case SPARSE_COMPRESSED_RECORDS_:
809 if (!sX(IndexingStatistics(CDF,vdrOffset,zVar,
810 NULL,NULL,NULL,
811 &nRecords,NULL),&pStatus)) return pStatus;
812 if (Var != NULL) {
813 if (Var->stage.areaOffset != NO_OFFSET &&
814 Var->stage.firstRec != NO_RECORD &&
815 Var->stage.dotOffset == NO_OFFSET) {
816 Int32 tmp = (Var->stage.lastRec > tMaxRec ? tMaxRec : Var->stage.lastRec);
817 nRecords += (tmp - Var->stage.firstRec + 1);
818 }
819 }
820 break;
821 case SPARSE_ARRAYS_:
822 case SPARSE_RECORDS_AND_ARRAYS_:
823 return CDF_INTERNAL_ERROR;
824 case STANDARD_:
825 case IN_MULTI_: {
826 Int32 maxRec;
827 if (!sX(ReadVDR(CDF,CDF->fp,vdrOffset,zVar,
828 VDR_MAXREC,&maxRec,
829 VDR_NULL),&pStatus)) {
830 AbortAccess (CDF, UPDATE, noDELETE);
831 return pStatus;
832 }
833 nRecords = maxRec + 1;
834 break;
835 }
836 }
837 ASSIGNnotNULL (nRecordsP, nRecords)
838 break;
839 }
840 /****************************************************************************
841 * rVAR_NUMallocRECS_/zVAR_NUMallocRECS_,
842 ****************************************************************************/
843 case rVAR_NUMallocRECS_:
844 case zVAR_NUMallocRECS_: {
845 Logical zOp = (Va->item == zVAR_NUMallocRECS_), zVar;
846 struct CDFstruct *CDF; Int32 offset, nAllocated; int vType;
847 long *nAllocatedP = va_arg (Va->ap, long *);
848 SelectCDF (Cur->cdf, CDF)
849 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
850 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
851
852 zVar = CurrentVarMode(CDF,zOp);
853 if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
854 else offset = CDF->CURrVarOffset;
855
856 if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
857 VDR_NULL),&pStatus)) {
858 AbortAccess (CDF, UPDATE, noDELETE);
859 return pStatus;
860 }
861 if (!sX(VariableType(CDF,offset,zVar,&vType),&pStatus)) {
862 AbortAccess (CDF, UPDATE, noDELETE);
863 return pStatus;
864 }
865 /**************************************************************************
866 * Depending on the variable type...
867 **************************************************************************/
868 switch (vType) {
869 case STANDARD_:
870 case SPARSE_RECORDS_:
871 case COMPRESSED_:
872 case SPARSE_COMPRESSED_RECORDS_:
873 case SPARSE_ARRAYS_:
874 case SPARSE_RECORDS_AND_ARRAYS_:
875
876 if (!sX(IndexingStatistics(CDF,offset,
877 zVar,NULL,NULL,
878 &nAllocated,
879 NULL,NULL),&pStatus)) return pStatus;
880 break;
881 case IN_MULTI_: {
882 Int32 maxRec;
883 if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
884 VDR_MAXREC,&maxRec,
885 VDR_NULL),&pStatus)) {
886 AbortAccess (CDF, UPDATE, noDELETE);
887 return pStatus;
888 }
889 nAllocated = maxRec + 1;
890 break;
891 }
892 }
893 ASSIGNnotNULL (nAllocatedP, nAllocated)
894 break;
895 }
896 /****************************************************************************
897 * rVAR_ALLOCATEDFROM_/zVAR_ALLOCATEDFROM_
898 * Determines the next allocated record AT or AFTER `startRec' (meaning that
899 * `startRec' could be the record number returned).
900 ****************************************************************************/
901 case rVAR_ALLOCATEDFROM_:
902 case zVAR_ALLOCATEDFROM_: {
903 Logical zOp = (Va->item == zVAR_ALLOCATEDFROM_), zVar, found;
904 struct CDFstruct *CDF; Int32 offset, nextRec;
905 Int32 startRec = (Int32) va_arg (Va->ap, long);
906 long *fromRec = va_arg (Va->ap, long *);
907 SelectCDF (Cur->cdf, CDF)
908 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
909 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
910 if (startRec <= NO_RECORD) return BAD_REC_NUM;
911
912 zVar = CurrentVarMode(CDF,zOp);
913 if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
914 else offset = CDF->CURrVarOffset;
915
916 if (!sX(NextRecord(CDF,offset,zVar,startRec,&nextRec,&found),&pStatus)) {
917 AbortAccess (CDF, UPDATE, noDELETE);
918 return pStatus;
919 }
920 if (!found) return NO_SUCH_RECORD;
921 *fromRec = (long) nextRec;
922 break;
923 }
924 /****************************************************************************
925 * rVAR_ALLOCATEDTO_/zVAR_ALLOCATEDTO_
926 * Determines the last record (before the next unallocated record) allocated
927 * AT or AFTER `startRec'. This can span non-contiguous blocks of records.
928 ****************************************************************************/
929 case rVAR_ALLOCATEDTO_:
930 case zVAR_ALLOCATEDTO_: {
931 Logical zOp = (Va->item == zVAR_ALLOCATEDTO_), zVar, found;
932 struct CDFstruct *CDF; Int32 vdrOffset, lastRec;
933 Int32 startRec = (Int32) va_arg (Va->ap, long);
934 long *toRec = va_arg (Va->ap, long *);
935 SelectCDF (Cur->cdf, CDF)
936 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
937 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
938 if (startRec <= NO_RECORD) return BAD_REC_NUM;
939
940 zVar = CurrentVarMode(CDF,zOp);
941 if (zModeON(CDF) || zVar) vdrOffset = CDF->CURzVarOffset;
942 else vdrOffset = CDF->CURrVarOffset;
943
944 /**************************************************************************
945 * Determine the last record in the block containing the starting record.
946 **************************************************************************/
947 if (!sX(SearchForRecord(CDF,vdrOffset,zVar,startRec,
948 NULL,&lastRec,NULL,&found),&pStatus)) {
949 AbortAccess (CDF, UPDATE, noDELETE);
950 return pStatus;
951 }
952 if (!found) return NO_SUCH_RECORD;
953 /**************************************************************************
954 * Keep searching until an unallocated record is encountered.
955 **************************************************************************/
956 while (found) {
957 Int32 nextRec = (Int32) (lastRec + 1);
958 if (!sX(SearchForRecord(CDF,vdrOffset,zVar,nextRec,
959 NULL,&lastRec,NULL,&found),&pStatus)) {
960 AbortAccess (CDF, UPDATE, noDELETE);
961 return pStatus;
962 }
963 }
964 /**************************************************************************
965 * Return the last allocated record detected.
966 **************************************************************************/
967 *toRec = (long) lastRec;
968 break;
969 }
970 /****************************************************************************
971 * rVAR_COMPRESSION_/zVAR_COMPRESSION_
972 ****************************************************************************/
973 case rVAR_COMPRESSION_:
974 case zVAR_COMPRESSION_: {
975 Logical zOp = (Va->item == zVAR_COMPRESSION_), zVar;
976 struct CDFstruct *CDF; /* struct VarStruct *Var; */ struct CPRstruct CPR;
977 Int32 VDRoffset, PRoffset, flags; int parmN;
978 long *cType = va_arg (Va->ap, long *); /* Compression type. */
979 long *cParms = va_arg (Va->ap, long *); /* Compression parameters. */
980 long *cPct = va_arg (Va->ap, long *); /* Compression percentage. */
981 /**************************************************************************
982 * Select/validate/locate CDF and variable.
983 **************************************************************************/
984 SelectCDF (Cur->cdf, CDF)
985 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
986 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
987
988 zVar = CurrentVarMode(CDF,zOp);
989 if (zModeON(CDF) || zVar) VDRoffset = CDF->CURzVarOffset;
990 else VDRoffset = CDF->CURrVarOffset;
991
992 /**************************************************************************
993 * Read fields from VDR.
994 **************************************************************************/
995 if (!sX(ReadVDR(CDF,CDF->fp,VDRoffset,zVar,
996 VDR_FLAGS,&flags,
997 VDR_CPRorSPR,&PRoffset,
998 VDR_NULL),&pStatus)) {
999 AbortAccess (CDF, UPDATE, noDELETE);
1000 return pStatus;
1001 }
1002 /**************************************************************************
1003 * If the compression bit is set, read the CPR.
1004 **************************************************************************/
1005 if (VARcompressionBITset(flags)) {
1006 if (!sX(ReadCPR(CDF->fp,PRoffset,
1007 CPR_RECORD,&CPR,
1008 CPR_NULL),&pStatus)) {
1009 AbortAccess (CDF, UPDATE, noDELETE);
1010 return pStatus;
1011 }
1012 *cType = CPR.cType;
1013 for (parmN = 0; parmN < CPR.pCount; parmN++) {
1014 cParms[parmN] = CPR.cParms[parmN];
1015 }
1016 if (!sX(CalcCompressionPct(CDF,VDRoffset,zVar,cPct),&pStatus)) {
1017 AbortAccess (CDF, UPDATE, noDELETE);
1018 return pStatus;
1019 }
1020 }
1021 else {
1022 *cType = NO_COMPRESSION;
1023 *cPct = 100;
1024 }
1025 break;
1026 }
1027 /****************************************************************************
1028 * rVAR_SPARSEARRAYS_/zVAR_SPARSEARRAYS_
1029 ****************************************************************************/
1030 case rVAR_SPARSEARRAYS_:
1031 case zVAR_SPARSEARRAYS_: {
1032 Logical zOp = (Va->item == zVAR_SPARSEARRAYS_), zVar;
1033 struct CDFstruct *CDF; /* struct VarStruct *Var; */ struct SPRstruct SPR;
1034 Int32 VDRoffset, PRoffset, flags; int parmN;
1035 long *sArraysType = va_arg (Va->ap, long *); /* Sparseness type. */
1036 long *sArraysParms = va_arg (Va->ap, long *); /* Sparseness parameters. */
1037 long *sArraysPct = va_arg (Va->ap, long *); /* Sparseness percentage. */
1038 /**************************************************************************
1039 * Select/validate/locate CDF and variable.
1040 **************************************************************************/
1041 SelectCDF (Cur->cdf, CDF)
1042 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
1043 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
1044
1045 zVar = CurrentVarMode(CDF,zOp);
1046 if (zModeON(CDF) || zVar) VDRoffset = CDF->CURzVarOffset;
1047 else VDRoffset = CDF->CURrVarOffset;
1048
1049 /**************************************************************************
1050 * Read fields from VDR.
1051 **************************************************************************/
1052 if (!sX(ReadVDR(CDF,CDF->fp,VDRoffset,zVar,
1053 VDR_FLAGS,&flags,
1054 VDR_CPRorSPR,&PRoffset,
1055 VDR_NULL),&pStatus)) {
1056 AbortAccess (CDF, UPDATE, noDELETE);
1057 return pStatus;
1058 }
1059 /**************************************************************************
1060 * If the sparse arrays bit is set, read the SPR.
1061 **************************************************************************/
1062 if (SPARSEarraysBITset(flags)) {
1063 if (!sX(ReadSPR(CDF->fp,PRoffset,
1064 SPR_RECORD,&SPR,
1065 SPR_NULL),&pStatus)) {
1066 AbortAccess (CDF, UPDATE, noDELETE);
1067 return pStatus;
1068 }
1069 *sArraysType = SPR.sArraysType;
1070 for (parmN = 0; parmN < SPR.pCount; parmN++) {
1071 sArraysParms[parmN] = SPR.sArraysParms[parmN];
1072 }
1073 *sArraysPct = 100;
1074 }
1075 else {
1076 *sArraysType = NO_SPARSEARRAYS;
1077 *sArraysPct = 100;
1078 }
1079 break;
1080 }
1081 /****************************************************************************
1082 * rVAR_SPARSERECORDS_/zVAR_SPARSERECORDS_
1083 ****************************************************************************/
1084 case rVAR_SPARSERECORDS_:
1085 case zVAR_SPARSERECORDS_: {
1086 Logical zOp = (Va->item == zVAR_SPARSERECORDS_), zVar;
1087 struct CDFstruct *CDF; /* struct VarStruct *Var; */
1088 Int32 VDRoffset, sRecords;
1089 long *sRecordsType = va_arg (Va->ap, long *);
1090 /**************************************************************************
1091 * Select/validate/locate CDF and variable.
1092 **************************************************************************/
1093 SelectCDF (Cur->cdf, CDF)
1094 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
1095 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
1096
1097 zVar = CurrentVarMode(CDF,zOp);
1098 if (zModeON(CDF) || zVar) VDRoffset = CDF->CURzVarOffset;
1099 else VDRoffset = CDF->CURrVarOffset;
1100
1101 /**************************************************************************
1102 * Read sparse records field from VDR.
1103 **************************************************************************/
1104 if (!sX(ReadVDR(CDF,CDF->fp,VDRoffset,zVar,
1105 VDR_sRECORDS,&sRecords,
1106 VDR_NULL),&pStatus)) {
1107 AbortAccess (CDF, UPDATE, noDELETE);
1108 return pStatus;
1109 }
1110 *sRecordsType = sRecords;
1111 break;
1112 }
1113 /****************************************************************************
1114 * rVAR_NUMBER_/zVAR_NUMBER_
1115 * Determines the variable number for a specified variable name.
1116 ****************************************************************************/
1117 case rVAR_NUMBER_:
1118 case zVAR_NUMBER_: {
1119 Logical zOp = (Va->item == zVAR_NUMBER_), zVar;
1120 struct CDFstruct *CDF;
1121 char *varName = va_arg (Va->ap, char *);
1122 long *varNum = va_arg (Va->ap, long *);
1123 Int32 varN, offset;
1124 SelectCDF (Cur->cdf, CDF)
1125 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
1126 tStatus = FindVarByName (CDF, varName, &offset, &zVar, NULL);
1127 switch (tStatus) {
1128 case CDF_OK:
1129 break;
1130 case NO_SUCH_VAR:
1131 return tStatus;
1132 default:
1133 if (!sX(tStatus,&pStatus)) {
1134 AbortAccess (CDF, UPDATE, noDELETE);
1135 return tStatus;
1136 }
1137 }
1138 if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
1139 VDR_NUM,&varN,
1140 VDR_NULL),&pStatus)) {
1141 AbortAccess (CDF, UPDATE, noDELETE);
1142 return pStatus;
1143 }
1144 if (zModeON(CDF))
1145 *varNum = BOO(zVar,CDF->NrVars,0) + varN;
1146 else
1147 if (zOp)
1148 if (zVar)
1149 *varNum = varN;
1150 else
1151 return NO_SUCH_VAR; /* Wrong type of variable. */
1152 else
1153 if (zVar)
1154 return NO_SUCH_VAR; /* Wrong type of variable. */
1155 else
1156 *varNum = varN;
1157 break;
1158 }
1159 /****************************************************************************
1160 * rVAR_BLOCKINGFACTOR_/zVAR_BLOCKINGFACTOR_,
1161 ****************************************************************************/
1162 case rVAR_BLOCKINGFACTOR_:
1163 case zVAR_BLOCKINGFACTOR_: {
1164 Logical zOp = (Va->item == zVAR_BLOCKINGFACTOR_), zVar;
1165 struct CDFstruct *CDF;
1166 long *nExtendRecs = va_arg (Va->ap, long *);
1167 Int32 tRecs, offset;
1168 SelectCDF (Cur->cdf, CDF)
1169 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
1170 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
1171
1172 zVar = CurrentVarMode(CDF,zOp);
1173 if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
1174 else offset = CDF->CURrVarOffset;
1175
1176 if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
1177 VDR_BLOCKING,&tRecs,
1178 VDR_NULL),&pStatus)) {
1179 AbortAccess (CDF, UPDATE, noDELETE);
1180 return pStatus;
1181 }
1182 *nExtendRecs = tRecs;
1183 break;
1184 }
1185 /****************************************************************************
1186 * rVAR_nINDEXRECORDS_/zVAR_nINDEXRECORDS_,
1187 * rVAR_nINDEXENTRIES_/zVAR_nINDEXENTRIES_,
1188 * rVAR_nINDEXLEVELS_/zVAR_nINDEXLEVELS_,
1189 ****************************************************************************/
1190 case rVAR_nINDEXRECORDS_:
1191 case zVAR_nINDEXRECORDS_:
1192 case rVAR_nINDEXENTRIES_:
1193 case zVAR_nINDEXENTRIES_:
1194 case rVAR_nINDEXLEVELS_:
1195 case zVAR_nINDEXLEVELS_: {
1196 Logical zOp = (Va->item == zVAR_nINDEXRECORDS_ ||
1197 Va->item == zVAR_nINDEXENTRIES_ ||
1198 Va->item == zVAR_nINDEXLEVELS_), zVar;
1199 struct CDFstruct *CDF; Int32 offset, count;
1200 long *countP = va_arg (Va->ap, long *);
1201 SelectCDF (Cur->cdf, CDF)
1202 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
1203 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
1204
1205 zVar = CurrentVarMode(CDF,zOp);
1206 if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
1207 else offset = CDF->CURrVarOffset;
1208
1209 /**************************************************************************
1210 * If a multi-file CDF, pass back a count of zero (0) and an info/warning
1211 * status code. If a single-file CDF, scan through the linked list of VXRs
1212 * counting the parameter requested.
1213 **************************************************************************/
1214 if (!CDF->singleFile) {
1215 count = 0;
1216 sX (MULTI_FILE_FORMAT, &pStatus);
1217 }
1218 else {
1219 switch (Va->item) {
1220 case rVAR_nINDEXRECORDS_:
1221 case zVAR_nINDEXRECORDS_:
1222 if (!sX(IndexingStatistics(CDF,offset,zVar,
1223 &count,NULL,NULL,
1224 NULL,NULL),&pStatus)) return pStatus;
1225 break;
1226 case rVAR_nINDEXENTRIES_:
1227 case zVAR_nINDEXENTRIES_:
1228 if (!sX(IndexingStatistics(CDF,offset,zVar,
1229 NULL,&count,NULL,
1230 NULL,NULL),&pStatus)) return pStatus;
1231 break;
1232 case rVAR_nINDEXLEVELS_:
1233 case zVAR_nINDEXLEVELS_:
1234 if (!sX(IndexingStatistics(CDF,offset,zVar,
1235 NULL,NULL,NULL,
1236 NULL,&count),&pStatus)) return pStatus;
1237 break;
1238 }
1239 }
1240 ASSIGNnotNULL (countP, count)
1241 break;
1242 }
1243 /****************************************************************************
1244 * rVAR_PADVALUE_/zVAR_PADVALUE_
1245 ****************************************************************************/
1246 case rVAR_PADVALUE_:
1247 case zVAR_PADVALUE_: {
1248 Logical zOp = (Va->item == zVAR_PADVALUE_), zVar;
1249 struct CDFstruct *CDF;
1250 void *padValue = va_arg (Va->ap, void *);
1251 Int32 offset, dataType, numElems, flags;
1252 SelectCDF (Cur->cdf, CDF)
1253 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
1254 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
1255
1256 zVar = CurrentVarMode(CDF,zOp);
1257 if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
1258 else offset = CDF->CURrVarOffset;
1259
1260 if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
1261 VDR_FLAGS,&flags,
1262 VDR_DATATYPE,&dataType,
1263 VDR_NUMELEMS,&numElems,
1264 VDR_NULL),&pStatus)) {
1265 AbortAccess (CDF, UPDATE, noDELETE);
1266 return pStatus;
1267 }
1268
1269 /**********************************************************************
1270 The length of the pad value for a CDF_CHAR variable is the
1271 length of the variable (i.e. CHAR/162, etc.). If the length
1272 of the pad value is greater than 16, it causes segmentation fault
1273 for the IDL CDF interface routine.
1274 ***********************************************************************/
1275 if (dataType == CDF_CHAR || dataType == CDF_UCHAR)
1276 numElems = 1;
1277
1278 if (PADvalueBITset(flags)) {
1279 if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
1280 VDR_PADVALUE,padValue,
1281 VDR_NULL),&pStatus)) {
1282 AbortAccess (CDF, UPDATE, noDELETE);
1283 return pStatus;
1284 }
1285 if (!sX(ConvertBuffer(CDF->encoding,CDF->decoding,
1286 CDF->negToPosFp0,dataType,
1287 numElems,padValue,padValue),&pStatus)) {
1288 AbortAccess (CDF, UPDATE, noDELETE);
1289 return pStatus;
1290 }
1291 }
1292 else {
1293 DefaultPadValue (dataType, numElems, padValue);
1294 if (!sX(ConvertBuffer(HostEncoding(),CDF->decoding,
1295 CDF->negToPosFp0,dataType,
1296 numElems,padValue,padValue),&pStatus)) {
1297 AbortAccess (CDF, UPDATE, noDELETE);
1298 return pStatus;
1299 }
1300 sX (NO_PADVALUE_SPECIFIED, &pStatus);
1301 }
1302 break;
1303 }
1304 /****************************************************************************
1305 * rVAR_DATA_/zVAR_DATA_,
1306 ****************************************************************************/
1307 case rVAR_DATA_:
1308 case zVAR_DATA_: {
1309 Logical zOp = (Va->item == zVAR_DATA_);
1310 struct CDFstruct *CDF; struct VarStruct *Var;
1311 Int32 phyRecNum, offset; struct rdSTRUCT *rd;
1312 char *value = va_arg (Va->ap, char *);
1313 SelectCDF (Cur->cdf, CDF)
1314 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
1315 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
1316 if (!sX(InitCurrentVar(CDF,zOp,&Var),&pStatus)) {
1317 AbortAccess (CDF, UPDATE, noDELETE);
1318 return pStatus;
1319 }
1320 rd = BOO(zModeON(CDF),&(Var->zRD),BOO(zOp,&(Var->zRD),&(CDF->rRD)));
1321 if (!CDF->singleFile && Var->fp == NULL) {
1322 if (!sX(OpenVar(CDF,Var),&pStatus)) {
1323 AbortAccess (CDF, UPDATE, noDELETE);
1324 return pStatus;
1325 }
1326 }
1327 phyRecNum = BOO(Var->recVary,rd->recNumber,0);
1328 offset = IndicesValueOffset(Var->numDims,
1329 rd->dimIndices,
1330 Var->dimVarys,
1331 Var->nPhyDimValues) * Var->NvalueBytes;
1332 if (!sX(ReadVarValues(CDF,Var,phyRecNum,
1333 offset,INT32_ONE,value),&pStatus)) {
1334 AbortAccess (CDF, UPDATE, noDELETE);
1335 return pStatus;
1336 }
1337 Var->accessed_at = CDF->pseudo_clock++;
1338 break;
1339 }
1340 /****************************************************************************
1341 * rVAR_HYPERDATA_/zVAR_HYPERDATA_,
1342 ****************************************************************************/
1343 case rVAR_HYPERDATA_:
1344 case zVAR_HYPERDATA_: {
1345 Logical zOp = (Va->item == zVAR_HYPERDATA_);
1346 struct CDFstruct *CDF;
1347 struct VarStruct *Var;
1348 int dimN;
1349 struct rdSTRUCT *rd;
1350 #if LIMITof64K
1351 long Nvalues, Nbytes;
1352 #endif
1353 char *buffer = va_arg (Va->ap, char *);
1354 SelectCDF (Cur->cdf, CDF)
1355 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
1356 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
1357
1358 if (!sX(InitCurrentVar(CDF,zOp,&Var),&pStatus)) {
1359 AbortAccess (CDF, UPDATE, noDELETE);
1360 return pStatus;
1361 }
1362 rd = BOO(zModeON(CDF),&(Var->zRD),BOO(zOp,&(Var->zRD),&(CDF->rRD)));
1363 for (dimN = 0; dimN < Var->numDims; dimN++) {
1364 long maxIndex = rd->dimIndices[dimN] +
1365 ((rd->dimCounts[dimN] - 1) * rd->dimIntervals[dimN]);
1366 if (maxIndex >= Var->dimSizes[dimN]) return BAD_DIM_INDEX;
1367 }
1368 #if LIMITof64K
1369 Nvalues = rd->recCount;
1370 for (dimN = 0; dimN < Var->numDims; dimN++) Nvalues *= rd->dimCounts[dimN];
1371 Nbytes = Nvalues * Var->NvalueBytes;
1372 if (TOObigIBMpc(Nbytes)) return IBM_PC_OVERFLOW;
1373 #endif
1374 if (!CDF->singleFile && Var->fp == NULL) {
1375 if (!sX(OpenVar(CDF,Var),&pStatus)) {
1376 AbortAccess (CDF, UPDATE, noDELETE);
1377 return pStatus;
1378 }
1379 }
1380 if (!sX(HyperRead(CDF,Var,rd,buffer),&pStatus)) {
1381 AbortAccess (CDF, UPDATE, noDELETE);
1382 return pStatus;
1383 }
1384 Var->accessed_at = CDF->pseudo_clock++;
1385 break;
1386 }
1387 /****************************************************************************
1388 * rVAR_SEQDATA_/zVAR_SEQDATA_,
1389 ****************************************************************************/
1390 case rVAR_SEQDATA_:
1391 case zVAR_SEQDATA_: {
1392 Logical zOp = (Va->item == zVAR_SEQDATA_);
1393 struct CDFstruct *CDF; struct VarStruct *Var; Int32 recNum, offset;
1394 void *value = va_arg (Va->ap, char *);
1395 SelectCDF (Cur->cdf, CDF)
1396 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
1397 if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
1398 if (!sX(InitCurrentVar(CDF,zOp,&Var),&pStatus)) {
1399 AbortAccess (CDF, UPDATE, noDELETE);
1400 return pStatus;
1401 }
1402 if (!CDF->singleFile && Var->fp == NULL) {
1403 if (!sX(OpenVar(CDF,Var),&pStatus)) {
1404 AbortAccess (CDF, UPDATE, noDELETE);
1405 return pStatus;
1406 }
1407 }
1408 recNum = Var->seqValueOffset / Var->NphyRecValues;
1409 if (recNum > Var->maxRec) return END_OF_VAR;
1410 offset = (Var->seqValueOffset % Var->NphyRecValues) * Var->NvalueBytes;
1411 if (!sX(ReadVarValues(CDF,Var,recNum,offset,INT32_ONE,value),&pStatus)) {
1412 AbortAccess (CDF, UPDATE, noDELETE);
1413 return pStatus;
1414 }
1415 Var->seqValueOffset++;
1416 Var->accessed_at = CDF->pseudo_clock++;
1417 break;
1418 }
1419 /****************************************************************************
1420 * rVARs_RECDATA_/zVARs_RECDATA_
1421 * Read data records for up to all of the rVariables/zVariables.
1422 ****************************************************************************/
1423 case rVARs_RECDATA_:
1424 case zVARs_RECDATA_: {
1425 Logical zOp = (Va->item == zVARs_RECDATA_), zVar;
1426 struct VarStruct *Var; struct CDFstruct *CDF;
1427 Int32 recNum, varNt; Byte *tBuffer; int varX;
1428 long nVars = va_arg (Va->ap, long);
1429 long *varNs = va_arg (Va->ap, long *);
1430 void *buffer = va_arg (Va->ap, char *);
1431 #if LIMITof64K
1432 long nBytes;
1433 #endif
1434 SelectCDF (Cur->cdf, CDF)
1435 if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
1436 if (nVars < 1) return BAD_NUM_VARS;
1437 for (varX = 0; varX < nVars; varX++) {
1438 if (!sX(VarIdentity(CDF,(Int32)varNs[varX],
1439 zOp,&varNt,&zVar,NULL),&pStatus)) {
1440 return pStatus;
1441 }
1442 if (!sX(InitVar(CDF,varNt,zVar,NULL),&pStatus)) {
1443 AbortAccess (CDF, UPDATE, noDELETE);
1444 return pStatus;
1445 }
1446 }
1447 #if LIMITof64K
1448 for (varX = 0, nBytes = 0; varX < nVars; varX++) {
1449 if (!sX(VarIdentity(CDF,varNs[varX],zOp,NULL,NULL,&Var),&pStatus)) {
1450 return pStatus;
1451 }
1452 nBytes += Var->NphyRecBytes;
1453 }
1454 if (TOObigIBMpc(nBytes)) return IBM_PC_OVERFLOW;
1455 #endif
1456 for (varX = 0, tBuffer = buffer; varX < nVars; varX++) {
1457 if (!sX(VarIdentity(CDF,(Int32)varNs[varX],
1458 zOp,NULL,NULL,&Var),&pStatus)) {
1459 return pStatus;
1460 }
1461 if (!CDF->singleFile && Var->fp == NULL) {
1462 if (!sX(OpenVar(CDF,Var),&pStatus)) {
1463 AbortAccess (CDF, UPDATE, noDELETE);
1464 return pStatus;
1465 }
1466 }
1467 recNum = BOO(Var->recVary,BOO(zOp,Var->zRD.recNumber,
1468 CDF->rRD.recNumber),0);
1469 if (!sX(ReadVarValues(CDF,Var,recNum,INT32_ZERO,
1470 Var->NphyRecValues,tBuffer),&pStatus)) {
1471 AbortAccess (CDF, UPDATE, noDELETE);
1472 return pStatus;
1473 }
1474 tBuffer += (size_t) Var->NphyRecBytes;
1475 Var->accessed_at = CDF->pseudo_clock++;
1476 }
1477
1478 break;
1479 }
1480 /****************************************************************************
1481 * ATTR_NAME_,
1482 * Note that a temporary variable is used when reading the attribute name.
1483 * This is because the caller may have only allocated enough memory for the
1484 * size name they expect (ie., less than CDF_ATTR_NAME_LEN characters). Since
1485 * the attribute name is NUL-terminated in the CDF, only the actual characters
1486 * of the name will be copied to the caller's buffer.
1487 ****************************************************************************/
1488 case ATTR_NAME_: {
1489 struct CDFstruct *CDF;
1490 char *attrName = va_arg (Va->ap, char *), tName[CDF_ATTR_NAME_LEN+1];
1491 SelectCDF (Cur->cdf, CDF)
1492 if (!CURRENTattrSELECTED(CDF)) return NO_ATTR_SELECTED;
1493 if (!sX(ReadADR(CDF->fp,CDF->CURattrOffset,
1494 ADR_NAME,tName,
1495 ADR_NULL),&pStatus)){
1496 AbortAccess (CDF, UPDATE, noDELETE);
1497 return pStatus;
1498 }
1499 strcpyX (attrName, tName, CDF_ATTR_NAME_LEN);
1500 break;
1501 }
1502 /****************************************************************************
1503 * ATTR_NUMBER_,
1504 ****************************************************************************/
1505 case ATTR_NUMBER_: {
1506 struct CDFstruct *CDF;
1507 char *attrName = va_arg (Va->ap, char *);
1508 long *attrNum = va_arg (Va->ap, long *);
1509 Int32 attrNumT, offset;
1510 SelectCDF (Cur->cdf, CDF)
1511 tStatus = FindAttrByName (CDF, attrName, &offset);
1512 switch (tStatus) {
1513 case CDF_OK:
1514 break;
1515 case NO_SUCH_ATTR:
1516 return tStatus;
1517 default:
1518 if (!sX(tStatus,&pStatus)) {
1519 AbortAccess (CDF, UPDATE, noDELETE);
1520 return tStatus;
1521 }
1522 }
1523 if (!sX(ReadADR(CDF->fp,offset,
1524 ADR_NUM,&attrNumT,
1525 ADR_NULL),&pStatus)) {
1526 AbortAccess (CDF, UPDATE, noDELETE);
1527 return pStatus;
1528 }
1529 *attrNum = attrNumT;
1530 break;
1531 }
1532 /****************************************************************************
1533 * ATTR_SCOPE_,
1534 ****************************************************************************/
1535 case ATTR_SCOPE_: {
1536 struct CDFstruct *CDF;
1537 long *scope = va_arg (Va->ap, long *);
1538 Int32 tScope;
1539 SelectCDF (Cur->cdf, CDF)
1540 if (!CURRENTattrSELECTED(CDF)) return NO_ATTR_SELECTED;
1541 if (!sX(ReadADR(CDF->fp,CDF->CURattrOffset,
1542 ADR_SCOPE,&tScope,
1543 ADR_NULL),&pStatus)) {
1544 AbortAccess (CDF, UPDATE, noDELETE);
1545 return pStatus;
1546 }
1547 *scope = DEFINITEscope(tScope);
1548 break;
1549 }
1550 /****************************************************************************
1551 * ATTR_MAXgENTRY_/ATTR_MAXrENTRY_/ATTR_MAXzENTRY_
1552 * ATTR_NUMgENTRIES_/ATTR_NUMrENTRIES_/ATTR_NUMzENTRIES_
1553 ****************************************************************************/
1554 case ATTR_MAXgENTRY_:
1555 case ATTR_NUMgENTRIES_:
1556 case ATTR_MAXrENTRY_:
1557 case ATTR_NUMrENTRIES_:
1558 case ATTR_MAXzENTRY_:
1559 case ATTR_NUMzENTRIES_: {
1560 Logical maxOp = ONEof3(Va->item,ATTR_MAXgENTRY_,
1561 ATTR_MAXrENTRY_,
1562 ATTR_MAXzENTRY_);
1563 int entryType = BOO(maxOp,E3p(Va->item,ATTR_MAXgENTRY_,
1564 ATTR_MAXrENTRY_,
1565 ATTR_MAXzENTRY_),
1566 E3p(Va->item,ATTR_NUMgENTRIES_,
1567 ATTR_NUMrENTRIES_,
1568 ATTR_NUMzENTRIES_));
1569 struct CDFstruct *CDF;
1570 long *value = va_arg (Va->ap, long *);
1571 Int32 scope, gr, z;
1572 SelectCDF (Cur->cdf, CDF)
1573 if (!CURRENTattrSELECTED(CDF)) return NO_ATTR_SELECTED;
1574 if (!sX(ReadADR(CDF->fp,CDF->CURattrOffset,
1575 ADR_SCOPE,&scope,
1576 ADR_NULL),&pStatus)) {
1577 AbortAccess (CDF, UPDATE, noDELETE);
1578 return pStatus;
1579 }
1580 if (GLOBALscope(scope)) {
1581 if (entryType != gENTRYt) return ILLEGAL_FOR_SCOPE;
1582 }
1583 else {
1584 if (entryType == gENTRYt) return ILLEGAL_FOR_SCOPE;
1585 }
1586 if (!sX(ReadADR(CDF->fp,CDF->CURattrOffset,
1587 BOO(maxOp,ADR_MAXgrENTRY,ADR_NgrENTRIES),&gr,
1588 BOO(maxOp,ADR_MAXzENTRY,ADR_NzENTRIES),&z,
1589 ADR_NULL),&pStatus)) {
1590 AbortAccess (CDF, UPDATE, noDELETE);
1591 return pStatus;
1592 }
1593 if (GLOBALscope(scope))
1594 *value = (long) gr;
1595 else
1596 if (zModeON(CDF))
1597 if (entryType == rENTRYt)
1598 *value = (long) BOO(maxOp,NO_ENTRY,0);
1599 /* Never any rEntries in zMode. */
1600 else
1601 *value = (long) BOO(maxOp,BOO(z > NO_ENTRY,CDF->NrVars+z,gr),gr+z);
1602 else
1603 *value = (long) E3(entryType,BOO(maxOp,NO_ENTRY,0),gr,z);
1604 break;
1605 }
1606 /****************************************************************************
1607 * gENTRY_DATATYPE_/rENTRY_DATATYPE_/zENTRY_DATATYPE_
1608 * gENTRY_NUMELEMS_/rENTRY_NUMELEMS_/zENTRY_NUMELEMS_
1609 * If this CDF is prior to CDF V2.1.1, the current attribute is named
1610 * "VALIDMIN", "VALIDMAX", "SCALEMIN", or "SCALEMAX", this is a true rEntry,
1611 * and the rEntry corresponds to an rVariable named "EPOCH", then return
1612 * the CDF_EPOCH data type if the actual data type is CDF_REAL8 or CDF_DOUBLE.
1613 * (The CDF_EPOCH data type was not introduced until CDF V2.1.1). Note that
1614 * only rVariables were supported prior to CDF V2.3.
1615 ****************************************************************************/
1616 case gENTRY_DATATYPE_:
1617 case gENTRY_NUMELEMS_:
1618 case rENTRY_DATATYPE_:
1619 case rENTRY_NUMELEMS_:
1620 case zENTRY_DATATYPE_:
1621 case zENTRY_NUMELEMS_: {
1622 Logical dataOp = ONEof3(Va->item,gENTRY_DATATYPE_,
1623 rENTRY_DATATYPE_,
1624 zENTRY_DATATYPE_);
1625 int entryType = BOO(dataOp,E3p(Va->item,gENTRY_DATATYPE_,
1626 rENTRY_DATATYPE_,
1627 zENTRY_DATATYPE_),
1628 E3p(Va->item,gENTRY_NUMELEMS_,
1629 rENTRY_NUMELEMS_,
1630 zENTRY_NUMELEMS_));
1631 struct CDFstruct *CDF;
1632 long *value = va_arg (Va->ap, long *);
1633 Int32 tValue, eOffset;
1634 SelectCDF (Cur->cdf, CDF)
1635 if (!CURRENTattrSELECTED(CDF)) return NO_ATTR_SELECTED;
1636 if (E3(entryType,
1637 CDF->CURgrEntryNum,
1638 CDF->CURgrEntryNum,
1639 CDF->CURzEntryNum) == RESERVED_ENTRYNUM) return NO_ENTRY_SELECTED;
1640 if (!sX(CheckEntryOp(CDF,entryType),&pStatus)) return pStatus;
1641 eOffset = E3(entryType,CDF->CURgrEntryOffset,
1642 CDF->CURgrEntryOffset,
1643 CDF->CURzEntryOffset);
1644 if (eOffset == RESERVED_ENTRYOFFSET) return NO_SUCH_ENTRY;
1645 if (!sX(ReadAEDR(CDF->fp,eOffset,
1646 BOO(dataOp,AEDR_DATATYPE,AEDR_NUMELEMS),&tValue,
1647 AEDR_NULL),&pStatus)) {
1648 AbortAccess (CDF, UPDATE, noDELETE);
1649 return pStatus;
1650 }
1651 if (dataOp && CDF->fakeEPOCH) {
1652 char aName[CDF_ATTR_NAME_LEN+1];
1653 if (!sX(ReadADR(CDF->fp,CDF->CURattrOffset,
1654 ADR_NAME,aName,
1655 ADR_NULL),&pStatus)) {
1656 AbortAccess (CDF, UPDATE, noDELETE);
1657 return pStatus;
1658 }
1659 if (!strcmpITB(aName,"VALIDMIN") || !strcmpITB(aName,"VALIDMAX") ||
1660 !strcmpITB(aName,"SCALEMIN") || !strcmpITB(aName,"SCALEMAX")) {
1661 Int32 vOffset; char vName[CDF_VAR_NAME_LEN+1];
1662 tStatus = FindVarByNumber (CDF, E3(entryType, CDF->CURgrEntryNum,
1663 CDF->CURgrEntryNum,
1664 CDF->CURzEntryNum),
1665 FALSE, &vOffset);
1666 switch (tStatus) {
1667 case NO_SUCH_VAR:
1668 break;
1669 default:
1670 if (!sX(tStatus,&pStatus)) {
1671 AbortAccess (CDF, UPDATE, noDELETE);
1672 return tStatus;
1673 }
1674 if (!sX(ReadVDR(CDF,CDF->fp,vOffset,FALSE,
1675 VDR_NAME,vName,
1676 VDR_NULL),&pStatus)) {
1677 AbortAccess (CDF, UPDATE, noDELETE);
1678 return pStatus;
1679 }
1680 if (!strcmpITB(vName,"EPOCH") &&
1681 FLOAT8dataType(tValue)) tValue = CDF_EPOCH;
1682 if (!strcmpITB(vName,"EPOCH") &&
1683 FLOAT16dataType(tValue)) tValue = CDF_EPOCH16;
1684 break;
1685 }
1686 }
1687 }
1688 *value = tValue;
1689 break;
1690 }
1691 /****************************************************************************
1692 * gENTRY_DATA_/rENTRY_DATA_/zENTRY_DATA_,
1693 ****************************************************************************/
1694 case gENTRY_DATA_:
1695 case rENTRY_DATA_:
1696 case zENTRY_DATA_: {
1697 int entryType = E3p(Va->item,gENTRY_DATA_,rENTRY_DATA_,zENTRY_DATA_);
1698 struct CDFstruct *CDF;
1699 Int32 offset, dataType, numElems;
1700 void *value = va_arg (Va->ap, void *);
1701 SelectCDF (Cur->cdf, CDF)
1702 if (!CURRENTattrSELECTED(CDF)) return NO_ATTR_SELECTED;
1703 if (E3(entryType,
1704 CDF->CURgrEntryNum,
1705 CDF->CURgrEntryNum,
1706 CDF->CURzEntryNum) == RESERVED_ENTRYNUM) return NO_ENTRY_SELECTED;
1707 if (!sX(CheckEntryOp(CDF,entryType),&pStatus)) return pStatus;
1708 offset = E3(entryType,CDF->CURgrEntryOffset,
1709 CDF->CURgrEntryOffset,
1710 CDF->CURzEntryOffset);
1711 if (offset == RESERVED_ENTRYOFFSET) return NO_SUCH_ENTRY;
1712 if (!sX(ReadAEDR(CDF->fp,offset,
1713 AEDR_DATATYPE,&dataType,
1714 AEDR_NUMELEMS,&numElems,
1715 AEDR_VALUE,value,
1716 AEDR_NULL),&pStatus)) {
1717 AbortAccess (CDF, UPDATE, noDELETE);
1718 return pStatus;
1719 }
1720 if (!sX(ConvertBuffer(CDF->encoding,CDF->decoding,
1721 CDF->negToPosFp0,dataType,
1722 numElems,value,value),&pStatus)) {
1723 AbortAccess (CDF, UPDATE, noDELETE);
1724 return pStatus;
1725 }
1726 break;
1727 }
1728 /****************************************************************************
1729 * Unknown item, must be the next function.
1730 ****************************************************************************/
1731 default: {
1732 Va->fnc = Va->item;
1733 break;
1734 }
1735 }
1736 return pStatus;
1737 }
1738