1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* Copyright by the Board of Trustees of the University of Illinois. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the files COPYING and Copyright.html. COPYING can be found at the root *
* of the source code distribution tree; Copyright.html can be found at the *
* root level of an installed copy of the electronic HDF5 document set and *
* is linked from the top-level documents page. It can also be found at *
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
* access to either file, you may request a copy from help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* This program demonstrates how to create and use "external links" in
* HDF5.
*
* External links point from one HDF5 file to an object (Group, Dataset, or
* committed Datatype) in another file.
*/
#include "hdf5.h"
#include <string.h>
#define SOURCE_FILE "extlink_source.h5"
#define TARGET_FILE "extlink_target.h5"
#define PREFIX_SOURCE_FILE "extlink_prefix_source.h5"
#define SOFT_LINK_FILE "soft_link.h5"
#define SOFT_LINK_NAME "soft_link_to_group"
#define UD_SOFT_LINK_NAME "ud_soft_link"
#define TARGET_GROUP "target_group"
#define UD_SOFT_CLASS 65
#define HARD_LINK_FILE "hard_link.h5"
#define HARD_LINK_NAME "hard_link_to_group"
#define UD_HARD_LINK_NAME "ud_hard_link"
#define UD_HARD_CLASS 66
#define PLIST_LINK_PROP "plist_link_prop"
#define UD_PLIST_CLASS 66
/* Basic external link example
*
* Creates two files and uses an external link to access an object in the
* second file from the first file.
*/
static void extlink_example(void)
{
hid_t source_file_id, targ_file_id;
hid_t group_id, group2_id;
/* Create two files, a source and a target */
source_file_id = H5Fcreate(SOURCE_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
targ_file_id = H5Fcreate(TARGET_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
/* Create a group in the target file for the external link to point to. */
group_id = H5Gcreate2(targ_file_id, "target_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
/* Close the group and the target file */
H5Gclose(group_id);
/* Create an external link in the source file pointing to the target group.
* We could instead have created the external link first, then created the
* group it points to; the order doesn't matter.
*/
H5Lcreate_external(TARGET_FILE, "target_group", source_file_id, "ext_link", H5P_DEFAULT, H5P_DEFAULT);
/* Now we can use the external link to create a new group inside the
* target group (even though the target file is closed!). The external
* link works just like a soft link.
*/
group_id = H5Gcreate2(source_file_id, "ext_link/new_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
/* The group is inside the target file and we can access it normally.
* Here, group_id and group2_id point to the same group inside the
* target file.
*/
group2_id = H5Gopen2(targ_file_id, "target_group/new_group", H5P_DEFAULT);
/* Don't forget to close the IDs we opened. */
H5Gclose(group2_id);
H5Gclose(group_id);
H5Fclose(targ_file_id);
H5Fclose(source_file_id);
/* The link from the source file to the target file will work as long as
* the target file can be found. If the target file is moved, renamed,
* or deleted in the filesystem, HDF5 won't be able to find it and the
* external link will "dangle."
*/
}
/* External link prefix example
*
* Uses a group access property list to set a "prefix" for the filenames
* accessed through an external link.
*
* Group access property lists inherit from link access property lists;
* the external link prefix property is actually a property of LAPLs.
*
* This example requires a "red" directory and a "blue" directory to exist
* where it is run (so to run this example on Unix, first mkdir red and mkdir
* blue).
*/
static void extlink_prefix_example(void)
{
hid_t source_file_id, red_file_id, blue_file_id;
hid_t group_id, group2_id;
hid_t gapl_id;
/* Create three files, a source and two targets. The targets will have
* the same name, but one will be located in the red directory and one will
* be located in the blue directory */
source_file_id = H5Fcreate(PREFIX_SOURCE_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
red_file_id = H5Fcreate("red/prefix_target.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
blue_file_id = H5Fcreate("blue/prefix_target.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
/* This test needs a red and a blue directory in the filesystem. If they're not present,
* trying to create the files above will fail.
*/
if(red_file_id < 0 || blue_file_id < 0)
printf("This test requires directories named 'red' and 'blue' to exist. Did you forget to create them?\n");
/* Create an external link in the source file pointing to the root group of
* a file named prefix_target.h5. This file doesn't exist in the current
* directory, but the files in the red and blue directories both have this
* name.
*/
H5Lcreate_external("prefix_target.h5", "/", source_file_id, "ext_link", H5P_DEFAULT, H5P_DEFAULT);
/* If we tried to traverse the external link now, we would fail (since the
* file it points to doesn't exist). Instead, we'll create a group access
* property list that will provide a prefix path to the external link.
* Group access property lists inherit the properties of link access
* property lists.
*/
gapl_id = H5Pcreate(H5P_GROUP_ACCESS);
H5Pset_elink_prefix(gapl_id, "red/");
/* Now if we traverse the external link, HDF5 will look for an external
* file named red/prefix_target.h5, which exists.
* To pass the group access property list, we need to use H5Gopen2.
*/
group_id = H5Gopen2(source_file_id, "ext_link", gapl_id);
/* Now we can use the open group ID to create a new group inside the
* "red" file.
*/
group2_id = H5Gcreate2(group_id, "pink", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
/* Close both groups. */
H5Gclose(group2_id);
H5Gclose(group_id);
/* If we change the prefix, the same external link can find a file in the blue
* directory.
*/
H5Pset_elink_prefix(gapl_id, "blue/");
group_id = H5Gopen2(source_file_id, "ext_link", gapl_id);
group2_id = H5Gcreate2(group_id, "sky blue", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
/* Close both groups. */
H5Gclose(group2_id);
H5Gclose(group_id);
/* Each file has had a group created inside it using the same external link. */
group_id = H5Gopen2(red_file_id, "pink", H5P_DEFAULT);
group2_id = H5Gopen2(blue_file_id, "sky blue", H5P_DEFAULT);
/* Clean up our open IDs */
H5Gclose(group2_id);
H5Gclose(group_id);
H5Pclose(gapl_id);
H5Fclose(blue_file_id);
H5Fclose(red_file_id);
H5Fclose(source_file_id);
/* User-defined links can expand on the ability to pass in parameters
* using an access property list; for instance, a user-defined link
* might function like an external link but allow the full filename to be
* passed in through the access property list.
*/
}
/* Soft Link example
*
* Create a new class of user-defined links that behave like HDF5's built-in
* soft links.
*
* This isn't very useful by itself (HDF5's soft links already do the same
* thing), but it can serve as an example for how to reference objects by
* name.
*/
/* We need to define the callback function that the soft link will use.
* It is defined after the example below.
* To keep the example simple, these links don't have a query callback.
* In general, link classes should always be query-able.
* We might also have wanted to supply a creation callback that checks
* that a path was supplied in the udata.
*/
static hid_t UD_soft_traverse(const char *link_name, hid_t cur_group,
const void *udata, size_t udata_size, hid_t lapl_id);
static void soft_link_example(void)
{
hid_t file_id;
hid_t group_id;
/* Define the link class that we'll use to register "user-defined soft
* links" using the callbacks we defined above.
* A link class can have NULL for any callback except its traverse
* callback.
*/
const H5L_class_t UD_soft_class[1] = {{
H5L_LINK_CLASS_T_VERS, /* Version number for this struct.
* This field is always H5L_LINK_CLASS_T_VERS */
(H5L_type_t)UD_SOFT_CLASS, /* Link class id number. This can be any
* value between H5L_TYPE_UD_MIN (64) and
* H5L_TYPE_MAX (255). It should be a
* value that isn't already being used by
* another kind of link. We'll use 65. */
"UD_soft_link", /* Link class name for debugging */
NULL, /* Creation callback */
NULL, /* Move callback */
NULL, /* Copy callback */
UD_soft_traverse, /* The actual traversal function */
NULL, /* Deletion callback */
NULL /* Query callback */
}};
/* First, create a file and an object within the file for the link to
* point to.
*/
file_id = H5Fcreate(SOFT_LINK_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
group_id = H5Gcreate2(file_id, TARGET_GROUP, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Gclose(group_id);
/* This is how we create a normal soft link to the group.
*/
H5Lcreate_soft(TARGET_GROUP, file_id, SOFT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT);
/* To do the same thing using a user-defined link, we first have to
* register the link class we defined.
*/
H5Lregister(UD_soft_class);
/* Now create a user-defined link. We give it the path to the group
* as its udata.1
*/
H5Lcreate_ud(file_id, UD_SOFT_LINK_NAME, (H5L_type_t)UD_SOFT_CLASS, TARGET_GROUP,
strlen(TARGET_GROUP) + 1, H5P_DEFAULT, H5P_DEFAULT);
/* We can access the group through the UD soft link like we would through
* a normal soft link. This link will still dangle if the object's
* original name is changed or unlinked.
*/
group_id = H5Gopen2(file_id, UD_SOFT_LINK_NAME, H5P_DEFAULT);
/* The group is now open normally. Don't forget to close it! */
H5Gclose(group_id);
H5Fclose(file_id);
}
/* UD_soft_traverse
* The actual traversal function simply needs to open the correct object by
* name and return its ID.
*/
static hid_t UD_soft_traverse(const char *link_name, hid_t cur_group,
const void *udata, size_t udata_size, hid_t lapl_id)
{
const char *target = (const char *) udata;
hid_t ret_value;
/* Pass the udata straight through to HDF5. If it's invalid, let HDF5
* return an error.
*/
ret_value = H5Oopen(cur_group, target, lapl_id);
return ret_value;
}
/* Hard Link example
*
* Create a new class of user-defined links that behave like HDF5's built-in
* hard links.
*
* This isn't very useful by itself (HDF5's hard links already do the same
* thing), but it can serve as an example for how to reference objects by
* address.
*/
/* We need to define the callback functions that the hard link will use.
* These are defined after the example below.
* To keep the example simple, these links don't have a query callback.
* Generally, real link classes should always be query-able.
*/
static herr_t UD_hard_create(const char *link_name, hid_t loc_group,
const void *udata, size_t udata_size, hid_t lcpl_id);
static herr_t UD_hard_delete(const char *link_name, hid_t loc_group,
const void *udata, size_t udata_size);
static hid_t UD_hard_traverse(const char *link_name, hid_t cur_group,
const void *udata, size_t udata_size, hid_t lapl_id);
static void hard_link_example(void)
{
hid_t file_id;
hid_t group_id;
H5L_info_t li;
/* Define the link class that we'll use to register "user-defined hard
* links" using the callbacks we defined above.
* A link class can have NULL for any callback except its traverse
* callback.
*/
const H5L_class_t UD_hard_class[1] = {{
H5L_LINK_CLASS_T_VERS, /* Version number for this struct.
* This field is always H5L_LINK_CLASS_T_VERS */
(H5L_type_t)UD_HARD_CLASS, /* Link class id number. This can be any
* value between H5L_TYPE_UD_MIN (64) and
* H5L_TYPE_MAX (255). It should be a
* value that isn't already being used by
* another kind of link. We'll use 66. */
"UD_hard_link", /* Link class name for debugging */
UD_hard_create, /* Creation callback */
NULL, /* Move callback */
NULL, /* Copy callback */
UD_hard_traverse, /* The actual traversal function */
UD_hard_delete, /* Deletion callback */
NULL /* Query callback */
}};
/* First, create a file and an object within the file for the link to
* point to.
*/
file_id = H5Fcreate(HARD_LINK_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
group_id = H5Gcreate2(file_id, TARGET_GROUP, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Gclose(group_id);
/* This is how we create a normal hard link to the group. This
* creates a second "name" for the group.
*/
H5Lcreate_hard(file_id, TARGET_GROUP, file_id, HARD_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT);
/* To do the same thing using a user-defined link, we first have to
* register the link class we defined.
*/
H5Lregister(UD_hard_class);
/* Since hard links link by object address, we'll need to retrieve
* the target group's address. We do this by calling H5Lget_info
* on a hard link to the object.
*/
H5Lget_info(file_id, TARGET_GROUP, &li, H5P_DEFAULT);
/* Now create a user-defined link. We give it the group's address
* as its udata.
*/
H5Lcreate_ud(file_id, UD_HARD_LINK_NAME, (H5L_type_t)UD_HARD_CLASS, &(li.u.address),
sizeof(li.u.address), H5P_DEFAULT, H5P_DEFAULT);
/* The UD hard link has now incremented the group's reference count
* like a normal hard link would. This means that we can unlink the
* other two links to that group and it won't be deleted until the
* UD hard link is deleted.
*/
H5Ldelete(file_id, TARGET_GROUP, H5P_DEFAULT);
H5Ldelete(file_id, HARD_LINK_NAME, H5P_DEFAULT);
/* The group is still accessible through the UD hard link. If this were
* a soft link instead, the object would have been deleted when the last
* hard link to it was unlinked. */
group_id = H5Gopen2(file_id, UD_HARD_LINK_NAME, H5P_DEFAULT);
/* The group is now open normally. Don't forget to close it! */
H5Gclose(group_id);
/* Removing the user-defined hard link will delete the group. */
H5Ldelete(file_id, UD_HARD_LINK_NAME, H5P_DEFAULT);
H5Fclose(file_id);
}
/* Callbacks for User-defined hard links. */
/* UD_hard_create
* The most important thing this callback does is to increment the reference
* count on the target object. Without this step, the object could be
* deleted while this link still pointed to it, resulting in possible data
* corruption!
* The create callback also checks the arguments used to create this link.
* If this function returns a negative value, the call to H5Lcreate_ud()
* will also return failure and the link will not be created.
*/
static herr_t UD_hard_create(const char *link_name, hid_t loc_group,
const void *udata, size_t udata_size, hid_t lcpl_id)
{
haddr_t addr;
hid_t target_obj = -1;
herr_t ret_value = 0;
/* Make sure that the address passed in looks valid */
if(udata_size != sizeof(haddr_t))
{
ret_value = -1;
goto done;
}
addr = *((const haddr_t *) udata);
/* Open the object this link points to so that we can increment
* its reference count. This also ensures that the address passed
* in points to a real object (although this check is not perfect!) */
target_obj= H5Oopen_by_addr(loc_group, addr);
if(target_obj < 0)
{
ret_value = -1;
goto done;
}
/* Increment the reference count of the target object */
if(H5Oincr_refcount(target_obj) < 0)
{
ret_value = -1;
goto done;
}
done:
/* Close the target object if we opened it */
if(target_obj >= 0)
H5Oclose(target_obj);
return ret_value;
}
/* UD_hard_delete
* Since the creation function increments the object's reference count, it's
* important to decrement it again when the link is deleted.
*/
static herr_t UD_hard_delete(const char *link_name, hid_t loc_group,
const void *udata, size_t udata_size)
{
haddr_t addr;
hid_t target_obj = -1;
herr_t ret_value = 0;
/* Sanity check; we have already verified the udata's size in the creation
* callback.
*/
if(udata_size != sizeof(haddr_t))
{
ret_value = -1;
goto done;
}
addr = *((const haddr_t *) udata);
/* Open the object this link points to */
target_obj= H5Oopen_by_addr(loc_group, addr);
if(target_obj < 0)
{
ret_value = -1;
goto done;
}
/* Decrement the reference count of the target object */
if(H5Odecr_refcount(target_obj) < 0)
{
ret_value = -1;
goto done;
}
done:
/* Close the target object if we opened it */
if(target_obj >= 0)
H5Oclose(target_obj);
return ret_value;
}
/* UD_hard_traverse
* The actual traversal function simply needs to open the correct object and
* return its ID.
*/
static hid_t UD_hard_traverse(const char *link_name, hid_t cur_group,
const void *udata, size_t udata_size, hid_t lapl_id)
{
haddr_t addr;
hid_t ret_value = -1;
/* Sanity check; we have already verified the udata's size in the creation
* callback.
*/
if(udata_size != sizeof(haddr_t))
return -1;
addr = *((const haddr_t *) udata);
/* Open the object by address. If H5Oopen_by_addr fails, ret_value will
* be negative to indicate that the traversal function failed.
*/
ret_value = H5Oopen_by_addr(cur_group, addr);
return ret_value;
}
/* Plist example
*
* Create a new class of user-defined links that open objects within a file
* based on a value passed in through a link access property list.
*
* Group, dataset, and datatype access property lists all inherit from link
* access property lists, so they can be used instead of LAPLs.
*/
/* We need to define the callback functions that this link type will use.
* These are defined after the example below.
* These links have no udata, so they don't need a query function.
*/
static hid_t UD_plist_traverse(const char *link_name, hid_t cur_group,
const void *udata, size_t udata_size, hid_t lapl_id);
static void plist_link_example(void)
{
hid_t file_id;
hid_t group_id, group2_id;
hid_t gapl_id;
char *path = NULL;
/* Define the link class that we'll use to register "plist
* links" using the callback we defined above.
* A link class can have NULL for any callback except its traverse
* callback.
*/
const H5L_class_t UD_plist_class[1] = {{
H5L_LINK_CLASS_T_VERS, /* Version number for this struct.
* This field is always H5L_LINK_CLASS_T_VERS */
(H5L_type_t)UD_PLIST_CLASS, /* Link class id number. This can be any
* value between H5L_TYPE_UD_MIN (64) and
* H5L_TYPE_MAX (255). It should be a
* value that isn't already being used by
* another kind of link. We'll use 67. */
"UD_plist_link", /* Link class name for debugging */
NULL, /* Creation callback */
NULL, /* Move callback */
NULL, /* Copy callback */
UD_plist_traverse, /* The actual traversal function */
NULL, /* Deletion callback */
NULL /* Query callback */
}};
/* First, create a file and two objects within the file for the link to
* point to.
*/
file_id = H5Fcreate(HARD_LINK_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
group_id = H5Gcreate2(file_id, "group_1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Gclose(group_id);
group_id = H5Gcreate2(file_id, "group_1/group_2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Gclose(group_id);
/* Register "plist links" and create one. It has no udata at all. */
H5Lregister(UD_plist_class);
H5Lcreate_ud(file_id, "plist_link", (H5L_type_t)UD_PLIST_CLASS, NULL, 0,
H5P_DEFAULT, H5P_DEFAULT);
/* Create a group access property list to pass in the target for the
* plist link.
*/
gapl_id = H5Pcreate(H5P_GROUP_ACCESS);
/* There is no HDF5 API for setting the property that controls these
* links, so we have to add the property manually
*/
H5Pinsert2(gapl_id, PLIST_LINK_PROP, sizeof(const char *), &(path), NULL, NULL, NULL, NULL, NULL, NULL);
/* Set the property to point to the first group. */
path = "group_1";
H5Pset(gapl_id, PLIST_LINK_PROP, &path);
/* Open the first group through the plist link using the GAPL we just
* created */
group_id = H5Gopen2(file_id, "plist_link", gapl_id);
/* If we change the value set on the property list, it will change where
* the plist link points.
*/
path = "group_1/group_2";
H5Pset(gapl_id, PLIST_LINK_PROP, &path);
group2_id = H5Gopen2(file_id, "plist_link", gapl_id);
/* group_id points to group_1 and group2_id points to group_2, both opened
* through the same link.
* Using more than one of this type of link could quickly become confusing,
* since they will all use the same property list; however, there is
* nothing to prevent the links from changing the property list in their
* traverse callbacks.
*/
/* Clean up */
H5Pclose(gapl_id);
H5Gclose(group_id);
H5Gclose(group2_id);
H5Fclose(file_id);
}
/* Traversal callback for User-defined plist links. */
/* UD_plist_traverse
* Open a path passed in through the property list.
*/
static hid_t UD_plist_traverse(const char *link_name, hid_t cur_group,
const void *udata, size_t udata_size, hid_t lapl_id)
{
char * path;
hid_t ret_value = -1;
/* If the link property isn't set or can't be found, traversal fails. */
if(H5Pexist(lapl_id, PLIST_LINK_PROP) < 0)
goto error;
if(H5Pget(lapl_id, PLIST_LINK_PROP, &path) < 0)
goto error;
/* Open the object by address. If H5Oopen_by_addr fails, ret_value will
* be negative to indicate that the traversal function failed.
*/
ret_value = H5Oopen(cur_group, path, lapl_id);
return ret_value;
error:
return -1;
}
/* Main function
*
* Invokes the example functions.
*/
int
main(void)
{
printf("Testing basic external links.\n");
extlink_example();
printf("Testing external link prefixes.\n");
extlink_prefix_example();
printf("Testing user-defined soft links.\n");
soft_link_example();
printf("Testing user-defined hard links.\n");
hard_link_example();
printf("Testing user-defined property list links.\n");
plist_link_example();
return 0;
}
|