1 /******************************************************************************
2 *
3 * NSSDC/CDF CDF library miscellaneous functions, part 2.
4 *
5 * Version 1.3b, 4-Mar-97, Hughes STX.
6 *
7 * Modification history:
8 *
9 * V1.0 15-Dec-94, J Love Original version.
10 * V1.1 6-Jan-95, J Love Encode/decode changes. More cache-residency.
11 * V1.1a 20-Jan-95, J Love IRIX 6.0 (64-bit).
12 * V1.1b 15-Mar-95, J Love Solaris 2.3 IDL i/f. Fixed `recNum' parameter
13 * of `LastAllocatedRecord'. Gnu C on OSF/1.
14 * V1.2 21-Mar-95, J Love POSIX.
15 * V1.2a 18-Apr-95, J Love More POSIX.
16 * V1.2b 13-Jun-95, J Love Linux.
17 * V1.2c 7-Sep-95, J Love CDFexport-related changes. Fixed possible
18 * memory leak.
19 * V1.3 5-Sep-96, J Love CDF V2.6.
20 * V1.3a 21-Feb-97, J Love Removed RICE.
21 * V1.3b 4-Mar-97, J Love Windows NT for MS Visual C/C++ on an IBM PC.
22 * V2.0 08-Apr-04, M Liu Modified LocateCurrentVar function to save
23 * the current selected variable's offset.
24 * Modified FindVarByNumber and FindVarByName
25 * functions to start searching for the variable
26 * from the current selected variable, if it's
27 * cwselected, instead of always from the
28 * beginning. Remove the calls to FindVarByNumber
29 * if a variable is already selected.
30 * V2.1 04-May-04, M Liu Corrected Int32ToCDFid and CDFidToInt32 to
31 * handle 64-bit for Solaris/sparc.
32 * V2.2 21-Jun-05, M Liu Corrected Int32ToCDFid and CDFidToInt32 to
33 * handle 64-bit Intel/AMD running Linux.
34 * V3.2 20-Jun-07, D Berger Modified the "FindAttr...", "FindEntry..."
35 * routines, and the "SetCUR..." routines and
36 * added ResetReadOnlyState to handle READONLYon
37 * mode.
38 *
39 ******************************************************************************/
40
41 #include "cdflib.h"
42
43 /******************************************************************************
44 * sX.
45 * Determine what should be done with a status code. For each call to
46 * `CDFlib', status is returned as follows...
47 *
48 * 1. The first ERROR encountered terminates the call and is returned. This
49 * routine will not overwrite an existing error code.
50 * 2. The last WARNING encountered is returned. INFOs encountered after a
51 * WARNING are ignored.
52 * 3. In the absence of any WARNINGs, the last INFO is returned.
53 * 4. In the absence of any WARNINGs or INFOs, CDF_OK is returned.
54 *
55 * This routine returns FALSE if the pending status code is an ERROR; otherwise
56 * it returns TRUE.
57 *
58 ******************************************************************************/
59
sX(cStatus,pStatus)60 STATICforIDL Logical sX (cStatus, pStatus)
61 CDFstatus cStatus; /* Status code to be checked. */
62 CDFstatus *pStatus; /* Pending status code. */
63 {
64 if (cStatus == CDF_OK) return TRUE; /* Ok, do nothing. */
65 if (cStatus < CDF_WARN) { /* Error. */
66 if (*pStatus > CDF_WARN) *pStatus = cStatus;
67 return FALSE;
68 }
69 if (cStatus > CDF_OK) { /* Info. */
70 if (CDF_OK <= *pStatus) *pStatus = cStatus;
71 return TRUE;
72 }
73 *pStatus = cStatus; /* Warning. */
74 return TRUE;
75 }
76
77 /******************************************************************************
78 * LocateCurrentVar.
79 ******************************************************************************/
80
LocateCurrentVar(CDF,zOp,offset,zVar,Var)81 STATICforIDL CDFstatus LocateCurrentVar (CDF, zOp, offset, zVar, Var)
82 struct CDFstruct *CDF; /* In: Pointer to CDF. */
83 Logical zOp; /* In: TRUE if current zVariable is to be
84 accessed; FALSE if current rVariable. N/A
85 if zMode is on (since the current zVariable
86 number will always be used). */
87 Int32 *offset; /* Out: Offset of the current variable's VDR.
88 This may be a NULL pointer. */
89 Logical *zVar; /* Out: TRUE if a true zVariable; FALSE if
90 a true rVariable. This may be a NULL
91 pointer. */
92 struct VarStruct **Var; /* Out: Pointer to variable. This will be NULL
93 if the variable has yet to be initialized.
94 This may be a NULL pointer. */
95 {
96 CDFstatus tStatus;
97 Int32 tOffset;
98 /****************************************************************************
99 * Pass back the offset of the VDR.
100 ****************************************************************************/
101 if (zModeON(CDF)) {
102 if (CDF->CURzVarNum < CDF->NrVars) {
103 ASSIGNnotNULL(zVar, FALSE)
104 tStatus = FindVarByNumber (CDF, CDF->CURzVarNum, FALSE, &tOffset);
105 if (StatusOK(tStatus)) {
106 ASSIGNnotNULL (Var, CDF->rVars[(int)CDF->CURzVarNum])
107 ASSIGNnotNULL (offset, tOffset)
108 CDF->CURzVarOffset = tOffset;
109 }
110 }
111 else {
112 ASSIGNnotNULL(zVar, TRUE)
113 tStatus = FindVarByNumber (CDF, CDF->CURzVarNum - CDF->NrVars, TRUE,
114 &tOffset);
115 if (StatusOK(tStatus)) {
116 ASSIGNnotNULL (Var, CDF->zVars[(int)(CDF->CURzVarNum - CDF->NrVars)])
117 ASSIGNnotNULL (offset, tOffset)
118 CDF->CURzVarOffset = tOffset;
119 }
120 }
121 }
122 else {
123 ASSIGNnotNULL (zVar, zOp)
124 tStatus = FindVarByNumber (CDF,BOO(zOp,CDF->CURzVarNum,
125 CDF->CURrVarNum),zOp,&tOffset);
126 if (StatusOK(tStatus)) {
127 ASSIGNnotNULL (Var, BOO(zOp,CDF->zVars[(int)CDF->CURzVarNum],
128 CDF->rVars[(int)CDF->CURrVarNum]))
129 ASSIGNnotNULL (offset, tOffset)
130 if (zOp)
131 CDF->CURzVarOffset = tOffset;
132 else
133 CDF->CURrVarOffset = tOffset;
134 }
135 }
136 return tStatus;
137 }
138
139 /******************************************************************************
140 * CurrentVarMode.
141 ******************************************************************************/
142
CurrentVarMode(CDF,zOp)143 STATICforIDL Logical CurrentVarMode (CDF, zOp)
144 struct CDFstruct *CDF; /* In: Pointer to CDF. */
145 Logical zOp; /* In: TRUE if current zVariable is to be
146 accessed; FALSE if current rVariable. N/A
147 if zMode is on (since the current zVariable
148 number will always be used). */
149 {
150
151 if (zModeON(CDF)) {
152 if (CDF->CURzVarNum < CDF->NrVars)
153 return FALSE;
154 else
155 return TRUE;
156 }
157 else
158 return zOp;
159 }
160
161 /******************************************************************************
162 * InitCurrentVar.
163 ******************************************************************************/
164
InitCurrentVar(CDF,zOp,Var)165 STATICforIDL CDFstatus InitCurrentVar (CDF, zOp, Var)
166 struct CDFstruct *CDF; /* In: Pointer to CDF. */
167 Logical zOp; /* In: TRUE if current zVariable is to be
168 accessed; FALSE if current rVariable. N/A
169 if zMode is on (since the current zVariable
170 number will always be used [even when a real
171 rVariable is being accessed]). */
172 struct VarStruct **Var; /* Out: Pointer to variable. */
173 {
174 CDFstatus tStatus;
175 /****************************************************************************
176 * Pass back the pointer to its variable structure. The variable will
177 * be initialized for access if necessary.
178 ****************************************************************************/
179 if (zModeON(CDF))
180 if (CDF->CURzVarNum < CDF->NrVars)
181 tStatus = InitVar (CDF, CDF->CURzVarNum, FALSE, Var);
182 else
183 tStatus = InitVar (CDF, CDF->CURzVarNum - CDF->NrVars, TRUE, Var);
184 else
185 tStatus = InitVar (CDF,BOO(zOp,CDF->CURzVarNum,CDF->CURrVarNum),zOp,Var);
186 return tStatus;
187 }
188
189 /******************************************************************************
190 * InitVar.
191 ******************************************************************************/
192
InitVar(CDF,varN,zVar,VarP)193 STATICforIDL CDFstatus InitVar (CDF, varN, zVar, VarP)
194 struct CDFstruct *CDF; /* In: Pointer to CDF. */
195 Int32 varN; /* In: Real variable number (ignoring the
196 zMode). */
197 Logical zVar; /* In: TRUE if a real zVariable (ignoring
198 the zMode). */
199 struct VarStruct **VarP; /* Out: Pointer to variable. */
200 {
201 CDFstatus pStatus = CDF_OK;
202 struct VarStruct *Var = BOO(zVar,CDF->zVars[(int)varN],
203 CDF->rVars[(int)varN]);
204 /****************************************************************************
205 * Check if the variable has already been initialized. If not, allocate and
206 * initialize its variable structure.
207 ****************************************************************************/
208 if (Var == NULL) {
209 /**************************************************************************
210 * Allocate a variable structure.
211 **************************************************************************/
212 Var = (struct VarStruct *) cdf_AllocateMemory (sizeof(struct VarStruct), NULL);
213 if (Var == NULL) return BAD_MALLOC;
214 /**************************************************************************
215 * Determine offset of the VDR in the dotCDF file.
216 **************************************************************************/
217 if (!sX(FindVarByNumber(CDF,varN,zVar,&(Var->VDRoffset)),&pStatus)) {
218 cdf_FreeMemory (Var, NULL);
219 return pStatus;
220 }
221
222 /**************************************************************************
223 * Initialize miscellaneous fields of the variable structure.
224 **************************************************************************/
225 Var->zVar = zVar;
226 Var->varN = varN;
227 Var->fp = NULL;
228 Var->varCacheSize = NUMcacheVAR; /* N/A if single-file CDF. */
229 Var->accessed_at = CDF->pseudo_clock++;
230 Var->firstRecInVVR = NO_RECORD;
231 Var->lastRecInVVR = NO_RECORD;
232 Var->offsetOfVVR = NO_OFFSET;
233 /**************************************************************************
234 * Read fields to be held in memory for efficiency.
235 **************************************************************************/
236 if (!sX(ReadVDR(CDF,CDF->fp,Var->VDRoffset,Var->zVar,
237 VDR_MAXREC,&(Var->maxRec),
238 VDR_NULL),&pStatus)) {
239 cdf_FreeMemory (Var, NULL);
240 return pStatus;
241 }
242 /**************************************************************************
243 * More initialization.
244 **************************************************************************/
245 if (!sX(InitVar2(CDF,Var),&pStatus)) {
246 cdf_FreeMemory (Var, NULL);
247 return pStatus;
248 }
249 /**************************************************************************
250 * Store pointer to variable structure.
251 **************************************************************************/
252 if (zVar)
253 CDF->zVars[(int)varN] = Var;
254 else
255 CDF->rVars[(int)varN] = Var;
256 }
257 /****************************************************************************
258 * Pass back pointer to variable.
259 ****************************************************************************/
260 ASSIGNnotNULL (VarP, Var)
261 return pStatus;
262 }
263
264 /******************************************************************************
265 * InitVar2.
266 ******************************************************************************/
267
InitVar2(CDF,Var)268 STATICforIDL CDFstatus InitVar2 (CDF, Var)
269 struct CDFstruct *CDF;
270 struct VarStruct *Var;
271 {
272 int dimN; CDFstatus pStatus = CDF_OK; struct CPRstruct CPR; int i;
273 Int32 flags, dataType, numElems, CPRoffset, sRecords;
274 /****************************************************************************
275 * Read necessary fields from the VDR.
276 ****************************************************************************/
277 if (!sX(ReadVDR(CDF,CDF->fp,Var->VDRoffset,Var->zVar,
278 VDR_FLAGS,&flags,
279 VDR_DATATYPE,&dataType,
280 VDR_NUMELEMS,&numElems,
281 VDR_sRECORDS,&sRecords,
282 VDR_NULL),&pStatus)) return pStatus;
283 /****************************************************************************
284 * Determine if the variable has a known data type.
285 ****************************************************************************/
286 if (!ValidDataType(dataType)) return BAD_DATA_TYPE;
287 /****************************************************************************
288 * Calculate the dimensionality and variances of the variable based on the
289 * current zMode.
290 ****************************************************************************/
291 if (!sX(CalcDimParms(CDF,Var->VDRoffset,
292 Var->zVar,&(Var->numDims),
293 Var->dimSizes,Var->dimVarys),&pStatus)) return pStatus;
294 Var->recVary = BOO(RECvaryBITset(flags),VARY,NOVARY);
295 /****************************************************************************
296 * Calculate the number of values for each dimension.
297 ****************************************************************************/
298 CalcNumDimValues (CDF, Var);
299 /****************************************************************************
300 * Calculate the element and value sizes.
301 ****************************************************************************/
302 Var->NvalueElems = numElems;
303 Var->NelemBytes = CDFelemSize (dataType);
304 Var->NvalueBytes = Var->NvalueElems * Var->NelemBytes;
305 /****************************************************************************
306 * Calculate the number of physical and virtual values per record.
307 ****************************************************************************/
308 CalcRecValues (Var);
309 /****************************************************************************
310 * Calculate the number of elements and the size (in bytes) of physical and
311 * conceptual records.
312 ****************************************************************************/
313 Var->NphyRecElems = Var->NphyRecValues * Var->NvalueElems;
314 Var->NvirtRecElems = Var->NvirtRecValues * Var->NvalueElems;
315 Var->NphyRecBytes = Var->NphyRecValues * Var->NvalueBytes;
316 Var->NvirtRecBytes = Var->NvirtRecValues * Var->NvalueBytes;
317 /**************************************************************************
318 * Initialize current positioning.
319 **************************************************************************/
320 Var->seqValueOffset = 0;
321 Var->zRD.recNumber = 0;
322 Var->zRD.recCount = 1;
323 Var->zRD.recInterval = 1;
324 for (dimN = 0; dimN < Var->numDims; dimN++) {
325 Var->zRD.dimIndices[dimN] = 0;
326 Var->zRD.dimCounts[dimN] = Var->dimSizes[dimN];
327 Var->zRD.dimIntervals[dimN] = 1;
328 }
329 /****************************************************************************
330 * Determine variable type.
331 ****************************************************************************/
332 if (!sX(VariableType(CDF,Var->VDRoffset,
333 Var->zVar,&(Var->vType)),&pStatus)) return pStatus;
334 /**************************************************************************
335 * What to do if a record is missing.
336 **************************************************************************/
337 Var->prevIfMissing = (sRecords == PREV_SPARSERECORDS);
338 /**************************************************************************
339 * Based on the variable type...
340 **************************************************************************/
341 switch (Var->vType) {
342 case STANDARD_:
343 case SPARSE_RECORDS_:
344 if (!sX(LastRecord(CDF,Var->VDRoffset,Var->zVar,
345 &(Var->maxAllocated)),&pStatus)) return pStatus;
346 Var->maxWritten = Var->maxAllocated;
347 break;
348 case COMPRESSED_:
349 case SPARSE_COMPRESSED_RECORDS_:
350 if (!sX(ReadVDR(CDF,CDF->fp,Var->VDRoffset,Var->zVar,
351 VDR_CPRorSPR,&CPRoffset,
352 VDR_NULL),&pStatus)) return pStatus;
353 if (!sX(ReadCPR(CDF->fp,CPRoffset,
354 CPR_RECORD,&CPR,
355 CPR_NULL),&pStatus)) return pStatus;
356 Var->cType = CPR.cType;
357 for (i = 0; i < CPR.pCount; i++) Var->cParms[i] = CPR.cParms[i];
358 Var->reservePct = 0;
359 break;
360 case SPARSE_ARRAYS_:
361 case SPARSE_RECORDS_AND_ARRAYS_:
362 return UNKNOWN_SPARSENESS;
363 case IN_MULTI_:
364 break;
365 default:
366 return CDF_INTERNAL_ERROR;
367 }
368 /**************************************************************************
369 * Initialize staging area (although n/a for most variable types).
370 **************************************************************************/
371 Var->stage.areaOffset = NO_OFFSET;
372 Var->stage.firstRec = NO_RECORD;
373 Var->stage.lastRec = NO_RECORD;
374 Var->stage.dotOffset = NO_OFFSET;
375 Var->stage.modified = FALSE;
376 /****************************************************************************
377 * Calculate the blocking factor based on variable type...
378 ****************************************************************************/
379 if (!sX(CalcBF(CDF,Var),&pStatus)) return pStatus;
380 /****************************************************************************
381 * Determine the encoding and decoding functions to be used.
382 ****************************************************************************/
383 if (!sX(ConversionFunction(dataType,HostEncoding(),
384 CDF->encoding,CDF->negToPosFp0,
385 &(Var->EncodeFunction)),&pStatus)) return pStatus;
386 if (!sX(ConversionFunction(dataType,CDF->encoding,
387 CDF->decoding,CDF->negToPosFp0,
388 &(Var->DecodeFunction)),&pStatus)) return pStatus;
389 return pStatus;
390 }
391
392 /******************************************************************************
393 * CalcRecValues.
394 ******************************************************************************/
395
CalcRecValues(Var)396 STATICforIDL void CalcRecValues (Var)
397 struct VarStruct *Var;
398 {
399 int dimN;
400 Var->NphyRecValues = 1;
401 Var->NvirtRecValues = 1;
402 for (dimN = 0; dimN < Var->numDims; dimN++) {
403 Var->NvirtRecValues *= Var->dimSizes[dimN];
404 if (Var->dimVarys[dimN]) Var->NphyRecValues *= Var->dimSizes[dimN];
405 }
406 return;
407 }
408
409 /******************************************************************************
410 * CalcNumDimValues.
411 ******************************************************************************/
412
CalcNumDimValues(CDF,Var)413 STATICforIDL void CalcNumDimValues (CDF, Var)
414 struct CDFstruct *CDF;
415 struct VarStruct *Var;
416 {
417 int dimN, dimNx;
418 if (!CDF->rowMajor) {
419 for (dimN = 0; dimN < Var->numDims; dimN++) {
420 Var->nPhyDimValues[dimN] = 1;
421 for (dimNx = 0; dimNx < dimN; dimNx++) {
422 if (Var->dimVarys[dimNx]) {
423 Var->nPhyDimValues[dimN] *= Var->dimSizes[dimNx];
424 }
425 }
426 }
427 }
428 else {
429 for (dimN = 0; dimN < Var->numDims; dimN++) {
430 Var->nPhyDimValues[dimN] = 1;
431 for (dimNx = dimN + 1; dimNx < Var->numDims; dimNx++) {
432 if (Var->dimVarys[dimNx]) {
433 Var->nPhyDimValues[dimN] *= Var->dimSizes[dimNx];
434 }
435 }
436 }
437 }
438 return;
439 }
440
441 /******************************************************************************
442 * CalcBF.
443 ******************************************************************************/
444
CalcBF(CDF,Var)445 STATICforIDL CDFstatus CalcBF (CDF, Var)
446 struct CDFstruct *CDF;
447 struct VarStruct *Var;
448 {
449 CDFstatus pStatus = CDF_OK; Int32 bF;
450 if (!sX(ReadVDR(CDF,CDF->fp,Var->VDRoffset,Var->zVar,
451 VDR_BLOCKING,&bF,
452 VDR_NULL),&pStatus)) return pStatus;
453 switch (Var->vType) {
454 case STANDARD_:
455 if (Var->recVary)
456 if (bF == 0) {
457 Int32 min = ((MIN_BLOCKING_BYTES_standard-1)/Var->NphyRecBytes)+1;
458 Var->blockingFactor = MAXIMUM(min,MIN_BLOCKING_RECS_standard);
459 }
460 else
461 Var->blockingFactor = bF;
462 else
463 Var->blockingFactor = 1;
464 break;
465 case SPARSE_RECORDS_:
466 if (Var->recVary)
467 if (bF == 0) {
468 Int32 min = ((MIN_BLOCKING_BYTES_sparse-1)/Var->NphyRecBytes)+1;
469 Var->blockingFactor = MAXIMUM(min,MIN_BLOCKING_RECS_sparse);
470 }
471 else
472 Var->blockingFactor = bF;
473 else
474 Var->blockingFactor = 1;
475 break;
476 case COMPRESSED_:
477 case SPARSE_COMPRESSED_RECORDS_:
478 Var->blockingFactor = bF;
479 break;
480 case SPARSE_ARRAYS_:
481 case SPARSE_RECORDS_AND_ARRAYS_:
482 return UNKNOWN_SPARSENESS;
483 case IN_MULTI_:
484 Var->blockingFactor = 1;
485 break;
486 default:
487 return CDF_INTERNAL_ERROR;
488 }
489 return pStatus;
490 }
491
492 /******************************************************************************
493 * UpdateConversions.
494 ******************************************************************************/
495
UpdateConversions(CDF)496 STATICforIDL CDFstatus UpdateConversions (CDF)
497 struct CDFstruct *CDF;
498 {
499 CDFstatus pStatus = CDF_OK; Logical zVar;
500 for (zVar = 0; zVar <= 1; zVar++) {
501 int varN; Int32 nVars = BOO(zVar,CDF->NzVars,CDF->NrVars);
502 for (varN = 0; varN < nVars; varN++) {
503 struct VarStruct *Var = BOO(zVar,CDF->zVars[varN],CDF->rVars[varN]);
504 if (Var != NULL) {
505 Int32 dataType;
506 if (!sX(ReadVDR(CDF,CDF->fp,Var->VDRoffset,Var->zVar,
507 VDR_DATATYPE,&dataType,
508 VDR_NULL),&pStatus)) return pStatus;
509 if (!sX(ConversionFunction(dataType,HostEncoding(),
510 CDF->encoding,CDF->negToPosFp0,
511 &(Var->EncodeFunction)),&pStatus)) return
512 pStatus;
513 if (!sX(ConversionFunction(dataType,CDF->encoding,
514 CDF->decoding,CDF->negToPosFp0,
515 &(Var->DecodeFunction)),&pStatus)) return
516 pStatus;
517 }
518 }
519 }
520 return pStatus;
521 }
522
523 /******************************************************************************
524 * UpdateNEWzMode.
525 ******************************************************************************/
526
UpdateNEWzMode(CDF)527 STATICforIDL CDFstatus UpdateNEWzMode (CDF)
528 struct CDFstruct *CDF;
529 {
530 CDFstatus pStatus = CDF_OK; Logical zVar;
531 for (zVar = 0; zVar <= 1; zVar++) {
532 int varN; Int32 nVars = BOO(zVar,CDF->NzVars,CDF->NrVars);
533 for (varN = 0; varN < nVars; varN++) {
534 struct VarStruct *Var = BOO(zVar,CDF->zVars[varN],CDF->rVars[varN]);
535 if (Var != NULL) {
536 if (!sX(CalcDimParms(CDF,Var->VDRoffset,
537 Var->zVar,&(Var->numDims),
538 Var->dimSizes,
539 Var->dimVarys),&pStatus)) return pStatus;
540 CalcNumDimValues (CDF, Var);
541 CalcRecValues (Var);
542 Var->NvirtRecElems = Var->NvirtRecValues * Var->NvalueElems;
543 Var->NvirtRecBytes = Var->NvirtRecValues * Var->NvalueBytes;
544 }
545 }
546 }
547 return pStatus;
548 }
549
550 /******************************************************************************
551 * VarIdentity.
552 * Returns information about the real identity of a variable.
553 ******************************************************************************/
554
VarIdentity(CDF,varN,zOp,varNt,zVar,Var)555 STATICforIDL CDFstatus VarIdentity (CDF, varN, zOp, varNt, zVar, Var)
556 struct CDFstruct *CDF; /* In: Pointer to CDF. */
557 Int32 varN; /* In: Variable number - zModed. */
558 Logical zOp; /* In: TRUE if zVariable; FALSE if rVariable.
559 This is also zModed. */
560 Int32 *varNt; /* Out: Real variable number. */
561 Logical *zVar; /* Out: Real variable type: TRUE if a
562 zVariable; FALSE if an rVariable. */
563 struct VarStruct **Var; /* Out: Pointer to variable. */
564 {
565 if (zModeON(CDF))
566 if (0 <= varN && varN < CDF->NrVars) {
567 ASSIGNnotNULL (varNt, varN)
568 ASSIGNnotNULL (zVar, FALSE)
569 ASSIGNnotNULL (Var, CDF->rVars[(int)varN])
570 }
571 else
572 if (varN < CDF->NrVars + CDF->NzVars) {
573 ASSIGNnotNULL (varNt, varN - CDF->NrVars)
574 ASSIGNnotNULL (zVar, TRUE)
575 ASSIGNnotNULL (Var, CDF->zVars[(int)varN])
576 }
577 else
578 return NO_SUCH_VAR;
579 else
580 if (0 <= varN && varN < BOO(zOp,CDF->NzVars,CDF->NrVars)) {
581 ASSIGNnotNULL (varNt, varN)
582 ASSIGNnotNULL (zVar, zOp)
583 ASSIGNnotNULL (Var, BOO(zOp,CDF->zVars[(int)varN],
584 CDF->rVars[(int)varN]))
585 }
586 else
587 return NO_SUCH_VAR;
588 return CDF_OK;
589 }
590
591 /******************************************************************************
592 * OpenVar.
593 * Open a variable for read and/or write access (if this is a multi-file CDF
594 * and the variable file is closed). It is assumed that the variable has been
595 * initialized for access and that the variable is closed (and in a multi-file
596 * CDF).
597 ******************************************************************************/
598
OpenVar(CDF,Var)599 STATICforIDL CDFstatus OpenVar (CDF, Var)
600 struct CDFstruct *CDF;
601 struct VarStruct *Var;
602 {
603 CDFstatus pStatus = CDF_OK;
604 char a_mode[MAX_aMODE_LEN+1], pathname[DU_MAX_PATH_LEN+1];
605 /****************************************************************************
606 * Try to open the variable file.
607 ****************************************************************************/
608 BuildFilePath (BOO(Var->zVar,Zt,Vt), CDF->CDFname, CDF->no_append,
609 CDF->upper_case_ext, CDF->version_numbers, Var->varN,
610 pathname);
611 if (CDF->status == READ_WRITE)
612 strcpyX (a_mode, READ_PLUS_a_mode, MAX_aMODE_LEN);
613 else
614 strcpyX (a_mode, READ_ONLY_a_mode, MAX_aMODE_LEN);
615 Var->fp = V_open (pathname, a_mode);
616 /****************************************************************************
617 * If the open failed, close a variable file and try. If that attempt fails
618 * return an error.
619 ****************************************************************************/
620 if (Var->fp == NULL) {
621 if (!sX(CloseLRUvar(CDF),&pStatus)) return pStatus;
622 Var->fp = V_open (pathname, a_mode);
623 if (Var->fp == NULL) return VAR_OPEN_ERROR;
624 }
625 /****************************************************************************
626 * The open was successful - try to set the proper cache size.
627 ****************************************************************************/
628 if (!CACHEv(Var->fp,Var->varCacheSize)) {
629 V_close (Var->fp, NULL, NULL);
630 Var->fp = NULL;
631 return BAD_CACHE_SIZE;
632 }
633 return pStatus;
634 }
635
636 /******************************************************************************
637 * LastRecord.
638 ******************************************************************************/
639
LastRecord(CDF,VDRoffset,zVar,recNum)640 STATICforIDL CDFstatus LastRecord (CDF, VDRoffset, zVar, recNum)
641 struct CDFstruct *CDF; /* In: Pointer to CDF. */
642 Int32 VDRoffset; /* In: Offset of VDR. */
643 Logical zVar; /* In: TRUE if a real zVariable; FALSE if rVariable. */
644 Int32 *recNum; /* Out: Last record allocated. */
645 {
646 CDFstatus pStatus = CDF_OK;
647 Int32 VXRoffset, nUsedEntries, lastRecs[MAX_VXR_ENTRIES];
648 if (!sX(ReadVDR(CDF,CDF->fp,VDRoffset,zVar,
649 VDR_VXRTAIL,&VXRoffset,
650 VDR_NULL),&pStatus)) return pStatus;
651 if (VXRoffset == 0)
652 *recNum = NO_RECORD;
653 else {
654 if (!sX(ReadVXR(CDF->fp,VXRoffset,
655 VXR_NUSEDENTRIES,&nUsedEntries,
656 VXR_LASTREC,lastRecs,
657 VXR_NULL),&pStatus)) return pStatus;
658 if ((int)nUsedEntries > MAX_VXR_ENTRIES) return CORRUPTED_V2_CDF;
659 *recNum = lastRecs[(int)(nUsedEntries-1)];
660 }
661 return pStatus;
662 }
663
664 /******************************************************************************
665 * IndicesValueOffset.
666 ******************************************************************************/
667
IndicesValueOffset(numDims,dimIndices,dimVarys,nPhyDimValues)668 STATICforIDL Int32 IndicesValueOffset (numDims, dimIndices, dimVarys,
669 nPhyDimValues)
670 Int32 numDims;
671 Int32 *dimIndices;
672 Int32 *dimVarys;
673 Int32 *nPhyDimValues;
674 {
675 Int32 offset = 0; int dimN;
676 for (dimN = 0; dimN < numDims; dimN++) {
677 if (dimVarys[dimN]) offset += (dimIndices[dimN] * nPhyDimValues[dimN]);
678 }
679 return offset;
680 }
681
682 /******************************************************************************
683 * ValueOffsetIndices.
684 ******************************************************************************/
685
ValueOffsetIndices(offset,rowMajor,numDims,dimVarys,nPhyDimValues,indices)686 STATICforIDL void ValueOffsetIndices (offset, rowMajor, numDims, dimVarys,
687 nPhyDimValues, indices)
688 Int32 offset;
689 Logical rowMajor;
690 Int32 numDims;
691 Int32 *dimVarys;
692 Int32 *nPhyDimValues;
693 Int32 *indices;
694 {
695 int dimN, i;
696 for (i = 0, dimN = BOO(rowMajor,0,(int)(numDims-1));
697 i < numDims; i++, BOO(rowMajor,dimN++,dimN--)) {
698 if (dimVarys[dimN]) {
699 indices[dimN] = offset / nPhyDimValues[dimN];
700 offset = offset % nPhyDimValues[dimN];
701 }
702 else
703 indices[dimN] = 0;
704 }
705 return;
706 }
707
708 /******************************************************************************
709 * RecordByteOffset.
710 ******************************************************************************/
711
RecordByteOffset(CDF,Var,phyRecN,offsetP)712 STATICforIDL CDFstatus RecordByteOffset (CDF, Var, phyRecN, offsetP)
713 struct CDFstruct *CDF;
714 struct VarStruct *Var;
715 Int32 phyRecN;
716 Int32 *offsetP;
717 {
718 CDFstatus pStatus = CDF_OK;
719 Int32 firstRec=-1, lastRec=-1, offset=-1;
720 switch (Var->vType) {
721 case STANDARD_:
722 case SPARSE_RECORDS_: {
723 if (Var->firstRecInVVR <= phyRecN && phyRecN <= Var->lastRecInVVR) {
724 *offsetP = (Int32) (Var->offsetOfVVR + VVR_BASE_SIZE +
725 (Var->NphyRecBytes * (phyRecN - Var->firstRecInVVR)));
726 break;
727 }
728 else {
729 if (!sX(SearchForRecord(CDF,Var->VDRoffset,Var->zVar,
730 phyRecN,&firstRec,&lastRec,
731 &offset,NULL),&pStatus)) return pStatus;
732 *offsetP = (Int32) (offset + VVR_BASE_SIZE +
733 (Var->NphyRecBytes * (phyRecN - firstRec)));
734 Var->firstRecInVVR = firstRec;
735 Var->lastRecInVVR = lastRec;
736 Var->offsetOfVVR = offset;
737 break;
738 }
739 }
740 case COMPRESSED_:
741 case SPARSE_COMPRESSED_RECORDS_:
742 case SPARSE_ARRAYS_:
743 case SPARSE_RECORDS_AND_ARRAYS_:
744 return CDF_INTERNAL_ERROR;
745 case IN_MULTI_:
746 *offsetP = (Int32) (phyRecN * Var->NphyRecBytes);
747 break;
748 default:
749 return CDF_INTERNAL_ERROR;
750 }
751 return pStatus;
752 }
753
754 /******************************************************************************
755 * ConfigureNEWzMode.
756 ******************************************************************************/
757
ConfigureNEWzMode(CDF)758 STATICforIDL CDFstatus ConfigureNEWzMode (CDF)
759 struct CDFstruct *CDF;
760 {
761 CDFstatus pStatus = CDF_OK;
762 if (!sX(UpdateNEWzMode(CDF),&pStatus)) return pStatus;
763 InitCURobjectsStates (CDF);
764 return pStatus;
765 }
766
767 /******************************************************************************
768 * InitCURobjectsStates.
769 * Note that initializing is done regardless of the current zMode.
770 ******************************************************************************/
771
InitCURobjectsStates(CDF)772 STATICforIDL void InitCURobjectsStates (CDF)
773 struct CDFstruct *CDF;
774 {
775 struct VarStruct *Var; int dimN, varNum;
776 /****************************************************************************
777 * Initialize current attributes/entries/variables.
778 ****************************************************************************/
779 CDF->CURattrOffset = RESERVED_ATTROFFSET;
780 CDF->CURattrOffset64 = (OFF_T) RESERVED_ATTROFFSET;
781 CDF->CURgrEntryNum = RESERVED_ENTRYNUM;
782 CDF->CURgrEntryOffset = RESERVED_ENTRYOFFSET;
783 CDF->CURgrEntryOffset64 = (OFF_T) RESERVED_ENTRYOFFSET;
784 CDF->CURzEntryNum = RESERVED_ENTRYNUM;
785 CDF->CURzEntryOffset = RESERVED_ENTRYOFFSET;
786 CDF->CURzEntryOffset64 = (OFF_T) RESERVED_ENTRYOFFSET;
787 CDF->CURrVarNum = RESERVED_VARNUM;
788 CDF->CURzVarNum = RESERVED_VARNUM;
789
790 if (CDF->fp != NULL)
791 {
792 CDF->fp->CurADRIndex = RESERVED_ENTRYNUM;
793 CDF->fp->CurAEDRIndex = RESERVED_ENTRYNUM;
794 };
795
796 /****************************************************************************
797 * Initialize current positioning for EACH rVariable.
798 ****************************************************************************/
799 for (varNum = 0; varNum < CDF->NrVars; varNum++) {
800 Var = CDF->rVars[varNum];
801 if (Var != NULL) {
802 Var->seqValueOffset = 0;
803 Var->seqValueOffset64 = (OFF_T) 0;
804 Var->zRD.recNumber = 0;
805 Var->zRD.recCount = 1;
806 Var->zRD.recInterval = 1;
807 for (dimN = 0; dimN < Var->numDims; dimN++) {
808 Var->zRD.dimIndices[dimN] = 0;
809 Var->zRD.dimCounts[dimN] = Var->dimSizes[dimN];
810 Var->zRD.dimIntervals[dimN] = 1;
811 }
812 }
813 }
814 /****************************************************************************
815 * Initialize current positioning for EACH zVariable.
816 ****************************************************************************/
817 for (varNum = 0; varNum < CDF->NzVars; varNum++) {
818 Var = CDF->zVars[varNum];
819 if (Var != NULL) {
820 Var->seqValueOffset = 0;
821 Var->seqValueOffset64 = (OFF_T) 0;
822 Var->zRD.recNumber = 0;
823 Var->zRD.recCount = 1;
824 Var->zRD.recInterval = 1;
825 for (dimN = 0; dimN < Var->numDims; dimN++) {
826 Var->zRD.dimIndices[dimN] = 0;
827 Var->zRD.dimCounts[dimN] = Var->dimSizes[dimN];
828 Var->zRD.dimIntervals[dimN] = 1;
829 }
830 }
831 }
832 /****************************************************************************
833 * Initialize current positioning for ALL rVariables.
834 ****************************************************************************/
835 CDF->rRD.recNumber = 0;
836 CDF->rRD.recCount = 1;
837 CDF->rRD.recInterval = 1;
838 for (dimN = 0; dimN < CDF->rNumDims; dimN++) {
839 CDF->rRD.dimIndices[dimN] = 0;
840 CDF->rRD.dimCounts[dimN] = CDF->rDimSizes[dimN];
841 CDF->rRD.dimIntervals[dimN] = 1;
842 }
843 return;
844 }
845
846 /******************************************************************************
847 * FindAttrByName.
848 ******************************************************************************/
849
FindAttrByName(CDF,searchName,offset)850 STATICforIDL CDFstatus FindAttrByName (CDF, searchName, offset)
851 struct CDFstruct *CDF; /* In: Pointer to CDF. */
852 char *searchName; /* In: Attribute name to find. */
853 Int32 *offset; /* Out: Offset of ADR that was found. */
854 {
855 Int32 numAttrs, tOffset, nextADR, fstADR;
856 char attrName[CDF_ATTR_NAME_LEN+1];
857 CDFstatus pStatus = CDF_OK;
858 int attrN;
859 long read_only_mode;
860
861 pStatus = CDFlib(CONFIRM_, CDF_READONLY_MODE_, &read_only_mode, NULL_);
862 if (pStatus != CDF_OK) return pStatus;
863
864 /**************************************************************************
865 * If in READONLYon mode, set CurADRIndex to the referenced attribute number.
866 ***************************************************************************/
867 if (read_only_mode == READONLYon)
868 {
869 for (attrN = 0; attrN < CDF->fp->GDR->NumAttr; attrN++)
870 {
871 if (!strcmpITB(CDF->fp->ADRList[attrN]->Name,searchName))
872 {
873 CDF->fp->CurADRIndex = attrN;
874 ASSIGNnotNULL (offset, DUMMY_ENTRYOFFSET);
875 return CDF_OK;
876 };
877 };
878 }
879 else
880 {
881 /************************************************************************
882 * Read number of attributes and the offset of the first ADR from the GDR.
883 ************************************************************************/
884 if (!sX(ReadGDR(CDF->fp,CDF->GDRoffset,
885 GDR_NUMATTR,&numAttrs,
886 GDR_ADRHEAD,&fstADR,
887 GDR_NULL),&pStatus)) return pStatus;
888 /************************************************************************
889 * Read from ADRs until a matching attribute name is found.
890 * Note that if this is a V2.0 CDF, the last ADR will not have an
891 * offset of zero for the next ADR. For that reason, we will loop
892 * through the number of attributes read from the GDR (and then stop).
893 ************************************************************************/
894 if (CDF->CURattrOffset != RESERVED_ATTROFFSET)
895 tOffset = CDF->CURattrOffset;
896 else
897 tOffset = fstADR;
898
899 for (attrN = 0; attrN < numAttrs; attrN++) {
900 if (!sX(ReadADR(CDF->fp,tOffset,
901 ADR_NAME,attrName,
902 ADR_ADRNEXT,&nextADR,
903 ADR_NULL),&pStatus)) return pStatus;
904 if (!strcmpITB(attrName,searchName)) {
905 ASSIGNnotNULL (offset, tOffset)
906 return CDF_OK;
907 }
908 if (nextADR != 0)
909 tOffset = nextADR;
910 else
911 tOffset = fstADR;
912 }
913 };
914 /****************************************************************************
915 * Attribute name not found, return error.
916 ****************************************************************************/
917 return NO_SUCH_ATTR;
918 }
919
920 /******************************************************************************
921 * FindAttrByNumber.
922 ******************************************************************************/
923
FindAttrByNumber(CDF,searchNum,offset)924 STATICforIDL CDFstatus FindAttrByNumber (CDF, searchNum, offset)
925 struct CDFstruct *CDF; /* In: Pointer to the CDF. */
926 Int32 searchNum; /* In: The attribute number to be found. */
927 Int32 *offset; /* Out: The offset of the located ADR. */
928 {
929 Int32 numAttrs, tOffset, attrNum, nextADR, fstADR;
930 CDFstatus pStatus = CDF_OK;
931 Int32 attrN;
932 long read_only_mode;
933 /****************************************************************************
934 * Validate.
935 ****************************************************************************/
936 if (searchNum < 0) return BAD_ATTR_NUM;
937 /****************************************************************************
938 * First check if the next attribute is the one being searched for. For this
939 * to be the case, an attribute must currently be selected, the next attribute
940 * must exist, and the next attribute's number must be the attribute number
941 * being searched for. But don't try this if a V2.0 CDF because of the bad
942 * terminating offset of the ADR linked list in those CDFs.
943 ****************************************************************************/
944 /*
945 if (!CDF->badTerminatingOffsets) {
946 if (CDF->CURattrOffset != RESERVED_ATTROFFSET) {
947 Int32 nextOffset;
948 if (!sX(ReadADR(CDF->fp,CDF->CURattrOffset,
949 ADR_ADRNEXT,&nextOffset,
950 ADR_NULL),&pStatus)) return pStatus;
951 if (nextOffset != 0) {
952 Int32 nextNum;
953 if (!sX(ReadADR(CDF->fp,nextOffset,
954 ADR_NUM,&nextNum,
955 ADR_NULL),&pStatus)) return pStatus;
956 if (nextNum == searchNum) {
957 *offset = nextOffset;
958 return pStatus;
959 }
960 }
961 }
962 }
963 */
964 pStatus = CDFlib(CONFIRM_, CDF_READONLY_MODE_, &read_only_mode, NULL_);
965 if (pStatus != CDF_OK) return pStatus;
966
967 /***************************************************************************
968 * If in read only mode, set CurADRIndex to the searched for atribute number.
969 ***************************************************************************/
970 if (read_only_mode == READONLYon)
971 {
972 if (CDF->fp->GDR->NumAttr <= searchNum) return NO_SUCH_ATTR;
973 if (searchNum < 0 || searchNum >= CDF->fp->GDR->NumAttr)
974 return NO_SUCH_ATTR;
975 CDF->fp->CurADRIndex = searchNum;
976 ASSIGNnotNULL (offset, DUMMY_ENTRYOFFSET);
977 return CDF_OK;
978 }
979 else
980 {
981 /************************************************************************
982 * The next attribute isn't the one being searched for. First read the
983 * number of attributes and the offset of the first ADR from the GDR.
984 ************************************************************************/
985 if (!sX(ReadGDR(CDF->fp,CDF->GDRoffset,
986 GDR_NUMATTR,&numAttrs,
987 GDR_ADRHEAD,&fstADR,
988 GDR_NULL),&pStatus)) return pStatus;
989 if (numAttrs <= searchNum) return NO_SUCH_ATTR;
990
991 if (CDF->CURattrOffset != RESERVED_ATTROFFSET)
992 tOffset = CDF->CURattrOffset;
993 else
994 tOffset = fstADR;
995 /************************************************************************
996 * Read from ADRs until a matching attribute number is found.
997 * Note that if this is a V2.0 CDF, the last ADR will not have an
998 * offset of zero for the next ADR. For that reason, we will loop
999 * through the number of attributes read from the GDR (and then stop).
1000 ************************************************************************/
1001 for (attrN = 0; attrN < numAttrs; attrN++) {
1002 if (!sX(ReadADR(CDF->fp,tOffset,
1003 ADR_NUM,&attrNum,
1004 ADR_ADRNEXT,&nextADR,
1005 ADR_NULL),&pStatus)) return pStatus;
1006 if (attrNum == searchNum) {
1007 ASSIGNnotNULL (offset, tOffset)
1008 return CDF_OK;
1009 }
1010 if (nextADR != 0)
1011 tOffset = nextADR;
1012 else
1013 tOffset = fstADR;
1014 }
1015 /************************************************************************
1016 * Attribute number not found, internal error or corrupted CDF.
1017 ************************************************************************/
1018 return CORRUPTED_V2_CDF;
1019 }
1020 }
1021
1022 /******************************************************************************
1023 * FindEntryByNumber.
1024 ******************************************************************************/
1025
FindEntryByNumber(CDF,ADRoffset,zEntry,entryN,offset)1026 STATICforIDL CDFstatus FindEntryByNumber (CDF, ADRoffset, zEntry, entryN,
1027 offset)
1028 struct CDFstruct *CDF; /* In: Pointer to the CDF. */
1029 Int32 ADRoffset; /* In: Offset of attribute's ADR. */
1030 Logical zEntry; /* In: TRUE if AzEDR list to be searched.
1031 FALSE if AgrEDR list to be searched. */
1032 Int32 entryN; /* In: The entry number being searched for. */
1033 Int32 *offset; /* Out: The offset of the located AEDR. */
1034 {
1035 Int32 numEntries, tOffset, entryNum, nextADR;
1036 CDFstatus pStatus = CDF_OK;
1037 Int32 entryX;
1038 long read_only_mode;
1039 /****************************************************************************
1040 * Read number of entries and the offset of the first AEDR from the ADR.
1041 ****************************************************************************/
1042 if (!sX(ReadADR(CDF->fp,ADRoffset,
1043 BOO(zEntry,ADR_NzENTRIES,ADR_NgrENTRIES),&numEntries,
1044 BOO(zEntry,ADR_AzEDRHEAD,ADR_AgrEDRHEAD),&tOffset,
1045 ADR_NULL),&pStatus)) return pStatus;
1046 pStatus = CDFlib(CONFIRM_, CDF_READONLY_MODE_, &read_only_mode, NULL_);
1047 if (pStatus != CDF_OK) return pStatus;
1048 if (read_only_mode == READONLYon)
1049 {
1050 /***********************************************************************
1051 * If the requested entry exists, set CurAEDRIndex to the entry number and
1052 * set CURzEntrySel to reflect if the entry is in the z list or the gr
1053 * list.
1054 ************************************************************************/
1055 if (zEntry && entryN <= CDF->fp->ADRList[CDF->fp->CurADRIndex]->MAXzEntry)
1056 {
1057 if (CDF->fp->ADRList[CDF->fp->CurADRIndex]->zAEDRList[entryN] != NULL)
1058 {
1059 CDF->fp->CURzEntrySel = TRUE;
1060 CDF->fp->CurAEDRIndex = entryN;
1061 ASSIGNnotNULL (offset, DUMMY_ENTRYOFFSET);
1062 return pStatus;
1063 }
1064 else
1065 {
1066 return NO_SUCH_ENTRY;
1067 }
1068 }
1069 else if (!zEntry && entryN <= CDF->fp->ADRList[CDF->fp->CurADRIndex]->
1070 MAXgrEntry)
1071 {
1072 if (CDF->fp->ADRList[CDF->fp->CurADRIndex]->grAEDRList[entryN]
1073 != NULL)
1074 {
1075 CDF->fp->CURzEntrySel = FALSE;
1076 CDF->fp->CurAEDRIndex = entryN;
1077 ASSIGNnotNULL (offset, DUMMY_ENTRYOFFSET);
1078 return pStatus;
1079 }
1080 else
1081 {
1082 return NO_SUCH_ENTRY;
1083 };
1084 }
1085
1086 else
1087 {
1088 return NO_SUCH_ENTRY;
1089 };
1090 };
1091 /****************************************************************************
1092 * Read from AEDRs until a matching entry number is found.
1093 * Note that if this is a V2.0 CDF, the last AEDR will not have an
1094 * offset of zero for the next AEDR. For that reason, we will loop
1095 * through the number of entries read from the ADR (and then stop).
1096 ****************************************************************************/
1097 for (entryX = 0; entryX < numEntries; entryX++) {
1098 if (!sX(ReadAEDR(CDF->fp,tOffset,
1099 AEDR_NUM,&entryNum,
1100 AEDR_AEDRNEXT,&nextADR,
1101 AEDR_NULL),&pStatus)) return pStatus;
1102 if (entryNum == entryN) {
1103 ASSIGNnotNULL (offset, tOffset)
1104 return CDF_OK;
1105 }
1106 tOffset = nextADR;
1107 }
1108 /****************************************************************************
1109 * Entry number not found.
1110 ****************************************************************************/
1111 return NO_SUCH_ENTRY;
1112 }
1113
1114 /******************************************************************************
1115 * FindLastAttr.
1116 ******************************************************************************/
1117
FindLastAttr(CDF,lastOffset)1118 STATICforIDL CDFstatus FindLastAttr (CDF, lastOffset)
1119 struct CDFstruct *CDF; /* In: Pointer to the CDF. */
1120 Int32 *lastOffset; /* Out: Offset of last attribute's ADR. */
1121 {
1122 CDFstatus pStatus = CDF_OK;
1123 Int32 nAttrs, offset;
1124 Int32 attrN;
1125 long read_only_mode;
1126
1127 pStatus = CDFlib(CONFIRM_, CDF_READONLY_MODE_, &read_only_mode, NULL_);
1128 if (pStatus != CDF_OK) return pStatus;
1129
1130 /*************************************************************************
1131 * If in READONLYon mode, set CurADRIndex to the index of the last
1132 * attribute in menmory.
1133 *************************************************************************/
1134 if (read_only_mode == READONLYon)
1135 {
1136 *lastOffset = DUMMY_ATTROFFSET;
1137 CDF->fp->CurADRIndex = CDF->fp->GDR->NumAttr - 1;
1138 }
1139 else
1140 {
1141 /************************************************************************
1142 * Read number of attributes and the offset of the first ADR. If there are
1143 * no attributes, return an offset of zero.
1144 ************************************************************************/
1145 if (!sX(ReadGDR(CDF->fp,CDF->GDRoffset,
1146 GDR_NUMATTR,&nAttrs,
1147 GDR_NULL),&pStatus)) return pStatus;
1148 if (nAttrs == 0) {
1149 *lastOffset = 0;
1150 return pStatus;
1151 }
1152 /************************************************************************
1153 * There is at least one attribute.
1154 * Note that if this is a V2.0 CDF, the last ADR will not have an offset of
1155 * zero for the next ADR. For that reason, we will loop through the number
1156 * of attributes read from the GDR (and then stop).
1157 ************************************************************************/
1158 if (!sX(ReadGDR(CDF->fp,CDF->GDRoffset,
1159 GDR_ADRHEAD,&offset,
1160 GDR_NULL),&pStatus)) return pStatus;
1161 for (attrN = 0; attrN < nAttrs - 1; attrN++) {
1162 if (!sX(ReadADR(CDF->fp,offset,
1163 ADR_ADRNEXT,&offset,
1164 ADR_NULL),&pStatus)) return pStatus;
1165 }
1166 *lastOffset = offset;
1167 };
1168 return pStatus;
1169 }
1170
1171 /******************************************************************************
1172 * FindLastEntry.
1173 ******************************************************************************/
1174
FindLastEntry(CDF,ADRoffset,zEntry,lastOffset)1175 STATICforIDL CDFstatus FindLastEntry (CDF, ADRoffset, zEntry, lastOffset)
1176 struct CDFstruct *CDF; /* In: Pointer to the CDF. */
1177 Int32 ADRoffset; /* In: Offset of attribute's ADR. */
1178 Logical zEntry; /* In: TRUE if (real) zEntry is being searched
1179 for; FALSE if gEntry/rEntry. */
1180 Int32 *lastOffset; /* Out: The offset of the last AEDR. */
1181 {
1182 CDFstatus pStatus = CDF_OK;
1183 Int32 offset, nEntries;
1184 Int32 entryX;
1185 long read_only_mode;
1186
1187 pStatus = CDFlib(CONFIRM_, CDF_READONLY_MODE_, &read_only_mode, NULL_);
1188 if (pStatus != CDF_OK) return pStatus;
1189
1190 /***********************************************************************
1191 * If in READONLYon mode, set CurAEDRIndex to MAXzEntry or MAXgrEntry, as
1192 * appropriate.
1193 ***********************************************************************/
1194 if (read_only_mode == READONLYon)
1195 {
1196 *lastOffset = DUMMY_ENTRYOFFSET;
1197 if (zEntry == TRUE)
1198 {
1199 CDF->fp->CurAEDRIndex =
1200 CDF->fp->ADRList[CDF->fp->CurADRIndex]->MAXzEntry;
1201 }
1202 else
1203 {
1204 CDF->fp->CurAEDRIndex =
1205 CDF->fp->ADRList[CDF->fp->CurADRIndex]->MAXgrEntry; };
1206 }
1207 else
1208 {
1209 /************************************************************************
1210 * Read offset of first AEDR and determine if there are any entries (of the
1211 * specified type). If there are none, pass back an offset of zero.
1212 ************************************************************************/
1213 if (!sX(ReadADR(CDF->fp,ADRoffset,
1214 BOO(zEntry,ADR_AzEDRHEAD,ADR_AgrEDRHEAD),
1215 &offset,ADR_NULL),&pStatus)) return pStatus;
1216 if (offset == 0) {
1217 *lastOffset = 0;
1218 return pStatus;
1219 }
1220 /************************************************************************
1221 * There is at least one entry. Read the actual number of entries and then
1222 * scan through to the last one.
1223 * Note that if this is a V2.0 CDF, the last AEDR will not have an
1224 * offset of zero for the next AEDR. For that reason, we will loop
1225 * through the number of entries (minus one) read from the ADR (and then
1226 * stop).
1227 ************************************************************************/
1228 if (!sX(ReadADR(CDF->fp,ADRoffset,
1229 BOO(zEntry,ADR_NzENTRIES,ADR_NgrENTRIES),&nEntries,
1230 ADR_NULL),&pStatus)) return pStatus;
1231 for (entryX = 0; entryX < nEntries - 1; entryX++) {
1232 if (!sX(ReadAEDR(CDF->fp,offset,
1233 AEDR_AEDRNEXT,&offset,
1234 AEDR_NULL),&pStatus)) return pStatus;
1235 }
1236 *lastOffset = offset;
1237 }
1238 return pStatus;
1239 }
1240
1241 /******************************************************************************
1242 * FindPrevEntry.
1243 ******************************************************************************/
1244
FindPrevEntry(CDF,ADRoffset,searchOffset,zEntry,prevOffset)1245 STATICforIDL CDFstatus FindPrevEntry (CDF, ADRoffset, searchOffset, zEntry,
1246 prevOffset)
1247 struct CDFstruct *CDF; /* Pointer to the CDF. */
1248 Int32 ADRoffset; /* Offset of attribute's ADR. */
1249 Int32 searchOffset; /* The entry offset being searched for. */
1250 Logical zEntry; /* TRUE if (real) zEntry is being searched for;
1251 FALSE if gEntry/rEntry. */
1252 Int32 *prevOffset; /* The offset of the previous AEDR. */
1253 {
1254 CDFstatus pStatus = CDF_OK;
1255 Int32 offset, nEntries, nextOffset;
1256 Int32 entryX;
1257 /****************************************************************************
1258 * Read the offset of the first AEDR. If that offset is the same as the
1259 * search offset, return an offset of zero.
1260 ****************************************************************************/
1261 if (!sX(ReadADR(CDF->fp,ADRoffset,
1262 BOO(zEntry,ADR_AzEDRHEAD,ADR_AgrEDRHEAD),&offset,
1263 ADR_NULL),&pStatus)) return pStatus;
1264 if (offset == searchOffset) {
1265 *prevOffset = 0;
1266 return pStatus;
1267 }
1268 /****************************************************************************
1269 * The first AEDR is not at the search offset. Read the actual number of
1270 * entries and then scan through them looking for the AEDR offset being
1271 * searched for. If the search offset is not found, then either the CDF is
1272 * corrupted or an internal logic error has occurred.
1273 * Note that if this is a V2.0 CDF, the last AEDR will not have an
1274 * offset of zero for the next AEDR. For that reason, we will loop
1275 * through the number of entries read from the ADR (and then stop).
1276 ****************************************************************************/
1277 if (!sX(ReadADR(CDF->fp,ADRoffset,
1278 BOO(zEntry,ADR_NzENTRIES,ADR_NgrENTRIES),&nEntries,
1279 ADR_NULL),&pStatus)) return pStatus;
1280 for (entryX = 0; entryX < nEntries; entryX++) {
1281 if (!sX(ReadAEDR(CDF->fp,offset,
1282 AEDR_AEDRNEXT,&nextOffset,
1283 AEDR_NULL),&pStatus)) return pStatus;
1284 if (nextOffset == searchOffset) {
1285 *prevOffset = offset;
1286 return pStatus;
1287 }
1288 offset = nextOffset;
1289 }
1290 return CORRUPTED_V2_CDF;
1291 }
1292
1293 /******************************************************************************
1294 * FindVarByName.
1295 * Both the rVariable and zVariable lists are searched (since variable names
1296 * are unique in a CDF).
1297 ******************************************************************************/
1298
FindVarByName(CDF,searchName,offset,zVar,Var)1299 STATICforIDL CDFstatus FindVarByName (CDF, searchName, offset, zVar, Var)
1300 struct CDFstruct *CDF; /* In: Pointer to the CDF. */
1301 char *searchName; /* In: The variable name being searched for. */
1302 Int32 *offset; /* Out: Offset of the zVDR/rVDR. */
1303 Logical *zVar; /* Out: TRUE if a zVariable. */
1304 struct VarStruct **Var; /* Out: Pointer to variable structure. */
1305 {
1306 int varN;
1307 char varName[CDF_VAR_NAME_LEN+1];
1308 CDFstatus pStatus = CDF_OK;
1309 Int32 tOffset, nextVDR;
1310 Int32 headOffset;
1311 /****************************************************************************
1312 * Read from rVDRs until a matching variable name is found.
1313 * Note that if this is a V2.0 CDF, the last rVDR will not have an
1314 * offset of zero for the next rVDR. For that reason, we will loop
1315 * through the number of rVariables (and then stop).
1316 ****************************************************************************/
1317 if (!sX(ReadGDR(CDF->fp,CDF->GDRoffset,
1318 GDR_rVDRHEAD,&headOffset,
1319 GDR_NULL),&pStatus)) return pStatus;
1320
1321 if (CDF->CURrVarNum != RESERVED_VARNUM)
1322 tOffset = CDF->CURrVarOffset;
1323 else
1324 tOffset = headOffset;
1325
1326 for (varN = 0; varN < CDF->NrVars; varN++) {
1327 if (!sX(ReadVDR(CDF,CDF->fp,tOffset,FALSE,
1328 VDR_NAME,varName,
1329 VDR_VDRNEXT,&nextVDR,
1330 VDR_NULL),&pStatus)) return pStatus;
1331 if (!strcmpITB(varName,searchName)) {
1332 ASSIGNnotNULL (offset, tOffset)
1333 ASSIGNnotNULL (zVar, FALSE)
1334 ASSIGNnotNULL (Var, CDF->rVars[varN])
1335 return CDF_OK;
1336 }
1337 if (nextVDR == 0) tOffset = headOffset;
1338 else tOffset = nextVDR;
1339 }
1340 /****************************************************************************
1341 * Read from zVDRs until a matching variable name is found.
1342 ****************************************************************************/
1343 if (!sX(ReadGDR(CDF->fp,CDF->GDRoffset,
1344 GDR_zVDRHEAD,&headOffset,
1345 GDR_NULL),&pStatus)) return pStatus;
1346 /*
1347 if (CDF->CURzVarNum != RESERVED_VARNUM)
1348 tOffset = CDF->CURzVarOffset;
1349 else
1350 */
1351 tOffset = headOffset;
1352
1353 for (varN = 0; varN < CDF->NzVars; varN++) {
1354 if (!sX(ReadVDR(CDF,CDF->fp,tOffset,TRUE,
1355 VDR_NAME,varName,
1356 VDR_VDRNEXT,&nextVDR,
1357 VDR_NULL),&pStatus)) return pStatus;
1358 if (!strcmpITB(varName,searchName)) {
1359 ASSIGNnotNULL (offset, tOffset)
1360 ASSIGNnotNULL (zVar, TRUE)
1361 ASSIGNnotNULL (Var, CDF->zVars[varN])
1362 return CDF_OK;
1363 }
1364 if (nextVDR == 0) tOffset = headOffset;
1365 else tOffset = nextVDR;
1366 }
1367 /****************************************************************************
1368 * Variable name not found, return error.
1369 ****************************************************************************/
1370 return NO_SUCH_VAR;
1371 }
1372
1373 /******************************************************************************
1374 * FindVarByNumber.
1375 ******************************************************************************/
1376
FindVarByNumber(CDF,searchNum,zVar,offset)1377 STATICforIDL CDFstatus FindVarByNumber (CDF, searchNum, zVar, offset)
1378 struct CDFstruct *CDF; /* In: Pointer to CDF. */
1379 Int32 searchNum; /* In: Variable number to be searched for. */
1380 Logical zVar; /* In: TRUE if a (real) zVariable number should be
1381 found. */
1382 Int32 *offset; /* Out: offset of the VDR. */
1383 {
1384 CDFstatus pStatus = CDF_OK;
1385 Int32 nVars = BOO(zVar,CDF->NzVars,CDF->NrVars);
1386 Int32 tOffset, varNum, nextVDR, fstOffset;
1387 int varN;
1388 /****************************************************************************
1389 * Read offset of first VDR.
1390 ****************************************************************************/
1391 if (searchNum < 0) return BAD_VAR_NUM;
1392 if (!sX(ReadGDR(CDF->fp,CDF->GDRoffset,
1393 BOO(zVar,GDR_zVDRHEAD,GDR_rVDRHEAD),&fstOffset,
1394 GDR_NULL),&pStatus)) return pStatus;
1395 if (nVars <= searchNum) return NO_SUCH_VAR;
1396 /****************************************************************************
1397 * Read from VDRs until a matching variable number is found.
1398 * Note that if this is a V2.0 CDF, the last VDR will not have an
1399 * offset of zero for the next VDR. For that reason, we will loop
1400 * through the number of variables (and then stop).
1401 ****************************************************************************/
1402
1403 if (zModeON(CDF)) {
1404 tOffset = fstOffset;
1405 if (CDF->CURzVarNum != RESERVED_VARNUM) {
1406 long numT = BOO(zVar, CDF->CURzVarNum-CDF->NrVars, CDF->CURzVarNum);
1407 if (numT > -1 && numT <= searchNum) tOffset = CDF->CURzVarOffset;
1408 }
1409 }
1410 else {
1411 if (zVar) {
1412 if (CDF->CURzVarNum != RESERVED_VARNUM && CDF->CURzVarNum < searchNum)
1413 tOffset = CDF->CURzVarOffset;
1414 else
1415 tOffset = fstOffset;
1416 } else {
1417 if (CDF->CURrVarNum != RESERVED_VARNUM && CDF->CURrVarNum < searchNum)
1418 tOffset = CDF->CURrVarOffset;
1419 else
1420 tOffset = fstOffset;
1421 }
1422 }
1423
1424 /****************************************************************************
1425 * Search for the variable from the current selected variabale, instead of
1426 * the top of the variable list. It will speed up the search process if the
1427 * variables are accessed in a orderly sequence.
1428 ****************************************************************************/
1429 for (varN = 0; varN < nVars; varN++) {
1430 if (!sX(ReadVDR(CDF,CDF->fp,tOffset,zVar,
1431 VDR_NUM,&varNum,
1432 VDR_VDRNEXT, &nextVDR,
1433 VDR_NULL),&pStatus)) return pStatus;
1434 if (varNum == searchNum) {
1435 ASSIGNnotNULL (offset, tOffset)
1436 return CDF_OK;
1437 }
1438 if (nextVDR != 0) /* Reaching the end of the list? */
1439 tOffset = nextVDR; /* No.... Continue. */
1440 else
1441 tOffset = fstOffset; /* Yes... Go back to the top. */
1442 }
1443 /****************************************************************************
1444 * Variable number not found, return error.
1445 ****************************************************************************/
1446 return CORRUPTED_V2_CDF;
1447 }
1448
1449 /******************************************************************************
1450 * VerifyNoRecordsWritten.
1451 * Verifies that no records have been written. Both the rVariable and
1452 * zVariable lists are searched.
1453 ******************************************************************************/
1454
VerifyNoRecordsWritten(CDF,no)1455 STATICforIDL CDFstatus VerifyNoRecordsWritten (CDF, no)
1456 struct CDFstruct *CDF; /* In: Pointer to the CDF. */
1457 Logical *no; /* Out: If TRUE, no records written. */
1458 {
1459 CDFstatus pStatus = CDF_OK; Int32 tOffset, maxRec; int varN; Logical zVar;
1460 /****************************************************************************
1461 * Read from r/zVDRs until a maximum record greater than NO_RECORD is found.
1462 * Note that if this is a V2.0 CDF, the last rVDR will not have an
1463 * offset of zero for the next rVDR. For that reason, we will loop
1464 * through the number of variables (and then stop).
1465 ****************************************************************************/
1466 for (zVar = 0; zVar <= 1; zVar++) {
1467 if (!sX(ReadGDR(CDF->fp,CDF->GDRoffset,
1468 BOO(zVar,GDR_zVDRHEAD,GDR_rVDRHEAD),&tOffset,
1469 GDR_NULL),&pStatus)) return pStatus;
1470 for (varN = 0; varN < BOO(zVar,CDF->NzVars,CDF->NrVars); varN++) {
1471 if (!sX(ReadVDR(CDF,CDF->fp,tOffset,zVar,
1472 VDR_MAXREC,&maxRec,
1473 VDR_VDRNEXT,&tOffset,
1474 VDR_NULL),&pStatus)) return pStatus;
1475 if (maxRec > NO_RECORD) {
1476 *no = FALSE;
1477 return pStatus;
1478 }
1479 }
1480 }
1481 /****************************************************************************
1482 * No records written.
1483 ****************************************************************************/
1484 *no = TRUE;
1485 return pStatus;
1486 }
1487
1488 /******************************************************************************
1489 * VerifyNoPadsSpecified.
1490 * Verifies that no pad values have been specified. Both the rVariable
1491 * and zVariable lists are searched.
1492 ******************************************************************************/
1493
VerifyNoPadsSpecified(CDF,no)1494 STATICforIDL CDFstatus VerifyNoPadsSpecified (CDF, no)
1495 struct CDFstruct *CDF; /* In: Pointer to the CDF. */
1496 Logical *no; /* Out: If TRUE, no pad values written. */
1497 {
1498 CDFstatus pStatus = CDF_OK;
1499 Int32 tOffset, flags32;
1500 int varN;
1501 /****************************************************************************
1502 * Read from rVDRs until a pad value is found.
1503 * Note that if this is a V2.0 CDF, the last rVDR will not have an
1504 * offset of zero for the next rVDR. For that reason, we will loop
1505 * through the number of rVariables (and then stop).
1506 ****************************************************************************/
1507 if (!sX(ReadGDR(CDF->fp,CDF->GDRoffset,
1508 GDR_rVDRHEAD,&tOffset,
1509 GDR_NULL),&pStatus)) return pStatus;
1510 for (varN = 0; varN < CDF->NrVars; varN++) {
1511 if (!sX(ReadVDR(CDF,CDF->fp,tOffset,FALSE,
1512 VDR_FLAGS,&flags32,
1513 VDR_NULL),&pStatus)) return pStatus;
1514 if (PADvalueBITset(flags32)) {
1515 *no = FALSE;
1516 return pStatus;
1517 }
1518 if (!sX(ReadVDR(CDF,CDF->fp,tOffset,FALSE,
1519 VDR_VDRNEXT,&tOffset,
1520 VDR_NULL),&pStatus)) return pStatus;
1521 }
1522 /****************************************************************************
1523 * Read from zVDRs until a pad value is found.
1524 ****************************************************************************/
1525 if (!sX(ReadGDR(CDF->fp,CDF->GDRoffset,
1526 GDR_zVDRHEAD,&tOffset,
1527 GDR_NULL),&pStatus)) return pStatus;
1528 for (varN = 0; varN < CDF->NzVars; varN++) {
1529 if (!sX(ReadVDR(CDF,CDF->fp,tOffset,TRUE,
1530 VDR_FLAGS,&flags32,
1531 VDR_NULL),&pStatus)) return pStatus;
1532 if (PADvalueBITset(flags32)) {
1533 *no = FALSE;
1534 return pStatus;
1535 }
1536 if (!sX(ReadVDR(CDF,CDF->fp,tOffset,TRUE,
1537 VDR_VDRNEXT,&tOffset,
1538 VDR_NULL),&pStatus)) return pStatus;
1539 }
1540 /****************************************************************************
1541 * No pad values specified.
1542 ****************************************************************************/
1543 *no = TRUE;
1544 return pStatus;
1545 }
1546
1547 /******************************************************************************
1548 * VerifyNoEntriesWritten.
1549 ******************************************************************************/
1550
VerifyNoEntriesWritten(CDF,no)1551 STATICforIDL CDFstatus VerifyNoEntriesWritten (CDF, no)
1552 struct CDFstruct *CDF;
1553 Logical *no;
1554 {
1555 CDFstatus pStatus = CDF_OK;
1556 Int32 numAttrs, tOffset, nEntries;
1557 int attrN;
1558 /****************************************************************************
1559 * Read number of attributes and the offset of the first ADR from the GDR.
1560 ****************************************************************************/
1561 if (!sX(ReadGDR(CDF->fp,CDF->GDRoffset,
1562 GDR_NUMATTR,&numAttrs,
1563 GDR_ADRHEAD,&tOffset,
1564 GDR_NULL),&pStatus)) return pStatus;
1565 /****************************************************************************
1566 * Read from ADRs until an entry is found.
1567 * Note that if this is a V2.0 CDF, the last ADR will not have an
1568 * offset of zero for the next ADR. For that reason, we will loop
1569 * through the number of attributes read from the GDR (and then stop).
1570 ****************************************************************************/
1571 for (attrN = 0; attrN < numAttrs; attrN++) {
1572 if (!sX(ReadADR(CDF->fp,tOffset,
1573 ADR_NgrENTRIES,&nEntries,
1574 ADR_NULL),&pStatus)) return pStatus;
1575 if (nEntries > 0) {
1576 *no = FALSE;
1577 return pStatus;
1578 }
1579 if (!sX(ReadADR(CDF->fp,tOffset,
1580 ADR_NzENTRIES,&nEntries,
1581 ADR_NULL),&pStatus)) return pStatus;
1582 if (nEntries > 0) {
1583 *no = FALSE;
1584 return pStatus;
1585 }
1586 if (!sX(ReadADR(CDF->fp,tOffset,
1587 ADR_ADRNEXT,&tOffset,
1588 ADR_NULL),&pStatus)) return pStatus;
1589 }
1590 /****************************************************************************
1591 * No entries detected.
1592 ****************************************************************************/
1593 *no = TRUE;
1594 return pStatus;
1595 }
1596
1597 /******************************************************************************
1598 * DefaultPadValue.
1599 * `memmove' is used rather than an assignment statement (for the data
1600 * types greater in size than one byte) because there is no guarantee that the
1601 * address which receives the pad value is aligned properly. If it isn't, a
1602 * bus error could occur on some computers.
1603 ******************************************************************************/
1604
DefaultPadValue(dataType,numElems,padValue)1605 STATICforIDL void DefaultPadValue (dataType, numElems, padValue)
1606 Int32 dataType;
1607 Int32 numElems;
1608 void *padValue;
1609 {
1610 size_t nBytes = CDFelemSize (dataType);
1611 Byte *ptr = padValue;
1612 double padE[2]; /* The "largest" data type element. */
1613 int i;
1614 switch (dataType) {
1615 case CDF_BYTE:
1616 *((sChar *) &padE) = (sChar) DEFAULT_BYTE_PADVALUE;
1617 break;
1618 case CDF_INT1:
1619 *((sChar *) &padE) = (sChar) DEFAULT_INT1_PADVALUE;
1620 break;
1621 case CDF_UINT1:
1622 *((uChar *) &padE) = (uChar) DEFAULT_UINT1_PADVALUE;
1623 break;
1624 case CDF_INT2:
1625 *((Int16 *) &padE) = (Int16) DEFAULT_INT2_PADVALUE;
1626 break;
1627 case CDF_UINT2:
1628 *((uInt16 *) &padE) = (uInt16) DEFAULT_UINT2_PADVALUE;
1629 break;
1630 case CDF_INT4:
1631 *((Int32 *) &padE) = (Int32) DEFAULT_INT4_PADVALUE;
1632 break;
1633 case CDF_UINT4:
1634 *((uInt32 *) &padE) = (uInt32) DEFAULT_UINT4_PADVALUE;
1635 break;
1636 case CDF_REAL4:
1637 *((float *) &padE) = (float) DEFAULT_REAL4_PADVALUE;
1638 break;
1639 case CDF_FLOAT:
1640 *((float *) &padE) = (float) DEFAULT_FLOAT_PADVALUE;
1641 break;
1642 case CDF_REAL8:
1643 *((double *) &padE) = (double) DEFAULT_REAL8_PADVALUE;
1644 break;
1645 case CDF_DOUBLE:
1646 *((double *) &padE) = (double) DEFAULT_DOUBLE_PADVALUE;
1647 break;
1648 case CDF_EPOCH:
1649 *((double *) &padE) = (double) DEFAULT_EPOCH_PADVALUE;
1650 break;
1651 case CDF_EPOCH16:
1652 *((double *) &padE) = (double) DEFAULT_EPOCH_PADVALUE;
1653 *(((double *) &padE) + 1) = (double) DEFAULT_EPOCH_PADVALUE;
1654 break;
1655 case CDF_CHAR:
1656 *((sChar *) &padE) = (sChar) DEFAULT_CHAR_PADVALUE;
1657 break;
1658 case CDF_UCHAR:
1659 *((uChar *) &padE) = (uChar) DEFAULT_UCHAR_PADVALUE;
1660 break;
1661 }
1662 for (i = 0; i < numElems; i++, ptr += nBytes) memmove (ptr, &padE, nBytes);
1663 return;
1664 }
1665
1666 /******************************************************************************
1667 * DefaultPadBuffer.
1668 ******************************************************************************/
1669
DefaultPadBuffer(CDF,Var,nValues,buffer)1670 STATICforIDL CDFstatus DefaultPadBuffer (CDF, Var, nValues, buffer)
1671 struct CDFstruct *CDF;
1672 struct VarStruct *Var;
1673 Int32 nValues;
1674 void *buffer;
1675 {
1676 CDFstatus pStatus = CDF_OK;
1677 Byte *tBuffer = buffer; Int32 i; Int32 dataType, numElems;
1678 if (!sX(ReadVDR(CDF,CDF->fp,Var->VDRoffset,Var->zVar,
1679 VDR_DATATYPE,&dataType,
1680 VDR_NUMELEMS,&numElems,
1681 VDR_NULL),&pStatus)) return pStatus;
1682 for (i = 0; i < nValues; i++, tBuffer += (int) Var->NvalueBytes) {
1683 DefaultPadValue (dataType, numElems, tBuffer);
1684 }
1685 return pStatus;
1686 }
1687
1688 /******************************************************************************
1689 * PadBuffer.
1690 ******************************************************************************/
1691
PadBuffer(CDF,Var,nValues,buffer)1692 STATICforIDL CDFstatus PadBuffer (CDF, Var, nValues, buffer)
1693 struct CDFstruct *CDF; /* Pointer to CDF. */
1694 struct VarStruct *Var; /* Pointer to variable. */
1695 Int32 nValues; /* Number of values in buffer. */
1696 void *buffer; /* Buffer to pad. */
1697 {
1698 CDFstatus pStatus = CDF_OK;
1699 Int32 flags, dataType, numElems;
1700 /****************************************************************************
1701 * Read the flags, data type, and number of elements fields of the VDR.
1702 ****************************************************************************/
1703 if (!sX(ReadVDR(CDF,CDF->fp,Var->VDRoffset,Var->zVar,
1704 VDR_FLAGS,&flags,
1705 VDR_DATATYPE,&dataType,
1706 VDR_NUMELEMS,&numElems,
1707 VDR_NULL),&pStatus)) return pStatus;
1708 /****************************************************************************
1709 * If a pad value has been specified for the variable, read the pad value
1710 * from the VDR and duplicate for the desired number of values. Otherwise,
1711 * copy the desired number of default pad values into the buffer. Then
1712 * convert the padded buffer into the desired decoding.
1713 ****************************************************************************/
1714 if (PADvalueBITset(flags)) {
1715 Byte *tBuffer = buffer; Int32 valueN;
1716 if (!sX(ReadVDR(CDF,CDF->fp,Var->VDRoffset,Var->zVar,
1717 VDR_PADVALUE,tBuffer,
1718 VDR_NULL),&pStatus)) return pStatus;
1719 for (valueN = 1; valueN < nValues; valueN++) {
1720 memmove (tBuffer + ((size_t) Var->NvalueBytes), tBuffer,
1721 (size_t) Var->NvalueBytes);
1722 tBuffer += (size_t) Var->NvalueBytes;
1723 }
1724 if (!sX(ConvertBuffer(CDF->encoding,CDF->decoding,
1725 CDF->negToPosFp0,dataType,
1726 (nValues * numElems),
1727 buffer,buffer),&pStatus)) return pStatus;
1728 }
1729 else {
1730 if (!sX(DefaultPadBuffer(CDF,Var,nValues,buffer),&pStatus)) return pStatus;
1731 if (!sX(ConvertBuffer(HostEncoding(),CDF->decoding,
1732 CDF->negToPosFp0,dataType,
1733 (nValues * numElems),
1734 buffer,buffer),&pStatus)) return pStatus;
1735 }
1736 return pStatus;
1737 }
1738
1739 /******************************************************************************
1740 * HostEncoding.
1741 * Returns encoding type of host machine.
1742 ******************************************************************************/
1743
HostEncoding()1744 STATICforIDL Int32 HostEncoding ()
1745 {
1746 #if defined(sun)
1747 return ((Int32) SUN_ENCODING);
1748 #endif
1749 #if defined(vax)
1750 return ((Int32) VAX_ENCODING);
1751 #endif
1752 #if defined(MIPSEL)
1753 return ((Int32) DECSTATION_ENCODING);
1754 #endif
1755 #if defined(MIPSEB)
1756 return ((Int32) SGi_ENCODING);
1757 #endif
1758 #if defined(IBMPC) || defined(macosXintel)
1759 return ((Int32) IBMPC_ENCODING);
1760 #endif
1761 #if defined(IBMRS)
1762 return ((Int32) IBMRS_ENCODING);
1763 #endif
1764 #if defined(HP)
1765 return ((Int32) HP_ENCODING);
1766 #endif
1767 #if defined(NeXT)
1768 return ((Int32) NeXT_ENCODING);
1769 #endif
1770 #if defined(alphaosf)
1771 return ((Int32) ALPHAOSF1_ENCODING);
1772 #endif
1773 #if defined(alphavmsD) || defined(posixSHELLalphaD)
1774 return ((Int32) ALPHAVMSd_ENCODING);
1775 #endif
1776 #if defined(alphavmsG) || defined(posixSHELLalphaG)
1777 return ((Int32) ALPHAVMSg_ENCODING);
1778 #endif
1779 #if defined(alphavmsI) || defined(posixSHELLalphaI)
1780 return ((Int32) ALPHAVMSi_ENCODING);
1781 #endif
1782 #if defined(mac) || defined(POWERPC) || defined(macosXppc)
1783 return ((Int32) PPC_ENCODING);
1784 #endif
1785 }
1786
1787 /******************************************************************************
1788 * HostDecoding.
1789 * Returns decoding type of host machine.
1790 ******************************************************************************/
1791
HostDecoding()1792 STATICforIDL Int32 HostDecoding ()
1793 {
1794 #if defined(sun)
1795 return ((Int32) SUN_DECODING);
1796 #endif
1797 #if defined(vax)
1798 return ((Int32) VAX_DECODING);
1799 #endif
1800 #if defined(MIPSEL)
1801 return ((Int32) DECSTATION_DECODING);
1802 #endif
1803 #if defined(MIPSEB)
1804 return ((Int32) SGi_DECODING);
1805 #endif
1806 #if defined(IBMPC) || defined(macosXintel)
1807 return ((Int32) IBMPC_DECODING);
1808 #endif
1809 #if defined(IBMRS)
1810 return ((Int32) IBMRS_DECODING);
1811 #endif
1812 #if defined(HP)
1813 return ((Int32) HP_DECODING);
1814 #endif
1815 #if defined(NeXT)
1816 return ((Int32) NeXT_DECODING);
1817 #endif
1818 #if defined(alphaosf)
1819 return ((Int32) ALPHAOSF1_DECODING);
1820 #endif
1821 #if defined(alphavmsD) || defined(posixSHELLalphaD)
1822 return ((Int32) ALPHAVMSd_DECODING);
1823 #endif
1824 #if defined(alphavmsG) || defined(posixSHELLalphaG)
1825 return ((Int32) ALPHAVMSg_DECODING);
1826 #endif
1827 #if defined(alphavmsI)
1828 return ((Int32) ALPHAVMSi_DECODING);
1829 #endif
1830 #if defined(mac) || defined(POWERPC) || defined(macosXppc)
1831 return ((Int32) PPC_DECODING);
1832 #endif
1833 }
1834
1835 /******************************************************************************
1836 * IntegerOrder.
1837 * Returns integer order based on encoding (decoding).
1838 ******************************************************************************/
1839
IntegerOrder(ed)1840 STATICforIDL int IntegerOrder (ed)
1841 Int32 ed; /* Encoding/decoding. */
1842 {
1843 switch (ed) {
1844 case NETWORK_ENCODING:
1845 case SUN_ENCODING:
1846 case SGi_ENCODING:
1847 case IBMRS_ENCODING:
1848 case HP_ENCODING:
1849 case NeXT_ENCODING:
1850 case PPC_ENCODING:
1851 return BIGendianORDER;
1852 case DECSTATION_ENCODING:
1853 case ALPHAOSF1_ENCODING:
1854 case ALPHAVMSd_ENCODING:
1855 case ALPHAVMSg_ENCODING:
1856 case ALPHAVMSi_ENCODING:
1857 case IBMPC_ENCODING:
1858 case VAX_ENCODING:
1859 return LITTLEendianORDER;
1860 default:
1861 return 0; /* Internal error. */
1862 }
1863 }
1864
1865 /******************************************************************************
1866 * FpType.
1867 * Returns floating-point type based on encoding (decoding).
1868 ******************************************************************************/
1869
FpType(ed)1870 STATICforIDL int FpType (ed)
1871 Int32 ed; /* Encoding/decoding. */
1872 {
1873 switch (ed) {
1874 case NETWORK_ENCODING:
1875 case SUN_ENCODING:
1876 case SGi_ENCODING:
1877 case IBMRS_ENCODING:
1878 case HP_ENCODING:
1879 case NeXT_ENCODING:
1880 case PPC_ENCODING:
1881 return FP_1;
1882 case DECSTATION_ENCODING:
1883 case ALPHAOSF1_ENCODING:
1884 case IBMPC_ENCODING:
1885 case ALPHAVMSi_ENCODING:
1886 return FP_2;
1887 case VAX_ENCODING:
1888 case ALPHAVMSd_ENCODING:
1889 return FP_3;
1890 case ALPHAVMSg_ENCODING:
1891 return FP_4;
1892 default:
1893 return 0;
1894 }
1895 }
1896
1897 /******************************************************************************
1898 * CDFelemSize.
1899 ******************************************************************************/
1900
CDFelemSize(dataType)1901 STATICforIDL int CDFelemSize (dataType)
1902 long dataType;
1903 {
1904 switch (dataType) {
1905 case CDF_BYTE: return 1;
1906 case CDF_INT1: return 1;
1907 case CDF_INT2: return 2;
1908 case CDF_INT4: return 4;
1909 case CDF_UINT1: return 1;
1910 case CDF_UINT2: return 2;
1911 case CDF_UINT4: return 4;
1912 case CDF_REAL4: return 4;
1913 case CDF_REAL8: return 8;
1914 case CDF_FLOAT: return 4;
1915 case CDF_DOUBLE: return 8;
1916 case CDF_EPOCH: return 8;
1917 case CDF_EPOCH16: return 16;
1918 case CDF_CHAR: return 1;
1919 case CDF_UCHAR: return 1;
1920 }
1921 return 0;
1922 }
1923
1924 /******************************************************************************
1925 * EquivDataTypes.
1926 ******************************************************************************/
1927
EquivDataTypes(dataType1,dataType2)1928 STATICforIDL Logical EquivDataTypes (dataType1, dataType2)
1929 Int32 dataType1;
1930 Int32 dataType2;
1931 {
1932 switch (dataType1) {
1933 case CDF_BYTE:
1934 case CDF_INT1:
1935 case CDF_UINT1:
1936 case CDF_CHAR:
1937 case CDF_UCHAR:
1938 switch (dataType2) {
1939 case CDF_BYTE:
1940 case CDF_INT1:
1941 case CDF_UINT1:
1942 case CDF_CHAR:
1943 case CDF_UCHAR:
1944 return TRUE;
1945 default:
1946 return FALSE;
1947 }
1948 case CDF_INT2:
1949 case CDF_UINT2:
1950 switch (dataType2) {
1951 case CDF_INT2:
1952 case CDF_UINT2:
1953 return TRUE;
1954 default:
1955 return FALSE;
1956 }
1957 case CDF_INT4:
1958 case CDF_UINT4:
1959 switch (dataType2) {
1960 case CDF_INT4:
1961 case CDF_UINT4:
1962 return TRUE;
1963 default:
1964 return FALSE;
1965 }
1966 case CDF_REAL4:
1967 case CDF_FLOAT:
1968 switch (dataType2) {
1969 case CDF_REAL4:
1970 case CDF_FLOAT:
1971 return TRUE;
1972 default:
1973 return FALSE;
1974 }
1975 case CDF_REAL8:
1976 case CDF_DOUBLE:
1977 case CDF_EPOCH:
1978 switch (dataType2) {
1979 case CDF_REAL8:
1980 case CDF_DOUBLE:
1981 case CDF_EPOCH:
1982 return TRUE;
1983 default:
1984 return FALSE;
1985 }
1986 case CDF_EPOCH16:
1987 switch (dataType2) {
1988 case CDF_EPOCH16:
1989 return TRUE;
1990 default:
1991 return FALSE;
1992 }
1993 }
1994 return FALSE; /* CDF_INTERNAL_ERROR or CORRUPTED_V2_CDF? */
1995 }
1996
1997 /******************************************************************************
1998 * strcmpITB. Do a STRing CoMPare Ignoring any Trailing Blanks.
1999 ******************************************************************************/
2000
strcmpITB(string1,string2)2001 STATICforIDL int strcmpITB (string1, string2)
2002 char *string1;
2003 char *string2;
2004 {
2005 size_t len1 = strlen(string1);
2006 size_t len2 = strlen(string2);
2007 while (len1 > 0 && string1[len1-1] == ' ') len1--;
2008 while (len2 > 0 && string2[len2-1] == ' ') len2--;
2009 if (len1 == len2)
2010 return strncmp (string1, string2, len1);
2011 else
2012 return strcmp (string1, string2);
2013 }
2014
2015
2016 /******************************************************************************
2017 * FreeCDFid.
2018 * Free a CDF's dynamically allocated memory.
2019 ******************************************************************************/
2020
FreeCDFid(CDF,aborting)2021 STATICforIDL void FreeCDFid (CDF, aborting)
2022 struct CDFstruct *CDF;
2023 Logical aborting;
2024 {
2025 /****************************************************************************
2026 * Free file names/paths.
2027 ****************************************************************************/
2028 if (CDF->CDFname != NULL) cdf_FreeMemory (CDF->CDFname, NULL);
2029 if (CDF->scratchDir != NULL) cdf_FreeMemory (CDF->scratchDir, NULL);
2030 /****************************************************************************
2031 * Free rVariable structures.
2032 ****************************************************************************/
2033 if (CDF->rVars != NULL) {
2034 int varNum;
2035 for (varNum = 0; varNum < CDF->NrVars; varNum++) {
2036 if (CDF->rVars[varNum] != NULL) cdf_FreeMemory (CDF->rVars[varNum], NULL);
2037 }
2038 cdf_FreeMemory (CDF->rVars, NULL);
2039 }
2040 /****************************************************************************
2041 * Free zVariable structures.
2042 ****************************************************************************/
2043 if (CDF->zVars != NULL) {
2044 int varNum;
2045 for (varNum = 0; varNum < CDF->NzVars; varNum++) {
2046 if (CDF->zVars[varNum] != NULL) cdf_FreeMemory (CDF->zVars[varNum], NULL);
2047 }
2048 cdf_FreeMemory (CDF->zVars, NULL);
2049 }
2050 /****************************************************************************
2051 * Free CDF structure. The CDF structure's magic number is "killed" just in
2052 * case the application tries to use the CDFid again.
2053 ****************************************************************************/
2054 if (aborting)
2055 CDF->magic = ABORTEDid_MAGIC_NUMBER;
2056 else {
2057 CDF->magic = KILLEDid_MAGIC_NUMBER;
2058 cdf_FreeMemory (CDF, NULL);
2059 }
2060 return;
2061 }
2062
2063 /******************************************************************************
2064 * CloseLRUvar.
2065 * Close a variable/zVariable file to free a file pointer.
2066 ******************************************************************************/
2067
CloseLRUvar(CDF)2068 STATICforIDL CDFstatus CloseLRUvar (CDF)
2069 struct CDFstruct *CDF;
2070 {
2071 struct VarStruct *Var, *oldestVar = NULL;
2072 uLong oldest_access = CDF->pseudo_clock; int varNum;
2073 /****************************************************************************
2074 * Scan through rVariables looking for oldest access.
2075 ****************************************************************************/
2076 for (varNum = 0; varNum < CDF->NrVars; varNum++) {
2077 Var = CDF->rVars[varNum];
2078 if (Var != NULL) {
2079 if (Var->fp != NULL) {
2080 if (Var->accessed_at < oldest_access) {
2081 oldest_access = Var->accessed_at;
2082 oldestVar = Var;
2083 }
2084 }
2085 }
2086 }
2087 /****************************************************************************
2088 * Scan through zVariables looking for oldest access.
2089 ****************************************************************************/
2090 for (varNum = 0; varNum < CDF->NzVars; varNum++) {
2091 Var = CDF->zVars[varNum];
2092 if (Var != NULL) {
2093 if (Var->fp != NULL) {
2094 if (Var->accessed_at < oldest_access) {
2095 oldest_access = Var->accessed_at;
2096 oldestVar = Var;
2097 }
2098 }
2099 }
2100 }
2101 /****************************************************************************
2102 * If a variable was found, close the associated file.
2103 ****************************************************************************/
2104 if (oldestVar != NULL) {
2105 if (!CLOSEv(oldestVar->fp,NULL,NULL)) {
2106 oldestVar->fp = NULL;
2107 return VAR_CLOSE_ERROR;
2108 }
2109 oldestVar->fp = NULL;
2110 }
2111 return CDF_OK;
2112 }
2113
2114 /******************************************************************************
2115 * CheckEntryOp.
2116 ******************************************************************************/
2117
CheckEntryOp(CDF,entryType)2118 STATICforIDL CDFstatus CheckEntryOp (CDF, entryType)
2119 struct CDFstruct *CDF;
2120 int entryType;
2121 {
2122 Int32 scope; CDFstatus pStatus = CDF_OK;
2123 if (!sX(ReadADR(CDF->fp,CDF->CURattrOffset,
2124 ADR_SCOPE,&scope,
2125 ADR_NULL),&pStatus)) {
2126 AbortAccess (CDF, UPDATE, noDELETE);
2127 return pStatus;
2128 }
2129 if (GLOBALscope(scope)) {
2130 if (entryType != gENTRYt) return ILLEGAL_FOR_SCOPE;
2131 }
2132 else {
2133 if (entryType == gENTRYt) return ILLEGAL_FOR_SCOPE;
2134 if (BADzOP(CDF,entryType == rENTRYt)) return ILLEGAL_IN_zMODE;
2135 }
2136 return pStatus;
2137 }
2138
2139 /******************************************************************************
2140 * SetCURgrEntry.
2141 ******************************************************************************/
2142
SetCURgrEntry(CDF,useCurrent,entryNum)2143 STATICforIDL CDFstatus SetCURgrEntry (CDF, useCurrent, entryNum)
2144 struct CDFstruct *CDF;
2145 Logical useCurrent; /* TRUE if current g/rEntry offset can be used to speed
2146 up the search. */
2147 Int32 entryNum; /* The new g/rEntry number. */
2148 {
2149 CDFstatus pStatus = CDF_OK, tStatus;
2150 Int32 scope, offset, attrNum, attrNumX, entryNumX, nextOffset;
2151 long read_only_mode;
2152 /****************************************************************************
2153 * Check if the new g/rEntry number is the reserved entry number.
2154 ****************************************************************************/
2155 if (entryNum == RESERVED_ENTRYNUM) {
2156 CDF->CURgrEntryNum = RESERVED_ENTRYNUM;
2157 CDF->fp->CurAEDRIndex = RESERVED_ENTRYNUM;
2158 CDF->CURgrEntryOffset = RESERVED_ENTRYOFFSET;
2159 return pStatus;
2160 }
2161 /****************************************************************************
2162 * Check that a current attribute is selected.
2163 ****************************************************************************/
2164 if (CDF->CURattrOffset == RESERVED_ATTROFFSET) {
2165 CDF->CURgrEntryNum = entryNum;
2166 CDF->fp->CurAEDRIndex = RESERVED_ENTRYNUM;
2167 CDF->CURgrEntryOffset = RESERVED_ENTRYOFFSET;
2168 return pStatus;
2169 }
2170 /****************************************************************************
2171 * Get the scope and number of the current attribute. If READONLYon, the
2172 * scope and number are already in th mteadata structures.
2173 ****************************************************************************/
2174 pStatus = CDFlib(CONFIRM_, CDF_READONLY_MODE_, &read_only_mode, NULL_);
2175 if (pStatus != CDF_OK) return pStatus;
2176 if (read_only_mode == READONLYon)
2177 {
2178 scope = CDF->fp->ADRList[CDF->fp->CurADRIndex]->Scope;
2179 attrNum = CDF->fp->CurADRIndex;
2180 }
2181 else
2182 {
2183 if (!sX(ReadADR(CDF->fp,CDF->CURattrOffset,
2184 ADR_SCOPE,&scope,
2185 ADR_NUM,&attrNum,
2186 ADR_NULL),&pStatus)) return pStatus;
2187 };
2188 /****************************************************************************
2189 * If the current attribute is variable-scoped and zMode is on, then the
2190 * current g/rEntry offset is n/a.
2191 ****************************************************************************/
2192 if (VARIABLEscope(scope) && zModeON(CDF)) {
2193 CDF->CURgrEntryNum = entryNum;
2194 CDF->fp->CurAEDRIndex = RESERVED_ENTRYNUM;
2195 CDF->CURgrEntryOffset = RESERVED_ENTRYOFFSET;
2196 return pStatus;
2197 }
2198 /****************************************************************************
2199 * IF READONLYoff, check if the next entry is the one being searched for.
2200 * For this to be the case, an entry must currently be selected and must be
2201 * associated with the current attribute, the next entry must exist, and the
2202 * next entry's number must be the entry number being searched for. But
2203 * don't try this if a V2.0 CDF because of the bad terminating offset of the
2204 * AEDR linked lists in those CDFs.
2205 ****************************************************************************/
2206 if (read_only_mode == READONLYoff && useCurrent &&
2207 !CDF->badTerminatingOffsets) {
2208 if (CDF->CURgrEntryOffset != RESERVED_ENTRYOFFSET) {
2209 if (!sX(ReadAEDR(CDF->fp,CDF->CURgrEntryOffset,
2210 AEDR_ATTRNUM,&attrNumX,
2211 AEDR_AEDRNEXT,&nextOffset,
2212 AEDR_NULL),&pStatus)) return pStatus;
2213 if (attrNumX == attrNum && nextOffset != 0) {
2214 if (!sX(ReadAEDR(CDF->fp,nextOffset,
2215 AEDR_NUM,&entryNumX,
2216 AEDR_NULL),&pStatus)) return pStatus;
2217 if (entryNumX == entryNum) {
2218 CDF->CURgrEntryNum = entryNum;
2219 CDF->CURgrEntryOffset = nextOffset;
2220 return pStatus;
2221 }
2222 }
2223 }
2224 }
2225 /****************************************************************************
2226 * Search the list of AEDRs for the entry.
2227 ****************************************************************************/
2228 tStatus = FindEntryByNumber (CDF, CDF->CURattrOffset, FALSE, entryNum,
2229 &offset);
2230 switch (tStatus) {
2231 case CDF_OK:
2232 break;
2233 case NO_SUCH_ENTRY:
2234 offset = RESERVED_ENTRYOFFSET;
2235 break;
2236 default:
2237 return tStatus;
2238 }
2239 CDF->CURgrEntryNum = entryNum;
2240 CDF->CURgrEntryOffset = offset;
2241 return pStatus;
2242 }
2243
2244 /******************************************************************************
2245 * SetCURzEntry.
2246 ******************************************************************************/
2247
SetCURzEntry(CDF,useCurrent,entryNum)2248 STATICforIDL CDFstatus SetCURzEntry (CDF, useCurrent, entryNum)
2249 struct CDFstruct *CDF;
2250 Logical useCurrent; /* TRUE if current zEntry offset can be used to speed
2251 up the search. */
2252 Int32 entryNum; /* The new zEntry number. */
2253 {
2254 CDFstatus pStatus = CDF_OK, tStatus;
2255 Int32 scope, offset, attrNum, attrNumX, entryNumX, nextOffset;
2256 Logical zEntry;
2257 Int32 entryN;
2258 long read_only_mode;
2259 /****************************************************************************
2260 * Check if the new zEntry number is the reserved entry number.
2261 ****************************************************************************/
2262 if (entryNum == RESERVED_ENTRYNUM) {
2263 CDF->CURzEntryNum = RESERVED_ENTRYNUM;
2264 CDF->fp->CurAEDRIndex = RESERVED_ENTRYNUM;
2265 CDF->CURzEntryOffset = RESERVED_ENTRYOFFSET;
2266 return pStatus;
2267 }
2268 /****************************************************************************
2269 * Check that a current attribute is selected.
2270 ****************************************************************************/
2271 if (CDF->CURattrOffset == RESERVED_ATTROFFSET) {
2272 CDF->CURzEntryNum = entryNum;
2273 CDF->fp->CurAEDRIndex = RESERVED_ENTRYNUM;
2274 CDF->CURzEntryOffset = RESERVED_ENTRYOFFSET;
2275 return pStatus;
2276 }
2277 /****************************************************************************
2278 * Read the scope and number of the current attribute. If READONLYon, they
2279 * are already in memory.
2280 ****************************************************************************/
2281 pStatus = CDFlib(CONFIRM_, CDF_READONLY_MODE_, &read_only_mode, NULL_);
2282 if (pStatus != CDF_OK) return pStatus;
2283 if (read_only_mode == READONLYon)
2284 {
2285 scope = CDF->fp->ADRList[CDF->fp->CurADRIndex]->Scope;
2286 attrNum = CDF->fp->CurADRIndex;
2287 }
2288 else
2289 {
2290 if (!sX(ReadADR(CDF->fp,CDF->CURattrOffset,
2291 ADR_SCOPE,&scope,
2292 ADR_NUM,&attrNum,
2293 ADR_NULL),&pStatus)) return pStatus;
2294 };
2295 /****************************************************************************
2296 * If the current attribute is global-scoped, then the current zEntry offset
2297 * is n/a.
2298 ****************************************************************************/
2299 if (GLOBALscope(scope)) {
2300 CDF->CURzEntryNum = entryNum;
2301 CDF->fp->CurAEDRIndex = RESERVED_ENTRYNUM;
2302 CDF->CURzEntryOffset = RESERVED_ENTRYOFFSET;
2303 return pStatus;
2304 }
2305 /****************************************************************************
2306 * Determine if a AgrEDR or AzEDR and the true entry number.
2307 ****************************************************************************/
2308 if (zModeON(CDF)) {
2309 if (entryNum < CDF->NrVars) {
2310 zEntry = FALSE;
2311 entryN = entryNum;
2312 }
2313 else {
2314 zEntry = TRUE;
2315 entryN = entryNum - CDF->NrVars;
2316 }
2317 }
2318 else {
2319 zEntry = TRUE;
2320 entryN = entryNum;
2321 }
2322 /****************************************************************************
2323 * IF READONLYoff, check if the next entry is the one being searched for.
2324 * For this to be the case, an entry must currently be selected and must be
2325 * associated with the current attribute, the next entry must exist, and the
2326 * next entry's number must be the entry number being searched for. But don't
2327 * try this if a V2.0 CDF because of the bad terminating offset of the AEDR
2328 * linked lists in those CDFs.
2329 ****************************************************************************/
2330 if (read_only_mode == READONLYoff && useCurrent &&
2331 !CDF->badTerminatingOffsets) {
2332 if (CDF->CURzEntryOffset != RESERVED_ENTRYOFFSET) {
2333 if (!sX(ReadAEDR(CDF->fp,CDF->CURzEntryOffset,
2334 AEDR_ATTRNUM,&attrNumX,
2335 AEDR_AEDRNEXT,&nextOffset,
2336 AEDR_NULL),&pStatus)) return pStatus;
2337 if (attrNumX == attrNum && nextOffset != 0) {
2338 if (!sX(ReadAEDR(CDF->fp,nextOffset,
2339 AEDR_NUM,&entryNumX,
2340 AEDR_NULL),&pStatus)) return pStatus;
2341 if (entryNumX == entryN) {
2342 CDF->CURzEntryNum = entryNum;
2343 CDF->CURzEntryOffset = nextOffset;
2344 return pStatus;
2345 }
2346 }
2347 }
2348 }
2349 /****************************************************************************
2350 * Search the list of AEDRs for the entry.
2351 ****************************************************************************/
2352 tStatus = FindEntryByNumber (CDF, CDF->CURattrOffset, zEntry, entryN,
2353 &offset);
2354 switch (tStatus) {
2355 case CDF_OK:
2356 break;
2357 case NO_SUCH_ENTRY:
2358 offset = RESERVED_ENTRYOFFSET;
2359 break;
2360 default:
2361 return tStatus;
2362 }
2363 CDF->CURzEntryNum = entryNum;
2364 CDF->CURzEntryOffset = offset;
2365 return pStatus;
2366 }
2367
2368 /******************************************************************************
2369 * Int32ToCDFid.
2370 ******************************************************************************/
2371
Int32ToCDFid(id)2372 STATICforIDL CDFid Int32ToCDFid (id)
2373 Int32 id;
2374 {
2375 #if defined(alphaosf) || defined(IRIX64bit) || defined(SOLARIS64) || \
2376 defined(__amd64) || defined(__x86_64__) || defined(__ia64__) || \
2377 defined(__PPC64__) || defined(__ppc64__)
2378 # if defined(alphaosf)
2379 if (id == 0)
2380 return RESERVED_CDFID;
2381 else
2382 return ((CDFid) ((long) id | (long) 0x100000000));
2383 # else
2384 union {
2385 CDFid id;
2386 Int32 i[2];
2387 } u;
2388 # if defined(IRIX64bit) || defined(SOLARIS64) || defined(__PPC64__) || \
2389 defined(__ppc64__)
2390 # if defined(IRIX64bit)
2391 u.i[0] = 0;
2392 # else
2393 u.i[0] = 1;
2394 # endif
2395 u.i[1] = id;
2396 # else
2397 # if defined(__MACH__) /* Mac on Intel */
2398 u.i[1] = 1;
2399 u.i[0] = id;
2400 # else
2401 u.i[1] = 0;
2402 u.i[0] = id;
2403 # endif
2404 # endif
2405 return u.id;
2406 # endif
2407 #else
2408 return ((CDFid) id);
2409 #endif
2410 }
2411
2412 /******************************************************************************
2413 * CDFidToInt32.
2414 * On 64-bit machines (OSF/1, IRIX 6.x and Solaris in 64-bit mode),
2415 * truncation may occur when the pointer (CDFid) is assigned to a 32-bit
2416 * integer.
2417 ******************************************************************************/
2418
CDFidToInt32(id)2419 STATICforIDL Int32 CDFidToInt32 (id)
2420 CDFid id;
2421 {
2422 #if defined(alphaosf) || defined(IRIX64bit) || defined(SOLARIS64) || \
2423 defined(__amd64) || defined(__x86_64__) || defined(__ia64__) || \
2424 defined(__PPC64__) || defined(__ppc64__)
2425 union {
2426 CDFid id;
2427 Int32 i[2];
2428 } u;
2429 u.id = id;
2430 # if defined(alphaosf) || defined(__amd64) || defined(__x86_64__) || \
2431 defined(__ia64__)
2432 return u.i[0];
2433 # endif
2434 # if defined(IRIX64bit) || defined(SOLARIS64) || defined(__PPC64__) || \
2435 defined(__ppc64__)
2436 return u.i[1];
2437 # endif
2438 #else
2439 return ((Int32) id);
2440 #endif
2441 }
2442
2443 /******************************************************************************
2444 * VariableType.
2445 ******************************************************************************/
2446
VariableType(CDF,vdrOffset,zVar,vType)2447 STATICforIDL CDFstatus VariableType (CDF, vdrOffset, zVar, vType)
2448 struct CDFstruct *CDF;
2449 Int32 vdrOffset;
2450 Logical zVar;
2451 int *vType;
2452 {
2453 CDFstatus pStatus = CDF_OK; Int32 flags, sRecords;
2454 if (!sX(ReadVDR(CDF,CDF->fp,vdrOffset,zVar,
2455 VDR_FLAGS,&flags,
2456 VDR_sRECORDS,&sRecords,
2457 VDR_NULL),&pStatus)) return pStatus;
2458 if (CDF->singleFile) {
2459 if (VARcompressionBITset(flags) && SPARSEarraysBITset(flags)) {
2460 return CORRUPTED_V2_CDF;
2461 }
2462 if (sRecords == NO_SPARSERECORDS) {
2463 *vType = STANDARD_;
2464 if (VARcompressionBITset(flags)) *vType = COMPRESSED_;
2465 if (SPARSEarraysBITset(flags)) *vType = SPARSE_ARRAYS_;
2466 }
2467 else {
2468 *vType = SPARSE_RECORDS_;
2469 if (VARcompressionBITset(flags)) *vType = SPARSE_COMPRESSED_RECORDS_;
2470 if (SPARSEarraysBITset(flags)) *vType = SPARSE_RECORDS_AND_ARRAYS_;
2471 }
2472 }
2473 else {
2474 *vType = IN_MULTI_;
2475 if (VARcompressionBITset(flags)) return CORRUPTED_V2_CDF;
2476 if (SPARSEarraysBITset(flags)) return CORRUPTED_V2_CDF;
2477 if (sRecords != NO_SPARSERECORDS) return CORRUPTED_V2_CDF;
2478 }
2479 return pStatus;
2480 }
2481
2482 /******************************************************************************
2483 * CompressionParmsCount.
2484 ******************************************************************************/
2485
CompressionParmsCount(cType)2486 STATICforIDL int CompressionParmsCount (cType)
2487 Int32 cType;
2488 {
2489 switch (cType) {
2490 case NO_COMPRESSION: return 0;
2491 case RLE_COMPRESSION: return NUM_RLE_PARMS;
2492 case HUFF_COMPRESSION: return NUM_HUFF_PARMS;
2493 case AHUFF_COMPRESSION: return NUM_AHUFF_PARMS;
2494 case GZIP_COMPRESSION: return NUM_GZIP_PARMS;
2495 /* case ZLIB_COMPRESSION: return NUM_ZLIB_PARMS; */
2496 }
2497 return 0; /* CORRUPTED_V2_CDF or CDF_INTERNAL_ERROR? */
2498 }
2499
2500 /******************************************************************************
2501 * SparsenessParmsCount.
2502 ******************************************************************************/
2503
SparsenessParmsCount(sArraysType)2504 STATICforIDL int SparsenessParmsCount (sArraysType)
2505 Int32 sArraysType;
2506 {
2507 switch (sArraysType) {
2508 case NO_SPARSEARRAYS:
2509 return 0;
2510 }
2511 return 0; /* CORRUPTED_V2_CDF or CDF_INTERNAL_ERROR? */
2512 }
2513
2514 /******************************************************************************
2515 * Compress.
2516 ******************************************************************************/
2517
Compress(iFp,iOffset,iSize,iError,cType,cParms,oFp,oOffset,oSize,oError)2518 STATICforIDL CDFstatus Compress (iFp, iOffset, iSize, iError, cType, cParms,
2519 oFp, oOffset, oSize, oError)
2520 vFILE *iFp;
2521 Int32 iOffset;
2522 Int32 iSize;
2523 CDFstatus iError;
2524 Int32 cType;
2525 Int32 cParms[];
2526 vFILE *oFp;
2527 Int32 oOffset;
2528 Int32 *oSize;
2529 CDFstatus oError;
2530 {
2531 CDFstatus pStatus = CDF_OK;
2532 switch (cType) {
2533 case RLE_COMPRESSION: {
2534 if (cParms[0] != RLE_OF_ZEROs) return UNKNOWN_COMPRESSION;
2535 if (!sX(CompressRLE0(iFp,iOffset,iSize,iError,
2536 oFp,oOffset,oSize,oError),&pStatus)) return pStatus;
2537 break;
2538 }
2539 case HUFF_COMPRESSION:
2540 if (cParms[0] != OPTIMAL_ENCODING_TREES) return UNKNOWN_COMPRESSION;
2541 if (!sX(CompressHUFF0(iFp,iOffset,
2542 iSize,iError,oFp,
2543 oOffset,oSize,oError),&pStatus)) return pStatus;
2544 break;
2545 case AHUFF_COMPRESSION:
2546 if (cParms[0] != OPTIMAL_ENCODING_TREES) return UNKNOWN_COMPRESSION;
2547 if (!sX(CompressAHUFF0(iFp,iOffset,
2548 iSize,iError,oFp,
2549 oOffset,oSize,oError),&pStatus)) return pStatus;
2550 break;
2551 case GZIP_COMPRESSION:
2552 if (!INCLUSIVE(1,cParms[0],9)) return UNKNOWN_COMPRESSION;
2553 if (!sX(CompressGZIP(iFp,iOffset,iSize,iError,
2554 oFp,oOffset,oSize,
2555 oError,cParms[0]),&pStatus)) return pStatus;
2556 break;
2557 default:
2558 return UNKNOWN_COMPRESSION;
2559 }
2560 return pStatus;
2561 }
2562
2563 /******************************************************************************
2564 * Decompress.
2565 ******************************************************************************/
2566
Decompress(iFp,iOffset,iSize,iError,cType,cParms,oFp,oOffset,oError)2567 STATICforIDL CDFstatus Decompress (iFp, iOffset, iSize, iError, cType, cParms,
2568 oFp, oOffset, oError)
2569 vFILE *iFp;
2570 Int32 iOffset;
2571 Int32 iSize;
2572 CDFstatus iError;
2573 Int32 cType;
2574 Int32 cParms[];
2575 vFILE *oFp;
2576 Int32 oOffset;
2577 CDFstatus oError;
2578 {
2579 CDFstatus pStatus = CDF_OK;
2580 switch (cType) {
2581 case RLE_COMPRESSION: {
2582 if (cParms[0] != RLE_OF_ZEROs) return UNKNOWN_COMPRESSION;
2583 if (!sX(DecompressRLE0(iFp,iOffset,iSize,iError,
2584 oFp,oOffset,oError),&pStatus)) return pStatus;
2585 break;
2586 }
2587 case HUFF_COMPRESSION:
2588 if (cParms[0] != OPTIMAL_ENCODING_TREES) return UNKNOWN_COMPRESSION;
2589 if (!sX(DecompressHUFF0(iFp,iOffset,iError,
2590 oFp,oOffset,oError),&pStatus)) return pStatus;
2591 break;
2592 case AHUFF_COMPRESSION:
2593 if (cParms[0] != OPTIMAL_ENCODING_TREES) return UNKNOWN_COMPRESSION;
2594 if (!sX(DecompressAHUFF0(iFp,iOffset,iError,
2595 oFp,oOffset,oError),&pStatus)) return pStatus;
2596 break;
2597 case GZIP_COMPRESSION:
2598 if (!INCLUSIVE(1,cParms[0],9)) return UNKNOWN_COMPRESSION;
2599 if (!sX(DecompressGZIP(iFp,iOffset,iError,
2600 oFp,oOffset,oError),&pStatus)) return pStatus;
2601 break;
2602 default:
2603 return UNKNOWN_COMPRESSION;
2604 }
2605 return pStatus;
2606 }
2607
2608 /******************************************************************************
2609 * DecompressToStage.
2610 ******************************************************************************/
2611
DecompressToStage(CDF,Var,offset,uSize)2612 STATICforIDL CDFstatus DecompressToStage (CDF, Var, offset, uSize)
2613 struct CDFstruct *CDF;
2614 struct VarStruct *Var;
2615 Int32 offset;
2616 Int32 uSize;
2617 {
2618 CDFstatus pStatus = CDF_OK; Int32 irType, tOffset;
2619 if (!sX(ReadIrType(CDF->fp,offset,&irType),&pStatus)) return pStatus;
2620 switch (irType) {
2621 case VVR_: {
2622 tOffset = offset + VVR_BASE_SIZE;
2623 if (!sX(CopyBytes(CDF->fp,tOffset,
2624 CDF_READ_ERROR,
2625 uSize,CDF->stage.fp,
2626 Var->stage.areaOffset,
2627 SCRATCH_WRITE_ERROR),&pStatus)) return pStatus;
2628 break;
2629 }
2630 case CVVR_: {
2631 struct CVVRstruct CVVR;
2632 if (!sX(ReadCVVR(CDF->fp,offset,
2633 CVVR_RECORDx,&CVVR,
2634 CVVR_NULL),&pStatus)) return pStatus;
2635 tOffset = offset + CVVR_BASE_SIZE;
2636 if (!sX(Decompress(CDF->fp,tOffset,
2637 CVVR.cSize,CDF_READ_ERROR,
2638 Var->cType,Var->cParms,CDF->stage.fp,
2639 Var->stage.areaOffset,
2640 SCRATCH_WRITE_ERROR),&pStatus)) return pStatus;
2641 break;
2642 }
2643 default:
2644 return CORRUPTED_V2_CDF;
2645 }
2646 return pStatus;
2647 }
2648
2649 /******************************************************************************
2650 * ResetReadOnlyState.
2651 ******************************************************************************/
2652
ResetReadOnlyState(CDF)2653 STATICforIDL void ResetReadOnlyState (CDF)
2654 struct CDFstruct *CDF;
2655 {
2656 Int32 i, j;
2657 /*************************************************************************
2658 * Free all allocated memory associated with the metadata READONLYon data
2659 * structures and clear all the state variables.
2660 *************************************************************************/
2661 if (CDF->fp != NULL && CDF->fp->GDR != NULL)
2662 {
2663 for (i = 0; i < CDF->fp->GDR->NumAttr; i++)
2664 {
2665 if (CDF->fp->ADRList[i] != NULL)
2666 {
2667 for (j = 0; j <= CDF->fp->ADRList[i]->MAXgrEntry; j++)
2668 {
2669 if (CDF->fp->ADRList[i]->grAEDRList[j] != NULL)
2670 {
2671 cdf_FreeMemory(
2672 CDF->fp->ADRList[i]->grAEDRList[j]->Value, NULL);
2673 CDF->fp->ADRList[i]->grAEDRList[j]->Value = NULL;
2674 cdf_FreeMemory(CDF->fp->ADRList[i]->grAEDRList[j],
2675 NULL);
2676 CDF->fp->ADRList[i]->grAEDRList[j] = NULL;
2677 };
2678 };
2679 for (j = 0; j <= CDF->fp->ADRList[i]->MAXzEntry; j++)
2680 {
2681 if (CDF->fp->ADRList[i]->zAEDRList[j] != NULL)
2682 {
2683 cdf_FreeMemory(
2684 CDF->fp->ADRList[i]->zAEDRList[j]->Value, NULL);
2685 CDF->fp->ADRList[i]->zAEDRList[j]->Value = NULL;
2686 cdf_FreeMemory(CDF->fp->ADRList[i]->zAEDRList[j], NULL);
2687 CDF->fp->ADRList[i]->zAEDRList[j] = NULL;
2688 };
2689 };
2690 };
2691 cdf_FreeMemory(CDF->fp->ADRList[i], NULL);
2692 CDF->fp->ADRList[i] = NULL;
2693 };
2694 if (CDF->fp->ADRList != NULL)
2695 {
2696 cdf_FreeMemory(CDF->fp->ADRList, NULL);
2697 CDF->fp->ADRList = NULL;
2698 };
2699 cdf_FreeMemory(CDF->fp->GDR, NULL);
2700 CDF->fp->GDR = NULL;
2701 CDF->fp->CurADRIndex = RESERVED_ENTRYNUM;
2702 CDF->fp->CurAEDRIndex = RESERVED_ENTRYNUM;
2703 CDF->CURattrOffset = RESERVED_ATTROFFSET;
2704 CDF->CURgrEntryOffset = RESERVED_ENTRYOFFSET;
2705 CDF->CURzEntryOffset = RESERVED_ENTRYOFFSET;
2706 };
2707 }
2708