1 /******************************************************************************
2 *
3 *  NSSDC/CDF                                        CDF `confirm' operations.
4 *
5 *  Version 1.5a, 21-Feb-97, Hughes STX.
6 *
7 *  Modification history:
8 *
9 *   V1.0  20-May-92, J Love     Original version (was part of `cdflib.c').
10 *   V1.1  21-Aug-92, J Love     CDF V2.3 (shareable/NeXT/zVar).
11 *   V1.2  21-Dec-93, J Love     CDF V2.4.
12 *   V1.2a 22-Feb-94, J Love     Spelling lesson.
13 *   V1.3  19-Dec-94, J Love     CDF V2.5.
14 *   V1.3a 24-Feb-95, J Love	Solaris 2.3 IDL i/f.
15 *   V1.4  15-May-95, J Love	Added <CONFIRM_,CDF_>.
16 *   V1.4a  8-Jun-95, J Love	Added <CONFIRM_,r/zVAR_PADVALUE_>.
17 *   V1.4b  4-Aug-95, J Love	CDFexport-related changes.
18 *   V1.5   5-Sep-96, J Love	CDF V2.6.
19 *   V1.5a 21-Feb-97, J Love	Removed RICE.
20 *
21 ******************************************************************************/
22 
23 #include "cdflib.h"
24 #include "cdflib64.h"
25 
26 /******************************************************************************
27 * CDFcon.
28 ******************************************************************************/
29 
CDFcon(Va,Cur)30 STATICforIDL CDFstatus CDFcon (Va, Cur)
31 struct VAstruct *Va;
32 struct CurStruct *Cur;
33 {
34 CDFstatus tStatus, pStatus = CDF_OK;
35 
36 switch (Va->item) {
37   /****************************************************************************
38   * CDF_
39   ****************************************************************************/
40   case CDF_: {
41     CDFid *id = va_arg (Va->ap, CDFid *);
42     *id = (CDFid) Cur->cdf;
43     break;
44   }
45   /****************************************************************************
46   * CDF_STATUS_
47   ****************************************************************************/
48   case CDF_STATUS_: {
49     CDFstatus *status = va_arg (Va->ap, CDFstatus *);
50     *status = Cur->status;
51     break;
52   }
53   /****************************************************************************
54   * CDF_NAME_
55   ****************************************************************************/
56   case CDF_NAME_: {
57     struct CDFstruct *CDF;
58     char *CDFname = va_arg (Va->ap, char *);
59     SelectCDF (Cur->cdf, CDF)
60     strcpyX (CDFname, CDF->CDFname, CDF_PATHNAME_LEN);
61     break;
62   }
63   /****************************************************************************
64   * CDF_ACCESS_
65   * The `SelectCDF' macro returns NO_MORE_ACCESS if that is the case.
66   ****************************************************************************/
67   case CDF_ACCESS_: {
68     if (Cur->cdf == NULL) return NO_CDF_SELECTED;
69     if (Cur->cdf->magic == ABORTEDid_MAGIC_NUMBER) return NO_MORE_ACCESS;
70     break;
71   }
72   /****************************************************************************
73   * CDF_READONLY_MODE_
74   ****************************************************************************/
75   case CDF_READONLY_MODE_: {
76     struct CDFstruct *CDF;
77     long *mode = va_arg (Va->ap, long *);
78     SelectCDF (Cur->cdf, CDF)
79     *mode = BOO(CDF->readOnly,READONLYon,READONLYoff);
80     break;
81   }
82   /****************************************************************************
83   * CDF_zMODE_
84   ****************************************************************************/
85   case CDF_zMODE_: {
86     struct CDFstruct *CDF;
87     long *mode = va_arg (Va->ap, long *);
88     SelectCDF (Cur->cdf, CDF)
89     *mode = CDF->zMode;
90     break;
91   }
92   /****************************************************************************
93   * CDF_NEGtoPOSfp0_MODE_
94   ****************************************************************************/
95   case CDF_NEGtoPOSfp0_MODE_: {
96     struct CDFstruct *CDF;
97     long *mode = va_arg (Va->ap, long *);
98     SelectCDF (Cur->cdf, CDF)
99     *mode = BOO(CDF->negToPosFp0,NEGtoPOSfp0on,NEGtoPOSfp0off);
100     break;
101   }
102   /****************************************************************************
103   * CDF_DECODING_
104   ****************************************************************************/
105   case CDF_DECODING_: {
106     struct CDFstruct *CDF;
107     long *decoding = va_arg (Va->ap, long *);
108     SelectCDF (Cur->cdf, CDF)
109     *decoding = CDF->decoding;
110     break;
111   }
112   /****************************************************************************
113   * CDF_CACHESIZE_
114   ****************************************************************************/
115   case CDF_CACHESIZE_: {
116     struct CDFstruct *CDF;
117     long *nBuffers = va_arg (Va->ap, long *);
118     SelectCDF (Cur->cdf, CDF)
119     *nBuffers = (long) CDF->workingCacheSize;
120     break;
121   }
122   /****************************************************************************
123   * STAGE_CACHESIZE_
124   ****************************************************************************/
125   case STAGE_CACHESIZE_: {
126     struct CDFstruct *CDF;
127     long *nBuffers = va_arg (Va->ap, long *);
128     SelectCDF (Cur->cdf, CDF)
129     *nBuffers = (long) CDF->stage.cacheSize;
130     break;
131   }
132   /****************************************************************************
133   * COMPRESS_CACHESIZE_
134   ****************************************************************************/
135   case COMPRESS_CACHESIZE_: {
136     struct CDFstruct *CDF;
137     long *nBuffers = va_arg (Va->ap, long *);
138     SelectCDF (Cur->cdf, CDF)
139     *nBuffers = (long) CDF->compressCacheSize;
140     break;
141   }
142   /****************************************************************************
143   * rVAR_CACHESIZE_/zVAR_CACHESIZE_
144   ****************************************************************************/
145   case rVAR_CACHESIZE_:
146   case zVAR_CACHESIZE_: {
147     Logical zOp = (Va->item == zVAR_CACHESIZE_);
148     struct CDFstruct *CDF;
149     struct VarStruct *Var;
150     long *nBuffers = va_arg (Va->ap, long *);
151     SelectCDF (Cur->cdf, CDF)
152     if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
153     if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
154     if (!CDF->singleFile) {
155       if (!sX(InitCurrentVar(CDF,zOp,&Var),&pStatus)) {
156 	AbortAccess (CDF, UPDATE, noDELETE);
157 	return pStatus;
158       }
159       *nBuffers = (long) Var->varCacheSize;
160     }
161     else
162       sX (SINGLE_FILE_FORMAT, &pStatus);
163     break;
164   }
165   /****************************************************************************
166   * rVAR_/zVAR_
167   ****************************************************************************/
168   case rVAR_:
169   case zVAR_: {
170     Logical zOp = (Va->item == zVAR_);
171     struct CDFstruct *CDF;
172     long *varNum = va_arg (Va->ap, long *);
173     SelectCDF (Cur->cdf, CDF)
174     if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
175     if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
176     *varNum = BOO(zOp,CDF->CURzVarNum,CDF->CURrVarNum);
177     break;
178   }
179   /****************************************************************************
180   * rVAR_PADVALUE_/zVAR_PADVALUE_
181   ****************************************************************************/
182   case rVAR_PADVALUE_:
183   case zVAR_PADVALUE_: {
184     Logical zOp = (Va->item == zVAR_PADVALUE_), zVar;
185     struct CDFstruct *CDF;
186     Int32 offset, flags;
187     SelectCDF (Cur->cdf, CDF)
188     if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
189     if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
190 /*
191     if (!sX(LocateCurrentVar(CDF,zOp,&offset,&zVar,NULL),&pStatus)) {
192       AbortAccess (CDF, UPDATE, noDELETE);
193       return pStatus;
194     }
195 */
196 
197     zVar = CurrentVarMode(CDF,zOp);
198     if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
199     else offset = CDF->CURrVarOffset;
200 
201     if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
202 		    VDR_FLAGS,&flags,
203 		    VDR_NULL),&pStatus)) {
204       AbortAccess (CDF, UPDATE, noDELETE);
205       return pStatus;
206     }
207     if (!PADvalueBITset(flags)) sX (NO_PADVALUE_SPECIFIED, &pStatus);
208     break;
209   }
210   /****************************************************************************
211   * rVAR_EXISTENCE_/zVAR_EXISTENCE_, confirm the existence of a named variable.
212   ****************************************************************************/
213   case rVAR_EXISTENCE_:
214   case zVAR_EXISTENCE_: {
215     Logical zOp = (Va->item == zVAR_EXISTENCE_), zVar;
216     struct CDFstruct *CDF;
217     char *varName = va_arg (Va->ap, char *);
218     SelectCDF (Cur->cdf, CDF)
219     if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
220     tStatus = FindVarByName (CDF, varName, NULL, &zVar, NULL);
221     switch (tStatus) {
222       case CDF_OK:
223 	break;
224       case NO_SUCH_VAR:
225 	return tStatus;
226       default:
227 	AbortAccess (CDF, UPDATE, noDELETE);
228 	return tStatus;
229     }
230     if (!zModeON(CDF)) {
231       if ((zVar && !zOp) || (!zVar && zOp)) return NO_SUCH_VAR; /*Wrong type*/
232     }
233     break;
234   }
235   /****************************************************************************
236   * rVARs_RECNUMBER_/rVARs_RECCOUNT_/rVARs_RECINTERVAL_
237   ****************************************************************************/
238   case rVARs_RECNUMBER_:
239   case rVARs_RECCOUNT_:
240   case rVARs_RECINTERVAL_: {
241     struct CDFstruct *CDF;
242     long *value = va_arg (Va->ap, long *);
243     SelectCDF (Cur->cdf, CDF)
244     if (BADzOP(CDF,TRUE)) return ILLEGAL_IN_zMODE;
245     if (CDF->NrVars == 0) {
246       if (!sX(NO_VARS_IN_CDF,&pStatus)) return pStatus;
247     }
248     switch (Va->item) {
249       case rVARs_RECNUMBER_:
250 	*value = CDF->rRD.recNumber;
251 	break;
252       case rVARs_RECCOUNT_:
253 	*value = CDF->rRD.recCount;
254 	break;
255       case rVARs_RECINTERVAL_:
256 	*value = CDF->rRD.recInterval;
257 	break;
258     }
259     break;
260   }
261   /****************************************************************************
262   * zVAR_RECNUMBER_/zVAR_RECCOUNT_/zVAR_RECINTERVAL_
263   ****************************************************************************/
264   case zVAR_RECNUMBER_:
265   case zVAR_RECCOUNT_:
266   case zVAR_RECINTERVAL_: {
267     struct CDFstruct *CDF;
268     struct VarStruct *Var;
269     long *value = va_arg (Va->ap, long *);
270     SelectCDF (Cur->cdf, CDF)
271     if (!CURRENTvarSELECTED(CDF,TRUE)) return NO_VAR_SELECTED;
272     if (!sX(InitCurrentVar(CDF,TRUE,&Var),&pStatus)) {
273       AbortAccess (CDF, UPDATE, noDELETE);
274       return pStatus;
275     }
276     switch (Va->item) {
277       case zVAR_RECNUMBER_:
278 	*value = Var->zRD.recNumber;
279 	break;
280       case zVAR_RECCOUNT_:
281 	*value = Var->zRD.recCount;
282 	break;
283       case zVAR_RECINTERVAL_:
284 	*value = Var->zRD.recInterval;
285 	break;
286     }
287     break;
288   }
289   /****************************************************************************
290   * rVARs_DIMINDICES_/rVARs_DIMCOUNTS_/rVARs_DIMINTERVALS_
291   ****************************************************************************/
292   case rVARs_DIMINDICES_:
293   case rVARs_DIMCOUNTS_:
294   case rVARs_DIMINTERVALS_: {
295     struct CDFstruct *CDF; int dimN;
296     long *values = va_arg (Va->ap, long *);
297     SelectCDF (Cur->cdf, CDF)
298     if (BADzOP(CDF,TRUE)) return ILLEGAL_IN_zMODE;
299     if (CDF->NrVars == 0) {
300       if (!sX(NO_VARS_IN_CDF,&pStatus)) return pStatus;
301     }
302     switch (Va->item) {
303       case rVARs_DIMINDICES_:
304 	for (dimN = 0; dimN < CDF->rNumDims; dimN++)
305 	   values[dimN] = CDF->rRD.dimIndices[dimN];
306 	break;
307       case rVARs_DIMCOUNTS_:
308 	for (dimN = 0; dimN < CDF->rNumDims; dimN++)
309 	   values[dimN] = CDF->rRD.dimCounts[dimN];
310 	break;
311       case rVARs_DIMINTERVALS_:
312 	for (dimN = 0; dimN < CDF->rNumDims; dimN++)
313 	   values[dimN] = CDF->rRD.dimIntervals[dimN];
314 	break;
315     }
316     break;
317   }
318   /****************************************************************************
319   * zVAR_DIMINDICES_/zVAR_DIMCOUNTS_/zVAR_DIMINTERVALS_
320   ****************************************************************************/
321   case zVAR_DIMINDICES_:
322   case zVAR_DIMCOUNTS_:
323   case zVAR_DIMINTERVALS_: {
324     struct CDFstruct *CDF;
325     struct VarStruct *Var;
326     int dimN;
327     long *values = va_arg (Va->ap, long *);
328     SelectCDF (Cur->cdf, CDF)
329     if (!CURRENTvarSELECTED(CDF,TRUE)) return NO_VAR_SELECTED;
330     if (!sX(InitCurrentVar(CDF,TRUE,&Var),&pStatus)) {
331       AbortAccess (CDF, UPDATE, noDELETE);
332       return pStatus;
333     }
334     switch (Va->item) {
335       case zVAR_DIMINDICES_:
336 	for (dimN = 0; dimN < Var->numDims; dimN++)
337 	   values[dimN] = Var->zRD.dimIndices[dimN];
338 	break;
339       case zVAR_DIMCOUNTS_:
340 	for (dimN = 0; dimN < Var->numDims; dimN++)
341 	   values[dimN] = Var->zRD.dimCounts[dimN];
342 	break;
343       case zVAR_DIMINTERVALS_:
344 	for (dimN = 0; dimN < Var->numDims; dimN++)
345 	   values[dimN] = Var->zRD.dimIntervals[dimN];
346 	break;
347     }
348     break;
349   }
350   /****************************************************************************
351   * rVAR_SEQPOS_/zVAR_SEQPOS_
352   ****************************************************************************/
353   case rVAR_SEQPOS_:
354   case zVAR_SEQPOS_: {
355     Logical zOp = (Va->item == zVAR_SEQPOS_);
356     struct CDFstruct *CDF; struct VarStruct *Var;
357     Int32 indices[CDF_MAX_DIMS]; int dimN;
358     long *recNumber = va_arg (Va->ap, long *);
359     long *dimIndices = va_arg (Va->ap, long *);
360     SelectCDF (Cur->cdf, CDF)
361     if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
362     if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
363     if (!sX(InitCurrentVar(CDF,zOp,&Var),&pStatus)) {
364       AbortAccess (CDF, UPDATE, noDELETE);
365       return pStatus;
366     }
367     *recNumber = (long) (Var->seqValueOffset / Var->NphyRecValues);
368     ValueOffsetIndices (Var->seqValueOffset % Var->NphyRecValues,
369 			CDF->rowMajor, Var->numDims, Var->dimVarys,
370 			Var->nPhyDimValues, indices);
371     for (dimN = 0; dimN < Var->numDims; dimN++) {
372        dimIndices[dimN] = (long) indices[dimN];
373     }
374     break;
375   }
376   /****************************************************************************
377   * rVAR_RESERVEPERCENT_/zVAR_RESERVEPERCENT_
378   ****************************************************************************/
379   case rVAR_RESERVEPERCENT_:
380   case zVAR_RESERVEPERCENT_: {
381     Logical zOp = (Va->item == zVAR_RESERVEPERCENT_);
382     struct CDFstruct *CDF; struct VarStruct *Var;
383     long *pct = va_arg (Va->ap, long *);
384     SelectCDF (Cur->cdf, CDF)
385     if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
386     if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
387     if (!sX(InitCurrentVar(CDF,zOp,&Var),&pStatus)) {
388       AbortAccess (CDF, UPDATE, noDELETE);
389       return pStatus;
390     }
391     switch (Var->vType) {
392       case COMPRESSED_:
393       case SPARSE_COMPRESSED_RECORDS_:
394 	*pct = (long) Var->reservePct;
395 	break;
396       case SPARSE_ARRAYS_:
397       case SPARSE_RECORDS_AND_ARRAYS_:
398 	return CDF_INTERNAL_ERROR;
399       case STANDARD_:
400       case SPARSE_RECORDS_:
401 	*pct = 0;
402 	sX (NA_FOR_VARIABLE, &pStatus);
403 	break;
404       case IN_MULTI_:
405 	*pct = 0;
406 	sX (MULTI_FILE_FORMAT, &pStatus);
407 	break;
408     }
409     break;
410   }
411   /****************************************************************************
412   * ATTR_
413   ****************************************************************************/
414   case ATTR_: {
415     struct CDFstruct *CDF; Int32 tAttrNum;
416     long *attrNum = va_arg (Va->ap, long *);
417     SelectCDF (Cur->cdf, CDF)
418     if (!CURRENTattrSELECTED(CDF)) return NO_ATTR_SELECTED;
419     if (!sX(ReadADR(CDF->fp,CDF->CURattrOffset,
420 		    ADR_NUM,&tAttrNum,
421 		    ADR_NULL),&pStatus)) {
422       AbortAccess (CDF, UPDATE, noDELETE);
423       return pStatus;
424     }
425     *attrNum = (long) tAttrNum;
426     break;
427   }
428   /****************************************************************************
429   * ATTR_EXISTENCE_, confirms the existence of a named attribute.
430   ****************************************************************************/
431   case ATTR_EXISTENCE_: {
432     struct CDFstruct *CDF;
433     char *attrName = va_arg (Va->ap, char *);
434     SelectCDF (Cur->cdf, CDF)
435     tStatus = FindAttrByName (CDF, attrName, NULL);
436     switch (tStatus) {
437       case CDF_OK:
438 	break;
439       case NO_SUCH_ATTR:
440 	return tStatus;;
441       default:
442 	AbortAccess (CDF, UPDATE, noDELETE);
443 	return tStatus;
444     }
445     break;
446   }
447   /****************************************************************************
448   * gENTRY_/rENTRY_/zENTRY_
449   ****************************************************************************/
450   case rENTRY_:
451   case gENTRY_:
452   case zENTRY_: {
453     Logical zOp = (Va->item == zENTRY_);
454     struct CDFstruct *CDF;
455     long *entryNum = va_arg (Va->ap, long *);
456     SelectCDF (Cur->cdf, CDF)
457     if (BADzOP(CDF,Va->item==rENTRY_)) return ILLEGAL_IN_zMODE;
458     if (BOO(zOp,CDF->CURzEntryNum,CDF->CURgrEntryNum) == RESERVED_ENTRYNUM)
459       return NO_ENTRY_SELECTED;
460     *entryNum = BOO(zOp,CDF->CURzEntryNum,CDF->CURgrEntryNum);
461     break;
462   }
463   /****************************************************************************
464   * gENTRY_EXISTENCE_/rENTRY_EXISTENCE_/zENTRY_EXISTENCE_, confirms the
465   * existence of a numbered entry for the current attribute.
466   ****************************************************************************/
467   case gENTRY_EXISTENCE_:
468   case rENTRY_EXISTENCE_:
469   case zENTRY_EXISTENCE_: {
470     int entryType = E3p(Va->item,gENTRY_EXISTENCE_,
471 				 rENTRY_EXISTENCE_,
472 				 zENTRY_EXISTENCE_);
473     struct CDFstruct *CDF; Logical zEntry;
474     long entryNum = va_arg (Va->ap, long), entryN;
475     SelectCDF (Cur->cdf, CDF)
476     if (!CURRENTattrSELECTED(CDF)) return NO_ATTR_SELECTED;
477     if (!sX(CheckEntryOp(CDF,entryType),&pStatus)) return pStatus;
478     if (entryNum < 0) return BAD_ENTRY_NUM;
479     switch (entryType) {
480       case gENTRYt:
481       case rENTRYt:
482 	zEntry = FALSE;
483 	entryN = entryNum;
484 	break;
485       case zENTRYt:
486 	zEntry = BOO(zModeON(CDF),BOO(entryNum < CDF->NrVars,FALSE,TRUE),TRUE);
487 	entryN = BOO(zModeON(CDF),BOO(entryNum < CDF->NrVars,entryNum,
488 				      entryNum - CDF->NrVars),entryNum);
489 	break;
490     }
491     tStatus = FindEntryByNumber(CDF,CDF->CURattrOffset,
492 				zEntry,(Int32)entryN,NULL);
493     switch (tStatus) {
494       case CDF_OK:
495 	break;
496       case NO_SUCH_ENTRY:
497 	return tStatus;
498       default:
499 	AbortAccess (CDF, UPDATE, noDELETE);
500 	return tStatus;
501     }
502     break;
503   }
504   /****************************************************************************
505   * CURgENTRY_EXISTENCE_/CURrENTRY_EXISTENCE_/CURzENTRY_EXISTENCE_, confirms
506   * the existence of the current entry number for the current attribute.
507   ****************************************************************************/
508   case CURgENTRY_EXISTENCE_:
509   case CURrENTRY_EXISTENCE_:
510   case CURzENTRY_EXISTENCE_: {
511     int entryType = E3p(Va->item,CURgENTRY_EXISTENCE_,
512 				 CURrENTRY_EXISTENCE_,
513 				 CURzENTRY_EXISTENCE_);
514     struct CDFstruct *CDF; Int32 offset;
515     SelectCDF (Cur->cdf, CDF)
516     if (!CURRENTattrSELECTED(CDF)) return NO_ATTR_SELECTED;
517     if (E3(entryType,
518 	   CDF->CURgrEntryNum,
519 	   CDF->CURgrEntryNum,
520 	   CDF->CURzEntryNum) == RESERVED_ENTRYNUM) return NO_ENTRY_SELECTED;
521     if (!sX(CheckEntryOp(CDF,entryType),&pStatus)) return pStatus;
522     offset = E3(entryType,CDF->CURgrEntryOffset,
523 			  CDF->CURgrEntryOffset,
524 			  CDF->CURzEntryOffset);
525     if (offset == RESERVED_ENTRYOFFSET) return NO_SUCH_ENTRY;
526     break;
527   }
528   /****************************************************************************
529   * CDF_CHECKSUM_
530   ****************************************************************************/
531   case CDF_CHECKSUM_: {
532     struct CDFstruct *CDF;
533     SelectCDF (Cur->cdf, CDF)
534     if (!sX(CDFVerifyChecksum(CDF),&pStatus)) return pStatus;
535     break;
536   }
537   /****************************************************************************
538   * Unknown item, must be the next function.
539   ****************************************************************************/
540   default: {
541     Va->fnc = Va->item;
542     break;
543   }
544 }
545 return pStatus;
546 }
547