1 /******************************************************************************
2 *
3 *  NSSDC/CDF                                        Write to internal record.
4 *
5 *  Version 1.5a, 28-Feb-97, Hughes STX.
6 *
7 *  Modification history:
8 *
9 *   V1.0   4-Nov-93, J Love     Original version.
10 *   V1.1  15-Nov-94, J Love     CDF V2.5.
11 *   V1.2   5-Jan-95, J Love	Encode/decode changes.
12 *   V1.2a 30-Jan-95, J Love	`Write32s' now checks count.
13 *   V1.2b 24-Feb-95, J Love	Solaris 2.3 IDL i/f.
14 *   V1.3  26-May-95, J Love	CDF V2.4 compatibility mode.  What?
15 *   V1.4  14-Jun-95, J Love	Use `ReadXYZ' routines.
16 *   V1.4a  6-Sep-95, J Love	CDFexport-related changes.
17 *   V1.5   3-Apr-96, J Love	CDF V2.6.
18 *   V1.5a 28-Feb-97, J Love	Windows NT for MS Visual C/C++ on an IBM PC.
19 *   V3.2a 11-Apr-08, M Liu      Modified Write32s to eliminate the potential
20 *                               buffer overflow.
21 *
22 ******************************************************************************/
23 
24 #include "cdflib.h"
25 
26 /******************************************************************************
27 * Local macro definitions.
28 ******************************************************************************/
29 
30 #define CWE CDF_WRITE_ERROR
31 
32 /******************************************************************************
33 * Write32.
34 ******************************************************************************/
35 
Write32(fp,value)36 STATICforIDL Logical Write32 (fp, value)
37 vFILE *fp;
38 Int32 *value;
39 {
40 #if defined(NETWORKbyteORDERcpu)
41   if (!WRITEv(value,(size_t)4,(size_t)1,fp)) return FALSE;
42 #else
43   Int32 tValue;
44   REVERSE4bIO (value, &tValue)
45   if (!WRITEv(&tValue,(size_t)4,(size_t)1,fp)) return FALSE;
46 #endif
47   return TRUE;
48 }
49 
50 /******************************************************************************
51 * Write32s.
52 ******************************************************************************/
53 
Write32s(fp,buffer,count)54 STATICforIDL Logical Write32s (fp, buffer, count)
55 vFILE *fp;
56 Int32 *buffer;
57 int count;
58 {
59 #define MAX_tBUFFER_SIZE 10             /* This must be set to the maximum
60 					   value that `count' may ever be.
61 					   Currently, that is either the
62 					   maximum number of dimensions or
63 					   the number of entries in a VXR. */
64 #if defined(NETWORKbyteORDERcpu)
65   if (count == 0) return TRUE;
66   if (count < 0 || count > MAX_tBUFFER_SIZE) return FALSE;
67   if (!WRITEv(buffer,(size_t)4,(size_t)count,fp)) return FALSE;
68 #else
69   Int32 tBuffer[MAX_tBUFFER_SIZE]; int i;
70   if (count == 0) return TRUE;
71   if (count < 0 || count > MAX_tBUFFER_SIZE) return FALSE;
72   for (i = 0; i < count; i++) {
73      REVERSE4bIO (&buffer[i], &tBuffer[i])
74   }
75   if (!WRITEv(tBuffer,(size_t)4,(size_t)count,fp)) return FALSE;
76 #endif
77   return TRUE;
78 }
79 
80 /******************************************************************************
81 * WriteIrSize.
82 *   The size is always in the first 4-byte field.
83 ******************************************************************************/
84 
WriteIrSize(fp,offset,irSize)85 STATICforIDL CDFstatus WriteIrSize (fp, offset, irSize)
86 vFILE *fp;
87 Int32 offset;
88 Int32 *irSize;
89 {
90   if (!SEEKv(fp,(long)offset,vSEEK_SET)) return CWE;
91   if (!Write32(fp,irSize)) return CWE;
92   return CDF_OK;
93 }
94 
95 /******************************************************************************
96 * WriteIrType.
97 *   The type is always in the second 4-byte field.
98 ******************************************************************************/
99 
WriteIrType(fp,offset,irType)100 STATICforIDL CDFstatus WriteIrType (fp, offset, irType)
101 vFILE *fp;
102 Int32 offset;
103 Int32 *irType;
104 {
105   long irTypeOffset = offset + sizeof(Int32);
106   if (!SEEKv(fp,irTypeOffset,vSEEK_SET)) return CWE;
107   if (!Write32(fp,irType)) return CWE;
108   return CDF_OK;
109 }
110 
111 /******************************************************************************
112 * WriteCDR.
113 ******************************************************************************/
114 
115 #if defined(STDARG)
WriteCDR(vFILE * fp,Int32 offset,...)116 STATICforIDL CDFstatus WriteCDR (vFILE *fp, Int32 offset, ...)
117 #else
118 STATICforIDL CDFstatus WriteCDR (va_alist)
119 va_dcl
120 #endif
121 {
122   va_list ap; CDFstatus pStatus = CDF_OK;
123 #if defined(STDARG)
124   va_start (ap, offset);
125 #else
126   vFILE *fp; Int32 offset;
127   VA_START (ap);
128   fp = va_arg (ap, vFILE *);
129   offset = va_arg (ap, Int32);
130 #endif
131   for (;;) {
132      int field = va_arg (ap, int);
133      switch (field) {
134        case CDR_NULL:
135 	 va_end (ap);
136 	 return pStatus;
137        case CDR_RECORD: {
138 	 struct CDRstruct *CDR = va_arg (ap, struct CDRstruct *);
139 	 char *copyRight = va_arg (ap, char *);
140 	 if (!SEEKv(fp,(long)offset,vSEEK_SET)) return CWE;
141 	 if (!Write32(fp,&(CDR->RecordSize))) return CWE;
142 	 if (!Write32(fp,&(CDR->RecordType))) return CWE;
143 	 if (!Write32(fp,&(CDR->GDRoffset))) return CWE;
144 	 if (!Write32(fp,&(CDR->Version))) return CWE;
145 	 if (!Write32(fp,&(CDR->Release))) return CWE;
146 	 if (!Write32(fp,&(CDR->Encoding))) return CWE;
147 	 if (!Write32(fp,&(CDR->Flags))) return CWE;
148 	 if (!Write32(fp,&(CDR->rfuA))) return CWE;
149 	 if (!Write32(fp,&(CDR->rfuB))) return CWE;
150 	 if (!Write32(fp,&(CDR->Increment))) return CWE;
151 	 if (!Write32(fp,&(CDR->rfuD))) return CWE;
152 	 if (!Write32(fp,&(CDR->rfuE))) return CWE;
153 	 if (copyRight != NULL) {
154 	   if (!WRITEv(copyRight,CDF_COPYRIGHT_LEN,1,fp)) return CWE;
155 	 }
156 	 break;
157        }
158        case CDR_COPYRIGHT: {
159 	 char *copyRight = va_arg (ap, char *);
160 	 long tOffset = offset + CDR_COPYRIGHT_OFFSET;
161 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
162 	 if (!WRITEv(copyRight,CDF_COPYRIGHT_LEN,1,fp)) return CWE;
163 	 break;
164        }
165        default: {
166 	 Int32 *buffer = va_arg (ap, Int32 *);
167 	 long tOffset = offset;
168 	 switch (field) {
169 	   case CDR_RECORDSIZE: tOffset += CDR_RECORDSIZE_OFFSET; break;
170 	   case CDR_RECORDTYPE: tOffset += CDR_RECORDTYPE_OFFSET; break;
171 	   case CDR_GDROFFSET: tOffset += CDR_GDROFFSET_OFFSET; break;
172 	   case CDR_VERSION: tOffset += CDR_VERSION_OFFSET; break;
173 	   case CDR_RELEASE: tOffset += CDR_RELEASE_OFFSET; break;
174 	   case CDR_ENCODING: tOffset += CDR_ENCODING_OFFSET; break;
175 	   case CDR_FLAGS: tOffset += CDR_FLAGS_OFFSET; break;
176 	   case CDR_INCREMENT: tOffset += CDR_INCREMENT_OFFSET; break;
177 	   default: return CDF_INTERNAL_ERROR;
178 	 }
179 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
180 	 if (!Write32(fp,buffer)) return CWE;
181 	 break;
182        }
183      }
184   }
185 }
186 
187 /******************************************************************************
188 * WriteGDR.
189 ******************************************************************************/
190 
191 #if defined(STDARG)
WriteGDR(vFILE * fp,Int32 offset,...)192 STATICforIDL CDFstatus WriteGDR (vFILE *fp, Int32 offset, ...)
193 #else
194 STATICforIDL CDFstatus WriteGDR (va_alist)
195 va_dcl
196 #endif
197 {
198   va_list ap; CDFstatus pStatus = CDF_OK;
199 #if defined(STDARG)
200   va_start (ap, offset);
201 #else
202   vFILE *fp; Int32 offset;
203   VA_START (ap);
204   fp = va_arg (ap, vFILE *);
205   offset = va_arg (ap, Int32);
206 #endif
207   for (;;) {
208      int field = va_arg (ap, int);
209      switch (field) {
210        case GDR_NULL:
211 	 va_end (ap);
212 	 return pStatus;
213        case GDR_RECORD: {
214 	 struct GDRstruct *GDR = va_arg (ap, struct GDRstruct *);
215 	 if (!SEEKv(fp,(long)offset,vSEEK_SET)) return CWE;
216 	 if (!Write32(fp,&(GDR->RecordSize))) return CWE;
217 	 if (!Write32(fp,&(GDR->RecordType))) return CWE;
218 	 if (!Write32(fp,&(GDR->rVDRhead))) return CWE;
219 	 if (!Write32(fp,&(GDR->zVDRhead))) return CWE;
220 	 if (!Write32(fp,&(GDR->ADRhead))) return CWE;
221 	 if (!Write32(fp,&(GDR->eof))) return CWE;
222 	 if (!Write32(fp,&(GDR->NrVars))) return CWE;
223 	 if (!Write32(fp,&(GDR->NumAttr))) return CWE;
224 	 if (!Write32(fp,&(GDR->rMaxRec))) return CWE;
225 	 if (!Write32(fp,&(GDR->rNumDims))) return CWE;
226 	 if (!Write32(fp,&(GDR->NzVars))) return CWE;
227 	 if (!Write32(fp,&(GDR->UIRhead))) return CWE;
228 	 if (!Write32(fp,&(GDR->rfuC))) return CWE;
229 	 if (!Write32(fp,&(GDR->rfuD))) return CWE;
230 	 if (!Write32(fp,&(GDR->rfuE))) return CWE;
231 	 if (!Write32s(fp,GDR->rDimSizes,(int)GDR->rNumDims)) return CWE;
232 	 break;
233        }
234        case GDR_rDIMSIZES: {
235 	 Int32 *rDimSizes = va_arg (ap, Int32 *), rNumDims; long tOffset;
236 	 if (!sX(ReadGDR(fp,offset,
237 			 GDR_rNUMDIMS,&rNumDims,
238 			 GDR_NULL),&pStatus)) return pStatus;
239 	 tOffset = offset + GDR_rDIMSIZES_OFFSET;
240 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
241 	 if (!Write32s(fp,rDimSizes,(int)rNumDims)) return CWE;
242 	 break;
243        }
244        default: {
245 	 Int32 *buffer = va_arg (ap, Int32 *);
246 	 Int32 tOffset = offset;
247 	 switch (field) {
248 	   case GDR_RECORDSIZE: tOffset += GDR_RECORDSIZE_OFFSET; break;
249 	   case GDR_RECORDTYPE: tOffset += GDR_RECORDTYPE_OFFSET; break;
250 	   case GDR_rVDRHEAD: tOffset += GDR_rVDRHEAD_OFFSET; break;
251 	   case GDR_zVDRHEAD: tOffset += GDR_zVDRHEAD_OFFSET; break;
252 	   case GDR_ADRHEAD: tOffset += GDR_ADRHEAD_OFFSET; break;
253 	   case GDR_EOF: tOffset += GDR_EOF_OFFSET; break;
254 	   case GDR_NrVARS: tOffset += GDR_NrVARS_OFFSET; break;
255 	   case GDR_NUMATTR: tOffset += GDR_NUMATTR_OFFSET; break;
256 	   case GDR_rMAXREC: tOffset += GDR_rMAXREC_OFFSET; break;
257 	   case GDR_rNUMDIMS: tOffset += GDR_rNUMDIMS_OFFSET; break;
258 	   case GDR_NzVARS: tOffset += GDR_NzVARS_OFFSET; break;
259 	   case GDR_UIRHEAD: tOffset += GDR_UIRHEAD_OFFSET; break;
260 	   default: return CDF_INTERNAL_ERROR;
261 	 }
262 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
263 	 if (!Write32(fp,buffer)) return CWE;
264 	 break;
265        }
266      }
267   }
268 }
269 
270 /******************************************************************************
271 * WriteADR.
272 ******************************************************************************/
273 
274 #if defined(STDARG)
WriteADR(vFILE * fp,Int32 offset,...)275 STATICforIDL CDFstatus WriteADR (vFILE *fp, Int32 offset, ...)
276 #else
277 STATICforIDL CDFstatus WriteADR (va_alist)
278 va_dcl
279 #endif
280 {
281   va_list ap; CDFstatus pStatus = CDF_OK;
282 #if defined(STDARG)
283   va_start (ap, offset);
284 #else
285   vFILE *fp; Int32 offset;
286   VA_START (ap);
287   fp = va_arg (ap, vFILE *);
288   offset = va_arg (ap, Int32);
289 #endif
290   for (;;) {
291      int field = va_arg (ap, int);
292      switch (field) {
293        case ADR_NULL:
294 	 va_end (ap);
295 	 return pStatus;
296        case ADR_RECORD: {
297 	 struct ADRstruct *ADR = va_arg (ap, struct ADRstruct *);
298 	 if (!SEEKv(fp,(long)offset,vSEEK_SET)) return CWE;
299 	 if (!Write32(fp,&(ADR->RecordSize))) return CWE;
300 	 if (!Write32(fp,&(ADR->RecordType))) return CWE;
301 	 if (!Write32(fp,&(ADR->ADRnext))) return CWE;
302 	 if (!Write32(fp,&(ADR->AgrEDRhead))) return CWE;
303 	 if (!Write32(fp,&(ADR->Scope))) return CWE;
304 	 if (!Write32(fp,&(ADR->Num))) return CWE;
305 	 if (!Write32(fp,&(ADR->NgrEntries))) return CWE;
306 	 if (!Write32(fp,&(ADR->MAXgrEntry))) return CWE;
307 	 if (!Write32(fp,&(ADR->rfuA))) return CWE;
308 	 if (!Write32(fp,&(ADR->AzEDRhead))) return CWE;
309 	 if (!Write32(fp,&(ADR->NzEntries))) return CWE;
310 	 if (!Write32(fp,&(ADR->MAXzEntry))) return CWE;
311 	 if (!Write32(fp,&(ADR->rfuE))) return CWE;
312 	 if (!WRITEv(ADR->Name,CDF_ATTR_NAME_LEN,1,fp)) return CWE;
313 	 break;
314        }
315        case ADR_NAME: {
316 	 char *aName = va_arg (ap, char *);
317 	 long tOffset = offset + ADR_NAME_OFFSET;
318 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
319 	 if (!WRITEv(aName,CDF_ATTR_NAME_LEN,1,fp)) return CWE;
320 	 break;
321        }
322        default: {
323 	 Int32 *buffer = va_arg (ap, Int32 *); long tOffset = offset;
324 	 switch (field) {
325 	   case ADR_RECORDSIZE: tOffset += ADR_RECORDSIZE_OFFSET; break;
326 	   case ADR_RECORDTYPE: tOffset += ADR_RECORDTYPE_OFFSET; break;
327 	   case ADR_ADRNEXT: tOffset += ADR_ADRNEXT_OFFSET; break;
328 	   case ADR_AgrEDRHEAD: tOffset += ADR_AgrEDRHEAD_OFFSET; break;
329 	   case ADR_SCOPE: tOffset += ADR_SCOPE_OFFSET; break;
330 	   case ADR_NUM: tOffset += ADR_NUM_OFFSET; break;
331 	   case ADR_NgrENTRIES: tOffset += ADR_NgrENTRIES_OFFSET; break;
332 	   case ADR_MAXgrENTRY: tOffset += ADR_MAXgrENTRY_OFFSET; break;
333 	   case ADR_AzEDRHEAD: tOffset += ADR_AzEDRHEAD_OFFSET; break;
334 	   case ADR_NzENTRIES: tOffset += ADR_NzENTRIES_OFFSET; break;
335 	   case ADR_MAXzENTRY: tOffset += ADR_MAXzENTRY_OFFSET; break;
336 	   default: return CDF_INTERNAL_ERROR;
337 	 }
338 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
339 	 if (!Write32(fp,buffer)) return CWE;
340 	 break;
341        }
342      }
343   }
344 }
345 
346 /******************************************************************************
347 * WriteAgrEDR/AzEDR.
348 *    If the entry value is being written, it is assumed that the value passed
349 * in is in the host machine's encoding.
350 ******************************************************************************/
351 
352 #if defined(STDARG)
WriteAEDR(struct CDFstruct * CDF,vFILE * fp,Int32 offset,...)353 STATICforIDL CDFstatus WriteAEDR (struct CDFstruct *CDF, vFILE *fp,
354 				  Int32 offset, ...)
355 #else
356 STATICforIDL CDFstatus WriteAEDR (va_alist)
357 va_dcl
358 #endif
359 {
360   va_list ap; CDFstatus pStatus = CDF_OK;
361 #if defined(STDARG)
362   va_start (ap, offset);
363 #else
364   struct CDFstruct *CDF; vFILE *fp; Int32 offset;
365   VA_START (ap);
366   CDF = va_arg (ap, struct CDFstruct *);
367   fp = va_arg (ap, vFILE *);
368   offset = va_arg (ap, Int32);
369 #endif
370   for (;;) {
371      int field = va_arg (ap, int);
372      switch (field) {
373        case AEDR_NULL:
374 	 va_end (ap);
375 	 return pStatus;
376        case AEDR_RECORD: {
377 	 struct AEDRstruct *AEDR = va_arg (ap, struct AEDRstruct *);
378 	 void *value = va_arg (ap, void *);
379 	 if (!SEEKv(fp,(long)offset,vSEEK_SET)) return CWE;
380 	 if (!Write32(fp,&(AEDR->RecordSize))) return CWE;
381 	 if (!Write32(fp,&(AEDR->RecordType))) return CWE;
382 	 if (!Write32(fp,&(AEDR->AEDRnext))) return CWE;
383 	 if (!Write32(fp,&(AEDR->AttrNum))) return CWE;
384 	 if (!Write32(fp,&(AEDR->DataType))) return CWE;
385 	 if (!Write32(fp,&(AEDR->Num))) return CWE;
386 	 if (!Write32(fp,&(AEDR->NumElems))) return CWE;
387 	 if (!Write32(fp,&(AEDR->rfuA))) return CWE;
388 	 if (!Write32(fp,&(AEDR->rfuB))) return CWE;
389 	 if (!Write32(fp,&(AEDR->rfuC))) return CWE;
390 	 if (!Write32(fp,&(AEDR->rfuD))) return CWE;
391 	 if (!Write32(fp,&(AEDR->rfuE))) return CWE;
392 	 if (value != NULL) {
393 	   if (!sX(WriteBuffer(CDF,fp,AEDR->DataType,
394 			       AEDR->NumElems,value),&pStatus)) return pStatus;
395 	 }
396 	 break;
397        }
398        case AEDR_VALUE: {
399 	 void *value = va_arg (ap, void *);
400 	 Int32 dataType, numElems; long tOffset;
401 	 if (!sX(ReadAEDR(fp,offset,
402 			  AEDR_DATATYPE,&dataType,
403 			  AEDR_NUMELEMS,&numElems,
404 			  AEDR_NULL),&pStatus)) return pStatus;
405 	 tOffset = offset + AEDR_VALUE_OFFSET;
406 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
407 	 if (!sX(WriteBuffer(CDF,fp,dataType,
408 			     numElems,value),&pStatus)) return pStatus;
409 	 break;
410        }
411        default: {
412 	 Int32 *buffer = va_arg (ap, Int32 *); long tOffset = offset;
413 	 switch (field) {
414 	   case AEDR_RECORDSIZE: tOffset += AEDR_RECORDSIZE_OFFSET; break;
415 	   case AEDR_RECORDTYPE: tOffset += AEDR_RECORDTYPE_OFFSET; break;
416 	   case AEDR_AEDRNEXT: tOffset += AEDR_AEDRNEXT_OFFSET; break;
417 	   case AEDR_ATTRNUM: tOffset += AEDR_ATTRNUM_OFFSET; break;
418 	   case AEDR_DATATYPE: tOffset += AEDR_DATATYPE_OFFSET; break;
419 	   case AEDR_NUM: tOffset += AEDR_NUM_OFFSET; break;
420 	   case AEDR_NUMELEMS: tOffset += AEDR_NUMELEMS_OFFSET; break;
421 	   default: return CDF_INTERNAL_ERROR;
422 	 }
423 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
424 	 if (!Write32(fp,buffer)) return CWE;
425 	 break;
426        }
427      }
428   }
429 }
430 
431 /******************************************************************************
432 * WriterVDR/zVDR.
433 *    If the pad value is being written, it is assumed that the value passed
434 * in is in the host machine's encoding.
435 ******************************************************************************/
436 
437 #if defined(STDARG)
WriteVDR(struct CDFstruct * CDF,vFILE * fp,Int32 offset,Logical zVar,...)438 STATICforIDL CDFstatus WriteVDR (struct CDFstruct *CDF, vFILE *fp,
439 				 Int32 offset, Logical zVar, ...)
440 #else
441 STATICforIDL CDFstatus WriteVDR (va_alist)
442 va_dcl
443 #endif
444 {
445   va_list ap; CDFstatus pStatus = CDF_OK;
446 #if defined(STDARG)
447   va_start (ap, zVar);
448 #else
449   struct CDFstruct *CDF; vFILE *fp; Int32 offset; Logical zVar;
450   VA_START (ap);
451   CDF = va_arg (ap, struct CDFstruct *);
452   fp = va_arg (ap, vFILE *);
453   offset = va_arg (ap, Int32);
454   zVar = va_arg (ap, Logical);
455 #endif
456   for (;;) {
457      int field = va_arg (ap, int);
458      switch (field) {
459        case VDR_NULL:
460 	 va_end (ap);
461 	 return pStatus;
462        case VDR_RECORD: {
463 	 struct VDRstruct *VDR = va_arg (ap, struct VDRstruct *);
464 	 void *padValue = va_arg (ap, void *);
465 	 Int32 nDims;
466 	 if (!SEEKv(fp,(long)offset,vSEEK_SET)) return CWE;
467 	 if (!Write32(fp,&(VDR->RecordSize))) return CWE;
468 	 if (!Write32(fp,&(VDR->RecordType))) return CWE;
469 	 if (!Write32(fp,&(VDR->VDRnext))) return CWE;
470 	 if (!Write32(fp,&(VDR->DataType))) return CWE;
471 	 if (!Write32(fp,&(VDR->MaxRec))) return CWE;
472 	 if (!Write32(fp,&(VDR->VXRhead))) return CWE;
473 	 if (!Write32(fp,&(VDR->VXRtail))) return CWE;
474 	 if (!Write32(fp,&(VDR->Flags))) return CWE;
475 	 if (!Write32(fp,&(VDR->sRecords))) return CWE;
476 	 if (!Write32(fp,&(VDR->rfuB))) return CWE;
477 	 if (!Write32(fp,&(VDR->rfuC))) return CWE;
478 	 if (!Write32(fp,&(VDR->rfuF))) return CWE;
479 	 if (!Write32(fp,&(VDR->NumElems))) return CWE;
480 	 if (!Write32(fp,&(VDR->Num))) return CWE;
481 	 if (!Write32(fp,&(VDR->CPRorSPRoffset))) return CWE;
482 	 if (!Write32(fp,&(VDR->blockingFactor))) return CWE;
483 	 if (!WRITEv(VDR->Name,CDF_VAR_NAME_LEN,1,fp)) return CWE;
484 	 if (zVar) {
485 	   if (!Write32(fp,&(VDR->zNumDims))) return CWE;
486 	   if (!Write32s(fp,VDR->zDimSizes,
487 			 (int)VDR->zNumDims)) return CWE;
488 	 }
489 	 if (zVar)
490 	   nDims = VDR->zNumDims;
491 	 else {
492 	   long tOffset = V_tell (fp); Int32 GDRoffset;
493 	   if (!sX(ReadCDR(fp,V2_CDR_OFFSET,
494 			   CDR_GDROFFSET,&GDRoffset,
495 			   CDR_NULL),&pStatus)) return pStatus;
496 	   if (!sX(ReadGDR(fp,GDRoffset,
497 			   GDR_rNUMDIMS,&nDims,
498 			   GDR_NULL),&pStatus)) return pStatus;
499 	   if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
500 	 }
501 	 if (!Write32s(fp,VDR->DimVarys,(int)nDims)) return CWE;
502 	 if (PADvalueBITset(VDR->Flags) && padValue != NULL) {
503 	   if (!sX(WriteBuffer(CDF,fp,VDR->DataType,
504 			       VDR->NumElems,
505 			       padValue),&pStatus)) return pStatus;
506 	 }
507 	 break;
508        }
509        case VDR_NAME: {
510 	 char *vName = va_arg (ap, char *);
511 	 long tOffset = offset + VDR_NAME_OFFSET;
512 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
513 	 if (!WRITEv(vName,CDF_VAR_NAME_LEN,1,fp)) return CWE;
514 	 break;
515        }
516        case VDR_zNUMDIMS: {
517 	 Int32 *numDims = va_arg (ap, Int32 *);
518 	 long tOffset = offset + zVDR_zNUMDIMS_OFFSET;
519 	 if (!zVar) return CDF_INTERNAL_ERROR;
520 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
521 	 if (!Write32(fp,numDims)) return CWE;
522 	 break;
523        }
524        case VDR_zDIMSIZES: {
525 	 Int32 *zDimSizes = va_arg (ap, Int32 *), zNumDims;
526 	 int dimN; long tOffset;
527 	 if (!zVar) return CDF_INTERNAL_ERROR;
528 	 if (!sX(ReadVDR(CDF,fp,offset,zVar,
529 			 VDR_zNUMDIMS,&zNumDims,
530 			 VDR_NULL),&pStatus)) return pStatus;
531 	 tOffset = offset + zVDR_zDIMSIZES_OFFSET;
532 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
533 	 for (dimN = 0; dimN < zNumDims; dimN++) {
534 	    if (!Write32(fp,&(zDimSizes[dimN]))) return CWE;
535 	 }
536 	 break;
537        }
538        case VDR_DIMVARYS: {
539 	 Int32 *dimVarys = va_arg (ap, Int32 *), nDims; long tOffset;
540 	 if (zVar) {
541 	   if (!sX(ReadVDR(CDF,fp,offset,zVar,
542 			   VDR_zNUMDIMS,&nDims,
543 			   VDR_NULL),&pStatus)) return pStatus;
544 	   tOffset = offset + zVDR_DIMVARYS_OFFSETb + (nDims * sizeof(Int32));
545 	 }
546 	 else {
547 	   Int32 GDRoffset;
548 	   if (!sX(ReadCDR(fp,V2_CDR_OFFSET,
549 			   CDR_GDROFFSET,&GDRoffset,
550 			   CDR_NULL),&pStatus)) return pStatus;
551 	   if (!sX(ReadGDR(fp,GDRoffset,
552 			   GDR_rNUMDIMS,&nDims,
553 			   GDR_NULL),&pStatus)) return pStatus;
554 	   tOffset = offset + rVDR_DIMVARYS_OFFSET;
555 	 }
556 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
557 	 if (!Write32s(fp,dimVarys,(int)nDims)) return CWE;
558 	 break;
559        }
560        case VDR_PADVALUE: {
561 	 void *padValue = va_arg (ap, void *);
562 	 Int32 dataType, numElems; long tOffset;
563 	 if (!sX(ReadVDR(CDF,fp,offset,zVar,
564 			 VDR_DATATYPE,&dataType,
565 			 VDR_NUMELEMS,&numElems,
566 			 VDR_NULL),&pStatus)) return pStatus;
567 	 if (zVar) {
568 	   Int32 zNumDims;
569 	   if (!sX(ReadVDR(CDF,fp,offset,zVar,
570 			   VDR_zNUMDIMS,&zNumDims,
571 			   VDR_NULL),&pStatus)) return pStatus;
572 	   tOffset = offset + zVDR_PADVALUE_OFFSETb +
573 		     (zNumDims * sizeof(Int32)) + (zNumDims * sizeof(Int32));
574 	 }
575 	 else {
576 	   Int32 rNumDims, GDRoffset;
577 	   if (!sX(ReadCDR(fp,V2_CDR_OFFSET,
578 			   CDR_GDROFFSET,&GDRoffset,
579 			   CDR_NULL),&pStatus)) return pStatus;
580 	   if (!sX(ReadGDR(fp,GDRoffset,
581 			   GDR_rNUMDIMS,&rNumDims,
582 			   GDR_NULL),&pStatus)) return pStatus;
583 	   tOffset = offset + rVDR_PADVALUE_OFFSETb + (rNumDims*sizeof(Int32));
584 	 }
585 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
586 	 if (!sX(WriteBuffer(CDF,fp,dataType,
587 			     numElems,padValue),&pStatus)) return pStatus;
588 	 break;
589        }
590        default: {
591 	 Int32 *buffer = va_arg (ap, Int32 *); long tOffset = offset;
592 	 switch (field) {
593 	   case VDR_RECORDSIZE: tOffset += VDR_RECORDSIZE_OFFSET; break;
594 	   case VDR_RECORDTYPE: tOffset += VDR_RECORDTYPE_OFFSET; break;
595 	   case VDR_VDRNEXT: tOffset += VDR_VDRNEXT_OFFSET; break;
596 	   case VDR_DATATYPE: tOffset += VDR_DATATYPE_OFFSET; break;
597 	   case VDR_MAXREC: tOffset += VDR_MAXREC_OFFSET; break;
598 	   case VDR_VXRHEAD: tOffset += VDR_VXRHEAD_OFFSET; break;
599 	   case VDR_VXRTAIL: tOffset += VDR_VXRTAIL_OFFSET; break;
600 	   case VDR_FLAGS: tOffset += VDR_FLAGS_OFFSET; break;
601 	   case VDR_sRECORDS: tOffset += VDR_sRECORDS_OFFSET; break;
602 	   case VDR_NUMELEMS: tOffset += VDR_NUMELEMS_OFFSET; break;
603 	   case VDR_NUM: tOffset += VDR_NUM_OFFSET; break;
604 	   case VDR_CPRorSPR: tOffset += VDR_CPRorSPR_OFFSET; break;
605 	   case VDR_BLOCKING: tOffset += VDR_BLOCKING_OFFSET; break;
606 	   default: return CDF_INTERNAL_ERROR;
607 	 }
608 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
609 	 if (!Write32(fp,buffer)) return CWE;
610 	 break;
611        }
612      }
613   }
614 }
615 
616 /******************************************************************************
617 * WriteVXR.
618 ******************************************************************************/
619 
620 #if defined(STDARG)
WriteVXR(vFILE * fp,Int32 offset,...)621 STATICforIDL CDFstatus WriteVXR (vFILE *fp, Int32 offset, ...)
622 #else
623 STATICforIDL CDFstatus WriteVXR (va_alist)
624 va_dcl
625 #endif
626 {
627   va_list ap; CDFstatus pStatus = CDF_OK;
628 #if defined(STDARG)
629   va_start (ap, offset);
630 #else
631   vFILE *fp; Int32 offset;
632   VA_START (ap);
633   fp = va_arg (ap, vFILE *);
634   offset = va_arg (ap, Int32);
635 #endif
636   for (;;) {
637      int field = va_arg (ap, int);
638      switch (field) {
639        case VXR_NULL:
640 	 va_end (ap);
641 	 return pStatus;
642        case VXR_RECORD: {
643 	 struct VXRstruct *VXR = va_arg (ap, struct VXRstruct *);
644 	 if (!SEEKv(fp,(long)offset,vSEEK_SET)) return CWE;
645 	 if (!Write32(fp,&(VXR->RecordSize))) return CWE;
646 	 if (!Write32(fp,&(VXR->RecordType))) return CWE;
647 	 if (!Write32(fp,&(VXR->VXRnext))) return CWE;
648 	 if (!Write32(fp,&(VXR->Nentries))) return CWE;
649 	 if (!Write32(fp,&(VXR->NusedEntries))) return CWE;
650 	 if (!Write32s(fp,VXR->First,(int)VXR->Nentries)) return CWE;
651 	 if (!Write32s(fp,VXR->Last,(int)VXR->Nentries)) return CWE;
652 	 if (!Write32s(fp,VXR->Offset,(int)VXR->Nentries)) return CWE;
653 	 break;
654        }
655        case VXR_FIRSTREC:
656        case VXR_LASTREC:
657        case VXR_OFFSET: {
658 	 Int32 *buffer = va_arg (ap, Int32 *), nEntries;
659 	 long tOffset = offset + VXR_FIRSTREC_OFFSET;
660 	 if (!sX(ReadVXR(fp,offset,
661 			 VXR_NENTRIES,&nEntries,
662 			 VXR_NULL),&pStatus)) return pStatus;
663 	 switch (field) {
664 	   case VXR_FIRSTREC: break;
665 	   case VXR_LASTREC: tOffset += nEntries * sizeof(Int32); break;
666 	   case VXR_OFFSET: tOffset += 2 * nEntries * sizeof(Int32); break;
667 	   default: return CDF_INTERNAL_ERROR;
668 	 }
669 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
670 	 if (!Write32s(fp,buffer,(int)nEntries)) return CWE;
671 	 break;
672        }
673        default: {
674 	 Int32 *buffer = va_arg (ap, Int32 *); long tOffset = offset;
675 	 switch (field) {
676 	   case VXR_RECORDSIZE: tOffset += VXR_RECORDSIZE_OFFSET; break;
677 	   case VXR_RECORDTYPE: tOffset += VXR_RECORDTYPE_OFFSET; break;
678 	   case VXR_VXRNEXT: tOffset += VXR_VXRNEXT_OFFSET; break;
679 	   case VXR_NENTRIES: tOffset += VXR_NENTRIES_OFFSET; break;
680 	   case VXR_NUSEDENTRIES: tOffset += VXR_NUSEDENTRIES_OFFSET; break;
681 	   default: return CDF_INTERNAL_ERROR;
682 	 }
683 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
684 	 if (!Write32(fp,buffer)) return CWE;
685 	 break;
686        }
687      }
688   }
689 }
690 
691 /******************************************************************************
692 * WriteVVR.
693 ******************************************************************************/
694 
695 #if defined(STDARG)
WriteVVR(vFILE * fp,Int32 offset,...)696 STATICforIDL CDFstatus WriteVVR (vFILE *fp, Int32 offset, ...)
697 #else
698 STATICforIDL CDFstatus WriteVVR (va_alist)
699 va_dcl
700 #endif
701 {
702   va_list ap; CDFstatus pStatus = CDF_OK;
703 #if defined(STDARG)
704   va_start (ap, offset);
705 #else
706   vFILE *fp; Int32 offset;
707   VA_START (ap);
708   fp = va_arg (ap, vFILE *);
709   offset = va_arg (ap, Int32);
710 #endif
711   for (;;) {
712      int field = va_arg (ap, int);
713      switch (field) {
714        case VVR_NULL:
715 	 va_end (ap);
716 	 return pStatus;
717        case VVR_RECORDx: {
718 	 struct VVRstruct *VVR = va_arg (ap, struct VVRstruct *);
719 	 if (!SEEKv(fp,(long)offset,vSEEK_SET)) return CWE;
720 	 if (!Write32(fp,&(VVR->RecordSize))) return CWE;
721 	 if (!Write32(fp,&(VVR->RecordType))) return CWE;
722 	 break;
723        }
724        default: {
725 	 Int32 *buffer = va_arg (ap, Int32 *); long tOffset = offset;
726 	 switch (field) {
727 	   case VVR_RECORDSIZE: tOffset += VVR_RECORDSIZE_OFFSET; break;
728 	   case VVR_RECORDTYPE: tOffset += VVR_RECORDTYPE_OFFSET; break;
729 	   default: return CDF_INTERNAL_ERROR;
730 	 }
731 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
732 	 if (!Write32(fp,buffer)) return CWE;
733 	 break;
734        }
735      }
736   }
737 }
738 
739 /******************************************************************************
740 * WriteUIR.
741 ******************************************************************************/
742 
743 #if defined(STDARG)
WriteUIR(vFILE * fp,Int32 offset,...)744 STATICforIDL CDFstatus WriteUIR (vFILE *fp, Int32 offset, ...)
745 #else
746 STATICforIDL CDFstatus WriteUIR (va_alist)
747 va_dcl
748 #endif
749 {
750   va_list ap; CDFstatus pStatus = CDF_OK;
751 #if defined(STDARG)
752   va_start (ap, offset);
753 #else
754   vFILE *fp; Int32 offset;
755   VA_START (ap);
756   fp = va_arg (ap, vFILE *);
757   offset = va_arg (ap, Int32);
758 #endif
759   for (;;) {
760      int field = va_arg (ap, int);
761      switch (field) {
762        case UIR_NULL:
763 	 va_end (ap);
764 	 return pStatus;
765        case UIR_RECORD: {
766 	 struct UIRstruct *UIR = va_arg (ap, struct UIRstruct *);
767 	 if (!SEEKv(fp,(long)offset,vSEEK_SET)) return CWE;
768 	 if (!Write32(fp,&(UIR->RecordSize))) return CWE;
769 	 if (!Write32(fp,&(UIR->RecordType))) return CWE;
770 	 if (!Write32(fp,&(UIR->NextUIR))) return CWE;
771 	 if (!Write32(fp,&(UIR->PrevUIR))) return CWE;
772 	 break;
773        }
774        default: {
775 	 Int32 *buffer = va_arg (ap, Int32 *); long tOffset = offset;
776 	 switch (field) {
777 	   case UIR_RECORDSIZE: tOffset += UIR_RECORDSIZE_OFFSET; break;
778 	   case UIR_RECORDTYPE: tOffset += UIR_RECORDTYPE_OFFSET; break;
779 	   case UIR_NEXTUIR: tOffset += UIR_NEXTUIR_OFFSET; break;
780 	   case UIR_PREVUIR: tOffset += UIR_PREVUIR_OFFSET; break;
781 	   default: return CDF_INTERNAL_ERROR;
782 	 }
783 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
784 	 if (!Write32(fp,buffer)) return CWE;
785 	 break;
786        }
787      }
788   }
789 }
790 
791 /******************************************************************************
792 * WriteCCR.
793 ******************************************************************************/
794 
795 #if defined(STDARG)
WriteCCR(vFILE * fp,Int32 offset,...)796 STATICforIDL CDFstatus WriteCCR (vFILE *fp, Int32 offset, ...)
797 #else
798 STATICforIDL CDFstatus WriteCCR (va_alist)
799 va_dcl
800 #endif
801 {
802   va_list ap; CDFstatus pStatus = CDF_OK;
803 #if defined(STDARG)
804   va_start (ap, offset);
805 #else
806   vFILE *fp; Int32 offset;
807   VA_START (ap);
808   fp = va_arg (ap, vFILE *);
809   offset = va_arg (ap, Int32);
810 #endif
811   for (;;) {
812      int field = va_arg (ap, int);
813      switch (field) {
814        case CCR_NULL:
815 	 va_end (ap);
816 	 return pStatus;
817        case CCR_RECORD: {
818 	 struct CCRstruct *CCR = va_arg (ap, struct CCRstruct *);
819 	 if (!SEEKv(fp,(long)offset,vSEEK_SET)) return CWE;
820 	 if (!Write32(fp,&(CCR->RecordSize))) return CWE;
821 	 if (!Write32(fp,&(CCR->RecordType))) return CWE;
822 	 if (!Write32(fp,&(CCR->CPRoffset))) return CWE;
823 	 if (!Write32(fp,&(CCR->uSize))) return CWE;
824 	 if (!Write32(fp,&(CCR->rfuA))) return CWE;
825 	 break;
826        }
827        default: {
828 	 Int32 *buffer = va_arg (ap, Int32 *); long tOffset = offset;
829 	 switch (field) {
830 	   case CCR_RECORDSIZE: tOffset += CCR_RECORDSIZE_OFFSET; break;
831 	   case CCR_RECORDTYPE: tOffset += CCR_RECORDTYPE_OFFSET; break;
832 	   case CCR_CPROFFSET: tOffset += CCR_CPROFFSET_OFFSET; break;
833 	   case CCR_USIZE: tOffset += CCR_USIZE_OFFSET; break;
834 	   case CCR_RFUa: tOffset += CCR_RFUa_OFFSET; break;
835 	   default: return CDF_INTERNAL_ERROR;
836 	 }
837 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
838 	 if (!Write32(fp,buffer)) return CWE;
839 	 break;
840        }
841      }
842   }
843 }
844 
845 /******************************************************************************
846 * WriteCPR.
847 ******************************************************************************/
848 
849 #if defined(STDARG)
WriteCPR(vFILE * fp,Int32 offset,...)850 STATICforIDL CDFstatus WriteCPR (vFILE *fp, Int32 offset, ...)
851 #else
852 STATICforIDL CDFstatus WriteCPR (va_alist)
853 va_dcl
854 #endif
855 {
856   va_list ap; CDFstatus pStatus = CDF_OK;
857 #if defined(STDARG)
858   va_start (ap, offset);
859 #else
860   vFILE *fp; Int32 offset;
861   VA_START (ap);
862   fp = va_arg (ap, vFILE *);
863   offset = va_arg (ap, Int32);
864 #endif
865   for (;;) {
866      int field = va_arg (ap, int);
867      switch (field) {
868        case CPR_NULL:
869 	 va_end (ap);
870 	 return pStatus;
871        case CPR_RECORD: {
872 	 struct CPRstruct *CPR = va_arg (ap, struct CPRstruct *); int i;
873 	 if (!SEEKv(fp,(long)offset,vSEEK_SET)) return CWE;
874 	 if (!Write32(fp,&(CPR->RecordSize))) return CWE;
875 	 if (!Write32(fp,&(CPR->RecordType))) return CWE;
876 	 if (!Write32(fp,&(CPR->cType))) return CWE;
877 	 if (!Write32(fp,&(CPR->rfuA))) return CWE;
878 	 if (!Write32(fp,&(CPR->pCount))) return CWE;
879 	 for (i = 0; i < CPR->pCount; i++) {
880 	    if (!Write32(fp,&(CPR->cParms[i]))) return CWE;
881 	 }
882 	 break;
883        }
884        default: {
885 	 Int32 *buffer = va_arg (ap, Int32 *); long tOffset = offset;
886 	 switch (field) {
887 	   case CPR_RECORDSIZE: tOffset += CPR_RECORDSIZE_OFFSET; break;
888 	   case CPR_RECORDTYPE: tOffset += CPR_RECORDTYPE_OFFSET; break;
889 	   case CPR_CTYPE: tOffset += CPR_CTYPE_OFFSET; break;
890 	   case CPR_RFUa: tOffset += CPR_RFUa_OFFSET; break;
891 	   case CPR_PCOUNT: tOffset += CPR_PCOUNT_OFFSET; break;
892 	   case CPR_CPARM1: tOffset += CPR_CPARM1_OFFSET; break;
893 	   case CPR_CPARM2: tOffset += CPR_CPARM2_OFFSET; break;
894 	   case CPR_CPARM3: tOffset += CPR_CPARM3_OFFSET; break;
895 	   case CPR_CPARM4: tOffset += CPR_CPARM4_OFFSET; break;
896 	   case CPR_CPARM5: tOffset += CPR_CPARM5_OFFSET; break;
897 	   default: return CDF_INTERNAL_ERROR;
898 	 }
899 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
900 	 if (!Write32(fp,buffer)) return CWE;
901 	 break;
902        }
903      }
904   }
905 }
906 
907 /******************************************************************************
908 * WriteSPR.
909 ******************************************************************************/
910 
911 #if defined(STDARG)
WriteSPR(vFILE * fp,Int32 offset,...)912 STATICforIDL CDFstatus WriteSPR (vFILE *fp, Int32 offset, ...)
913 #else
914 STATICforIDL CDFstatus WriteSPR (va_alist)
915 va_dcl
916 #endif
917 {
918   va_list ap; CDFstatus pStatus = CDF_OK;
919 #if defined(STDARG)
920   va_start (ap, offset);
921 #else
922   vFILE *fp; Int32 offset;
923   VA_START (ap);
924   fp = va_arg (ap, vFILE *);
925   offset = va_arg (ap, Int32);
926 #endif
927   for (;;) {
928      int field = va_arg (ap, int);
929      switch (field) {
930        case SPR_NULL:
931 	 va_end (ap);
932 	 return pStatus;
933        case SPR_RECORD: {
934 	 struct SPRstruct *SPR = va_arg (ap, struct SPRstruct *); int i;
935 	 if (!SEEKv(fp,(long)offset,vSEEK_SET)) return CWE;
936 	 if (!Write32(fp,&(SPR->RecordSize))) return CWE;
937 	 if (!Write32(fp,&(SPR->RecordType))) return CWE;
938 	 if (!Write32(fp,&(SPR->sArraysType))) return CWE;
939 	 if (!Write32(fp,&(SPR->rfuA))) return CWE;
940 	 if (!Write32(fp,&(SPR->pCount))) return CWE;
941 	 for (i = 0; i < SPR->pCount; i++) {
942 	    if (!Write32(fp,&(SPR->sArraysParms[i]))) return CWE;
943 	 }
944 	 break;
945        }
946        default: {
947 	 Int32 *buffer = va_arg (ap, Int32 *); long tOffset = offset;
948 	 switch (field) {
949 	   case SPR_RECORDSIZE: tOffset += SPR_RECORDSIZE_OFFSET; break;
950 	   case SPR_RECORDTYPE: tOffset += SPR_RECORDTYPE_OFFSET; break;
951 	   case SPR_STYPE: tOffset += SPR_STYPE_OFFSET; break;
952 	   case SPR_RFUa: tOffset += SPR_RFUa_OFFSET; break;
953 	   case SPR_PCOUNT: tOffset += SPR_PCOUNT_OFFSET; break;
954 	   case SPR_SPARM1: tOffset += SPR_SPARM1_OFFSET; break;
955 	   case SPR_SPARM2: tOffset += SPR_SPARM2_OFFSET; break;
956 	   case SPR_SPARM3: tOffset += SPR_SPARM3_OFFSET; break;
957 	   case SPR_SPARM4: tOffset += SPR_SPARM4_OFFSET; break;
958 	   case SPR_SPARM5: tOffset += SPR_SPARM5_OFFSET; break;
959 	   default: return CDF_INTERNAL_ERROR;
960 	 }
961 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
962 	 if (!Write32(fp,buffer)) return CWE;
963 	 break;
964        }
965      }
966   }
967 }
968 
969 /******************************************************************************
970 * WriteCVVR.
971 ******************************************************************************/
972 
973 #if defined(STDARG)
WriteCVVR(vFILE * fp,Int32 offset,...)974 STATICforIDL CDFstatus WriteCVVR (vFILE *fp, Int32 offset, ...)
975 #else
976 STATICforIDL CDFstatus WriteCVVR (va_alist)
977 va_dcl
978 #endif
979 {
980   va_list ap; CDFstatus pStatus = CDF_OK;
981 #if defined(STDARG)
982   va_start (ap, offset);
983 #else
984   vFILE *fp; Int32 offset;
985   VA_START (ap);
986   fp = va_arg (ap, vFILE *);
987   offset = va_arg (ap, Int32);
988 #endif
989   for (;;) {
990      int field = va_arg (ap, int);
991      switch (field) {
992        case CVVR_NULL:
993 	 va_end (ap);
994 	 return pStatus;
995        case CVVR_RECORDx: {
996 	 struct CVVRstruct *CVVR = va_arg (ap, struct CVVRstruct *);
997 	 if (!SEEKv(fp,(long)offset,vSEEK_SET)) return CWE;
998 	 if (!Write32(fp,&(CVVR->RecordSize))) return CWE;
999 	 if (!Write32(fp,&(CVVR->RecordType))) return CWE;
1000 	 if (!Write32(fp,&(CVVR->rfuA))) return CWE;
1001 	 if (!Write32(fp,&(CVVR->cSize))) return CWE;
1002 	 break;
1003        }
1004        default: {
1005 	 Int32 *buffer = va_arg (ap, Int32 *); long tOffset = offset;
1006 	 switch (field) {
1007 	   case CVVR_RECORDSIZE: tOffset += CVVR_RECORDSIZE_OFFSET; break;
1008 	   case CVVR_RECORDTYPE: tOffset += CVVR_RECORDTYPE_OFFSET; break;
1009 	   case CVVR_RFUa: tOffset += CVVR_RFUa_OFFSET; break;
1010 	   case CVVR_CSIZE: tOffset += CVVR_CSIZE_OFFSET; break;
1011 	   default: return CDF_INTERNAL_ERROR;
1012 	 }
1013 	 if (!SEEKv(fp,tOffset,vSEEK_SET)) return CWE;
1014 	 if (!Write32(fp,buffer)) return CWE;
1015 	 break;
1016        }
1017      }
1018   }
1019 }
1020