1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF. The full HDF copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF/releases/. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 /* $Id$ */
15
16 /***********************************************************************
17 *
18 * vrw.c
19 * Part of the HDF VSet interface.
20 * This module handles reading and writing of Vdatas.
21 *
22
23 LOCAL ROUTINES
24 VSPshutdown -- Free the Vtbuf buffer.
25
26 EXPORTED ROUTINES
27 VSseek -- Seeks to an element boundary within a vdata i.e. 2nd element.
28 VSread -- Reads a specified number of elements' worth of data from a vdata.
29 Data will be returned to you interlaced in the way you specified.
30 VSwrite -- Writes a specified number of elements' worth of data to a vdata.
31 You must specify how your data in your buffer is interlaced.
32 Creates an aid, and writes it out if this is the first time.
33
34 NOTE: Another pass needs to made through this file to update some of
35 the comments about certain sections of the code. -GV 9/8/97
36
37 ************************************************************************/
38
39 #define VSET_INTERFACE
40 #include "hdf.h"
41
42 #ifndef MIN
43 #define MIN(a,b) ((a) < (b) ? (a) : (b))
44 #endif /* MIN */
45
46 PRIVATE uint32 Vtbufsize = 0;
47 PRIVATE uint8 *Vtbuf = NULL;
48
49 /*******************************************************************************
50 NAME
51 VSPshutdown -- Free the Vtbuf buffer.
52
53 DESCRIPTION
54 For completeness, when the VSet interface is shut-down, free the Vtbuf.
55
56 Should only ever be called by the "atexit" function HDFend
57
58 RETURNS
59 Returns SUCCEED/FAIL
60
61 *******************************************************************************/
62 intn
VSPshutdown(void)63 VSPshutdown(void)
64 {
65 intn ret_value = SUCCEED;
66
67 /* free global buffers */
68 if(Vtbuf != NULL)
69 {
70 HDfree(Vtbuf);
71 Vtbuf = NULL;
72 Vtbufsize = 0;
73 } /* end if */
74
75 /* Clear the local buffers in vio.c */
76 ret_value = VSPhshutdown();
77
78 return ret_value;
79 } /* end VSPshutdown() */
80
81 /*******************************************************************************
82 NAME
83 VSseek
84
85 DESCRIPTION
86 Seeks to an element boundary within a vdata
87 Vdata must be attached with "r" or "w" access.
88 Specify eltpos = 0 for 1st element, 1 for 2nd element etc.
89
90 (eg returns 5 if seek to the 6th element, etc)
91
92 RETURNS
93 RETURNS FAIL on error
94 RETURNS position of element seeked to (0 or a +ve integer)
95
96 *******************************************************************************/
97 int32
VSseek(int32 vkey,int32 eltpos)98 VSseek(int32 vkey, /* IN: vdata key */
99 int32 eltpos /* IN: element position in vdata */)
100 {
101 int32 ret;
102 int32 offset;
103 vsinstance_t *w = NULL;
104 VDATA *vs = NULL;
105 int32 ret_value = SUCCEED;
106 CONSTR(FUNC, "VSseek");
107
108 /* clear error stack */
109 HEclear();
110
111 /* check if vdata is part of vdata group */
112 if (HAatom_group(vkey)!=VSIDGROUP)
113 HGOTO_ERROR(DFE_ARGS, FAIL);
114
115 /* get vdata instance */
116 if (NULL == (w = (vsinstance_t *) HAatom_object(vkey)))
117 HGOTO_ERROR(DFE_NOVS, FAIL);
118
119 /* get vdata itself and check it. Check element postion also. */
120 vs = w->vs;
121 if ((vs == NULL) || (eltpos < 0))
122 HGOTO_ERROR(DFE_ARGS, FAIL);
123
124 /* Don't allow seeks in 0-field vdatas */
125 if (vs->wlist.n<=0)
126 HGOTO_ERROR(DFE_BADFIELDS, FAIL);
127
128 /* calculate offset of element in vdata */
129 offset = eltpos * vs->wlist.ivsize;
130
131 /* seek to element */
132 if (( ret = Hseek(vs->aid, offset, DF_START)) == FAIL)
133 HGOTO_ERROR(DFE_BADSEEK, FAIL);
134
135 ret_value = (eltpos);
136
137 done:
138 if(ret_value == FAIL)
139 { /* Error condition cleanup */
140
141 } /* end if */
142
143 /* Normal function cleanup */
144 return ret_value;
145 } /* VSseek */
146
147 /*******************************************************************************
148 NAME
149 VSread
150
151 DESCRIPTION
152 Reads a specified number of elements' worth of data from a vdata.
153 Data will be returned to you interlaced in the way you specified.
154
155 RETURNS
156 RETURNS FAIL if error
157 RETURNS the number of elements read (0 or a +ve integer).
158
159 *******************************************************************************/
160 int32
VSread(int32 vkey,uint8 buf[],int32 nelt,int32 interlace)161 VSread(int32 vkey, /* IN: vdata key */
162 uint8 buf[], /* IN/OUT: space to put elements in */
163 int32 nelt, /* IN: number of elements to read */
164 int32 interlace /* IN: interlace to return elements in 'buf' */)
165 {
166 intn isize = 0;
167 intn order = 0;
168 intn index = 0;
169 intn esize = 0;
170 intn hsize = 0;
171 uint8 *Src;
172 uint8 *b1 = NULL;
173 uint8 *b2 = NULL;
174 int32 i, j;
175 int32 nv;
176 int32 offset;
177 int32 type;
178 int32 uvsize; /* size of "element" as NEEDED by user */
179 int32 total_bytes; /* total number of bytes that need to be read in */
180 int32 bytes; /* number of elements / bytes to read next time */
181 int32 chunk; /* number of records in a buffer */
182 int32 done; /* number of records to do / done */
183 DYN_VWRITELIST *w = NULL;
184 DYN_VREADLIST *r = NULL;
185 vsinstance_t *wi = NULL;
186 VDATA *vs = NULL;
187 int32 ret_value = SUCCEED;
188 CONSTR(FUNC, "VSread");
189
190 /* clear error stack */
191 HEclear();
192
193 /* check if vdata is part of vdata group */
194 if (HAatom_group(vkey) != VSIDGROUP)
195 HGOTO_ERROR(DFE_ARGS, FAIL);
196
197 /* get vdata instance */
198 if (NULL == (wi = (vsinstance_t *) HAatom_object(vkey)))
199 HGOTO_ERROR(DFE_NOVS, FAIL);
200
201 /* get vdata itself and check it */
202 vs = wi->vs;
203 if (vs == NULL)
204 HGOTO_ERROR(DFE_ARGS, FAIL);
205
206 /* check access id and number of vertices in vdata */
207 if ((vs->aid == 0) || (vs->nvertices == 0))
208 HGOTO_ERROR(DFE_ARGS, FAIL);
209
210 /* Don't allow reads in 0-field vdatas */
211 if (vs->wlist.n<=0)
212 HGOTO_ERROR(DFE_BADFIELDS, FAIL);
213
214 /* check if vdata exists in file */
215 if (vexistvs(vs->f, vs->oref) == FAIL)
216 HGOTO_ERROR(DFE_NOVS, FAIL);
217
218 /* check interlace parameter */
219 if (interlace != FULL_INTERLACE && interlace != NO_INTERLACE)
220 HGOTO_ERROR(DFE_ARGS, FAIL);
221
222 /* read/write lists */
223 w = &(vs->wlist);
224 r = &(vs->rlist);
225 hsize = (intn)vs->wlist.ivsize; /* size as stored in HDF */
226 total_bytes = hsize * nelt;
227
228 /*
229 Now, convert and repack field(s) from Vtbuf into buf.
230
231 This section of the code deals with interlacing. In all cases
232 the items for each of the fields are converted and shuffled
233 around from the internal buffer "Vtbuf" to the user's buffer
234 "buf".
235
236 There are 5 cases :
237 (A) user=NO_INTERLACE & vdata=FULL_INTERLACE)
238 (B) user=NO_INTERLACE & vdata=NO_INTERLACE)
239 (C) user=FULL_INTERLACE & vdata=FULL_INTERLACE)
240 (D) user=FULL_INTERLACE & vadat=NO_INTERLACE)
241 (E) SPECIAL CASE when only one field.
242
243 Cases (A)-(D) handles multiple fields.
244 Case (E) handles reading from a Vdata with a single field.
245
246 Cases (E) and (C) are the most frequently used. Limit buffer
247 allocations to VDATA_BUFFER_MAX size so that we conserve
248 memory. Doing this involves a certain degree of added code
249 complexity so don't bother doing it for the less frequent
250 cases. Cases E and C have been rolled together since they are
251 very similar and both need the incremental writing.
252
253 */
254
255 /* ----------------------------------------------------------------- */
256 /* CASE (E + C): Easy to unroll case */
257 if ((w->n == 1) || (interlace == FULL_INTERLACE && vs->interlace == FULL_INTERLACE))
258 {
259 /*
260 * figure out how many elements we can move at a time and
261 * make sure our buffer is big enough
262 */
263
264 if ((uint32) total_bytes < Vtbufsize)
265 {
266 chunk = nelt;
267 }
268 else
269 {
270 int32 buf_size;
271
272 /* we are bounded above by VDATA_BUFFER_MAX */
273 buf_size = MIN(total_bytes, VDATA_BUFFER_MAX);
274
275 /* make sure there is at least room for one record in our buffer */
276 chunk = buf_size / hsize + 1;
277
278 /* get a buffer big enough to hold the values */
279 Vtbufsize = (size_t)chunk * (size_t)hsize;
280 if (Vtbuf)
281 HDfree(Vtbuf);
282 if ((Vtbuf = (uint8 *) HDmalloc(Vtbufsize)) == NULL)
283 HGOTO_ERROR(DFE_NOSPACE, FAIL);
284 }
285
286 done = 0;
287
288 /* set loop invariant parameters */
289 Src = buf;
290 bytes = hsize * chunk;
291
292 for (uvsize = 0, j = 0; j < r->n; j++)
293 uvsize += w->esize[r->item[j]];
294
295 while (done < nelt)
296 {
297
298 /* chunk has changed so update the byte counts */
299 if (nelt - done < chunk)
300 {
301 chunk = nelt - done;
302 bytes = hsize * chunk;
303 }
304
305 /* ================ start reading ============================== */
306 if ((nv = Hread(vs->aid, bytes, (uint8 *) Vtbuf)) != bytes)
307 {
308 HERROR(DFE_READERROR);
309 HEreport("Tried to read %d, only read %d", bytes, nv);
310 HGOTO_DONE(FAIL);
311 }
312
313 /* CASE (E): Only a single field in the Vdata */
314 if (w->n == 1)
315 {
316 DFKconvert(Vtbuf,Src,w->type[0], (uint32) w->order[0] * (uint32)chunk, DFACC_READ, 0, 0);
317 } /* case (e) */
318 /* ----------------------------------------------------------------- */
319 /* CASE (C): iu=full, iv=full */
320 else
321 {
322 offset = 0;
323 for (j = 0; j < r->n; j++)
324 {
325 i = r->item[j];
326 b1 = Src + offset;
327 b2 = Vtbuf + (size_t)w->off[i];
328 type = (int32)w->type[r->item[j]];
329 esize = (intn)w->esize[i];
330 isize = (intn)w->isize[i];
331 order = (intn)w->order[i];
332
333 for (index = 0; index < order; index++)
334 {
335 DFKconvert(b2, b1, type, (uint32) chunk, DFACC_READ, (uint32) hsize, (uint32) uvsize);
336 b1 += (int) esize / order;
337 b2 += (int) isize / order;
338 }
339 offset += esize;
340 }
341 } /* case (E) */
342
343 /* record what we've done and move to next group */
344 done += chunk;
345 Src += chunk * uvsize;
346 } /* end while */
347 } /* case (C + E) */
348 else {
349 /*
350 * Handle the other cases now.
351 * These cases are less frequent so don't bother unrolling
352 * the loops for now. As a result, we may get into memory
353 * problems since we may end up allocating a huge buffer
354 */
355
356 /* alloc space (Vtbuf) for reading in the raw data from vdata */
357 if (Vtbufsize < (size_t)nelt * (size_t) hsize)
358 {
359 Vtbufsize = (size_t)nelt * (size_t) hsize;
360 if (Vtbuf)
361 HDfree(Vtbuf);
362 if ((Vtbuf = (uint8 *) HDmalloc(Vtbufsize)) == NULL)
363 HGOTO_ERROR(DFE_NOSPACE, FAIL);
364 }
365
366 /* ================ start reading ============================== */
367
368 nv = Hread(vs->aid, nelt * hsize, (uint8 *) Vtbuf);
369
370 if (nv != nelt * hsize)
371 {
372 HERROR(DFE_READERROR);
373 HEreport("Tried to read %d, only read %d", nelt * hsize, nv);
374 HGOTO_DONE(FAIL);
375 }
376
377 /* ----------------------------------------------------------------- */
378 /* CASE (A): user=none, vdata=full */
379 if (interlace == NO_INTERLACE && vs->interlace == FULL_INTERLACE)
380 {
381 b1 = buf;
382 for (j = 0; j < r->n; j++)
383 {
384 i = r->item[j];
385 b2 = Vtbuf + (size_t)w->off[i];
386 type = (int32)w->type[i];
387 isize = (intn)w->isize[i];
388 esize = (intn)w->esize[i];
389 order = (intn)w->order[i];
390
391 for (index = 0; index < order; index++)
392 {
393 DFKconvert(b2, b1, type, (uint32) nelt, DFACC_READ, (uint32) hsize, (uint32) esize);
394 b2 += isize / order;
395 b1 += esize / order;
396 }
397 b1 += ((nelt - 1) * esize);
398 }
399 } /* case (a) */
400
401 /* ----------------------------------------------------------------- */
402 /* CASE (B): user=none, vdata=none */
403 else if (interlace == NO_INTERLACE && vs->interlace == NO_INTERLACE)
404 {
405 b1 = buf;
406 for (j = 0; j < r->n; j++)
407 {
408 i = r->item[j];
409 b2 = Vtbuf + (size_t)w->off[i] * (size_t)nelt;
410 type = (int32)w->type[i];
411 esize = (intn)w->esize[i];
412 isize = (intn)w->isize[i];
413 order = (intn)w->order[i];
414
415 for (index = 0; index < order; index++)
416 {
417 DFKconvert(b2, b1, type, (uint32) nelt, DFACC_READ, (uint32) isize, (uint32) esize);
418 b1 += esize / order;
419 b2 += isize / order;
420 }
421 b1 += ((nelt - 1) * esize);
422 }
423 } /* case (b) */
424
425 /* ----------------------------------------------------------------- */
426 /* CASE (D): user=full, vdata=none */
427 else if (interlace == FULL_INTERLACE && vs->interlace == NO_INTERLACE)
428 {
429
430 for (uvsize = 0, j = 0; j < r->n; j++)
431 uvsize += w->esize[r->item[j]];
432
433 offset = 0;
434 for (j = 0; j < r->n; j++)
435 {
436 i = r->item[j];
437 b1 = buf + offset;
438 b2 = Vtbuf + (size_t)w->off[i] * (size_t)nelt;
439 type = (int32)w->type[i];
440 isize = (intn)w->isize[i];
441 esize = (intn)w->esize[i];
442 order = (intn)w->order[i];
443
444 for (index = 0; index < order; index++)
445 {
446 DFKconvert(b2, b1, type, (uint32) nelt, DFACC_READ, (uint32) isize, (uint32) uvsize);
447 b1 += esize / order;
448 b2 += isize / order;
449 }
450 offset += isize;
451 }
452 } /* case (d) */
453 } /* end else, cases a, b, and d */
454
455 ret_value = (nelt);
456
457 done:
458 if(ret_value == FAIL)
459 { /* Error condition cleanup */
460
461 } /* end if */
462
463 /* Normal function cleanup */
464 return ret_value;
465 } /* VSread */
466
467 /*******************************************************************************
468 NAME
469 VSwrite
470
471 DESCRIPTION
472 Writes a specified number of elements' worth of data to a vdata.
473 You must specify how your data in your buffer is interlaced.
474
475 NEW
476 create an aid, and write out if this is the first time.
477 (otherwise) subsequent writes result in link-blocks.
478
479 RETURNS
480 RETURNS FAIL if error
481 RETURNS the number of elements written (0 or a +ve integer).
482
483 *******************************************************************************/
484 int32
VSwrite(int32 vkey,const uint8 buf[],int32 nelt,int32 interlace)485 VSwrite(int32 vkey, /* IN: vdata key */
486 const uint8 buf[], /* IN: elements to write to vdata */
487 int32 nelt, /* IN: number of elements */
488 int32 interlace /* IN: interlace of elements 'buf' */)
489 {
490 intn isize = 0;
491 intn order = 0;
492 intn index = 0;
493 intn esize = 0;
494 uint8 *dest = NULL;
495 const uint8 *src, *Src;
496 int32 j;
497 int32 type;
498 int32 offset;
499 int32 position = 0;
500 int32 new_size;
501 int32 status;
502 int32 total_bytes; /* total number of bytes that need to be written out */
503 DYN_VWRITELIST *w = NULL;
504 int32 int_size; /* size of "element" as needed by user in memory */
505 intn hdf_size = 0; /* size of record in HDF file */
506 vsinstance_t *wi = NULL;
507 VDATA *vs = NULL;
508 int32 bytes; /* number of elements / bytes to write next time */
509 int32 chunk;
510 int32 done; /* number of records to do / done */
511 int32 ret_value = SUCCEED;
512 CONSTR(FUNC, "VSwrite");
513
514 /* clear error stack */
515 HEclear();
516
517 /* check if vdata is part of vdata group */
518 if (HAatom_group(vkey) != VSIDGROUP)
519 HGOTO_ERROR(DFE_ARGS, FAIL);
520
521 /* get vdata instance */
522 if (NULL == (wi = (vsinstance_t *) HAatom_object(vkey)))
523 HGOTO_ERROR(DFE_NOVS, FAIL);
524
525 /* get vdata itself and check it. Also check number of elements */
526 vs = wi->vs;
527 if ((nelt <= 0) || (vs == NULL))
528 HGOTO_ERROR(DFE_ARGS, FAIL);
529
530 /* check if write access to vdata */
531 if (vs->access != 'w')
532 HGOTO_ERROR(DFE_BADACC, FAIL);
533
534 /* check if vdata exists in the file */
535 if (FAIL == vexistvs(vs->f, vs->oref))
536 HGOTO_ERROR(DFE_NOVS, FAIL);
537
538 /* get write list */
539 w = & vs->wlist;
540 if (w->n == 0)
541 {
542 HERROR(DFE_NOVS);
543 HEreport("No fields set for writing");
544 HGOTO_DONE(FAIL);
545 }
546
547 /* check interlace of input buffer */
548 if (interlace != NO_INTERLACE && interlace != FULL_INTERLACE)
549 HGOTO_ERROR(DFE_ARGS, FAIL);
550
551 hdf_size = (intn)w->ivsize; /* as stored in HDF file */
552 total_bytes = hdf_size * nelt;
553
554 /* make sure we have a valid AID */
555 if (vs->aid == 0)
556 {
557 #ifdef OLD_WAY
558 vs->aid = Hstartwrite(vs->f, DFTAG_VS, vs->oref, total_bytes);
559 if (vs->aid == FAIL)
560 HGOTO_ERROR(DFE_BADAID, FAIL);
561 #else /* OLD_WAY */
562 HGOTO_ERROR(DFE_BADAID, FAIL);
563 #endif /* OLD_WAY */
564 }
565
566 /*
567 * promote to link-block if vdata exists and is not already one
568 * AND we are increasing its size
569 */
570 HQueryposition(vs->aid, &position);
571 new_size = (position / (intn)vs->wlist.ivsize) + nelt;
572
573 /* this should really be cached in the Vdata structure */
574 for (int_size = 0, j = 0; j < w->n; j++)
575 int_size += w->esize[j];
576
577 /*
578 First, convert and repack field(s) from Vtbuf into buf.
579
580 This section of the code deals with interlacing. In all cases
581 the items for each of the fields are converted and shuffled
582 around from the user's buffer "buf" to the internal's buffer
583 "Vtbuf". The data in "Vtbuf" is then written out to the vdata.
584
585 There are 5 cases :
586 (A) user=NO_INTERLACE & vdata=FULL_INTERLACE)
587 (B) user=NO_INTERLACE & vdata=NO_INTERLACE)
588 (C) user=FULL_INTERLACE & vdata=FULL_INTERLACE)
589 (D) user=FULL_INTERLACE & vadat=NO_INTERLACE)
590 (E) SPECIAL CASE when only one field.
591
592 Cases (A)-(D) handles multiple fields
593 Case (E) handles single field Vdatas
594
595 Cases (E) and (C) are the most frequently used. Limit buffer
596 allocations to VDATA_BUFFER_MAX size so that we conserve
597 memory. Doing this involves a certain degree of added code
598 complexity so don't bother doing it for the less frequent
599 cases. Cases E and C have been rolled together since they are
600 very similar and both need the incremental writing.
601
602 --------------------------------------------------------------------- */
603 /* CASE (E + C): Easy to unroll case */
604 if ((w->n == 1) || (interlace == FULL_INTERLACE && vs->interlace == FULL_INTERLACE))
605 {
606
607 /*
608 * figure out how many elements we can move at a time and
609 * make sure our buffer is big enough
610 */
611
612 if ((uint32) total_bytes < Vtbufsize)
613 {
614 chunk = nelt;
615 }
616 else
617 {
618 int32 buf_size;
619
620 /* we are bounded above by VDATA_BUFFER_MAX */
621 buf_size = MIN(total_bytes, VDATA_BUFFER_MAX);
622
623 /* make sure there is at least room for one record in our buffer */
624 chunk = buf_size / hdf_size + 1;
625
626 /* get a buffer big enough to hold the values */
627 Vtbufsize = (size_t)chunk * (size_t)hdf_size;
628 if (Vtbuf)
629 HDfree(Vtbuf);
630 if ((Vtbuf = (uint8 *) HDmalloc(Vtbufsize)) == NULL)
631 HGOTO_ERROR(DFE_NOSPACE, FAIL);
632 }
633
634 done = 0;
635
636 /* set loop invariant parameters */
637 Src = buf;
638 dest = Vtbuf;
639 bytes = hdf_size * chunk;
640
641 while (done < nelt)
642 {
643
644 /* chunk has changed so update the byte counts */
645 if (nelt - done < chunk)
646 {
647 chunk = nelt - done;
648 bytes = hdf_size * chunk;
649 }
650 /*
651 printf("Case E/C: [%d,%d] writing %d (elems) %d bytes\n", done, nelt, chunk, bytes);
652 */
653
654 offset = 0;
655 for (j = 0; j < w->n; j++)
656 {
657 src = Src + offset;
658 dest = Vtbuf + (size_t)w->off[j];
659 type = (int32)w->type[j];
660 esize = (intn)w->esize[j];
661 isize = (intn)w->isize[j];
662 order = (intn)w->order[j];
663
664 for (index = 0; index < order; index++)
665 {
666 DFKconvert((VOIDP)src, dest, type, (uint32) chunk, DFACC_WRITE, (uint32) int_size, (uint32) hdf_size);
667 dest += isize / order;
668 src += esize / order;
669 }
670 offset += esize;
671 }
672
673 /* write the converted data to the file */
674 status = Hwrite(vs->aid, bytes, (uint8 *) Vtbuf);
675 if (status != bytes)
676 HGOTO_ERROR(DFE_WRITEERROR, FAIL);
677
678 /* record what we've done and move to next group */
679 done += chunk;
680 Src += chunk * int_size;
681 }
682
683 } /* case (C + E) */
684
685 else
686 {
687
688 /*
689 * Handle the other cases now.
690 * These cases are less frequent so don't bother unrolling
691 * the loops for now. As a result, we may get into memory
692 * problems since we may end up allocating a huge buffer
693 */
694
695 /* alloc space (Vtbuf) for writing out the data */
696 if (Vtbufsize < (uint32) total_bytes)
697 {
698 Vtbufsize = (uint32)total_bytes;
699 if (Vtbuf)
700 HDfree(Vtbuf);
701 if ((Vtbuf = (uint8 *) HDmalloc(Vtbufsize)) == NULL)
702 HGOTO_ERROR(DFE_NOSPACE, FAIL);
703 }
704
705 /* ----------------------------------------------------------------- */
706 /* CASE (A): user=none, vdata=full */
707 if (interlace == NO_INTERLACE && vs->interlace == FULL_INTERLACE)
708 {
709
710 src = buf;
711 for (j = 0; j < w->n; j++)
712 {
713 dest = Vtbuf + (size_t)w->off[j];
714 type = (int32)w->type[j];
715 esize = (intn)w->esize[j];
716 isize = (intn)w->isize[j];
717 order = (intn)w->order[j];
718
719 for (index = 0; index < order; index++) {
720 DFKconvert((VOIDP)src, dest, type, (uint32) nelt, DFACC_WRITE, (uint32) esize, (uint32) hdf_size);
721 src += esize / order;
722 dest += isize / order;
723 }
724 src += ((nelt - 1) * esize);
725 }
726
727 } /* case (a) */
728
729 /* --------------------------------------------------------------------- */
730 /* CASE (B): user=none, vdata=none */
731 else if (interlace == NO_INTERLACE && vs->interlace == NO_INTERLACE)
732 {
733
734 src = buf;
735 for (j = 0; j < w->n; j++)
736 {
737 dest = Vtbuf + w->off[j] * nelt;
738 type = (int32)w->type[j];
739 esize = (intn)w->esize[j];
740 isize = (intn)w->isize[j];
741 order = (intn)w->order[j];
742
743 for (index = 0; index < order; index++) {
744 DFKconvert((VOIDP)src, dest, type, (uint32) nelt, DFACC_WRITE, (uint32) esize, (uint32) isize);
745 dest += isize / order;
746 src += esize / order;
747 }
748 src += ((nelt - 1) * esize);
749 }
750
751 } /* case (b) */
752
753 /* ----------------------------------------------------------------- */
754 /* CASE (D): user=full, vdata=none */
755 else if (interlace == FULL_INTERLACE && vs->interlace == NO_INTERLACE)
756 {
757 offset = 0;
758 for (j = 0; j < w->n; j++)
759 {
760 src = buf + offset;
761 dest = Vtbuf + w->off[j] * nelt;
762 type = (int32)w->type[j];
763 isize = (intn)w->isize[j];
764 esize = (intn)w->esize[j];
765 order = (intn)w->order[j];
766
767 for (index = 0; index < order; index++) {
768 DFKconvert((VOIDP)src, dest, type, (uint32) nelt, DFACC_WRITE, (uint32) int_size, (uint32) isize);
769 dest += isize / order;
770 src += esize / order;
771 }
772 offset += esize;
773 }
774 } /* case (d) */
775
776 status = Hwrite(vs->aid, total_bytes, (uint8 *) Vtbuf);
777 if (status != total_bytes)
778 HGOTO_ERROR(DFE_WRITEERROR, FAIL);
779
780 } /* cases a, b, and d */
781
782 /* update the internal structure to reflect write */
783 if (new_size > vs->nvertices)
784 vs->nvertices = new_size;
785 vs->marked = 1;
786
787 ret_value = (nelt);
788
789 done:
790 if(ret_value == FAIL)
791 { /* Error condition cleanup */
792
793 } /* end if */
794
795 /* Normal function cleanup */
796 return ret_value;
797 } /* VSwrite */
798
799