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
 int
 ss_blob_bound_f(ss_blob_t *blob,                /* Blob to query. */
                 hid_t *dset,                    /* OUT: Optional returned dataset handle. The handle is not duplicated and the
                                                  * caller should not close it. This is due to the fact that the handle
                                                  * duplication function (H5Dopen()) in HDF5 is file collective but this SSlib
                                                  * function is not. */
                 hsize_t *offsets,               /* OUT: Optional offset per dataset dimension for the starting position of the
                                                  * data owned by this blob. The array should be large enough to hold SS_MAXDIMS
                                                  * offsets. */
                 hsize_t *sizes,                 /* OUT: Optional size per dataset dimension for the portion of data owned by this
                                                  * blob. The array should be large enough to hold SS_MAXDIMS offsets. */
                 hid_t *fspace,                  /* OUT: Optional data space to be returned. This is the data space of the
                                                  * underlying dataset with a selection representing the blob's portion of that
                                                  * data space.  The caller should close this data space when no longer needed. */
                 hid_t *ftype                    /* OUT: Optional file datatype to be returned. The caller should close this
                                                  * datatype handle when no longer needed. */
                 )
 {
     SS_ENTER(ss_blob_bound_f, int);
     ss_gblob_t  *gblob=NULL;                    /* The gblob table associated with the file owning BLOB */
     size_t      d_idx=SS_NOSIZE;                /* An index into the gblob->d table */
     hid_t       fspace_duped=-1;                /* Duplicated data space to be closed on error */
     hid_t       ftype_duped=-1;                 /* Duplicated datatype to be closed on error */
     int         ndims=0;                        /* Number of dimensions; dimension counter; return value */
     int         i;

     SS_ASSERT_MEM(blob, ss_blob_t);
     if (!SS_BLOB(blob)->dsetaddr) SS_ERROR_FMT(USAGE, ("blob is not bound to a dataset"));
     if (SS_NOSIZE==(d_idx=ss_blob_didx(blob))) SS_ERROR(FAILED);
     gblob = SS_GFILE_LINK(blob)->gblob;
     SS_ASSERT(gblob);
     SS_ASSERT(SS_BLOB(blob)->dsetaddr==*((haddr_t*)&(gblob->d[d_idx].stat.objno)[0]));

     /* Dataset */
     if (dset) *dset = gblob->d[d_idx].dset;

     /* Offsets and/or sizes and the return value */
     if ((ndims=H5Sget_simple_extent_ndims(gblob->d[d_idx].dspace))<0) SS_ERROR(HDF5);
     for (i=0; i<ndims; i++) {
         if (offsets) offsets[i] = SS_BLOB(blob)->start[i];
         if (sizes) sizes[i] = SS_BLOB(blob)->count[i];
     }

     /* Data space and selection */
     if (fspace) {
         if ((*fspace = fspace_duped = H5Scopy(gblob->d[d_idx].dspace))<0) SS_ERROR(HDF5);
         if (H5Sselect_slab(*fspace, H5S_SELECT_SET, (hsize_t)0, SS_BLOB(blob)->start, SS_BLOB(blob)->count)<0)
             SS_ERROR(HDF5);
     }

     /* Datatype */
     if (ftype && (*ftype = ftype_duped = H5Tcopy(gblob->d[d_idx].dtype))<0) SS_ERROR(HDF5);

  SS_CLEANUP:
     if (fspace_duped>0) H5Sclose(fspace_duped);
     if (ftype_duped>0) H5Tclose(ftype_duped);
     SS_LEAVE(ndims);
 }