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