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 HDF5. The full HDF5 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/HDF5/releases. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 #include <stdlib.h>
15 #include <string.h>
16
17 #include "H5LTprivate.h"
18 #include "H5TBprivate.h"
19
20
21 /*-------------------------------------------------------------------------
22 *
23 * internal functions
24 *
25 *-------------------------------------------------------------------------
26 */
27
28 static hbool_t H5TB_find_field(const char *field,
29 const char *field_list);
30
31 static herr_t H5TB_attach_attributes(const char *table_title,
32 hid_t loc_id,
33 const char *dset_name,
34 hsize_t nfields,
35 hid_t tid);
36
37 static hid_t H5TB_create_type(hid_t loc_id,
38 const char *dset_name,
39 size_t type_size,
40 const size_t *field_offset,
41 const size_t *field_sizes,
42 hid_t ftype_id);
43
44 /*-------------------------------------------------------------------------
45 *
46 * Create functions
47 *
48 *-------------------------------------------------------------------------
49 */
50
51 /*-------------------------------------------------------------------------
52 * Function: H5TBmake_table
53 *
54 * Purpose: Make a table
55 *
56 * Return: Success: 0, Failure: -1
57 *
58 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
59 * Quincey Koziol
60 *
61 * Date: January 17, 2001
62 *
63 * Comments:
64 *
65 *-------------------------------------------------------------------------
66 */
H5TBmake_table(const char * table_title,hid_t loc_id,const char * dset_name,hsize_t nfields,hsize_t nrecords,size_t type_size,const char * field_names[],const size_t * field_offset,const hid_t * field_types,hsize_t chunk_size,void * fill_data,int compress,const void * buf)67 herr_t H5TBmake_table(const char *table_title,
68 hid_t loc_id,
69 const char *dset_name,
70 hsize_t nfields,
71 hsize_t nrecords,
72 size_t type_size,
73 const char *field_names[],
74 const size_t *field_offset,
75 const hid_t *field_types,
76 hsize_t chunk_size,
77 void *fill_data,
78 int compress,
79 const void *buf)
80 {
81 hid_t did = H5I_BADID;
82 hid_t sid = H5I_BADID;
83 hid_t mem_type_id = H5I_BADID;
84 hid_t plist_id = H5I_BADID;
85 hid_t attr_id = H5I_BADID;
86 hsize_t dims[1];
87 hsize_t dims_chunk[1];
88 hsize_t maxdims[1] = {H5S_UNLIMITED};
89 char attr_name[255];
90 char *member_name = NULL;
91 unsigned char *tmp_buf = NULL;
92 hsize_t i;
93 herr_t ret_val = -1;
94
95 /* check the arguments */
96 if (table_title == NULL) {
97 goto out;
98 }
99 if (dset_name == NULL) {
100 goto out;
101 }
102 if (field_names == NULL) {
103 goto out;
104 }
105
106 dims[0] = nrecords;
107 dims_chunk[0] = chunk_size;
108
109 /* create the memory data type. */
110 if((mem_type_id = H5Tcreate(H5T_COMPOUND, type_size)) < 0)
111 goto out;
112
113 /* insert fields. */
114 for(i = 0; i < nfields; i++)
115 if(H5Tinsert(mem_type_id, field_names[i], field_offset[i], field_types[i] ) < 0)
116 goto out;
117
118 /* create a simple data space with unlimited size */
119 if((sid = H5Screate_simple(1, dims, maxdims)) < 0)
120 goto out;
121
122 /* modify dataset creation properties, i.e. enable chunking */
123 if((plist_id = H5Pcreate(H5P_DATASET_CREATE)) < 0)
124 goto out;
125 if(H5Pset_chunk(plist_id, 1, dims_chunk) < 0)
126 goto out;
127
128 /* set the fill value using a struct as the data type. */
129 if(fill_data)
130 if(H5Pset_fill_value(plist_id, mem_type_id, fill_data) < 0)
131 goto out;
132
133 /*
134 dataset creation property list is modified to use
135 GZIP compression with the compression effort set to 6.
136 */
137 if(compress)
138 if(H5Pset_deflate(plist_id, 6) < 0)
139 goto out;
140
141 /* create the dataset. */
142 if((did = H5Dcreate2(loc_id, dset_name, mem_type_id, sid, H5P_DEFAULT, plist_id, H5P_DEFAULT)) < 0)
143 goto out;
144
145 /* only write if there is something to write */
146 if(buf)
147 if(H5Dwrite(did, mem_type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0)
148 goto out;
149
150 /* terminate access to the data space. */
151 if(H5Sclose(sid) < 0)
152 goto out;
153 sid = H5I_BADID;
154
155 /* end access to the dataset */
156 if(H5Dclose(did) < 0)
157 goto out;
158 did = H5I_BADID;
159
160 /* end access to the property list */
161 if(H5Pclose(plist_id) < 0)
162 goto out;
163 plist_id = H5I_BADID;
164
165 /*-------------------------------------------------------------------------
166 * set the conforming table attributes
167 *-------------------------------------------------------------------------
168 */
169
170 /* attach the CLASS attribute */
171 if(H5LTset_attribute_string(loc_id, dset_name, "CLASS", TABLE_CLASS) < 0)
172 goto out;
173
174 /* attach the VERSION attribute */
175 if(H5LTset_attribute_string(loc_id, dset_name, "VERSION", TABLE_VERSION) < 0)
176 goto out;
177
178 /* attach the TITLE attribute */
179 if(H5LTset_attribute_string(loc_id, dset_name, "TITLE", table_title) < 0)
180 goto out;
181
182 /* attach the FIELD_ name attribute */
183 for(i = 0; i < nfields; i++) {
184 /* get the member name */
185 if(NULL == (member_name = H5Tget_member_name(mem_type_id, (unsigned)i)))
186 goto out;
187
188 HDsnprintf(attr_name, sizeof(attr_name), "FIELD_%d_NAME", (int)i);
189
190 /* attach the attribute */
191 if(H5LTset_attribute_string(loc_id, dset_name, attr_name, member_name) < 0)
192 goto out;
193
194 H5free_memory(member_name);
195 member_name = NULL;
196 } /* end for */
197
198 /* attach the FIELD_ fill value attribute */
199 if(fill_data) {
200 tmp_buf = (unsigned char *)fill_data;
201
202 /* open the dataset. */
203 if((did = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
204 goto out;
205
206 if((sid = H5Screate(H5S_SCALAR)) < 0)
207 goto out;
208
209 for(i = 0; i < nfields; i++) {
210 HDsnprintf(attr_name, sizeof(attr_name), "FIELD_%d_FILL", (int)i);
211
212 if((attr_id = H5Acreate2(did, attr_name, field_types[i], sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
213 goto out;
214
215 if(H5Awrite(attr_id, field_types[i], tmp_buf + field_offset[i]) < 0)
216 goto out;
217
218 if(H5Aclose(attr_id) < 0)
219 goto out;
220 attr_id = H5I_BADID;
221 } /* end for */
222
223 /* terminate access to the data space. */
224 if(H5Sclose(sid) < 0)
225 goto out;
226 sid = H5I_BADID;
227
228 /* end access to the dataset */
229 if(H5Dclose(did) < 0)
230 goto out;
231 did = H5I_BADID;
232 } /* end if */
233
234 /* release the datatype. */
235 if(H5Tclose(mem_type_id) < 0)
236 goto out;
237 mem_type_id = H5I_BADID;
238
239 ret_val = 0;
240
241 out:
242 if(member_name)
243 H5free_memory(member_name);
244 if(attr_id > 0)
245 if(H5Aclose(attr_id) < 0)
246 ret_val = -1;
247 if(plist_id > 0)
248 if(H5Pclose(plist_id) < 0)
249 ret_val = -1;
250 if(sid > 0)
251 if(H5Sclose(sid) < 0)
252 ret_val = -1;
253 if(did > 0)
254 if(H5Dclose(did) < 0)
255 ret_val = -1;
256 if(mem_type_id > 0)
257 if(H5Tclose(mem_type_id) < 0)
258 ret_val = -1;
259
260 return ret_val;
261 } /* end H5TBmake_table() */
262
263 /*-------------------------------------------------------------------------
264 *
265 * Write functions
266 *
267 *-------------------------------------------------------------------------
268 */
269
270 /*-------------------------------------------------------------------------
271 * Function: H5TBappend_records
272 *
273 * Purpose: Appends records to a table
274 *
275 * Return: Success: 0, Failure: -1
276 *
277 * Programmers:
278 * Pedro Vicente, pvn@ncsa.uiuc.edu
279 * Quincey Koziol
280 *
281 * Date: November 19, 2001
282 *
283 * Comments: Uses memory offsets
284 *
285 *-------------------------------------------------------------------------
286 */
H5TBappend_records(hid_t loc_id,const char * dset_name,hsize_t nrecords,size_t type_size,const size_t * field_offset,const size_t * field_sizes,const void * buf)287 herr_t H5TBappend_records(hid_t loc_id,
288 const char *dset_name,
289 hsize_t nrecords,
290 size_t type_size,
291 const size_t *field_offset,
292 const size_t *field_sizes,
293 const void *buf)
294 {
295 hid_t did = H5I_BADID;
296 hid_t tid = H5I_BADID;
297 hid_t mem_type_id = H5I_BADID;
298 hsize_t nrecords_orig;
299 hsize_t nfields;
300 herr_t ret_val = -1;
301
302 /* check the arguments */
303 if (dset_name == NULL)
304 goto out;
305
306 /* get the original number of records and fields */
307 if(H5TBget_table_info(loc_id, dset_name, &nfields, &nrecords_orig) < 0)
308 goto out;
309
310 /* open the dataset. */
311 if((did = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
312 goto out;
313
314 /* get the datatypes */
315 if((tid = H5Dget_type(did)) < 0)
316 goto out;
317
318 if((mem_type_id = H5TB_create_type(loc_id, dset_name, type_size, field_offset, field_sizes, tid)) < 0)
319 goto out;
320
321 /* append the records */
322 if((H5TB_common_append_records(did, mem_type_id, (size_t)nrecords, nrecords_orig, buf)) < 0)
323 goto out;
324
325 ret_val = 0;
326
327 out:
328 if(tid > 0)
329 if(H5Tclose(tid) < 0)
330 ret_val = -1;
331 if(mem_type_id > 0)
332 if(H5Tclose(mem_type_id) < 0)
333 ret_val = -1;
334 if(did > 0)
335 if(H5Dclose(did) < 0)
336 ret_val = -1;
337
338 return ret_val;
339 } /* end H5TBappend_records() */
340
341 /*-------------------------------------------------------------------------
342 * Function: H5TBwrite_records
343 *
344 * Purpose: Writes records
345 *
346 * Return: Success: 0, Failure: -1
347 *
348 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
349 *
350 * Date: November 19, 2001
351 *
352 * Comments: Uses memory offsets
353 *
354 *-------------------------------------------------------------------------
355 */
H5TBwrite_records(hid_t loc_id,const char * dset_name,hsize_t start,hsize_t nrecords,size_t type_size,const size_t * field_offset,const size_t * field_sizes,const void * buf)356 herr_t H5TBwrite_records(hid_t loc_id,
357 const char *dset_name,
358 hsize_t start,
359 hsize_t nrecords,
360 size_t type_size,
361 const size_t *field_offset,
362 const size_t *field_sizes,
363 const void *buf)
364 {
365 hid_t did = H5I_BADID;
366 hid_t tid = H5I_BADID;
367 hid_t sid = H5I_BADID;
368 hid_t m_sid = H5I_BADID;
369 hid_t mem_type_id = H5I_BADID;
370 hsize_t count[1];
371 hsize_t offset[1];
372 hsize_t mem_size[1];
373 hsize_t dims[1];
374 herr_t ret_val = -1;
375
376 /* check the arguments */
377 if (dset_name == NULL)
378 goto out;
379
380 /* open the dataset. */
381 if((did = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
382 goto out;
383
384 /* get the datatype */
385 if((tid = H5Dget_type(did)) < 0)
386 goto out;
387
388 if((mem_type_id = H5TB_create_type(loc_id, dset_name, type_size, field_offset, field_sizes, tid)) < 0)
389 goto out;
390
391 /* get the dataspace handle */
392 if((sid = H5Dget_space(did)) < 0)
393 goto out;
394
395 /* get records */
396 if(H5Sget_simple_extent_dims(sid, dims, NULL) < 0)
397 goto out;
398
399 if(start + nrecords > dims[0])
400 goto out;
401
402 /* define a hyperslab in the dataset of the size of the records */
403 offset[0] = start;
404 count[0] = nrecords;
405 if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0)
406 goto out;
407
408 /* create a memory dataspace handle */
409 mem_size[0] = count[0];
410 if((m_sid = H5Screate_simple(1, mem_size, NULL)) < 0)
411 goto out;
412
413 if(H5Dwrite(did, mem_type_id, m_sid, sid, H5P_DEFAULT, buf) < 0)
414 goto out;
415
416 ret_val = 0;
417
418 out:
419 if(m_sid > 0)
420 if(H5Sclose(m_sid) < 0)
421 ret_val = -1;
422 if(sid > 0)
423 if(H5Sclose(sid) < 0)
424 ret_val = -1;
425 if(tid > 0)
426 if(H5Tclose(tid) < 0)
427 ret_val = -1;
428 if(mem_type_id > 0)
429 if(H5Tclose(mem_type_id) < 0)
430 ret_val = -1;
431 if(did > 0)
432 if(H5Dclose(did) < 0)
433 ret_val = -1;
434
435 return ret_val;
436 } /* end H5TBwrite_records() */
437
438 /*-------------------------------------------------------------------------
439 * Function: H5TBwrite_fields_name
440 *
441 * Purpose: Writes fields
442 *
443 * Return: Success: 0, Failure: -1
444 *
445 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
446 *
447 * Date: November 21, 2001
448 *
449 * Comments:
450 *
451 *-------------------------------------------------------------------------
452 */
H5TBwrite_fields_name(hid_t loc_id,const char * dset_name,const char * field_names,hsize_t start,hsize_t nrecords,size_t type_size,const size_t * field_offset,const size_t * field_sizes,const void * buf)453 herr_t H5TBwrite_fields_name(hid_t loc_id,
454 const char *dset_name,
455 const char *field_names,
456 hsize_t start,
457 hsize_t nrecords,
458 size_t type_size,
459 const size_t *field_offset,
460 const size_t *field_sizes,
461 const void *buf)
462 {
463 hid_t did = H5I_BADID;
464 hid_t tid = H5I_BADID;
465 hid_t write_type_id = H5I_BADID;
466 hid_t member_type_id = H5I_BADID;
467 hid_t nmtype_id = H5I_BADID;
468 hid_t m_sid = H5I_BADID;
469 hid_t file_space_id = H5I_BADID;
470 hid_t preserve_id = H5I_BADID;
471 hssize_t nfields;
472 hssize_t i, j;
473 hsize_t count[1];
474 hsize_t offset[1];
475 char *member_name = NULL;
476 size_t size_native;
477 herr_t ret_val = -1;
478
479 /* check the arguments */
480 if (dset_name == NULL)
481 goto out;
482 if (field_names == NULL)
483 goto out;
484
485 /* create xfer properties to preserve initialized data */
486 if((preserve_id = H5Pcreate(H5P_DATASET_XFER)) < 0)
487 goto out;
488 if(H5Pset_preserve(preserve_id, 1) < 0)
489 goto out;
490
491 /* open the dataset. */
492 if((did = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
493 goto out;
494
495 /* get the datatype */
496 if((tid = H5Dget_type(did)) < 0)
497 goto out;
498
499 /* get the number of fields */
500 if((nfields = H5Tget_nmembers(tid)) < 0)
501 goto out;
502
503 /* create a write id */
504 if((write_type_id = H5Tcreate(H5T_COMPOUND, type_size)) < 0)
505 goto out;
506
507 j = 0;
508
509 /* iterate though the members */
510 for(i = 0; i < nfields; i++) {
511 /* get the member name */
512 if(NULL == (member_name = H5Tget_member_name(tid, (unsigned)i)))
513 goto out;
514
515 if(H5TB_find_field(member_name, field_names)) {
516 /* get the member type */
517 if((member_type_id = H5Tget_member_type(tid, (unsigned)i)) < 0)
518 goto out;
519
520 /* convert to native type */
521 if((nmtype_id = H5Tget_native_type(member_type_id, H5T_DIR_DEFAULT)) < 0)
522 goto out;
523
524 if(0 == (size_native = H5Tget_size(nmtype_id)))
525 goto out;
526
527 /* adjust, if necessary */
528 if(field_sizes[j] != size_native)
529 if(H5Tset_size(nmtype_id, field_sizes[j]) < 0)
530 goto out;
531
532 /* the field in the file is found by its name */
533 if(field_offset) {
534 if(H5Tinsert(write_type_id, member_name, field_offset[j], nmtype_id) < 0)
535 goto out;
536 } /* end if */
537 /* only one field */
538 else {
539 if(H5Tinsert(write_type_id, member_name, (size_t)0, nmtype_id) < 0)
540 goto out;
541 } /* end else */
542
543 j++;
544
545 /* close */
546 if(H5Tclose(member_type_id) < 0)
547 goto out;
548 member_type_id = H5I_BADID;
549 if(H5Tclose(nmtype_id) < 0)
550 goto out;
551 nmtype_id = H5I_BADID;
552 } /* end if */
553
554 H5free_memory(member_name);
555 member_name = NULL;
556 } /* end for */
557
558 /* get the dataspace handle */
559 if((file_space_id = H5Dget_space(did)) < 0)
560 goto out;
561 if((m_sid = H5Screate_simple(1, &nrecords, NULL)) < 0)
562 goto out;
563
564 /* define a hyperslab in the dataset */
565 offset[0] = start;
566 count[0] = nrecords;
567 if(H5Sselect_hyperslab(file_space_id, H5S_SELECT_SET, offset, NULL, count, NULL) < 0)
568 goto out;
569
570 /* write */
571 if(H5Dwrite(did, write_type_id, m_sid, file_space_id, preserve_id, buf) < 0)
572 goto out;
573
574 ret_val = 0;
575
576 out:
577 if(member_name)
578 H5free_memory(member_name);
579 if(preserve_id > 0)
580 if(H5Pclose(preserve_id) < 0)
581 ret_val = -1;
582 if(write_type_id > 0)
583 if(H5Tclose(write_type_id) < 0)
584 ret_val = -1;
585 if(tid > 0)
586 if(H5Tclose(tid) < 0)
587 ret_val = -1;
588 if(file_space_id > 0)
589 if(H5Sclose(file_space_id) < 0)
590 ret_val = -1;
591 if(m_sid > 0)
592 if(H5Sclose(m_sid) < 0)
593 ret_val = -1;
594 if(did > 0)
595 if(H5Dclose(did) < 0)
596 ret_val = -1;
597
598 return ret_val;
599 } /* end H5TBwrite_fields_name() */
600
601 /*-------------------------------------------------------------------------
602 * Function: H5TBwrite_fields_index
603 *
604 * Purpose: Writes fields
605 *
606 * Return: Success: 0, Failure: -1
607 *
608 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
609 *
610 * Date: November 21, 2001
611 *
612 * Comments: Uses memory offsets
613 *
614 *-------------------------------------------------------------------------
615 */
H5TBwrite_fields_index(hid_t loc_id,const char * dset_name,hsize_t nfields,const int * field_index,hsize_t start,hsize_t nrecords,size_t type_size,const size_t * field_offset,const size_t * field_sizes,const void * buf)616 herr_t H5TBwrite_fields_index(hid_t loc_id,
617 const char *dset_name,
618 hsize_t nfields,
619 const int *field_index,
620 hsize_t start,
621 hsize_t nrecords,
622 size_t type_size,
623 const size_t *field_offset,
624 const size_t *field_sizes,
625 const void *buf)
626 {
627 hid_t did = H5I_BADID;
628 hid_t tid = H5I_BADID;
629 hid_t write_type_id = H5I_BADID;
630 hid_t member_type_id = H5I_BADID;
631 hid_t nmtype_id = H5I_BADID;
632 hid_t m_sid = H5I_BADID;
633 hid_t file_space_id = H5I_BADID;
634 hid_t preserve_id = H5I_BADID;
635 hsize_t count[1];
636 hsize_t offset[1];
637 hsize_t i;
638 size_t size_native;
639 char *member_name = NULL;
640 herr_t ret_val = -1;
641
642 /* check the arguments */
643 if (dset_name == NULL)
644 goto out;
645
646 /* create xfer properties to preserve initialized data */
647 if((preserve_id = H5Pcreate(H5P_DATASET_XFER)) < 0)
648 goto out;
649 if(H5Pset_preserve(preserve_id, 1) < 0)
650 goto out;
651
652 /* open the dataset. */
653 if((did = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
654 goto out;
655
656 /* get the datatype */
657 if((tid = H5Dget_type(did)) < 0)
658 goto out;
659
660 /* create a write id */
661 if((write_type_id = H5Tcreate(H5T_COMPOUND, type_size)) < 0)
662 goto out;
663
664 /* iterate tru the members */
665 for(i = 0; i < nfields; i++) {
666 unsigned j;
667
668 /* Range check value */
669 if(field_index[i] < 0)
670 goto out;
671
672 j = (unsigned)field_index[i];
673
674 /* get the member name */
675 if(NULL == (member_name = H5Tget_member_name(tid, j)))
676 goto out;
677
678 /* get the member type */
679 if((member_type_id = H5Tget_member_type(tid, j)) < 0)
680 goto out;
681
682 /* convert to native type */
683 if((nmtype_id = H5Tget_native_type(member_type_id,H5T_DIR_DEFAULT)) < 0)
684 goto out;
685
686 if(0 == (size_native = H5Tget_size(nmtype_id)))
687 goto out;
688
689 if(field_sizes[i] != size_native)
690 if(H5Tset_size(nmtype_id, field_sizes[i]) < 0)
691 goto out;
692
693 /* the field in the file is found by its name */
694 if(field_offset) {
695 if(H5Tinsert(write_type_id, member_name, field_offset[i], nmtype_id) < 0)
696 goto out;
697 } /* end if */
698 /* only one field */
699 else {
700 if(H5Tinsert(write_type_id, member_name, (size_t)0, nmtype_id) < 0)
701 goto out;
702 } /* end else */
703
704 /* close */
705 if(H5Tclose(member_type_id) < 0)
706 goto out;
707 member_type_id = H5I_BADID;
708 if(H5Tclose(nmtype_id) < 0)
709 goto out;
710 nmtype_id = H5I_BADID;
711
712 H5free_memory(member_name);
713 member_name = NULL;
714 } /* end for */
715
716 /* get the dataspace handles */
717 if((file_space_id = H5Dget_space(did)) < 0)
718 goto out;
719 if((m_sid = H5Screate_simple(1, &nrecords, NULL)) < 0)
720 goto out;
721
722 /* define a hyperslab in the dataset */
723 offset[0] = start;
724 count[0] = nrecords;
725 if(H5Sselect_hyperslab(file_space_id, H5S_SELECT_SET, offset, NULL, count, NULL) < 0)
726 goto out;
727
728 /* write */
729 if(H5Dwrite(did, write_type_id, m_sid, file_space_id, preserve_id, buf) < 0)
730 goto out;
731
732 ret_val = 0;
733
734 out:
735 if(member_name)
736 H5free_memory(member_name);
737 if(preserve_id > 0)
738 if(H5Pclose(preserve_id) < 0)
739 ret_val = -1;
740 if(write_type_id > 0)
741 if(H5Tclose(write_type_id) < 0)
742 ret_val = -1;
743 if(member_type_id > 0)
744 if(H5Tclose(member_type_id) < 0)
745 ret_val = -1;
746 if(nmtype_id > 0)
747 if(H5Tclose(nmtype_id) < 0)
748 ret_val = -1;
749 if(tid > 0)
750 if(H5Tclose(tid) < 0)
751 ret_val = -1;
752 if(file_space_id > 0)
753 if(H5Sclose(file_space_id) < 0)
754 ret_val = -1;
755 if(m_sid > 0)
756 if(H5Sclose(m_sid) < 0)
757 ret_val = -1;
758 if(did > 0)
759 if(H5Dclose(did) < 0)
760 ret_val = -1;
761
762 return ret_val;
763 } /* end H5TBwrite_fields_index() */
764
765
766 /*-------------------------------------------------------------------------
767 *
768 * Read functions
769 *
770 *-------------------------------------------------------------------------
771 */
772
773
774 /*-------------------------------------------------------------------------
775 * Function: H5TBread_table
776 *
777 * Purpose: Reads a table
778 *
779 * Return: Success: 0, Failure: -1
780 *
781 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
782 *
783 * Date: November 20, 2001
784 *
785 * Comments:
786 *
787 *-------------------------------------------------------------------------
788 */
H5TBread_table(hid_t loc_id,const char * dset_name,size_t type_size,const size_t * field_offset,const size_t * field_sizes,void * dst_buf)789 herr_t H5TBread_table(hid_t loc_id,
790 const char *dset_name,
791 size_t type_size,
792 const size_t *field_offset,
793 const size_t *field_sizes,
794 void *dst_buf)
795 {
796 hid_t did = H5I_BADID;
797 hid_t ftype_id = H5I_BADID;
798 hid_t mem_type_id = H5I_BADID;
799 hid_t sid = H5I_BADID;
800 hsize_t dims[1];
801 herr_t ret_val = -1;
802
803 /* check the arguments */
804 if (dset_name == NULL)
805 goto out;
806
807 /* open the dataset. */
808 if((did = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
809 goto out;
810
811 /* get the dataspace handle */
812 if((sid = H5Dget_space(did)) < 0)
813 goto out;
814
815 /* get dimensions */
816 if(H5Sget_simple_extent_dims(sid, dims, NULL) < 0)
817 goto out;
818
819 /* get the datatypes */
820 if((ftype_id = H5Dget_type (did)) < 0)
821 goto out;
822
823 if((mem_type_id = H5TB_create_type(loc_id, dset_name, type_size, field_offset, field_sizes, ftype_id)) < 0)
824 goto out;
825
826 /* read */
827 if(H5Dread(did, mem_type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, dst_buf) < 0)
828 goto out;
829
830 ret_val = 0;
831
832 out:
833 if(mem_type_id > 0)
834 if(H5Tclose(mem_type_id) < 0)
835 ret_val = -1;
836 if(ftype_id > 0)
837 if(H5Tclose(ftype_id) < 0)
838 ret_val = -1;
839 if(sid > 0)
840 if(H5Sclose(sid) < 0)
841 ret_val = -1;
842 if(did > 0)
843 if(H5Dclose(did) < 0)
844 ret_val = -1;
845
846 return ret_val;
847 } /* end H5TBread_table() */
848
849 /*-------------------------------------------------------------------------
850 * Function: H5TBread_records
851 *
852 * Purpose: Reads records
853 *
854 * Return: Success: 0, Failure: -1
855 *
856 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
857 *
858 * Date: November 19, 2001
859 *
860 * Comments:
861 *
862 *-------------------------------------------------------------------------
863 */
H5TBread_records(hid_t loc_id,const char * dset_name,hsize_t start,hsize_t nrecords,size_t type_size,const size_t * field_offset,const size_t * field_sizes,void * buf)864 herr_t H5TBread_records(hid_t loc_id,
865 const char *dset_name,
866 hsize_t start,
867 hsize_t nrecords,
868 size_t type_size,
869 const size_t *field_offset,
870 const size_t *field_sizes,
871 void *buf)
872 {
873 hid_t did = H5I_BADID;
874 hid_t ftype_id = H5I_BADID;
875 hid_t mem_type_id = H5I_BADID;
876 hsize_t nrecords_orig;
877 hsize_t nfields;
878 herr_t ret_val = -1;
879
880 /* check the arguments */
881 if (dset_name == NULL)
882 goto out;
883
884 /* get the number of records and fields */
885 if(H5TBget_table_info(loc_id, dset_name, &nfields, &nrecords_orig) < 0)
886 goto out;
887
888 /* open the dataset */
889 if((did = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
890 goto out;
891
892 /* get the datatypes */
893 if((ftype_id = H5Dget_type(did)) < 0)
894 goto out;
895
896 if((mem_type_id = H5TB_create_type(loc_id, dset_name, type_size, field_offset, field_sizes, ftype_id)) < 0)
897 goto out;
898
899 /* read the records */
900 if((H5TB_common_read_records(did, mem_type_id, start, (size_t)nrecords, nrecords_orig, buf)) < 0)
901 goto out;
902
903 ret_val = 0;
904
905 out:
906 if(mem_type_id > 0)
907 if(H5Tclose(mem_type_id) < 0)
908 ret_val = -1;
909 if(ftype_id > 0)
910 if(H5Tclose(ftype_id) < 0)
911 ret_val = -1;
912 if(did > 0)
913 if(H5Dclose(did) < 0)
914 ret_val = -1;
915
916 return ret_val;
917 } /* end H5TBread_records() */
918
919 /*-------------------------------------------------------------------------
920 * Function: H5TBread_fields_name
921 *
922 * Purpose: Reads fields
923 *
924 * Return: Success: 0, Failure: -1
925 *
926 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
927 *
928 * Date: November 19, 2001
929 *
930 * Comments:
931 *
932 *-------------------------------------------------------------------------
933 */
H5TBread_fields_name(hid_t loc_id,const char * dset_name,const char * field_names,hsize_t start,hsize_t nrecords,size_t type_size,const size_t * field_offset,const size_t * field_sizes,void * buf)934 herr_t H5TBread_fields_name(hid_t loc_id,
935 const char *dset_name,
936 const char *field_names,
937 hsize_t start,
938 hsize_t nrecords,
939 size_t type_size,
940 const size_t *field_offset,
941 const size_t *field_sizes,
942 void *buf)
943 {
944 hid_t did = H5I_BADID;
945 hid_t ftype_id = H5I_BADID;
946 hid_t mem_type_id = H5I_BADID;
947 hid_t mtype_id = H5I_BADID;
948 hid_t nmtype_id = H5I_BADID;
949 hid_t sid = H5I_BADID;
950 hid_t m_sid = H5I_BADID;
951 hssize_t nfields;
952 hsize_t count[1];
953 hsize_t offset[1];
954 hsize_t mem_size[1];
955 size_t size_native;
956 char *member_name = NULL;
957 hssize_t i, j;
958 herr_t ret_val = -1;
959
960
961 /* check the arguments */
962 if (dset_name == NULL)
963 goto out;
964 if (field_names == NULL)
965 goto out;
966
967 /* open the dataset */
968 if((did = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
969 goto out;
970
971 /* get the datatype */
972 if((ftype_id = H5Dget_type(did)) < 0)
973 goto out;
974
975 /* get the number of fields */
976 if((nfields = H5Tget_nmembers(ftype_id)) < 0)
977 goto out;
978
979 /* create a memory read id */
980 if((mem_type_id = H5Tcreate(H5T_COMPOUND, type_size)) < 0)
981 goto out;
982
983 /* iterate through the members */
984 for(i = 0, j = 0; i < nfields; i++) {
985 /* get the member name */
986 if(NULL == (member_name = H5Tget_member_name(ftype_id, (unsigned)i)))
987 goto out;
988
989 if(H5TB_find_field(member_name, field_names)) {
990 /* get the member type */
991 if((mtype_id = H5Tget_member_type(ftype_id, (unsigned)i)) < 0)
992 goto out;
993
994 /* convert to native type */
995 if((nmtype_id = H5Tget_native_type(mtype_id, H5T_DIR_DEFAULT)) < 0)
996 goto out;
997
998 if(0 == (size_native = H5Tget_size(nmtype_id)))
999 goto out;
1000
1001 if(field_sizes[j] != size_native)
1002 if(H5Tset_size(nmtype_id, field_sizes[j]) < 0)
1003 goto out;
1004
1005 /* the field in the file is found by its name */
1006 if(field_offset) {
1007 if(H5Tinsert(mem_type_id, member_name, field_offset[j], nmtype_id) < 0)
1008 goto out;
1009 } /* end if */
1010 else {
1011 if(H5Tinsert(mem_type_id, member_name, (size_t)0, nmtype_id) < 0)
1012 goto out;
1013 } /* end else */
1014
1015 /* close */
1016 if(H5Tclose(mtype_id) < 0)
1017 goto out;
1018 mtype_id = H5I_BADID;
1019 if(H5Tclose(nmtype_id) < 0)
1020 goto out;
1021 nmtype_id = H5I_BADID;
1022 j++;
1023 } /* end if */
1024
1025 H5free_memory(member_name);
1026 member_name = NULL;
1027 } /* end for */
1028
1029 /* check to make sure field was found, no reason to continue if it does not exist */
1030 if(j == 0)
1031 goto out;
1032
1033 /* get the dataspace handle */
1034 if((sid = H5Dget_space(did)) < 0)
1035 goto out;
1036
1037 /* define a hyperslab in the dataset */
1038 offset[0] = start;
1039 count[0] = nrecords;
1040 if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0)
1041 goto out;
1042
1043 /* create a memory dataspace handle */
1044 mem_size[0] = count[0];
1045 if((m_sid = H5Screate_simple(1, mem_size, NULL)) < 0)
1046 goto out;
1047
1048 /* read */
1049 if(H5Dread(did, mem_type_id, m_sid, sid, H5P_DEFAULT, buf) < 0)
1050 goto out;
1051
1052 ret_val = 0;
1053
1054 out:
1055 if(member_name)
1056 H5free_memory(member_name);
1057 if(mtype_id > 0)
1058 if(H5Tclose(mtype_id) < 0)
1059 ret_val = -1;
1060 if(nmtype_id > 0)
1061 if(H5Tclose(nmtype_id) < 0)
1062 ret_val = -1;
1063 if(mem_type_id > 0)
1064 if(H5Tclose(mem_type_id) < 0)
1065 ret_val = -1;
1066 if(ftype_id > 0)
1067 if(H5Tclose(ftype_id) < 0)
1068 ret_val = -1;
1069 if(m_sid > 0)
1070 if(H5Sclose(m_sid) < 0)
1071 ret_val = -1;
1072 if(sid > 0)
1073 if(H5Sclose(sid) < 0)
1074 ret_val = -1;
1075 if(did > 0)
1076 if(H5Dclose(did) < 0)
1077 ret_val = -1;
1078
1079 return ret_val;
1080 } /* end H5TBread_fields_name() */
1081
1082 /*-------------------------------------------------------------------------
1083 * Function: H5TBread_fields_index
1084 *
1085 * Purpose: Reads fields
1086 *
1087 * Return: Success: 0, Failure: -1
1088 *
1089 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
1090 *
1091 * Date: November 19, 2001
1092 *
1093 * Comments:
1094 *
1095 *-------------------------------------------------------------------------
1096 */
H5TBread_fields_index(hid_t loc_id,const char * dset_name,hsize_t nfields,const int * field_index,hsize_t start,hsize_t nrecords,size_t type_size,const size_t * field_offset,const size_t * field_sizes,void * buf)1097 herr_t H5TBread_fields_index(hid_t loc_id,
1098 const char *dset_name,
1099 hsize_t nfields,
1100 const int *field_index,
1101 hsize_t start,
1102 hsize_t nrecords,
1103 size_t type_size,
1104 const size_t *field_offset,
1105 const size_t *field_sizes,
1106 void *buf)
1107 {
1108 hid_t did = H5I_BADID;
1109 hid_t tid = H5I_BADID;
1110 hid_t read_type_id = H5I_BADID;
1111 hid_t member_type_id = H5I_BADID;
1112 hid_t nmtype_id = H5I_BADID;
1113 hid_t sid = H5I_BADID;
1114 hid_t m_sid = H5I_BADID;
1115 hsize_t count[1];
1116 hsize_t offset[1];
1117 hsize_t mem_size[1];
1118 hsize_t i;
1119 size_t size_native;
1120 char *member_name = NULL;
1121 herr_t ret_val = -1;
1122
1123 /* check the arguments */
1124 if (dset_name == NULL)
1125 goto out;
1126
1127 /* open the dataset. */
1128 if((did = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
1129 goto out;
1130
1131 /* get the datatype */
1132 if((tid = H5Dget_type(did)) < 0)
1133 goto out;
1134
1135 /* create a read id */
1136 if((read_type_id = H5Tcreate(H5T_COMPOUND, type_size)) < 0)
1137 goto out;
1138
1139 /* iterate tru the members */
1140 for(i = 0; i < nfields; i++) {
1141 unsigned j;
1142
1143 /* Range check */
1144 if(field_index[i] < 0)
1145 goto out;
1146
1147 j = (unsigned)field_index[i];
1148
1149 /* get the member name */
1150 if(NULL == (member_name = H5Tget_member_name(tid, (unsigned)j)))
1151 goto out;
1152
1153 /* get the member type */
1154 if((member_type_id = H5Tget_member_type(tid, (unsigned)j)) < 0)
1155 goto out;
1156
1157 /* convert to native type */
1158 if((nmtype_id = H5Tget_native_type(member_type_id, H5T_DIR_DEFAULT)) < 0)
1159 goto out;
1160
1161 if(0 == (size_native = H5Tget_size(nmtype_id)))
1162 goto out;
1163
1164 if(field_sizes[i] != size_native)
1165 if(H5Tset_size(nmtype_id, field_sizes[i]) < 0)
1166 goto out;
1167
1168 /* the field in the file is found by its name */
1169 if(field_offset) {
1170 if(H5Tinsert(read_type_id, member_name, field_offset[i], nmtype_id) < 0)
1171 goto out;
1172 } /* end if */
1173 else {
1174 if(H5Tinsert(read_type_id, member_name, (size_t)0, nmtype_id) < 0)
1175 goto out;
1176 } /* end else */
1177
1178 /* close the member type */
1179 if(H5Tclose(member_type_id) < 0)
1180 goto out;
1181 member_type_id = H5I_BADID;
1182 if(H5Tclose(nmtype_id) < 0)
1183 goto out;
1184 nmtype_id = H5I_BADID;
1185
1186 H5free_memory(member_name);
1187 member_name = NULL;
1188 } /* end for */
1189
1190 /* get the dataspace handle */
1191 if((sid = H5Dget_space(did)) < 0)
1192 goto out;
1193
1194 /* define a hyperslab in the dataset */
1195 offset[0] = start;
1196 count[0] = nrecords;
1197 if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0)
1198 goto out;
1199
1200 /* create a memory dataspace handle */
1201 mem_size[0] = count[0];
1202 if((m_sid = H5Screate_simple(1, mem_size, NULL)) < 0)
1203 goto out;
1204
1205 /* read */
1206 if(H5Dread( did, read_type_id, m_sid, sid, H5P_DEFAULT, buf) < 0)
1207 goto out;
1208
1209 ret_val = 0;
1210
1211 out:
1212 if(member_name)
1213 H5free_memory(member_name);
1214 if(read_type_id > 0)
1215 if(H5Tclose(read_type_id) < 0)
1216 ret_val = -1;
1217 if(member_type_id > 0)
1218 if(H5Tclose(member_type_id) < 0)
1219 ret_val = -1;
1220 if(nmtype_id > 0)
1221 if(H5Tclose(nmtype_id) < 0)
1222 ret_val = -1;
1223 if(tid > 0)
1224 if(H5Tclose(tid) < 0)
1225 ret_val = -1;
1226 if(m_sid > 0)
1227 if(H5Sclose(m_sid) < 0)
1228 ret_val = -1;
1229 if(sid > 0)
1230 if(H5Sclose(sid) < 0)
1231 ret_val = -1;
1232 if(did > 0)
1233 if(H5Dclose(did) < 0)
1234 ret_val = -1;
1235
1236 return ret_val;
1237 } /* end H5TBread_fields_index() */
1238
1239
1240 /*-------------------------------------------------------------------------
1241 *
1242 * Manipulation functions
1243 *
1244 *-------------------------------------------------------------------------
1245 */
1246
1247 /*-------------------------------------------------------------------------
1248 * Function: H5TBdelete_record
1249 *
1250 * Purpose: Delete records from middle of table ("pulling up" all the records after it)
1251 *
1252 * Return: Success: 0, Failure: -1
1253 *
1254 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
1255 *
1256 * Date: November 26, 2001
1257 *
1258 *-------------------------------------------------------------------------
1259 */
H5TBdelete_record(hid_t loc_id,const char * dset_name,hsize_t start,hsize_t nrecords)1260 herr_t H5TBdelete_record(hid_t loc_id,
1261 const char *dset_name,
1262 hsize_t start,
1263 hsize_t nrecords)
1264 {
1265 hid_t did = H5I_BADID;
1266 hid_t tid = H5I_BADID;
1267 hid_t sid = H5I_BADID;
1268 hid_t m_sid = H5I_BADID;
1269 hid_t mem_type_id = H5I_BADID;
1270 hsize_t nfields;
1271 hsize_t ntotal_records;
1272 hsize_t read_start;
1273 hsize_t read_nrecords;
1274 hsize_t count[1];
1275 hsize_t offset[1];
1276 hsize_t mem_size[1];
1277 hsize_t dims[1];
1278 size_t src_size;
1279 size_t *src_offset = NULL;
1280 size_t *src_sizes = NULL;
1281 unsigned char *tmp_buf = NULL;
1282 herr_t ret_val = -1;
1283
1284
1285 /* check the arguments */
1286 if (dset_name == NULL)
1287 goto out;
1288
1289 /*-------------------------------------------------------------------------
1290 * first we get information about type size and offsets on disk
1291 *-------------------------------------------------------------------------
1292 */
1293
1294 /* get the number of records and fields */
1295 if(H5TBget_table_info(loc_id, dset_name, &nfields, &ntotal_records) < 0)
1296 goto out;
1297
1298 if(NULL == (src_offset = (size_t *)HDmalloc((size_t)nfields * sizeof(size_t))))
1299 goto out;
1300 if(NULL == (src_sizes = (size_t *)HDmalloc((size_t)nfields * sizeof(size_t))))
1301 goto out;
1302
1303 /* get field info */
1304 if(H5TBget_field_info(loc_id, dset_name, NULL, src_sizes, src_offset, &src_size) < 0)
1305 goto out;
1306
1307 /* open the dataset. */
1308 if((did = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
1309 goto out;
1310
1311 /*-------------------------------------------------------------------------
1312 * read the records after the deleted one(s)
1313 *-------------------------------------------------------------------------
1314 */
1315
1316 read_start = start + nrecords;
1317 read_nrecords = ntotal_records - read_start;
1318
1319 if(read_nrecords) {
1320 if(NULL == (tmp_buf = (unsigned char *)HDcalloc((size_t)read_nrecords, src_size)))
1321 goto out;
1322
1323 /* read the records after the deleted one(s) */
1324 if(H5TBread_records(loc_id, dset_name, read_start, read_nrecords, src_size, src_offset, src_sizes, tmp_buf) < 0)
1325 goto out;
1326
1327 /*-------------------------------------------------------------------------
1328 * write the records in another position
1329 *-------------------------------------------------------------------------
1330 */
1331
1332 /* get the datatype */
1333 if((tid = H5Dget_type(did)) < 0)
1334 goto out;
1335
1336 /* get the dataspace handle */
1337 if((sid = H5Dget_space(did)) < 0)
1338 goto out;
1339
1340 /* create the memory data type. */
1341 if((mem_type_id = H5TB_create_type( loc_id, dset_name, src_size, src_offset, src_sizes, tid)) < 0)
1342 goto out;
1343
1344 /* define a hyperslab in the dataset of the size of the records */
1345 offset[0] = start;
1346 count[0] = read_nrecords;
1347 if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0)
1348 goto out;
1349
1350 /* create a memory dataspace handle */
1351 mem_size[0] = count[0];
1352 if((m_sid = H5Screate_simple(1, mem_size, NULL)) < 0)
1353 goto out;
1354
1355 if(H5Dwrite(did, mem_type_id, m_sid, sid, H5P_DEFAULT, tmp_buf) < 0)
1356 goto out;
1357
1358 /* close */
1359 if(H5Sclose(m_sid) < 0)
1360 goto out;
1361 m_sid = H5I_BADID;
1362 if(H5Tclose(mem_type_id) < 0)
1363 goto out;
1364 mem_type_id = H5I_BADID;
1365 if(H5Sclose(sid) < 0)
1366 goto out;
1367 sid = H5I_BADID;
1368 if(H5Tclose(tid) < 0)
1369 goto out;
1370 tid = H5I_BADID;
1371 } /* read_nrecords */
1372
1373 /*-------------------------------------------------------------------------
1374 * change the dataset dimension
1375 *-------------------------------------------------------------------------
1376 */
1377 dims[0] = ntotal_records - nrecords;
1378 if(H5Dset_extent(did, dims) < 0)
1379 goto out;
1380
1381 ret_val = 0;
1382
1383 out:
1384 if(tmp_buf)
1385 HDfree(tmp_buf);
1386 if(src_offset)
1387 HDfree(src_offset);
1388 if(src_sizes)
1389 HDfree(src_sizes);
1390 if(mem_type_id > 0)
1391 if(H5Tclose(mem_type_id) < 0)
1392 ret_val = -1;
1393 if(tid > 0)
1394 if(H5Tclose(tid) < 0)
1395 ret_val = -1;
1396 if(m_sid > 0)
1397 if(H5Sclose(m_sid) < 0)
1398 ret_val = -1;
1399 if(sid > 0)
1400 if(H5Sclose(sid) < 0)
1401 ret_val = -1;
1402 if(did > 0)
1403 if(H5Dclose(did) < 0)
1404 ret_val = -1;
1405
1406 return ret_val;
1407 } /* end H5TBdelete_record() */
1408
1409 /*-------------------------------------------------------------------------
1410 * Function: H5TBinsert_record
1411 *
1412 * Purpose: Inserts records into middle of table ("pushing down" all the records after it)
1413 *
1414 * Return: Success: 0, Failure: -1
1415 *
1416 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
1417 *
1418 * Date: November 26, 2001
1419 *
1420 * Comments: Uses memory offsets
1421 *
1422 *-------------------------------------------------------------------------
1423 */
H5TBinsert_record(hid_t loc_id,const char * dset_name,hsize_t start,hsize_t nrecords,size_t type_size,const size_t * field_offset,const size_t * field_sizes,void * buf)1424 herr_t H5TBinsert_record(hid_t loc_id,
1425 const char *dset_name,
1426 hsize_t start,
1427 hsize_t nrecords,
1428 size_t type_size,
1429 const size_t *field_offset,
1430 const size_t *field_sizes,
1431 void *buf)
1432 {
1433 hid_t did = H5I_BADID;
1434 hid_t tid = H5I_BADID;
1435 hid_t mem_type_id = H5I_BADID;
1436 hid_t sid = H5I_BADID;
1437 hid_t m_sid = H5I_BADID;
1438 hsize_t nfields;
1439 hsize_t ntotal_records;
1440 hsize_t read_nrecords;
1441 hsize_t count[1];
1442 hsize_t offset[1];
1443 hsize_t dims[1];
1444 hsize_t mem_dims[1];
1445 unsigned char *tmp_buf = NULL;
1446 herr_t ret_val = -1;
1447
1448 /* check the arguments */
1449 if (dset_name == NULL)
1450 goto out;
1451
1452 /*-------------------------------------------------------------------------
1453 * read the records after the inserted one(s)
1454 *-------------------------------------------------------------------------
1455 */
1456
1457 /* get the dimensions */
1458 if(H5TBget_table_info(loc_id, dset_name, &nfields, &ntotal_records) < 0)
1459 goto out;
1460
1461 /* open the dataset. */
1462 if((did = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
1463 goto out;
1464
1465 /* get the datatype */
1466 if((tid = H5Dget_type(did)) < 0)
1467 goto out;
1468
1469 /* create the memory data type. */
1470 if((mem_type_id = H5TB_create_type(loc_id, dset_name, type_size, field_offset, field_sizes, tid)) < 0)
1471 goto out;
1472
1473 read_nrecords = ntotal_records - start;
1474 if(NULL == (tmp_buf = (unsigned char *)HDcalloc((size_t) read_nrecords, type_size)))
1475 goto out;
1476
1477 /* read the records after the inserted one(s) */
1478 if(H5TBread_records(loc_id, dset_name, start, read_nrecords, type_size, field_offset, field_sizes, tmp_buf) < 0)
1479 goto out;
1480
1481 /* extend the dataset */
1482 dims[0] = ntotal_records + nrecords;
1483
1484 if(H5Dset_extent(did, dims) < 0)
1485 goto out;
1486
1487 /*-------------------------------------------------------------------------
1488 * write the inserted records
1489 *-------------------------------------------------------------------------
1490 */
1491
1492 /* create a simple memory data space */
1493 mem_dims[0] = nrecords;
1494 if((m_sid = H5Screate_simple(1, mem_dims, NULL)) < 0)
1495 goto out;
1496
1497 /* get the file data space */
1498 if((sid = H5Dget_space(did)) < 0)
1499 goto out;
1500
1501 /* define a hyperslab in the dataset to write the new data */
1502 offset[0] = start;
1503 count[0] = nrecords;
1504 if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0)
1505 goto out;
1506
1507 if(H5Dwrite(did, mem_type_id, m_sid, sid, H5P_DEFAULT, buf) < 0)
1508 goto out;
1509
1510 /* terminate access to the dataspace */
1511 if(H5Sclose(m_sid) < 0)
1512 goto out;
1513 m_sid = H5I_BADID;
1514 if(H5Sclose(sid) < 0)
1515 goto out;
1516 sid = H5I_BADID;
1517
1518 /*-------------------------------------------------------------------------
1519 * write the "pushed down" records
1520 *-------------------------------------------------------------------------
1521 */
1522
1523 /* create a simple memory data space */
1524 mem_dims[0] = read_nrecords;
1525 if((m_sid = H5Screate_simple(1, mem_dims, NULL)) < 0)
1526 goto out;
1527
1528 /* get the file data space */
1529 if((sid = H5Dget_space(did)) < 0)
1530 goto out;
1531
1532 /* define a hyperslab in the dataset to write the new data */
1533 offset[0] = start + nrecords;
1534 count[0] = read_nrecords;
1535 if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0)
1536 goto out;
1537
1538 if(H5Dwrite(did, mem_type_id, m_sid, sid, H5P_DEFAULT, tmp_buf) < 0)
1539 goto out;
1540
1541 ret_val = 0;
1542
1543 out:
1544 if(tmp_buf)
1545 HDfree(tmp_buf);
1546 if(sid > 0)
1547 if(H5Sclose(sid) < 0)
1548 ret_val = -1;
1549 if(m_sid > 0)
1550 if(H5Sclose(m_sid) < 0)
1551 ret_val = -1;
1552 if(mem_type_id > 0)
1553 if(H5Tclose(mem_type_id) < 0)
1554 ret_val = -1;
1555 if(tid > 0)
1556 if(H5Tclose(tid) < 0)
1557 ret_val = -1;
1558 if(did > 0)
1559 if(H5Dclose(did) < 0)
1560 ret_val = -1;
1561
1562 return ret_val;
1563 } /* end H5TBinsert_record() */
1564
1565 /*-------------------------------------------------------------------------
1566 * Function: H5TBadd_records_from
1567 *
1568 * Purpose: Add records from first table to second table
1569 *
1570 * Return: Success: 0, Failure: -1
1571 *
1572 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
1573 *
1574 * Date: December 5, 2001
1575 *
1576 * Comments:
1577 *
1578 *-------------------------------------------------------------------------
1579 */
H5TBadd_records_from(hid_t loc_id,const char * dset_name1,hsize_t start1,hsize_t nrecords,const char * dset_name2,hsize_t start2)1580 herr_t H5TBadd_records_from(hid_t loc_id,
1581 const char *dset_name1,
1582 hsize_t start1,
1583 hsize_t nrecords,
1584 const char *dset_name2,
1585 hsize_t start2)
1586 {
1587 hid_t did = H5I_BADID;
1588 hid_t tid = H5I_BADID;
1589 hid_t sid = H5I_BADID;
1590 hid_t m_sid = H5I_BADID;
1591 hsize_t count[1];
1592 hsize_t offset[1];
1593 hsize_t mem_size[1];
1594 hsize_t nfields;
1595 hsize_t ntotal_records;
1596 size_t type_size1;
1597 size_t src_size;
1598 size_t *src_offset = NULL;
1599 size_t *src_sizes = NULL;
1600 unsigned char *tmp_buf = NULL;
1601 herr_t ret_val = -1;
1602
1603 /* check the arguments */
1604 if (dset_name1 == NULL)
1605 goto out;
1606 if (dset_name2 == NULL)
1607 goto out;
1608
1609 /*-------------------------------------------------------------------------
1610 * first we get information about type size and offsets on disk
1611 *-------------------------------------------------------------------------
1612 */
1613
1614 /* get the number of records and fields */
1615 if(H5TBget_table_info(loc_id, dset_name1, &nfields, &ntotal_records) < 0)
1616 goto out;
1617
1618 if(NULL == (src_offset = (size_t *)HDmalloc((size_t)nfields * sizeof(size_t))))
1619 goto out;
1620 if(NULL == (src_sizes = (size_t *)HDmalloc((size_t)nfields * sizeof(size_t))))
1621 goto out;
1622
1623 /* get field info */
1624 if(H5TBget_field_info(loc_id, dset_name1, NULL, src_sizes, src_offset, &src_size) < 0)
1625 goto out;
1626
1627 /*-------------------------------------------------------------------------
1628 * Get information about the first table and read it
1629 *-------------------------------------------------------------------------
1630 */
1631
1632 /* open the 1st dataset. */
1633 if((did = H5Dopen2(loc_id, dset_name1, H5P_DEFAULT)) < 0)
1634 goto out;
1635
1636 /* get the datatype */
1637 if((tid = H5Dget_type(did)) < 0)
1638 goto out;
1639
1640 /* get the dataspace handle */
1641 if((sid = H5Dget_space(did)) < 0)
1642 goto out;
1643
1644 /* get the size of the datatype */
1645 if(0 == (type_size1 = H5Tget_size(tid)))
1646 goto out;
1647
1648 if(NULL == (tmp_buf = (unsigned char *)HDcalloc((size_t)nrecords, type_size1)))
1649 goto out;
1650
1651 /* define a hyperslab in the dataset of the size of the records */
1652 offset[0] = start1;
1653 count[0] = nrecords;
1654 if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0)
1655 goto out;
1656
1657 /* create a memory dataspace handle */
1658 mem_size[0] = count[0];
1659 if((m_sid = H5Screate_simple(1, mem_size, NULL)) < 0)
1660 goto out;
1661
1662 if(H5Dread(did, tid, m_sid, sid, H5P_DEFAULT, tmp_buf) < 0)
1663 goto out;
1664
1665 /*-------------------------------------------------------------------------
1666 * add to the second table
1667 *-------------------------------------------------------------------------
1668 */
1669 if(H5TBinsert_record(loc_id, dset_name2, start2, nrecords, src_size, src_offset, src_sizes, tmp_buf) < 0)
1670 goto out;
1671
1672 ret_val = 0;
1673
1674 out:
1675 if(tmp_buf)
1676 HDfree(tmp_buf);
1677 if(src_offset)
1678 HDfree(src_offset);
1679 if(src_sizes)
1680 HDfree(src_sizes);
1681 if(tid > 0)
1682 if(H5Tclose(tid) < 0)
1683 ret_val = -1;
1684 if(sid > 0)
1685 if(H5Sclose(sid) < 0)
1686 ret_val = -1;
1687 if(m_sid > 0)
1688 if(H5Sclose(m_sid) < 0)
1689 ret_val = -1;
1690 if(did > 0)
1691 if(H5Dclose(did) < 0)
1692 ret_val = -1;
1693
1694 return ret_val;
1695 } /* end H5TBadd_records_from() */
1696
1697 /*-------------------------------------------------------------------------
1698 * Function: H5TBcombine_tables
1699 *
1700 * Purpose: Combine records from two tables into a third
1701 *
1702 * Return: Success: 0, Failure: -1
1703 *
1704 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
1705 *
1706 * Date: December 10, 2001
1707 *
1708 * Comments:
1709 *
1710 *-------------------------------------------------------------------------
1711 */
H5TBcombine_tables(hid_t loc_id1,const char * dset_name1,hid_t loc_id2,const char * dset_name2,const char * dset_name3)1712 herr_t H5TBcombine_tables(hid_t loc_id1,
1713 const char *dset_name1,
1714 hid_t loc_id2,
1715 const char *dset_name2,
1716 const char *dset_name3)
1717 {
1718 /* identifiers for the 1st dataset. */
1719 hid_t did_1 = H5I_BADID;
1720 hid_t tid_1 = H5I_BADID;
1721 hid_t sid_1 = H5I_BADID;
1722 hid_t pid_1 = H5I_BADID;
1723 /* identifiers for the 2nd dataset. */
1724 hid_t did_2 = H5I_BADID;
1725 hid_t tid_2 = H5I_BADID;
1726 hid_t sid_2 = H5I_BADID;
1727 hid_t pid_2 = H5I_BADID;
1728 /* identifiers for the 3rd dataset. */
1729 hid_t did_3 = H5I_BADID;
1730 hid_t tid_3 = H5I_BADID;
1731 hid_t sid_3 = H5I_BADID;
1732 hid_t pid_3 = H5I_BADID;
1733 hid_t sid = H5I_BADID;
1734 hid_t m_sid = H5I_BADID;
1735 hid_t member_type_id = H5I_BADID;
1736 hid_t attr_id = H5I_BADID;
1737 hsize_t count[1];
1738 hsize_t offset[1];
1739 hsize_t mem_size[1];
1740 hsize_t nfields;
1741 hsize_t nrecords;
1742 hsize_t dims[1];
1743 hsize_t maxdims[1] = {H5S_UNLIMITED};
1744 hsize_t i;
1745 size_t type_size;
1746 size_t member_offset;
1747 size_t src_size;
1748 size_t *src_offset = NULL;
1749 size_t *src_sizes = NULL;
1750 char attr_name[255];
1751 unsigned char *tmp_buf = NULL;
1752 unsigned char *tmp_fill_buf = NULL;
1753 htri_t has_fill;
1754 herr_t ret_val = -1;
1755
1756 /* check the arguments */
1757 if (dset_name1 == NULL)
1758 goto out;
1759 if (dset_name2 == NULL)
1760 goto out;
1761 if (dset_name3 == NULL)
1762 goto out;
1763
1764 /*-------------------------------------------------------------------------
1765 * first we get information about type size and offsets on disk
1766 *-------------------------------------------------------------------------
1767 */
1768
1769 /* get the number of records and fields */
1770 if(H5TBget_table_info(loc_id1, dset_name1, &nfields, &nrecords) < 0)
1771 goto out;
1772
1773 if(NULL == (src_offset = (size_t *)HDmalloc((size_t)nfields * sizeof(size_t))))
1774 goto out;
1775 if(NULL == (src_sizes = (size_t *)HDmalloc((size_t)nfields * sizeof(size_t))))
1776 goto out;
1777
1778 /* get field info */
1779 if(H5TBget_field_info(loc_id1, dset_name1, NULL, src_sizes, src_offset, &src_size) < 0)
1780 goto out;
1781
1782 /*-------------------------------------------------------------------------
1783 * get information about the first table
1784 *-------------------------------------------------------------------------
1785 */
1786
1787 /* open the 1st dataset. */
1788 if((did_1 = H5Dopen2(loc_id1, dset_name1, H5P_DEFAULT)) < 0)
1789 goto out;
1790
1791 /* get the datatype */
1792 if((tid_1 = H5Dget_type(did_1)) < 0)
1793 goto out;
1794
1795 /* get the dataspace handle */
1796 if((sid_1 = H5Dget_space(did_1)) < 0)
1797 goto out;
1798
1799 /* get creation properties list */
1800 if((pid_1 = H5Dget_create_plist(did_1)) < 0)
1801 goto out;
1802
1803 /* get the dimensions */
1804 if(H5TBget_table_info(loc_id1, dset_name1, &nfields, &nrecords) < 0)
1805 goto out;
1806
1807 /*-------------------------------------------------------------------------
1808 * make the merged table with no data originally
1809 *-------------------------------------------------------------------------
1810 */
1811
1812 /* clone the property list */
1813 if((pid_3 = H5Pcopy(pid_1)) < 0)
1814 goto out;
1815
1816 /* clone the type id */
1817 if((tid_3 = H5Tcopy(tid_1)) < 0)
1818 goto out;
1819
1820 /*-------------------------------------------------------------------------
1821 * here we do not clone the file space from the 1st dataset, because we want to create
1822 * an empty table. Instead we create a new dataspace with zero records and expandable.
1823 *-------------------------------------------------------------------------
1824 */
1825 dims[0] = 0;
1826
1827 /* create a simple data space with unlimited size */
1828 if((sid_3 = H5Screate_simple(1, dims, maxdims)) < 0)
1829 goto out;
1830
1831 /* create the dataset */
1832 if((did_3 = H5Dcreate2(loc_id1, dset_name3, tid_3, sid_3, H5P_DEFAULT, pid_3, H5P_DEFAULT)) < 0)
1833 goto out;
1834
1835 /*-------------------------------------------------------------------------
1836 * attach the conforming table attributes
1837 *-------------------------------------------------------------------------
1838 */
1839 if(H5TB_attach_attributes("Merge table", loc_id1, dset_name3, nfields, tid_3) < 0)
1840 goto out;
1841
1842 /*-------------------------------------------------------------------------
1843 * get attributes
1844 *-------------------------------------------------------------------------
1845 */
1846 if(0 == (type_size = H5Tget_size(tid_3)))
1847 goto out;
1848
1849 /* alloc fill value attribute buffer */
1850 if(NULL == (tmp_fill_buf = (unsigned char *)HDmalloc(type_size)))
1851 goto out;
1852
1853 /* get the fill value attributes */
1854 if((has_fill = H5TBAget_fill(loc_id1, dset_name1, did_1, tmp_fill_buf)) < 0)
1855 goto out;
1856
1857 /*-------------------------------------------------------------------------
1858 * attach the fill attributes from previous table
1859 *-------------------------------------------------------------------------
1860 */
1861 if(has_fill) {
1862 if((sid = H5Screate(H5S_SCALAR)) < 0)
1863 goto out;
1864
1865 for(i = 0; i < nfields; i++) {
1866 /* get the member type */
1867 if((member_type_id = H5Tget_member_type(tid_3, (unsigned)i)) < 0)
1868 goto out;
1869
1870 /* get the member offset */
1871 member_offset = H5Tget_member_offset(tid_3, (unsigned)i);
1872
1873 HDsnprintf(attr_name, sizeof(attr_name), "FIELD_%d_FILL", (int)i);
1874
1875 if((attr_id = H5Acreate2(did_3, attr_name, member_type_id, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
1876 goto out;
1877
1878 if(H5Awrite(attr_id, member_type_id, tmp_fill_buf + member_offset) < 0)
1879 goto out;
1880
1881 if(H5Aclose(attr_id) < 0)
1882 goto out;
1883 attr_id = H5I_BADID;
1884
1885 if(H5Tclose(member_type_id) < 0)
1886 goto out;
1887 member_type_id = H5I_BADID;
1888 } /* end for */
1889
1890 /* close data space. */
1891 if(H5Sclose(sid) < 0)
1892 goto out;
1893 sid = H5I_BADID;
1894 } /* end if */
1895
1896 /*-------------------------------------------------------------------------
1897 * read data from 1st table
1898 *-------------------------------------------------------------------------
1899 */
1900 if(NULL == (tmp_buf = (unsigned char *)HDcalloc((size_t)nrecords, type_size)))
1901 goto out;
1902
1903 /* define a hyperslab in the dataset of the size of the records */
1904 offset[0] = 0;
1905 count[0] = nrecords;
1906 if(H5Sselect_hyperslab(sid_1, H5S_SELECT_SET, offset, NULL, count, NULL) < 0)
1907 goto out;
1908
1909 /* create a memory dataspace handle */
1910 mem_size[0] = count[0];
1911 if((m_sid = H5Screate_simple(1, mem_size, NULL)) < 0)
1912 goto out;
1913
1914 if(H5Dread(did_1, tid_1, m_sid, sid_1, H5P_DEFAULT, tmp_buf) < 0)
1915 goto out;
1916
1917 /*-------------------------------------------------------------------------
1918 * save data from 1st table into new table
1919 *-------------------------------------------------------------------------
1920 */
1921
1922 /* append the records to the new table */
1923 if(H5TBappend_records(loc_id1, dset_name3, nrecords, src_size, src_offset, src_sizes, tmp_buf) < 0)
1924 goto out;
1925
1926 /*-------------------------------------------------------------------------
1927 * release temporary resources
1928 *-------------------------------------------------------------------------
1929 */
1930 if(H5Sclose(m_sid) < 0)
1931 goto out;
1932 m_sid = H5I_BADID;
1933 HDfree(tmp_buf);
1934 tmp_buf = NULL;
1935
1936 /*-------------------------------------------------------------------------
1937 * get information about the 2nd table
1938 *-------------------------------------------------------------------------
1939 */
1940
1941 /* open the dataset. */
1942 if((did_2 = H5Dopen2(loc_id2, dset_name2, H5P_DEFAULT)) < 0)
1943 goto out;
1944
1945 /* get the datatype */
1946 if((tid_2 = H5Dget_type(did_2)) < 0)
1947 goto out;
1948
1949 /* get the dataspace handle */
1950 if((sid_2 = H5Dget_space(did_2)) < 0)
1951 goto out;
1952
1953 /* get the property list handle */
1954 if((pid_2 = H5Dget_create_plist(did_2)) < 0)
1955 goto out;
1956
1957 /* get the dimensions */
1958 if(H5TBget_table_info(loc_id2, dset_name2, &nfields, &nrecords) < 0)
1959 goto out;
1960
1961 /*-------------------------------------------------------------------------
1962 * read data from 2nd table
1963 *-------------------------------------------------------------------------
1964 */
1965
1966 if(NULL == (tmp_buf = (unsigned char *)HDcalloc((size_t)nrecords, type_size)))
1967 goto out;
1968
1969 /* define a hyperslab in the dataset of the size of the records */
1970 offset[0] = 0;
1971 count[0] = nrecords;
1972 if(H5Sselect_hyperslab(sid_2, H5S_SELECT_SET, offset, NULL, count, NULL) < 0)
1973 goto out;
1974
1975 /* create a memory dataspace handle */
1976 mem_size[0] = count[0];
1977 if((m_sid = H5Screate_simple(1, mem_size, NULL)) < 0)
1978 goto out;
1979
1980 if(H5Dread(did_2, tid_2, m_sid, sid_2, H5P_DEFAULT, tmp_buf) < 0)
1981 goto out;
1982
1983 /*-------------------------------------------------------------------------
1984 * save data from 2nd table into new table
1985 *-------------------------------------------------------------------------
1986 */
1987
1988 /* append the records to the new table */
1989 if(H5TBappend_records(loc_id1, dset_name3, nrecords, src_size, src_offset, src_sizes, tmp_buf) < 0)
1990 goto out;
1991
1992 ret_val = 0;
1993
1994 out:
1995 if(tmp_buf)
1996 HDfree(tmp_buf);
1997 if(tmp_fill_buf)
1998 HDfree(tmp_fill_buf);
1999 if(src_offset)
2000 HDfree(src_offset);
2001 if(src_sizes)
2002 HDfree(src_sizes);
2003 if(member_type_id > 0)
2004 if(H5Tclose(member_type_id) < 0)
2005 ret_val = -1;
2006 if(attr_id > 0)
2007 if(H5Aclose(attr_id) < 0)
2008 ret_val = -1;
2009 if(sid > 0)
2010 if(H5Sclose(sid) < 0)
2011 ret_val = -1;
2012 if(m_sid > 0)
2013 if(H5Sclose(m_sid) < 0)
2014 ret_val = -1;
2015 if(sid_1 > 0)
2016 if(H5Sclose(sid_1) < 0)
2017 ret_val = -1;
2018 if(tid_1 > 0)
2019 if(H5Tclose(tid_1) < 0)
2020 ret_val = -1;
2021 if(pid_1 > 0)
2022 if(H5Pclose(pid_1) < 0)
2023 ret_val = -1;
2024 if(did_1 > 0)
2025 if(H5Dclose(did_1) < 0)
2026 ret_val = -1;
2027 if(sid_2 > 0)
2028 if(H5Sclose(sid_2) < 0)
2029 ret_val = -1;
2030 if(tid_2 > 0)
2031 if(H5Tclose(tid_2) < 0)
2032 ret_val = -1;
2033 if(pid_2 > 0)
2034 if(H5Pclose(pid_2) < 0)
2035 ret_val = -1;
2036 if(did_2 > 0)
2037 if(H5Dclose(did_2) < 0)
2038 ret_val = -1;
2039 if(sid_3 > 0)
2040 if(H5Sclose(sid_3) < 0)
2041 ret_val = -1;
2042 if(tid_3 > 0)
2043 if(H5Tclose(tid_3) < 0)
2044 ret_val = -1;
2045 if(pid_3 > 0)
2046 if(H5Pclose(pid_3) < 0)
2047 ret_val = -1;
2048 if(did_3 > 0)
2049 if(H5Dclose(did_3) < 0)
2050 ret_val = -1;
2051
2052 return ret_val;
2053 } /* end H5TBcombine_tables() */
2054
2055 /*-------------------------------------------------------------------------
2056 * Function: H5TBinsert_field
2057 *
2058 * Purpose: Inserts a field
2059 *
2060 * Return: Success: 0, Failure: -1
2061 *
2062 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
2063 *
2064 * Date: January 30, 2002
2065 *
2066 * Comments:
2067 *
2068 *-------------------------------------------------------------------------
2069 */
H5TBinsert_field(hid_t loc_id,const char * dset_name,const char * field_name,hid_t field_type,hsize_t position,const void * fill_data,const void * buf)2070 herr_t H5TBinsert_field(hid_t loc_id,
2071 const char *dset_name,
2072 const char *field_name,
2073 hid_t field_type,
2074 hsize_t position,
2075 const void *fill_data,
2076 const void *buf)
2077 {
2078 /* identifiers for the 1st, original dataset */
2079 hid_t did_1 = H5I_BADID;
2080 hid_t tid_1 = H5I_BADID;
2081 hid_t sid_1 = H5I_BADID;
2082 hid_t pid_1 = H5I_BADID;
2083 hid_t msid_1 = H5I_BADID;
2084 /* identifiers for the 2nd, new dataset */
2085 hid_t did_2 = H5I_BADID;
2086 hid_t tid_2 = H5I_BADID;
2087 hid_t sid_2 = H5I_BADID;
2088 hid_t pid_2 = H5I_BADID;
2089 hid_t msid_2 = H5I_BADID;
2090 /* identifiers for the 3rd, final dataset */
2091 hid_t did_3 = H5I_BADID;
2092 hid_t tid_3 = H5I_BADID;
2093 hid_t sid_3 = H5I_BADID;
2094 hid_t member_type_id = H5I_BADID;
2095 hid_t write_type_id = H5I_BADID;
2096 hid_t preserve_id = H5I_BADID;
2097 hid_t attr_id = H5I_BADID;
2098 size_t member_size;
2099 size_t new_member_size = 0;
2100 size_t total_size;
2101 size_t curr_offset;
2102 hsize_t nfields;
2103 hsize_t nrecords;
2104 hsize_t dims_chunk[1];
2105 hsize_t dims[1];
2106 hsize_t maxdims[1] = { H5S_UNLIMITED };
2107 hsize_t count[1];
2108 hsize_t offset[1];
2109 hsize_t mem_size[1];
2110 hsize_t i;
2111 char table_title[255];
2112 char attr_name[255];
2113 char *member_name = NULL;
2114 unsigned char *tmp_buf = NULL;
2115 unsigned char *tmp_fill_buf = NULL;
2116 hbool_t inserted;
2117 herr_t ret_val = -1;
2118
2119 /* check the arguments */
2120 if (dset_name == NULL)
2121 goto out;
2122 if (field_name == NULL)
2123 goto out;
2124
2125 /* get the number of records and fields */
2126 if(H5TBget_table_info(loc_id, dset_name, &nfields, &nrecords) < 0)
2127 goto out;
2128
2129 /*-------------------------------------------------------------------------
2130 * get information about the old data type
2131 *-------------------------------------------------------------------------
2132 */
2133
2134 /* open the dataset. */
2135 if((did_1 = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
2136 goto out;
2137
2138 /* get creation properties list */
2139 if((pid_1 = H5Dget_create_plist(did_1)) < 0)
2140 goto out;
2141
2142 /* get the datatype */
2143 if((tid_1 = H5Dget_type(did_1)) < 0)
2144 goto out;
2145
2146 /* get the size of the datatype */
2147 if(0 == (total_size = H5Tget_size(tid_1)))
2148 goto out;
2149
2150 /* get the dataspace handle */
2151 if((sid_1 = H5Dget_space(did_1)) < 0)
2152 goto out;
2153
2154 /* get dimension */
2155 if(H5Sget_simple_extent_dims(sid_1, dims, NULL) < 0)
2156 goto out;
2157
2158 /*-------------------------------------------------------------------------
2159 * get attributes
2160 *-------------------------------------------------------------------------
2161 */
2162
2163 /* get the table title */
2164 if((H5TBAget_title(did_1, table_title)) < 0)
2165 goto out;
2166
2167 /* alloc fill value attribute buffer */
2168 if(NULL == (tmp_fill_buf = (unsigned char *)HDmalloc(total_size)))
2169 goto out;
2170
2171 /* get the fill value attributes */
2172 if((H5TBAget_fill(loc_id, dset_name, did_1, tmp_fill_buf)) < 0)
2173 goto out;
2174
2175 /*-------------------------------------------------------------------------
2176 * create a new data type
2177 *-------------------------------------------------------------------------
2178 */
2179
2180 /* get the new member size */
2181 if(0 == (member_size = H5Tget_size(field_type)))
2182 goto out;
2183
2184 /* create the data type. */
2185 if((tid_2 = H5Tcreate(H5T_COMPOUND, (size_t)(total_size + member_size))) < 0)
2186 goto out;
2187
2188 curr_offset = 0;
2189 inserted = FALSE;
2190
2191 /* insert the old fields, counting with the new one */
2192 for(i = 0; i < nfields + 1; i++) {
2193 hsize_t idx;
2194
2195 idx = i;
2196 if(inserted)
2197 idx = i - 1;
2198
2199 if(i == position) {
2200 /* get the new member size */
2201 if(0 == (new_member_size = H5Tget_size(field_type)))
2202 goto out;
2203
2204 /* insert the new field type */
2205 if(H5Tinsert(tid_2, field_name, curr_offset, field_type) < 0)
2206 goto out;
2207
2208 curr_offset += new_member_size;
2209
2210 inserted = TRUE;
2211 } /* end if */
2212 else {
2213 /* get the member name */
2214 if(NULL == (member_name = H5Tget_member_name(tid_1, (unsigned)idx)))
2215 goto out;
2216
2217 /* get the member type */
2218 if((member_type_id = H5Tget_member_type(tid_1, (unsigned)idx)) < 0)
2219 goto out;
2220
2221 /* get the member size */
2222 if(0 == (member_size = H5Tget_size(member_type_id)))
2223 goto out;
2224
2225 /* insert it into the new type */
2226 if(H5Tinsert(tid_2, member_name, curr_offset, member_type_id) < 0)
2227 goto out;
2228
2229 curr_offset += member_size;
2230
2231 H5free_memory(member_name);
2232 member_name = NULL;
2233
2234 /* close the member type */
2235 if(H5Tclose(member_type_id) < 0)
2236 goto out;
2237 member_type_id = H5I_BADID;
2238 } /* end else */
2239 } /* end for */
2240
2241 /*-------------------------------------------------------------------------
2242 * create a new temporary dataset
2243 *-------------------------------------------------------------------------
2244 */
2245
2246 /* retrieve the size of chunk */
2247 if(H5Pget_chunk(pid_1, 1, dims_chunk) < 0)
2248 goto out;
2249
2250 /* create a new simple data space with unlimited size, using the dimension */
2251 if((sid_2 = H5Screate_simple(1, dims, maxdims)) < 0)
2252 goto out;
2253
2254 /* modify dataset creation properties, i.e. enable chunking */
2255 if((pid_2 = H5Pcreate(H5P_DATASET_CREATE)) < 0)
2256 goto out;
2257 if(H5Pset_chunk(pid_2, 1, dims_chunk) < 0)
2258 goto out;
2259
2260 /* create the dataset. */
2261 if((did_2 = H5Dcreate2(loc_id, "new", tid_2, sid_2, H5P_DEFAULT, pid_2, H5P_DEFAULT)) < 0)
2262 goto out;
2263
2264 /*-------------------------------------------------------------------------
2265 * read data from 1st table
2266 *-------------------------------------------------------------------------
2267 */
2268
2269 if(NULL == (tmp_buf = (unsigned char *)HDcalloc((size_t)nrecords, (size_t)total_size)))
2270 goto out;
2271
2272 /* define a hyperslab in the dataset of the size of the records */
2273 offset[0] = 0;
2274 count[0] = nrecords;
2275 if(H5Sselect_hyperslab(sid_1, H5S_SELECT_SET, offset, NULL, count, NULL) < 0)
2276 goto out;
2277
2278 /* create a memory dataspace handle */
2279 mem_size[0] = count[0];
2280 if((msid_1 = H5Screate_simple(1, mem_size, NULL)) < 0)
2281 goto out;
2282
2283 if(H5Dread(did_1, tid_1, msid_1, H5S_ALL, H5P_DEFAULT, tmp_buf) < 0)
2284 goto out;
2285
2286 /*-------------------------------------------------------------------------
2287 * save data from 1st table into new table, using the 1st type id
2288 *-------------------------------------------------------------------------
2289 */
2290
2291 /* write */
2292 if(H5Dwrite(did_2, tid_1, msid_1, H5S_ALL, H5P_DEFAULT, tmp_buf) < 0)
2293 goto out;
2294
2295 /*-------------------------------------------------------------------------
2296 * save the function supplied data of the new field
2297 *-------------------------------------------------------------------------
2298 */
2299
2300 /* create a write id */
2301 if((write_type_id = H5Tcreate(H5T_COMPOUND, (size_t)new_member_size)) < 0)
2302 goto out;
2303
2304 /* the field in the file is found by its name */
2305 if(H5Tinsert(write_type_id, field_name, (size_t)0, field_type) < 0)
2306 goto out;
2307
2308 /* create xfer properties to preserve initialized data */
2309 if((preserve_id = H5Pcreate(H5P_DATASET_XFER)) < 0)
2310 goto out;
2311 if(H5Pset_preserve(preserve_id, 1) < 0)
2312 goto out;
2313
2314 /* only write if there is something to write */
2315 if(buf) {
2316 /* create a memory dataspace handle */
2317 if((msid_2 = H5Screate_simple(1, mem_size, NULL)) < 0)
2318 goto out;
2319
2320 /* write */
2321 if(H5Dwrite(did_2, write_type_id, msid_2, sid_2, preserve_id, buf) < 0)
2322 goto out;
2323 } /* end if */
2324
2325 /*-------------------------------------------------------------------------
2326 * delete 1st table
2327 *-------------------------------------------------------------------------
2328 */
2329 if(H5Ldelete(loc_id, dset_name, H5P_DEFAULT) < 0)
2330 goto out;
2331
2332 /*-------------------------------------------------------------------------
2333 * rename 2nd table
2334 *-------------------------------------------------------------------------
2335 */
2336 if(H5Lmove(loc_id, "new", H5L_SAME_LOC, dset_name, H5P_DEFAULT, H5P_DEFAULT) < 0)
2337 goto out;
2338
2339 /*-------------------------------------------------------------------------
2340 * attach the conforming table attributes
2341 *-------------------------------------------------------------------------
2342 */
2343
2344 /* get the number of records and fields */
2345 if(H5TBget_table_info(loc_id, dset_name, &nfields, &nrecords) < 0)
2346 goto out;
2347
2348 /* open the dataset. */
2349 if((did_3 = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
2350 goto out;
2351
2352 /* get the datatype */
2353 if((tid_3 = H5Dget_type(did_3)) < 0)
2354 goto out;
2355
2356 /* set the attributes */
2357 if(H5TB_attach_attributes(table_title, loc_id, dset_name, (hsize_t)nfields, tid_3) < 0)
2358 goto out;
2359
2360 /*-------------------------------------------------------------------------
2361 * attach the fill attributes from previous table
2362 *-------------------------------------------------------------------------
2363 */
2364 if((sid_3 = H5Screate(H5S_SCALAR)) < 0)
2365 goto out;
2366
2367 for(i = 0; i < (nfields - 1); i++) {
2368 size_t member_offset;
2369
2370 /* get the member type */
2371 if((member_type_id = H5Tget_member_type(tid_3, (unsigned)i)) < 0)
2372 goto out;
2373
2374 /* get the member offset */
2375 member_offset = H5Tget_member_offset(tid_3, (unsigned)i);
2376
2377 HDsnprintf(attr_name, sizeof(attr_name), "FIELD_%d_FILL", (int)i);
2378
2379 if((attr_id = H5Acreate2(did_3, attr_name, member_type_id, sid_3, H5P_DEFAULT, H5P_DEFAULT)) < 0)
2380 goto out;
2381
2382 if(H5Awrite(attr_id, member_type_id, tmp_fill_buf + member_offset) < 0)
2383 goto out;
2384
2385 if(H5Aclose(attr_id) < 0)
2386 goto out;
2387 attr_id = H5I_BADID;
2388
2389 /* close the member type */
2390 if(H5Tclose(member_type_id) < 0)
2391 goto out;
2392 member_type_id = H5I_BADID;
2393 } /* end for */
2394
2395 /*-------------------------------------------------------------------------
2396 * attach the fill attribute from the new field, if present
2397 *-------------------------------------------------------------------------
2398 */
2399 if(fill_data) {
2400 HDsnprintf(attr_name, sizeof(attr_name), "FIELD_%d_FILL", (int)(nfields - 1));
2401
2402 /* get the member type */
2403 if((member_type_id = H5Tget_member_type(tid_3, (unsigned)nfields - 1)) < 0)
2404 goto out;
2405
2406 if((attr_id = H5Acreate2(did_3, attr_name, member_type_id, sid_3, H5P_DEFAULT, H5P_DEFAULT)) < 0)
2407 goto out;
2408
2409 if(H5Awrite(attr_id, member_type_id, fill_data) < 0)
2410 goto out;
2411
2412 if(H5Aclose(attr_id) < 0)
2413 goto out;
2414 attr_id = H5I_BADID;
2415
2416 if(H5Tclose(member_type_id) < 0)
2417 goto out;
2418 member_type_id = H5I_BADID;
2419 } /* end fill_data */
2420
2421 ret_val = 0;
2422
2423 out:
2424 if(member_name)
2425 H5free_memory(member_name);
2426 if(tmp_buf)
2427 HDfree(tmp_buf);
2428 if(tmp_fill_buf)
2429 HDfree(tmp_fill_buf);
2430 if(preserve_id > 0)
2431 if(H5Pclose(preserve_id) < 0)
2432 ret_val = -1;
2433 if(msid_1 > 0)
2434 if(H5Sclose(msid_1) < 0)
2435 ret_val = -1;
2436 if(tid_1 > 0)
2437 if(H5Tclose(tid_1) < 0)
2438 ret_val = -1;
2439 if(pid_1 > 0)
2440 if(H5Pclose(pid_1) < 0)
2441 ret_val = -1;
2442 if(sid_1 > 0)
2443 if(H5Sclose(sid_1) < 0)
2444 ret_val = -1;
2445 if(did_1 > 0)
2446 if(H5Dclose(did_1) < 0)
2447 ret_val = -1;
2448 if(msid_2 > 0)
2449 if(H5Sclose(msid_2) < 0)
2450 ret_val = -1;
2451 if(sid_2 > 0)
2452 if(H5Sclose(sid_2) < 0)
2453 ret_val = -1;
2454 if(tid_2 > 0)
2455 if(H5Tclose(tid_2) < 0)
2456 ret_val = -1;
2457 if(pid_2 > 0)
2458 if(H5Pclose(pid_2) < 0)
2459 ret_val = -1;
2460 if(did_2 > 0)
2461 if(H5Dclose(did_2) < 0)
2462 ret_val = -1;
2463 if(sid_3 > 0)
2464 if(H5Sclose(sid_3) < 0)
2465 ret_val = -1;
2466 if(tid_3 > 0)
2467 if(H5Tclose(tid_3) < 0)
2468 ret_val = -1;
2469 if(did_3 > 0)
2470 if(H5Dclose(did_3) < 0)
2471 ret_val = -1;
2472
2473 return ret_val;
2474 } /* end H5TBinsert_field() */
2475
2476 /*-------------------------------------------------------------------------
2477 * Function: H5TBdelete_field
2478 *
2479 * Purpose: Deletes a field
2480 *
2481 * Return: Success: 0, Failure: -1
2482 *
2483 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
2484 *
2485 * Date: January 30, 2002
2486 *
2487 * Comments:
2488 *
2489 *-------------------------------------------------------------------------
2490 */
H5TBdelete_field(hid_t loc_id,const char * dset_name,const char * field_name)2491 herr_t H5TBdelete_field(hid_t loc_id,
2492 const char *dset_name,
2493 const char *field_name)
2494 {
2495 /* identifiers for the 1st original dataset */
2496 hid_t did_1 = H5I_BADID;
2497 hid_t tid_1 = H5I_BADID;
2498 hid_t sid_1 = H5I_BADID;
2499 hid_t pid_1 = H5I_BADID;
2500 /* identifiers for the 2nd new dataset */
2501 hid_t did_2 = H5I_BADID;
2502 hid_t tid_2 = H5I_BADID;
2503 hid_t sid_2 = H5I_BADID;
2504 hid_t pid_2 = H5I_BADID;
2505 /* identifiers for the 3rd final dataset */
2506 hid_t did_3 = H5I_BADID;
2507 hid_t tid_3 = H5I_BADID;
2508 hid_t member_type_id = H5I_BADID;
2509 hid_t preserve_id = H5I_BADID;
2510 hid_t read_type_id = H5I_BADID;
2511 hid_t write_type_id = H5I_BADID;
2512 hid_t attr_id = H5I_BADID;
2513 size_t member_size;
2514 size_t type_size1;
2515 size_t type_size2;
2516 size_t curr_offset;
2517 size_t delete_member_size = 0;
2518 size_t member_offset;
2519 hsize_t nfields;
2520 hsize_t nrecords;
2521 hsize_t dims_chunk[1];
2522 hsize_t dims[1];
2523 hsize_t maxdims[1] = { H5S_UNLIMITED };
2524 hsize_t i;
2525 char attr_name[255];
2526 char table_title[255];
2527 char *member_name = NULL;
2528 unsigned char *tmp_buf = NULL;
2529 unsigned char *tmp_fill_buf = NULL;
2530 htri_t has_fill = FALSE;
2531 herr_t ret_val = -1;
2532
2533
2534 /* check the arguments */
2535 if (dset_name == NULL)
2536 goto out;
2537 if (field_name == NULL)
2538 goto out;
2539
2540 /* get the number of records and fields */
2541 if(H5TBget_table_info(loc_id, dset_name, &nfields, &nrecords) < 0)
2542 goto out;
2543
2544 /*-------------------------------------------------------------------------
2545 * get information about the old data type
2546 *-------------------------------------------------------------------------
2547 */
2548
2549 /* open the dataset. */
2550 if((did_1 = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
2551 goto out;
2552
2553 /* get creation properties list */
2554 if((pid_1 = H5Dget_create_plist(did_1)) < 0)
2555 goto out;
2556
2557 /* get the datatype */
2558 if((tid_1 = H5Dget_type(did_1)) < 0)
2559 goto out;
2560
2561 /* get the size of the datatype */
2562 if(0 == (type_size1 = H5Tget_size(tid_1)))
2563 goto out;
2564
2565 /* get the dataspace handle */
2566 if((sid_1 = H5Dget_space(did_1)) < 0)
2567 goto out;
2568
2569 /* get dimension */
2570 if(H5Sget_simple_extent_dims(sid_1, dims, NULL) < 0)
2571 goto out;
2572
2573 /*-------------------------------------------------------------------------
2574 * create a new data type; first we find the size of the datatype to delete
2575 *-------------------------------------------------------------------------
2576 */
2577
2578 /* check out the field */
2579 for(i = 0; i < nfields; i++) {
2580 /* get the member name */
2581 if(NULL == (member_name = H5Tget_member_name(tid_1, (unsigned)i)))
2582 goto out;
2583
2584 /* we want to find the field to delete */
2585 if(H5TB_find_field(member_name, field_name)) {
2586 /* get the member type */
2587 if((member_type_id = H5Tget_member_type(tid_1, (unsigned)i)) < 0)
2588 goto out;
2589
2590 /* get the member size */
2591 if(0 == (delete_member_size = H5Tget_size(member_type_id)))
2592 goto out;
2593
2594 /* close the member type */
2595 if(H5Tclose(member_type_id) < 0)
2596 goto out;
2597 member_type_id = H5I_BADID;
2598
2599 H5free_memory(member_name);
2600 member_name = NULL;
2601
2602 break;
2603 } /* end if */
2604
2605 H5free_memory(member_name);
2606 member_name = NULL;
2607 } /* end for */
2608
2609 /* no field to delete was found */
2610 if(delete_member_size == 0)
2611 goto out;
2612
2613 /*-------------------------------------------------------------------------
2614 * create a new data type; we now insert all the fields into the new type
2615 *-------------------------------------------------------------------------
2616 */
2617
2618 type_size2 = type_size1 - delete_member_size;
2619
2620 /* create the data type. */
2621 if((tid_2 = H5Tcreate (H5T_COMPOUND, type_size2)) < 0)
2622 goto out;
2623
2624 curr_offset = 0;
2625
2626 /* alloc fill value attribute buffer */
2627 if(NULL == (tmp_fill_buf = (unsigned char *)HDmalloc((size_t)type_size2)))
2628 goto out;
2629
2630 /*-------------------------------------------------------------------------
2631 * get attributes from previous table in the process
2632 *-------------------------------------------------------------------------
2633 */
2634
2635 /* get the table title */
2636 if((H5TBAget_title(did_1, table_title)) < 0)
2637 goto out;
2638
2639 /* insert the old fields except the one to delete */
2640 for(i = 0; i < nfields; i++) {
2641 /* get the member name */
2642 if(NULL == (member_name = H5Tget_member_name(tid_1, (unsigned)i)))
2643 goto out;
2644
2645 /* we want to skip the field to delete */
2646 if(!H5TB_find_field(member_name, field_name)) {
2647 /* get the member type */
2648 if((member_type_id = H5Tget_member_type(tid_1, (unsigned)i)) < 0)
2649 goto out;
2650
2651 /* get the member size */
2652 if(0 == (member_size = H5Tget_size(member_type_id)))
2653 goto out;
2654
2655 /* insert it into the new type */
2656 if(H5Tinsert(tid_2, member_name, curr_offset, member_type_id) < 0)
2657 goto out;
2658
2659 /*-------------------------------------------------------------------------
2660 * get the fill value information
2661 *-------------------------------------------------------------------------
2662 */
2663
2664 HDsnprintf(attr_name, sizeof(attr_name), "FIELD_%d_FILL", (int)i);
2665
2666 /* check if we have the _FILL attribute */
2667 if((has_fill = H5LT_find_attribute(did_1, attr_name)) < 0)
2668 goto out;
2669
2670 /* get it */
2671 if(has_fill)
2672 if(H5LT_get_attribute_disk(did_1, attr_name, tmp_fill_buf + curr_offset) < 0)
2673 goto out;
2674
2675 curr_offset += member_size;
2676
2677 /* close the member type */
2678 if(H5Tclose(member_type_id) < 0)
2679 goto out;
2680 member_type_id = H5I_BADID;
2681 } /* end if */
2682
2683 H5free_memory(member_name);
2684 member_name = NULL;
2685 } /* end for */
2686
2687 /*-------------------------------------------------------------------------
2688 * create a new temporary dataset
2689 *-------------------------------------------------------------------------
2690 */
2691
2692 /* retrieve the size of chunk */
2693 if(H5Pget_chunk(pid_1, 1, dims_chunk) < 0)
2694 goto out;
2695
2696 /* create a new simple data space with unlimited size, using the dimension */
2697 if((sid_2 = H5Screate_simple(1, dims, maxdims)) < 0)
2698 goto out;
2699
2700 /* modify dataset creation properties, i.e. enable chunking */
2701 pid_2 = H5Pcreate(H5P_DATASET_CREATE);
2702 if(H5Pset_chunk(pid_2, 1, dims_chunk) < 0)
2703 goto out;
2704
2705 /* create the dataset. */
2706 if((did_2 = H5Dcreate2(loc_id, "new", tid_2, sid_2, H5P_DEFAULT, pid_2, H5P_DEFAULT)) < 0)
2707 goto out;
2708
2709 /*-------------------------------------------------------------------------
2710 * we have to read field by field of the old dataset and save it into the new one
2711 *-------------------------------------------------------------------------
2712 */
2713 for(i = 0; i < nfields; i++) {
2714 /* get the member name */
2715 if(NULL == (member_name = H5Tget_member_name(tid_1, (unsigned)i)))
2716 goto out;
2717
2718 /* skip the field to delete */
2719 if(!H5TB_find_field(member_name, field_name)) {
2720 /* get the member type */
2721 if((member_type_id = H5Tget_member_type(tid_1, (unsigned)i)) < 0)
2722 goto out;
2723
2724 /* get the member size */
2725 if(0 == (member_size = H5Tget_size(member_type_id)))
2726 goto out;
2727
2728 /* create a read id */
2729 if((read_type_id = H5Tcreate(H5T_COMPOUND, member_size)) < 0)
2730 goto out;
2731
2732 /* insert it into the new type */
2733 if(H5Tinsert(read_type_id, member_name, (size_t)0, member_type_id) < 0)
2734 goto out;
2735
2736 if(NULL == (tmp_buf = (unsigned char *)HDcalloc((size_t)nrecords, member_size)))
2737 goto out;
2738
2739 /* read */
2740 if(H5Dread(did_1, read_type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, tmp_buf) < 0)
2741 goto out;
2742
2743 /* create a write id */
2744 if((write_type_id = H5Tcreate(H5T_COMPOUND, member_size)) < 0)
2745 goto out;
2746
2747 /* the field in the file is found by its name */
2748 if(H5Tinsert(write_type_id, member_name, (size_t)0, member_type_id) < 0)
2749 goto out;
2750
2751 /* create xfer properties to preserve initialized data */
2752 if((preserve_id = H5Pcreate(H5P_DATASET_XFER)) < 0)
2753 goto out;
2754 if(H5Pset_preserve(preserve_id, 1) < 0)
2755 goto out;
2756
2757 /* write */
2758 if(H5Dwrite(did_2, write_type_id, H5S_ALL, H5S_ALL, preserve_id, tmp_buf) < 0)
2759 goto out;
2760
2761 /* end access to the property list */
2762 if(H5Pclose(preserve_id) < 0)
2763 goto out;
2764 preserve_id = H5I_BADID;
2765
2766 /* close the member type */
2767 if(H5Tclose(member_type_id) < 0)
2768 goto out;
2769 member_type_id = H5I_BADID;
2770
2771 /* close the read type */
2772 if(H5Tclose(read_type_id) < 0)
2773 goto out;
2774 read_type_id = H5I_BADID;
2775
2776 /* close the write type */
2777 if(H5Tclose(write_type_id) < 0)
2778 goto out;
2779 write_type_id = H5I_BADID;
2780
2781 HDfree(tmp_buf);
2782 tmp_buf = NULL;
2783 } /* end if */
2784
2785 /* release resources. */
2786 H5free_memory(member_name);
2787 member_name = NULL;
2788 } /* end for */
2789
2790 /*-------------------------------------------------------------------------
2791 * delete 1st table
2792 *-------------------------------------------------------------------------
2793 */
2794 if(H5Ldelete(loc_id, dset_name, H5P_DEFAULT) < 0)
2795 goto out;
2796
2797 /*-------------------------------------------------------------------------
2798 * rename 2nd table
2799 *-------------------------------------------------------------------------
2800 */
2801 if(H5Lmove(loc_id, "new", H5L_SAME_LOC, dset_name, H5P_DEFAULT, H5P_DEFAULT) < 0)
2802 goto out;
2803
2804 /*-------------------------------------------------------------------------
2805 * attach the conforming table attributes
2806 *-------------------------------------------------------------------------
2807 */
2808
2809 /* get the number of records and fields */
2810 if(H5TBget_table_info(loc_id, dset_name, &nfields, &nrecords) < 0)
2811 goto out;
2812
2813 /* open the dataset. */
2814 if((did_3 = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
2815 goto out;
2816
2817 /* get the datatype */
2818 if((tid_3 = H5Dget_type(did_3)) < 0)
2819 goto out;
2820
2821 /* set the attributes */
2822 if(H5TB_attach_attributes(table_title, loc_id, dset_name, nfields, tid_3) < 0)
2823 goto out;
2824
2825 /*-------------------------------------------------------------------------
2826 * attach the fill attributes from previous table
2827 *-------------------------------------------------------------------------
2828 */
2829 if(has_fill) {
2830 if((sid_1 = H5Screate(H5S_SCALAR)) < 0)
2831 goto out;
2832
2833 for(i = 0; i < nfields; i++) {
2834 /* get the member type */
2835 if((member_type_id = H5Tget_member_type(tid_3, (unsigned)i)) < 0)
2836 goto out;
2837
2838 /* get the member offset */
2839 member_offset = H5Tget_member_offset(tid_3, (unsigned)i);
2840
2841 HDsnprintf(attr_name, sizeof(attr_name), "FIELD_%d_FILL", (int)i);
2842
2843 if((attr_id = H5Acreate2(did_3, attr_name, member_type_id, sid_1, H5P_DEFAULT, H5P_DEFAULT)) < 0)
2844 goto out;
2845
2846 if(H5Awrite(attr_id, member_type_id, tmp_fill_buf + member_offset) < 0)
2847 goto out;
2848
2849 if(H5Aclose(attr_id) < 0)
2850 goto out;
2851 attr_id = H5I_BADID;
2852
2853 /* close the member type */
2854 if(H5Tclose(member_type_id) < 0)
2855 goto out;
2856 member_type_id = H5I_BADID;
2857 } /* end for */
2858
2859 /* close data space. */
2860 if(H5Sclose(sid_1) < 0)
2861 goto out;
2862 sid_1 = H5I_BADID;
2863 } /* end if */
2864
2865 ret_val = 0;
2866
2867 out:
2868 if(member_name)
2869 H5free_memory(member_name);
2870 if(tmp_fill_buf)
2871 HDfree(tmp_fill_buf);
2872 if(tmp_buf)
2873 HDfree(tmp_buf);
2874 if(attr_id > 0)
2875 if(H5Aclose(attr_id) < 0)
2876 ret_val = -1;
2877 if(preserve_id > 0)
2878 if(H5Pclose(preserve_id) < 0)
2879 ret_val = -1;
2880 if(member_type_id > 0)
2881 if(H5Tclose(member_type_id) < 0)
2882 ret_val = -1;
2883 if(read_type_id > 0)
2884 if(H5Tclose(read_type_id) < 0)
2885 ret_val = -1;
2886 if(write_type_id > 0)
2887 if(H5Tclose(write_type_id) < 0)
2888 ret_val = -1;
2889 if(tid_1 > 0)
2890 if(H5Tclose(tid_1) < 0)
2891 ret_val = -1;
2892 if(pid_1 > 0)
2893 if(H5Pclose(pid_1) < 0)
2894 ret_val = -1;
2895 if(sid_1 > 0)
2896 if(H5Sclose(sid_1) < 0)
2897 ret_val = -1;
2898 if(did_1 > 0)
2899 if(H5Dclose(did_1) < 0)
2900 ret_val = -1;
2901 if(sid_2 > 0)
2902 if(H5Sclose(sid_2) < 0)
2903 ret_val = -1;
2904 if(tid_2 > 0)
2905 if(H5Tclose(tid_2) < 0)
2906 ret_val = -1;
2907 if(pid_2 > 0)
2908 if(H5Pclose(pid_2) < 0)
2909 ret_val = -1;
2910 if(did_2 > 0)
2911 if(H5Dclose(did_2) < 0)
2912 ret_val = -1;
2913 if(tid_3 > 0)
2914 if(H5Tclose(tid_3) < 0)
2915 ret_val = -1;
2916 if(did_3 > 0)
2917 if(H5Dclose(did_3) < 0)
2918 ret_val = -1;
2919
2920 return ret_val;
2921 } /* end H5TBdelete_field() */
2922
2923 /*-------------------------------------------------------------------------
2924 *
2925 * Table attribute functions
2926 *
2927 *-------------------------------------------------------------------------
2928 */
2929
2930 /*-------------------------------------------------------------------------
2931 * Function: H5TBAget_title
2932 *
2933 * Purpose: Read the table title
2934 *
2935 * Return: Success: 0, Failure: -1
2936 *
2937 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
2938 *
2939 * Date: January 30, 2001
2940 *
2941 * Comments:
2942 *
2943 *-------------------------------------------------------------------------
2944 */
H5TBAget_title(hid_t loc_id,char * table_title)2945 herr_t H5TBAget_title(hid_t loc_id,
2946 char *table_title)
2947 {
2948
2949 /* Get the TITLE attribute */
2950 if(H5LT_get_attribute_disk(loc_id, "TITLE", table_title) < 0)
2951 return -1;
2952
2953 return 0;
2954 }
2955
2956 /*-------------------------------------------------------------------------
2957 * Function: H5TBAget_fill
2958 *
2959 * Purpose: Read the table attribute fill values
2960 *
2961 * Return: Success: TRUE/FALSE, Failure: -1
2962 *
2963 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
2964 *
2965 * Date: January 30, 2002
2966 *
2967 * Comments:
2968 *
2969 *-------------------------------------------------------------------------
2970 */
H5TBAget_fill(hid_t loc_id,const char * dset_name,hid_t dset_id,unsigned char * dst_buf)2971 htri_t H5TBAget_fill(hid_t loc_id,
2972 const char *dset_name,
2973 hid_t dset_id,
2974 unsigned char *dst_buf)
2975 {
2976 hsize_t nfields;
2977 hsize_t nrecords;
2978 hsize_t i;
2979 size_t *src_offset = NULL;
2980 char attr_name[255];
2981 htri_t has_fill = FALSE;
2982 htri_t ret_val = -1;
2983
2984 /* check the arguments */
2985 if (dset_name == NULL)
2986 goto out;
2987
2988 /* get the number of records and fields */
2989 if(H5TBget_table_info(loc_id, dset_name, &nfields, &nrecords) < 0)
2990 goto out;
2991
2992 if(NULL == (src_offset = (size_t *)HDmalloc((size_t)nfields * sizeof(size_t))))
2993 goto out;
2994
2995 /* get field info */
2996 if(H5TBget_field_info(loc_id, dset_name, NULL, NULL, src_offset, NULL) < 0)
2997 goto out;
2998
2999 for(i = 0; i < nfields; i++) {
3000 HDsnprintf(attr_name, sizeof(attr_name), "FIELD_%d_FILL", (int)i);
3001
3002 /* check if we have the _FILL attribute */
3003 if((has_fill = H5LT_find_attribute(dset_id, attr_name)) < 0)
3004 goto out;
3005
3006 /* get it */
3007 if(has_fill)
3008 if(H5LT_get_attribute_disk(dset_id, attr_name, dst_buf + src_offset[i]) < 0)
3009 goto out;
3010 } /* end for */
3011
3012 ret_val = has_fill;
3013
3014 out:
3015 if(src_offset)
3016 HDfree(src_offset);
3017
3018 return ret_val;
3019 } /* end H5TBAget_fill() */
3020
3021
3022 /*-------------------------------------------------------------------------
3023 *
3024 * Inquiry functions
3025 *
3026 *-------------------------------------------------------------------------
3027 */
3028
3029 /*-------------------------------------------------------------------------
3030 * Function: H5TBget_table_info
3031 *
3032 * Purpose: Gets the number of records and fields of a table
3033 *
3034 * Return: Success: 0, Failure: -1
3035 *
3036 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
3037 *
3038 * Date: November 19, 2001
3039 *
3040 * Comments:
3041 *
3042 *-------------------------------------------------------------------------
3043 */
H5TBget_table_info(hid_t loc_id,const char * dset_name,hsize_t * nfields,hsize_t * nrecords)3044 herr_t H5TBget_table_info(hid_t loc_id,
3045 const char *dset_name,
3046 hsize_t *nfields,
3047 hsize_t *nrecords)
3048 {
3049 hid_t tid = H5I_BADID;
3050 hid_t sid = H5I_BADID;
3051 hid_t did = H5I_BADID;
3052 hsize_t dims[1];
3053 int num_members;
3054 herr_t ret_val = -1;
3055
3056 /* check the arguments */
3057 if (dset_name == NULL)
3058 goto out;
3059
3060 /* open the dataset. */
3061 if((did = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
3062 goto out;
3063
3064 /* get the datatype */
3065 if((tid = H5Dget_type(did)) < 0)
3066 goto out;
3067
3068 /* get the number of members */
3069 if((num_members = H5Tget_nmembers(tid)) < 0)
3070 goto out;
3071
3072 /*-------------------------------------------------------------------------
3073 * get number of nfields
3074 *-------------------------------------------------------------------------
3075 */
3076 if(nfields)
3077 *nfields = (hsize_t)num_members;
3078
3079 /*-------------------------------------------------------------------------
3080 * get number of records
3081 *-------------------------------------------------------------------------
3082 */
3083 if(nrecords) {
3084 /* get the dataspace handle */
3085 if((sid = H5Dget_space(did)) < 0)
3086 goto out;
3087
3088 /* get dimension */
3089 if(H5Sget_simple_extent_dims(sid, dims, NULL) < 0)
3090 goto out;
3091
3092 /* terminate access to the dataspace */
3093 if(H5Sclose(sid) < 0)
3094 goto out;
3095 sid = H5I_BADID;
3096
3097 *nrecords = dims[0];
3098 } /* end if */
3099
3100 ret_val = 0;
3101
3102 out:
3103 if(sid > 0)
3104 if(H5Sclose(sid) < 0)
3105 ret_val = -1;
3106 if(tid > 0)
3107 if(H5Tclose(tid) < 0)
3108 ret_val = -1;
3109 if(did > 0)
3110 if(H5Dclose(did) < 0)
3111 ret_val = -1;
3112
3113 return ret_val;
3114 } /* end H5TBget_table_info() */
3115
3116 /*-------------------------------------------------------------------------
3117 * Function: H5TBget_field_info
3118 *
3119 * Purpose: Get information about fields
3120 *
3121 * Return: Success: 0, Failure: -1
3122 *
3123 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
3124 *
3125 * Date: November 19, 2001
3126 *
3127 * Comments:
3128 *
3129 *-------------------------------------------------------------------------
3130 */
H5TBget_field_info(hid_t loc_id,const char * dset_name,char * field_names[],size_t * field_sizes,size_t * field_offsets,size_t * type_size)3131 herr_t H5TBget_field_info(hid_t loc_id,
3132 const char *dset_name,
3133 char *field_names[],
3134 size_t *field_sizes,
3135 size_t *field_offsets,
3136 size_t *type_size)
3137 {
3138 hid_t did = H5I_BADID; /* dataset ID */
3139 hid_t tid = H5I_BADID; /* file type ID */
3140 hid_t n_tid = H5I_BADID; /* native type ID */
3141 hid_t m_tid = H5I_BADID; /* member type ID */
3142 hid_t nm_tid = H5I_BADID; /* native member ID */
3143 hssize_t nfields;
3144 hssize_t i;
3145 herr_t ret_val = -1;
3146
3147 /* check the arguments */
3148 if (dset_name == NULL)
3149 goto out;
3150
3151 /* open the dataset. */
3152 if((did = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
3153 goto out;
3154
3155 /* get the datatype */
3156 if((tid = H5Dget_type(did)) < 0)
3157 goto out;
3158
3159 if((n_tid = H5Tget_native_type(tid, H5T_DIR_DEFAULT)) < 0)
3160 goto out;
3161
3162 /* get the type size */
3163 if(type_size)
3164 if(0 == (*type_size = H5Tget_size(n_tid)))
3165 goto out;
3166
3167 /* get the number of members */
3168 if((nfields = H5Tget_nmembers(tid)) < 0)
3169 goto out;
3170
3171 /* iterate tru the members */
3172 for(i = 0; i < nfields; i++) {
3173 /* get the member name */
3174 if(field_names) {
3175 char *member_name;
3176
3177 if(NULL == (member_name = H5Tget_member_name(tid, (unsigned)i)))
3178 goto out;
3179 strcpy(field_names[i], member_name);
3180 H5free_memory(member_name);
3181 } /* end if */
3182
3183 /* get the member type */
3184 if((m_tid = H5Tget_member_type(tid, (unsigned)i)) < 0)
3185 goto out;
3186 if((nm_tid = H5Tget_native_type(m_tid, H5T_DIR_DEFAULT)) < 0)
3187 goto out;
3188
3189 /* get the member size */
3190 if(field_sizes)
3191 if(0 == (field_sizes[i] = H5Tget_size(nm_tid)))
3192 goto out;
3193
3194 /* get the member offset */
3195 if(field_offsets)
3196 field_offsets[i] = H5Tget_member_offset(n_tid, (unsigned) i);
3197
3198 /* close the member types */
3199 if(H5Tclose(m_tid) < 0)
3200 goto out;
3201 m_tid = H5I_BADID;
3202 if(H5Tclose(nm_tid) < 0)
3203 goto out;
3204 nm_tid = H5I_BADID;
3205 } /* end for */
3206
3207 ret_val = 0;
3208
3209 out:
3210 if(tid > 0)
3211 if(H5Tclose(tid) < 0)
3212 ret_val = -1;
3213 if(n_tid > 0)
3214 if(H5Tclose(n_tid) < 0)
3215 ret_val = -1;
3216 if(m_tid > 0)
3217 if(H5Tclose(m_tid) < 0)
3218 ret_val = -1;
3219 if(nm_tid > 0)
3220 if(H5Tclose(nm_tid) < 0)
3221 ret_val = -1;
3222 if(did > 0)
3223 if(H5Dclose(did) < 0)
3224 ret_val = -1;
3225
3226 return ret_val;
3227 } /* end H5TBget_field_info() */
3228
3229 /*-------------------------------------------------------------------------
3230 *
3231 * internal functions
3232 *
3233 *-------------------------------------------------------------------------
3234 */
3235
3236 /*-------------------------------------------------------------------------
3237 * Function: H5TB_find_field
3238 *
3239 * Purpose: Find a string field
3240 *
3241 * Return: Success: TRUE/FALSE, Failure: N/A
3242 *
3243 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
3244 *
3245 * Date: November 19, 2001
3246 *
3247 *-------------------------------------------------------------------------
3248 */
3249 H5_ATTR_PURE static
H5TB_find_field(const char * field,const char * field_list)3250 hbool_t H5TB_find_field(const char *field, const char *field_list)
3251 {
3252 const char *start = field_list;
3253 const char *end;
3254
3255 /* check the arguments */
3256 if (field == NULL)
3257 return FALSE;
3258 if (field_list == NULL)
3259 return FALSE;
3260
3261 while((end = HDstrstr(start, ",")) != 0) {
3262 ptrdiff_t count = end - start;
3263
3264 if(HDstrncmp(start, field, (size_t)count) == 0 && (size_t)count == HDstrlen(field))
3265 return TRUE;
3266 start = end + 1;
3267 } /* end while */
3268
3269 if(HDstrncmp(start, field, HDstrlen(field)) == 0)
3270 return TRUE;
3271
3272 return FALSE;
3273 } /* end H5TB_find_field() */
3274
3275 /*-------------------------------------------------------------------------
3276 * Function: H5TB_attach_attributes
3277 *
3278 * Purpose: Private function that creates the conforming table attributes;
3279 * Used by H5TBcombine_tables; not used by H5TBmake_table, which does not read
3280 * the fill value attributes from an existing table
3281 *
3282 * Return: Success: 0, Failure: -1
3283 *
3284 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
3285 *
3286 * Date: December 6, 2001
3287 *
3288 * Comments:
3289 *
3290 *-------------------------------------------------------------------------
3291 */
3292 static
H5TB_attach_attributes(const char * table_title,hid_t loc_id,const char * dset_name,hsize_t nfields,hid_t tid)3293 herr_t H5TB_attach_attributes(const char *table_title,
3294 hid_t loc_id,
3295 const char *dset_name,
3296 hsize_t nfields,
3297 hid_t tid)
3298 {
3299 char attr_name[255];
3300 char *member_name = NULL;
3301 hsize_t i;
3302 herr_t ret_val = -1;
3303
3304 /* attach the CLASS attribute */
3305 if(H5LTset_attribute_string(loc_id, dset_name, "CLASS", TABLE_CLASS) < 0)
3306 goto out;
3307
3308 /* attach the VERSION attribute */
3309 if(H5LTset_attribute_string(loc_id, dset_name, "VERSION", TABLE_VERSION) < 0)
3310 goto out;
3311
3312 /* attach the TITLE attribute */
3313 if(H5LTset_attribute_string(loc_id, dset_name, "TITLE", table_title) < 0)
3314 goto out;
3315
3316 /* attach the FIELD_ name attribute */
3317 for(i = 0; i < nfields; i++) {
3318 /* get the member name */
3319 if(NULL == (member_name = H5Tget_member_name(tid, (unsigned)i)))
3320 goto out;
3321
3322 HDsnprintf(attr_name, sizeof(attr_name), "FIELD_%d_NAME", (int)i);
3323
3324 /* attach the attribute */
3325 if(H5LTset_attribute_string(loc_id, dset_name, attr_name, member_name) < 0)
3326 goto out;
3327
3328 H5free_memory(member_name);
3329 member_name = NULL;
3330 } /* end for */
3331
3332 ret_val = 0;
3333
3334 out:
3335 if(member_name)
3336 H5free_memory(member_name);
3337
3338 return ret_val;
3339 } /* end H5TB_attach_attributes() */
3340
3341 /*-------------------------------------------------------------------------
3342 * Function: H5TB_create_type
3343 *
3344 * Purpose: Private function that creates a memory type ID
3345 *
3346 * Return: Success: the memory type ID, Failure: -1
3347 *
3348 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
3349 *
3350 * Date: March 31, 2004
3351 *
3352 * Comments:
3353 *
3354 *-------------------------------------------------------------------------
3355 */
3356 static
H5TB_create_type(hid_t loc_id,const char * dset_name,size_t type_size,const size_t * field_offset,const size_t * field_sizes,hid_t ftype_id)3357 hid_t H5TB_create_type(hid_t loc_id,
3358 const char *dset_name,
3359 size_t type_size,
3360 const size_t *field_offset,
3361 const size_t *field_sizes,
3362 hid_t ftype_id)
3363 {
3364 hid_t mem_type_id = H5I_BADID;
3365 hid_t mtype_id = H5I_BADID;
3366 hid_t nmtype_id = H5I_BADID;
3367 size_t size_native;
3368 hsize_t nfields = 0;
3369 char **fnames = NULL;
3370 unsigned i;
3371 hid_t ret_val = -1;
3372
3373 /* get the number of fields */
3374 if(H5TBget_table_info(loc_id, dset_name, &nfields, NULL) < 0)
3375 goto out;
3376
3377 if(NULL == (fnames = (char**)HDcalloc(sizeof(char*), (size_t)nfields)))
3378 goto out;
3379
3380 for(i = 0; i < nfields; i++)
3381 if(NULL == (fnames[i] = (char*)HDmalloc(HLTB_MAX_FIELD_LEN)))
3382 goto out;
3383
3384 /* get field info */
3385 if(H5TBget_field_info(loc_id, dset_name, fnames, NULL, NULL, NULL) < 0)
3386 goto out;
3387
3388 /* create the memory data type */
3389 if ((mem_type_id = H5Tcreate(H5T_COMPOUND, type_size)) < 0)
3390 goto out;
3391
3392 /* get each field ID and adjust its size, if necessary */
3393 for(i = 0; i < nfields; i++) {
3394 if((mtype_id = H5Tget_member_type(ftype_id, i)) < 0)
3395 goto out;
3396 if((nmtype_id = H5Tget_native_type(mtype_id, H5T_DIR_DEFAULT)) < 0)
3397 goto out;
3398 if(0 == (size_native = H5Tget_size(nmtype_id)))
3399 goto out;
3400 if(field_sizes[i] != size_native)
3401 if(H5Tset_size(nmtype_id, field_sizes[i]) < 0)
3402 goto out;
3403 if(H5Tinsert(mem_type_id, fnames[i], field_offset[i], nmtype_id) < 0)
3404 goto out;
3405 if(H5Tclose(mtype_id) < 0)
3406 goto out;
3407 mtype_id = H5I_BADID;
3408 if(H5Tclose(nmtype_id) < 0)
3409 goto out;
3410 nmtype_id = H5I_BADID;
3411 } /* end for */
3412
3413 ret_val = mem_type_id;
3414
3415 out:
3416 if(fnames) {
3417 for(i = 0; i < nfields; i++)
3418 if(fnames[i])
3419 HDfree(fnames[i]);
3420 HDfree(fnames);
3421 } /* end if */
3422 if(mtype_id > 0)
3423 if(H5Tclose(mtype_id) < 0)
3424 ret_val = -1;
3425 if(nmtype_id > 0)
3426 if(H5Tclose(nmtype_id) < 0)
3427 ret_val = -1;
3428 if(ret_val < 0 && mem_type_id > 0)
3429 H5Tclose(mem_type_id);
3430
3431 return ret_val;
3432 } /* end H5TB_create_type() */
3433
3434 /*-------------------------------------------------------------------------
3435 *
3436 * Functions shared between H5TB and H5PT
3437 *
3438 *-------------------------------------------------------------------------
3439 */
3440
3441 /*-------------------------------------------------------------------------
3442 * Function: H5TB_common_append_records
3443 *
3444 * Purpose: Common code for reading records shared between H5PT and H5TB
3445 *
3446 * Return: Success: 0, Failure: -1
3447 *
3448 * Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu
3449 * James Laird, jlaird@ncsa.uiuc.edu
3450 *
3451 * Date: March 8, 2004
3452 *
3453 * Comments: Called by H5TBappend_records and H5PTappend_records
3454 *
3455 *-------------------------------------------------------------------------
3456 */
H5TB_common_append_records(hid_t dataset_id,hid_t mem_type_id,size_t nrecords,hsize_t orig_table_size,const void * buf)3457 herr_t H5TB_common_append_records(hid_t dataset_id,
3458 hid_t mem_type_id,
3459 size_t nrecords,
3460 hsize_t orig_table_size,
3461 const void *buf)
3462 {
3463 hid_t sid = H5I_BADID;
3464 hid_t m_sid = H5I_BADID;
3465 hsize_t count[1];
3466 hsize_t offset[1];
3467 hsize_t dims[1];
3468 hsize_t mem_dims[1];
3469 herr_t ret_val = -1;
3470
3471 /* extend the dataset */
3472 dims[0] = nrecords + orig_table_size;
3473 if(H5Dset_extent(dataset_id, dims) < 0)
3474 goto out;
3475
3476 /* create a simple memory data space */
3477 mem_dims[0] = nrecords;
3478 if((m_sid = H5Screate_simple(1, mem_dims, NULL)) < 0)
3479 goto out;
3480
3481 /* get a copy of the new file data space for writing */
3482 if((sid = H5Dget_space(dataset_id)) < 0)
3483 goto out;
3484
3485 /* define a hyperslab in the dataset */
3486 offset[0] = orig_table_size;
3487 count[0] = nrecords;
3488 if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0)
3489 goto out;
3490
3491 /* write the records */
3492 if(H5Dwrite(dataset_id, mem_type_id, m_sid, sid, H5P_DEFAULT, buf) < 0)
3493 goto out;
3494
3495 ret_val = 0;
3496
3497 out:
3498 if(m_sid > 0)
3499 if(H5Sclose(m_sid) < 0)
3500 ret_val = -1;
3501 if(sid > 0)
3502 if(H5Sclose(sid) < 0)
3503 ret_val = -1;
3504
3505 return ret_val;
3506 } /* end H5TB_common_append_records() */
3507
3508 /*-------------------------------------------------------------------------
3509 * Function: H5TB_common_read_records
3510 *
3511 * Purpose: Common code for reading records shared between H5PT and H5TB
3512 *
3513 * Return: Success: 0, Failure: -1
3514 *
3515 * Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu
3516 * James Laird, jlaird@ncsa.uiuc.edu
3517 *
3518 * Date: March 8, 2004
3519 *
3520 * Comments: Called by H5TBread_records and H5PTread_records
3521 *
3522 *-------------------------------------------------------------------------
3523 */
H5TB_common_read_records(hid_t dataset_id,hid_t mem_type_id,hsize_t start,size_t nrecords,hsize_t table_size,void * buf)3524 herr_t H5TB_common_read_records(hid_t dataset_id,
3525 hid_t mem_type_id,
3526 hsize_t start,
3527 size_t nrecords,
3528 hsize_t table_size,
3529 void *buf)
3530 {
3531 hid_t sid = H5I_BADID;
3532 hid_t m_sid = H5I_BADID;
3533 hsize_t count[1];
3534 hsize_t offset[1];
3535 hsize_t mem_size[1];
3536 herr_t ret_val = -1;
3537
3538 /* make sure the read request is in bounds */
3539 if(start + nrecords > table_size)
3540 goto out;
3541
3542 /* get the dataspace handle */
3543 if((sid = H5Dget_space(dataset_id)) < 0)
3544 goto out;
3545
3546 /* define a hyperslab in the dataset of the size of the records */
3547 offset[0] = start;
3548 count[0] = nrecords;
3549 if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0)
3550 goto out;
3551
3552 /* create a memory dataspace handle */
3553 mem_size[0] = count[0];
3554 if((m_sid = H5Screate_simple(1, mem_size, NULL)) < 0)
3555 goto out;
3556 if((H5Dread(dataset_id, mem_type_id, m_sid, sid, H5P_DEFAULT, buf)) < 0)
3557 goto out;
3558
3559 ret_val = 0;
3560
3561 out:
3562 if(m_sid > 0)
3563 if(H5Sclose(m_sid) < 0)
3564 ret_val = -1;
3565 if(sid > 0)
3566 if(H5Sclose(sid) < 0)
3567 ret_val = -1;
3568
3569 return ret_val;
3570 } /* end H5TB_common_read_records() */
3571
3572