Пример #1
0
/*-------------------------------------------------------------------------
 * Function:    H5O_ainfo_decode
 *
 * Purpose:     Decode a message and return a pointer to a newly allocated one.
 *
 * Return:      Success:        Ptr to new message in native form.
 *              Failure:        NULL
 *
 * Programmer:  Quincey Koziol
 *              [email protected]
 *              Mar  6 2007
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_ainfo_decode(H5F_t *f, hid_t H5_ATTR_UNUSED dxpl_id, H5O_t H5_ATTR_UNUSED *open_oh,
    unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, const uint8_t *p)
{
    H5O_ainfo_t	*ainfo = NULL;  /* Attribute info */
    unsigned char flags;        /* Flags for encoding attribute info */
    void *ret_value = NULL;     /* Return value */

    FUNC_ENTER_NOAPI_NOINIT

    /* check args */
    HDassert(f);
    HDassert(p);

    /* Version of message */
    if(*p++ != H5O_AINFO_VERSION)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message")

    /* Allocate space for message */
    if(NULL == (ainfo = H5FL_MALLOC(H5O_ainfo_t)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    /* Get the flags for the message */
    flags = *p++;
    if(flags & ~H5O_AINFO_ALL_FLAGS)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad flag value for message")
    ainfo->track_corder = (flags & H5O_AINFO_TRACK_CORDER) ? TRUE : FALSE;
    ainfo->index_corder = (flags & H5O_AINFO_INDEX_CORDER) ? TRUE : FALSE;

    /* Set the number of attributes on the object to an invalid value, so we query it later */
    ainfo->nattrs = HSIZET_MAX;

    /* Max. creation order value for the object */
    if(ainfo->track_corder)
        UINT16DECODE(p, ainfo->max_crt_idx)
    else
        ainfo->max_crt_idx = H5O_MAX_CRT_ORDER_IDX;

    /* Address of fractal heap to store "dense" attributes */
    H5F_addr_decode(f, &p, &(ainfo->fheap_addr));

    /* Address of v2 B-tree to index names of attributes (names are always indexed) */
    H5F_addr_decode(f, &p, &(ainfo->name_bt2_addr));

    /* Address of v2 B-tree to index creation order of links, if there is one */
    if(ainfo->index_corder)
        H5F_addr_decode(f, &p, &(ainfo->corder_bt2_addr));
    else
        ainfo->corder_bt2_addr = HADDR_UNDEF;

    /* Set return value */
    ret_value = ainfo;

done:
    if(ret_value == NULL && ainfo != NULL)
        ainfo = H5FL_FREE(H5O_ainfo_t, ainfo);

    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_ainfo_decode() */
/*-------------------------------------------------------------------------
 * Function:	H5O_shmesg_decode
 *
 * Purpose:	Decode a shared message table message and return a pointer
 *              to a newly allocated H5O_shmesg_table_t struct.
 *
 * Return:	Success:	Ptr to new message in native struct.
 *		Failure:	NULL
 *
 * Programmer:  James Laird
 *              Jan 29, 2007
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_shmesg_decode(H5F_t *f, hid_t H5_ATTR_UNUSED dxpl_id, H5O_t H5_ATTR_UNUSED *open_oh,
    unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, const uint8_t *p)
{
    H5O_shmesg_table_t	*mesg;          /* Native message */
    void                *ret_value;     /* Return value */

    FUNC_ENTER_NOAPI_NOINIT

    /* Sanity check */
    HDassert(f);
    HDassert(p);

    if(NULL == (mesg = (H5O_shmesg_table_t *)H5MM_calloc(sizeof(H5O_shmesg_table_t))))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for shared message table message")

    /* Retrieve version, table address, and number of indexes */
    mesg->version = *p++;
    H5F_addr_decode(f, &p, &(mesg->addr));
    mesg->nindexes = *p++;

    /* Set return value */
    ret_value = (void *)mesg;

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_shmesg_decode() */
Пример #3
0
/*-------------------------------------------------------------------------
 * Function:    H5O_layout_decode
 *
 * Purpose:     Decode an data layout message and return a pointer to a
 *              new one created with malloc().
 *
 * Return:      Success:        Ptr to new message in native order.
 *
 *              Failure:        NULL
 *
 * Programmer:  Robb Matzke
 *              Wednesday, October  8, 1997
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
    unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
    H5O_layout_t           *mesg = NULL;
    unsigned               u;
    void                   *ret_value;          /* Return value */

    FUNC_ENTER_NOAPI_NOINIT(H5O_layout_decode)

    /* check args */
    HDassert(f);
    HDassert(p);

    /* decode */
    if(NULL == (mesg = H5FL_CALLOC(H5O_layout_t)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    mesg->version = *p++;
    if(mesg->version < H5O_LAYOUT_VERSION_1 || mesg->version > H5O_LAYOUT_VERSION_3)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for layout message")

    if(mesg->version < H5O_LAYOUT_VERSION_3) {
        unsigned	ndims;			/* Num dimensions in chunk           */

        /* Dimensionality */
        ndims = *p++;
        if(ndims > H5O_LAYOUT_NDIMS)
            HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "dimensionality is too large")

        /* Layout class */
        mesg->type = (H5D_layout_t)*p++;
        assert(H5D_CONTIGUOUS == mesg->type || H5D_CHUNKED == mesg->type || H5D_COMPACT == mesg->type);

        /* Reserved bytes */
        p += 5;

        /* Address */
        if(mesg->type == H5D_CONTIGUOUS) {
            H5F_addr_decode(f, &p, &(mesg->storage.u.contig.addr));

            /* Set the layout operations */
            mesg->ops = H5D_LOPS_CONTIG;
        } /* end if */
        else if(mesg->type == H5D_CHUNKED) {
            H5F_addr_decode(f, &p, &(mesg->storage.u.chunk.idx_addr));

            /* Set the layout operations */
            mesg->ops = H5D_LOPS_CHUNK;

            /* Set the chunk operations */
            /* (Only "btree" indexing type currently supported in this version) */
            mesg->storage.u.chunk.idx_type = H5D_CHUNK_BTREE;
            mesg->storage.u.chunk.ops = H5D_COPS_BTREE;
        } /* end if */
        else {
            /* Sanity check */
            HDassert(mesg->type == H5D_COMPACT);

            /* Set the layout operations */
            mesg->ops = H5D_LOPS_COMPACT;
        } /* end else */

        /* Read the size */
        if(mesg->type != H5D_CHUNKED) {
            /* Don't compute size of contiguous storage here, due to possible
             * truncation of the dimension sizes when they were stored in this
             * version of the layout message.  Compute the contiguous storage
             * size in the dataset code, where we've got the dataspace
             * information available also.  - QAK 5/26/04
             */
            p += ndims * 4;     /* Skip over dimension sizes (32-bit quantities) */
        } /* end if */
        else {
            mesg->u.chunk.ndims=ndims;
            for(u = 0; u < ndims; u++)
                UINT32DECODE(p, mesg->u.chunk.dim[u]);

            /* Compute chunk size */
            for(u = 1, mesg->u.chunk.size = mesg->u.chunk.dim[0]; u < ndims; u++)
                mesg->u.chunk.size *= mesg->u.chunk.dim[u];
        } /* end if */

        if(mesg->type == H5D_COMPACT) {
            UINT32DECODE(p, mesg->storage.u.compact.size);
            if(mesg->storage.u.compact.size > 0) {
                if(NULL == (mesg->storage.u.compact.buf = H5MM_malloc(mesg->storage.u.compact.size)))
                    HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for compact data buffer")
                HDmemcpy(mesg->storage.u.compact.buf, p, mesg->storage.u.compact.size);
                p += mesg->storage.u.compact.size;
            } /* end if */
        } /* end if */
    } /* end if */
    else {
        /* Layout class */
        mesg->type = (H5D_layout_t)*p++;

        /* Interpret the rest of the message according to the layout class */
        switch(mesg->type) {
            case H5D_COMPACT:
                UINT16DECODE(p, mesg->storage.u.compact.size);
                if(mesg->storage.u.compact.size > 0) {
                    if(NULL == (mesg->storage.u.compact.buf = H5MM_malloc(mesg->storage.u.compact.size)))
                        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for compact data buffer")
                    HDmemcpy(mesg->storage.u.compact.buf, p, mesg->storage.u.compact.size);
                    p += mesg->storage.u.compact.size;
                } /* end if */

                /* Set the layout operations */
                mesg->ops = H5D_LOPS_COMPACT;
                break;

            case H5D_CONTIGUOUS:
                H5F_addr_decode(f, &p, &(mesg->storage.u.contig.addr));
                H5F_DECODE_LENGTH(f, p, mesg->storage.u.contig.size);

                /* Set the layout operations */
                mesg->ops = H5D_LOPS_CONTIG;
                break;

            case H5D_CHUNKED:
                /* Dimensionality */
                mesg->u.chunk.ndims = *p++;
                if(mesg->u.chunk.ndims > H5O_LAYOUT_NDIMS)
                    HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "dimensionality is too large")

                /* B-tree address */
                H5F_addr_decode(f, &p, &(mesg->storage.u.chunk.idx_addr));

                /* Chunk dimensions */
                for(u = 0; u < mesg->u.chunk.ndims; u++)
                    UINT32DECODE(p, mesg->u.chunk.dim[u]);

                /* Compute chunk size */
                for(u = 1, mesg->u.chunk.size = mesg->u.chunk.dim[0]; u < mesg->u.chunk.ndims; u++)
                    mesg->u.chunk.size *= mesg->u.chunk.dim[u];

                /* Set the chunk operations */
                /* (Only "btree" indexing type supported with v3 of message format) */
                mesg->storage.u.chunk.idx_type = H5D_CHUNK_BTREE;
                mesg->storage.u.chunk.ops = H5D_COPS_BTREE;

                /* Set the layout operations */
                mesg->ops = H5D_LOPS_CHUNK;
                break;

            default:
                HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "Invalid layout class")
        } /* end switch */
    } /* end else */

    /* Set return value */
    ret_value = mesg;

done:
    if(ret_value == NULL)
        if(mesg)
            mesg = H5FL_FREE(H5O_layout_t, mesg);

    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_layout_decode() */
Пример #4
0
/*-------------------------------------------------------------------------
 * Function:	H5O_efl_decode
 *
 * Purpose:	Decode an external file list message and return a pointer to
 *		the message (and some other data).
 *
 * Return:	Success:	Ptr to a new message struct.
 *
 *		Failure:	NULL
 *
 * Programmer:	Robb Matzke
 *		Tuesday, November 25, 1997
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_efl_decode(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh,
    unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
    H5O_efl_t		*mesg = NULL;
    int			version;
    const char		*s = NULL;
    H5HL_t              *heap;
    size_t		u;      /* Local index variable */
    void *ret_value;            /* Return value */

    FUNC_ENTER_NOAPI_NOINIT(H5O_efl_decode)

    /* Check args */
    HDassert(f);
    HDassert(p);

    if(NULL == (mesg = (H5O_efl_t *)H5MM_calloc(sizeof(H5O_efl_t))))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    /* Version */
    version = *p++;
    if(version != H5O_EFL_VERSION)
	HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for external file list message")

    /* Reserved */
    p += 3;

    /* Number of slots */
    UINT16DECODE(p, mesg->nalloc);
    assert(mesg->nalloc>0);
    UINT16DECODE(p, mesg->nused);
    assert(mesg->nused <= mesg->nalloc);

    /* Heap address */
    H5F_addr_decode(f, &p, &(mesg->heap_addr));

#ifndef NDEBUG
    HDassert(H5F_addr_defined(mesg->heap_addr));

    if(NULL == (heap = H5HL_protect(f, dxpl_id, mesg->heap_addr, H5AC_READ)))
        HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read protect link value")

    s = (const char *)H5HL_offset_into(f, heap, 0);

    HDassert(s && !*s);

    if(H5HL_unprotect(f, dxpl_id, heap, mesg->heap_addr) < 0)
        HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read unprotect link value")
    heap = NULL;
#endif

    /* Decode the file list */
    mesg->slot = (H5O_efl_entry_t *)H5MM_calloc(mesg->nalloc * sizeof(H5O_efl_entry_t));
    if(NULL == mesg->slot)
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    if(NULL == (heap = H5HL_protect(f, dxpl_id, mesg->heap_addr, H5AC_READ)))
        HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read protect link value")
    for(u = 0; u < mesg->nused; u++) {
	/* Name */
	H5F_DECODE_LENGTH (f, p, mesg->slot[u].name_offset);

        s = (const char *)H5HL_offset_into(f, heap, mesg->slot[u].name_offset);
	HDassert(s && *s);
	mesg->slot[u].name = H5MM_xstrdup (s);
        HDassert(mesg->slot[u].name);

	/* File offset */
	H5F_DECODE_LENGTH (f, p, mesg->slot[u].offset);

	/* Size */
	H5F_DECODE_LENGTH (f, p, mesg->slot[u].size);
	HDassert(mesg->slot[u].size > 0);
    } /* end for */

    if(H5HL_unprotect(f, dxpl_id, heap, mesg->heap_addr) < 0)
        HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read unprotect link value")
    heap = NULL;

    /* Set return value */
    ret_value = mesg;

done:
    if(ret_value == NULL)
        if(mesg != NULL)
            H5MM_xfree(mesg);

    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_efl_decode() */
Пример #5
0
/*--------------------------------------------------------------------------
 NAME
    H5R__dereference
 PURPOSE
    Opens the HDF5 object referenced.
 USAGE
    hid_t H5R__dereference(ref, oapl_id, ref_type, ref)
        H5F_t *file;        IN: File the object being dereferenced is within
        hid_t oapl_id;      IN: Object access property list ID
        H5R_type_t ref_type; IN: Type of reference
        void *ref;          IN: Reference to open.

 RETURNS
    Valid ID on success, Negative on failure
 DESCRIPTION
    Given a reference to some object, open that object and return an ID for
    that object.
 GLOBAL VARIABLES
 COMMENTS, BUGS, ASSUMPTIONS
    Currently only set up to work with references to datasets
 EXAMPLES
 REVISION LOG
    Raymond Lu
    13 July 2011
    I added the OAPL_ID parameter for the object being referenced.  It only
    supports dataset access property list currently.

    M. Scot Breitenfeld
    3 March 2015
    Added a check for undefined reference pointer.
--------------------------------------------------------------------------*/
hid_t
H5R__dereference(H5F_t *file, hid_t oapl_id, H5R_type_t ref_type,
    const void *_ref)
{
    H5O_loc_t oloc;             /* Object location */
    H5G_name_t path;            /* Path of object */
    H5G_loc_t loc;              /* Group location */
    unsigned rc;		/* Reference count of object */
    H5O_type_t obj_type;        /* Type of object */
    hid_t ret_value = H5I_INVALID_HID;  /* Return value */

    FUNC_ENTER_PACKAGE_VOL

    HDassert(_ref);
    HDassert(ref_type > H5R_BADTYPE && ref_type < H5R_MAXTYPE);
    HDassert(file);

    /* Initialize the object location */
    H5O_loc_reset(&oloc);
    oloc.file = file;

    switch (ref_type) {
        case H5R_OBJECT:
        {
            oloc.addr = *(const hobj_ref_t *)_ref; /* Only object references currently supported */
            if (!H5F_addr_defined(oloc.addr) || oloc.addr == 0)
                HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "Undefined reference pointer")
            break;
        }

        case H5R_DATASET_REGION:
        {
            H5HG_t hobjid;  /* Heap object ID */
            uint8_t *buf;   /* Buffer to store serialized selection in */
            const uint8_t *p;           /* Pointer to OID to store */

            /* Get the heap ID for the dataset region */
            p = (const uint8_t *)_ref;
            H5F_addr_decode(oloc.file, &p, &(hobjid.addr));
            UINT32DECODE(p, hobjid.idx);

            if (!H5F_addr_defined(hobjid.addr) || hobjid.addr == 0)
                HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "Undefined reference pointer")

            /* Get the dataset region from the heap (allocate inside routine) */
            if(NULL == (buf = (uint8_t *)H5HG_read(oloc.file, &hobjid, NULL, NULL)))
                HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, H5I_INVALID_HID, "Unable to read dataset region information")

            /* Get the object oid for the dataset */
            p = buf;
            H5F_addr_decode(oloc.file, &p, &(oloc.addr));

            /* Free the buffer allocated in H5HG_read() */
            H5MM_xfree(buf);
            break;
        } /* end case H5R_DATASET_REGION */

        case H5R_BADTYPE:
        case H5R_MAXTYPE:
        default:
            HDassert("unknown reference type" && 0);
            HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, H5I_INVALID_HID, "internal error (unknown reference type)")
    } /* end switch */

    /* Get the # of links for object, and its type
     * (To check to make certain that this object hasn't been deleted
     *  since the reference was created)
     */
    if(H5O_get_rc_and_type(&oloc, &rc, &obj_type) < 0 || 0 == rc)
        HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, H5I_INVALID_HID, "dereferencing deleted object")

    /* Construct a group location for opening the object */
    H5G_name_reset(&path);
    loc.oloc = &oloc;
    loc.path = &path;

    /* Open the object */
    switch (obj_type) {
        case H5O_TYPE_GROUP:
        {
            H5G_t *group;               /* Pointer to group to open */

            if(NULL == (group = H5G_open(&loc)))
                HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5I_INVALID_HID, "not found")

            /* Create an atom for the group */
            if((ret_value = H5I_register(H5I_GROUP, group, TRUE)) < 0) {
                H5G_close(group);
                HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register group")
            } /* end if */

            break;
        }

        case H5O_TYPE_NAMED_DATATYPE:
        {
            H5T_t *type;                /* Pointer to datatype to open */

            if(NULL == (type = H5T_open(&loc)))
                HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, H5I_INVALID_HID, "not found")

            /* Create an atom for the datatype */
            if((ret_value = H5I_register(H5I_DATATYPE, type, TRUE)) < 0) {
                H5T_close(type);
                HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register datatype")
            } /* end if */

            break;
        }
Пример #6
0
/*-------------------------------------------------------------------------
 * Function:    H5F_sblock_load
 *
 * Purpose:     Loads the superblock from the file, and deserializes
 *              its information into the H5F_super_t structure.
 *
 * Return:      Success:        SUCCEED
 *              Failure:        NULL
 *
 * Programmer:  Mike McGreevy
 *              [email protected]
 *              April 8, 2009
 *
 *-------------------------------------------------------------------------
 */
static H5F_super_t *
H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, void *_udata)
{
    H5F_super_t        *sblock = NULL;      /* File's superblock */
    haddr_t             base_addr = HADDR_UNDEF;        /* Base address of file */
    uint8_t             sbuf[H5F_MAX_SUPERBLOCK_SIZE];     /* Buffer for superblock */
    H5P_genplist_t     *dxpl;               /* DXPL object */
    H5P_genplist_t     *c_plist;            /* File creation property list  */
    H5F_file_t         *shared;             /* shared part of `file'        */
    H5FD_t             *lf;                 /* file driver part of `shared' */
    haddr_t             stored_eoa;         /*relative end-of-addr in file  */
    haddr_t             eof;                /*end of file address           */
    uint8_t             sizeof_addr;        /* Size of offsets in the file (in bytes) */
    uint8_t             sizeof_size;        /* Size of lengths in the file (in bytes) */
    const size_t        fixed_size = H5F_SUPERBLOCK_FIXED_SIZE; /*fixed sizeof superblock   */
    size_t              variable_size;      /*variable sizeof superblock    */
    uint8_t            *p;                  /* Temporary pointer into encoding buffer */
    unsigned            super_vers;         /* Superblock version          */
    hbool_t            *dirtied = (hbool_t *)_udata;  /* Set up dirtied out value */
    H5F_super_t        *ret_value;          /* Return value */

    FUNC_ENTER_NOAPI_NOINIT

    /* check arguments */
    HDassert(f);
    HDassert(H5F_addr_eq(addr, 0));
    HDassert(dirtied);

    /* Short cuts */
    shared = f->shared;
    lf = shared->lf;

    /* Get the shared file creation property list */
    if(NULL == (c_plist = (H5P_genplist_t *)H5I_object(shared->fcpl_id)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get property list")

    /* Get the base address for the file in the VFD */
    if(HADDR_UNDEF == (base_addr = H5FD_get_base_addr(lf)))
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "failed to get base address for file driver")

    /* Allocate space for the superblock */
    if(NULL == (sblock = H5FL_CALLOC(H5F_super_t)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    /* Get the DXPL plist object for DXPL ID */
    if(NULL == (dxpl = (H5P_genplist_t *)H5I_object(dxpl_id)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get property list")

    /* Read fixed-size portion of the superblock */
    p = sbuf;
    H5_CHECK_OVERFLOW(fixed_size, size_t, haddr_t);
    if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, (haddr_t)fixed_size) < 0)
        HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed")
    if(H5FD_read(lf, dxpl, H5FD_MEM_SUPER, (haddr_t)0, fixed_size, p) < 0)
        HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock")

    /* Skip over signature (already checked when locating the superblock) */
    p += H5F_SIGNATURE_LEN;

    /* Superblock version */
    super_vers = *p++;
    if(super_vers > HDF5_SUPERBLOCK_VERSION_LATEST)
        HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad superblock version number")
    if(H5P_set(c_plist, H5F_CRT_SUPER_VERS_NAME, &super_vers) < 0)
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set superblock version")

    /* Record the superblock version */
    sblock->super_vers = super_vers;

    /* Sanity check */
    HDassert(((size_t)(p - sbuf)) == fixed_size);

    /* Determine the size of the variable-length part of the superblock */
    variable_size = (size_t)H5F_SUPERBLOCK_VARLEN_SIZE(super_vers, f);
    HDassert(variable_size > 0);
    HDassert(fixed_size + variable_size <= sizeof(sbuf));

    /* Read in variable-sized portion of superblock */
    if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, (haddr_t)(fixed_size + variable_size)) < 0)
        HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed")
    if(H5FD_read(lf, dxpl, H5FD_MEM_SUPER, (haddr_t)fixed_size, variable_size, p) < 0)
        HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read superblock")

    /* Check for older version of superblock format */
    if(super_vers < HDF5_SUPERBLOCK_VERSION_2) {
        uint32_t	status_flags;	    /* File status flags	   */
        unsigned        btree_k[H5B_NUM_BTREE_ID];  /* B-tree internal node 'K' values */
        unsigned        sym_leaf_k;         /* Symbol table leaf node's 'K' value */

        /* Freespace version (hard-wired) */
        if(HDF5_FREESPACE_VERSION != *p++)
            HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad free space version number")

        /* Root group version number (hard-wired) */
        if(HDF5_OBJECTDIR_VERSION != *p++)
            HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad object directory version number")

        /* Skip over reserved byte */
        p++;

        /* Shared header version number (hard-wired) */
        if(HDF5_SHAREDHEADER_VERSION != *p++)
            HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad shared-header format version number")

        /* Size of file addresses */
        sizeof_addr = *p++;
        if(sizeof_addr != 2 && sizeof_addr != 4 &&
                sizeof_addr != 8 && sizeof_addr != 16 && sizeof_addr != 32)
            HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number in an address")
        if(H5P_set(c_plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &sizeof_addr) < 0)
            HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set byte number in an address")
        shared->sizeof_addr = sizeof_addr;  /* Keep a local copy also */

        /* Size of file sizes */
        sizeof_size = *p++;
        if(sizeof_size != 2 && sizeof_size != 4 &&
                sizeof_size != 8 && sizeof_size != 16 && sizeof_size != 32)
            HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number for object size")
        if(H5P_set(c_plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &sizeof_size) < 0)
            HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set byte number for object size")
        shared->sizeof_size = sizeof_size;  /* Keep a local copy also */

        /* Skip over reserved byte */
        p++;

        /* Various B-tree sizes */
        UINT16DECODE(p, sym_leaf_k);
        if(sym_leaf_k == 0)
            HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, NULL, "bad symbol table leaf node 1/2 rank")
        if(H5P_set(c_plist, H5F_CRT_SYM_LEAF_NAME, &sym_leaf_k) < 0)
            HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set rank for symbol table leaf nodes")
        sblock->sym_leaf_k = sym_leaf_k;    /* Keep a local copy also */

        /* Need 'get' call to set other array values */
        if(H5P_get(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0)
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "unable to get rank for btree internal nodes")
        UINT16DECODE(p, btree_k[H5B_SNODE_ID]);
        if(btree_k[H5B_SNODE_ID] == 0)
            HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, NULL, "bad 1/2 rank for btree internal nodes")
        /*
         * Delay setting the value in the property list until we've checked
         * for the indexed storage B-tree internal 'K' value later.
         */

        /* File status flags (not really used yet) */
        UINT32DECODE(p, status_flags);
        HDassert(status_flags <= 255);
        sblock->status_flags = (uint8_t)status_flags;
        if(sblock->status_flags & ~H5F_SUPER_ALL_FLAGS)
            HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad flag value for superblock")

        /*
         * If the superblock version # is greater than 0, read in the indexed
         * storage B-tree internal 'K' value
         */
        if(super_vers > HDF5_SUPERBLOCK_VERSION_DEF) {
            UINT16DECODE(p, btree_k[H5B_CHUNK_ID]);
            /* Reserved bytes are present only in version 1 */
            if(super_vers == HDF5_SUPERBLOCK_VERSION_1)
                p += 2;   /* reserved */
        } /* end if */
        else
            btree_k[H5B_CHUNK_ID] = HDF5_BTREE_CHUNK_IK_DEF;

        /* Set the B-tree internal node values, etc */
        if(H5P_set(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0)
            HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set rank for btree internal nodes")
        HDmemcpy(sblock->btree_k, btree_k, sizeof(unsigned) * (size_t)H5B_NUM_BTREE_ID);    /* Keep a local copy also */

        /* Remainder of "variable-sized" portion of superblock */
        H5F_addr_decode(f, (const uint8_t **)&p, &sblock->base_addr/*out*/);
        H5F_addr_decode(f, (const uint8_t **)&p, &sblock->ext_addr/*out*/);
        H5F_addr_decode(f, (const uint8_t **)&p, &stored_eoa/*out*/);
        H5F_addr_decode(f, (const uint8_t **)&p, &sblock->driver_addr/*out*/);

        /* Allocate space for the root group symbol table entry */
        HDassert(!sblock->root_ent);
        if(NULL == (sblock->root_ent = (H5G_entry_t *)H5MM_calloc(sizeof(H5G_entry_t))))
            HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't allocate space for root group symbol table entry")

        /* decode the root group symbol table entry */
        if(H5G_ent_decode(f, (const uint8_t **)&p, sblock->root_ent) < 0)
            HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, NULL, "can't decode root group symbol table entry")

        /* Set the root group address to the correct value */
        sblock->root_addr = sblock->root_ent->header;

        /*
         * Check if superblock address is different from base address and
         * adjust base address and "end of address" address if so.
         */
        if(!H5F_addr_eq(base_addr, sblock->base_addr)) {
            /* Check if the superblock moved earlier in the file */
            if(H5F_addr_lt(base_addr, sblock->base_addr))
                stored_eoa -= (sblock->base_addr - base_addr);
            else
                /* The superblock moved later in the file */
                stored_eoa += (base_addr - sblock->base_addr);

            /* Adjust base address for offsets of the HDF5 data in the file */
            sblock->base_addr = base_addr;

            /* Set the base address for the file in the VFD now */
            if(H5FD_set_base_addr(lf, sblock->base_addr) < 0)
                HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "failed to set base address for file driver")

            /* Indicate that the superblock should be marked dirty */
            *dirtied = TRUE;
        } /* end if */

        /* This step is for h5repart tool only. If user wants to change file driver
         *  from family to sec2 while using h5repart, set the driver address to
         *  undefined to let the library ignore the family driver information saved
         *  in the superblock.
         */
        if(H5F_HAS_FEATURE(f, H5FD_FEAT_IGNORE_DRVRINFO)) {
            /* Eliminate the driver info */
            sblock->driver_addr = HADDR_UNDEF;

            /* Indicate that the superblock should be marked dirty */
            *dirtied = TRUE;
        } /* end if */

        /* Decode the optional driver information block */
        if(H5F_addr_defined(sblock->driver_addr)) {
            uint8_t dbuf[H5F_MAX_DRVINFOBLOCK_SIZE];     /* Buffer for driver info block */
            char drv_name[9];       /* Name of driver */
            unsigned drv_vers;      /* Version of driver info block */
            size_t drv_variable_size; /* Size of variable-length portion of driver info block, in bytes */

            /* Read in fixed-sized portion of driver info block */
            p = dbuf;
            if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, sblock->driver_addr + H5F_DRVINFOBLOCK_HDR_SIZE) < 0)
                HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed")
            if(H5FD_read(lf, dxpl, H5FD_MEM_SUPER, sblock->driver_addr, (size_t)H5F_DRVINFOBLOCK_HDR_SIZE, p) < 0)
                HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read driver information block")

            /* Version number */
            drv_vers = *p++;
            if(drv_vers != HDF5_DRIVERINFO_VERSION_0)
                HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "bad driver information block version number")

            p += 3; /* reserved bytes */

            /* Driver info size */
            UINT32DECODE(p, drv_variable_size);

            /* Sanity check */
            HDassert(H5F_DRVINFOBLOCK_HDR_SIZE + drv_variable_size <= sizeof(dbuf));

            /* Driver name and/or version */
            HDstrncpy(drv_name, (const char *)p, (size_t)8);
            drv_name[8] = '\0';
            p += 8; /* advance past name/version */

            /* Check if driver matches driver information saved. Unfortunately, we can't push this
             * function to each specific driver because we're checking if the driver is correct.
             */
            if(!HDstrncmp(drv_name, "NCSAfami", (size_t)8) && HDstrcmp(lf->cls->name, "family"))
                HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "family driver should be used")
            if(!HDstrncmp(drv_name, "NCSAmult", (size_t)8) && HDstrcmp(lf->cls->name, "multi"))
                HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "multi driver should be used")

            /* Read in variable-sized portion of driver info block */
            if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, sblock->driver_addr + H5F_DRVINFOBLOCK_HDR_SIZE + drv_variable_size) < 0)
                HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed")
            if(H5FD_read(lf, dxpl, H5FD_MEM_SUPER, sblock->driver_addr + H5F_DRVINFOBLOCK_HDR_SIZE, drv_variable_size, p) < 0)
                HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read file driver information")

            /* Decode driver information */
            if(H5FD_sb_decode(lf, drv_name, p) < 0)
                HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to decode driver information")
        } /* end if */
Пример #7
0
/*-------------------------------------------------------------------------
 * Function:    H5O_layout_decode
 *
 * Purpose:     Decode an data layout message and return a pointer to a
 *              new one created with malloc().
 *
 * Return:      Success:        Ptr to new message in native order.
 *
 *              Failure:        NULL
 *
 * Programmer:  Robb Matzke
 *              Wednesday, October  8, 1997
 *
 * Modifications:
 * 	Robb Matzke, 1998-07-20
 *	Rearranged the message to add a version number at the beginning.
 *
 *      Raymond Lu, 2002-2-26
 *      Added version number 2 case depends on if space has been allocated
 *      at the moment when layout header message is updated.
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p)
{
    H5O_layout_t           *mesg = NULL;
    unsigned               u;
    void                   *ret_value;          /* Return value */

    FUNC_ENTER_NOAPI_NOINIT(H5O_layout_decode);

    /* check args */
    assert(f);
    assert(p);

    /* decode */
    if (NULL==(mesg = H5FL_CALLOC(H5O_layout_t)))
        HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");

    /* Version. 1 when space allocated; 2 when space allocation is delayed */
    mesg->version = *p++;
    if (mesg->version<H5O_LAYOUT_VERSION_1 || mesg->version>H5O_LAYOUT_VERSION_3)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for layout message");

    if(mesg->version < H5O_LAYOUT_VERSION_3) {
        unsigned	ndims;			/* Num dimensions in chunk           */

        /* Dimensionality */
        ndims = *p++;
        if (ndims>H5O_LAYOUT_NDIMS)
            HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "dimensionality is too large");

        /* Layout class */
        mesg->type = (H5D_layout_t)*p++;
        assert(H5D_CONTIGUOUS == mesg->type || H5D_CHUNKED == mesg->type || H5D_COMPACT == mesg->type);

        /* Reserved bytes */
        p += 5;

        /* Address */
        if(mesg->type==H5D_CONTIGUOUS)
            H5F_addr_decode(f, &p, &(mesg->u.contig.addr));
        else if(mesg->type==H5D_CHUNKED)
            H5F_addr_decode(f, &p, &(mesg->u.chunk.addr));

        /* Read the size */
        if(mesg->type!=H5D_CHUNKED) {
	    mesg->unused.ndims=ndims;

            for (u = 0; u < ndims; u++)
                UINT32DECODE(p, mesg->unused.dim[u]);

            /* Don't compute size of contiguous storage here, due to possible
             * truncation of the dimension sizes when they were stored in this
             * version of the layout message.  Compute the contiguous storage
             * size in the dataset code, where we've got the dataspace
             * information available also.  - QAK 5/26/04
             */
        } /* end if */
        else {
            mesg->u.chunk.ndims=ndims;
            for (u = 0; u < ndims; u++)
                UINT32DECODE(p, mesg->u.chunk.dim[u]);

            /* Compute chunk size */
            for (u=1, mesg->u.chunk.size=mesg->u.chunk.dim[0]; u<ndims; u++)
                mesg->u.chunk.size *= mesg->u.chunk.dim[u];
        } /* end if */

        if(mesg->type == H5D_COMPACT) {
            UINT32DECODE(p, mesg->u.compact.size);
            if(mesg->u.compact.size > 0) {
                if(NULL==(mesg->u.compact.buf=H5MM_malloc(mesg->u.compact.size)))
                    HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for compact data buffer");
                HDmemcpy(mesg->u.compact.buf, p, mesg->u.compact.size);
                p += mesg->u.compact.size;
            }
        }
    } /* end if */
    else {
        /* Layout class */
        mesg->type = (H5D_layout_t)*p++;

        /* Interpret the rest of the message according to the layout class */
        switch(mesg->type) {
            case H5D_CONTIGUOUS:
                H5F_addr_decode(f, &p, &(mesg->u.contig.addr));
                H5F_DECODE_LENGTH(f, p, mesg->u.contig.size);
                break;

            case H5D_CHUNKED:
                /* Dimensionality */
                mesg->u.chunk.ndims = *p++;
                if (mesg->u.chunk.ndims>H5O_LAYOUT_NDIMS)
                    HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "dimensionality is too large");

                /* B-tree address */
                H5F_addr_decode(f, &p, &(mesg->u.chunk.addr));

                /* Chunk dimensions */
                for (u = 0; u < mesg->u.chunk.ndims; u++)
                    UINT32DECODE(p, mesg->u.chunk.dim[u]);

                /* Compute chunk size */
                for (u=1, mesg->u.chunk.size=mesg->u.chunk.dim[0]; u<mesg->u.chunk.ndims; u++)
                    mesg->u.chunk.size *= mesg->u.chunk.dim[u];
                break;

            case H5D_COMPACT:
                UINT16DECODE(p, mesg->u.compact.size);
                if(mesg->u.compact.size > 0) {
                    if(NULL==(mesg->u.compact.buf=H5MM_malloc(mesg->u.compact.size)))
                        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for compact data buffer");
                    HDmemcpy(mesg->u.compact.buf, p, mesg->u.compact.size);
                    p += mesg->u.compact.size;
                } /* end if */
                break;

            default:
                HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "Invalid layout class");
        } /* end switch */
    } /* end else */

    /* Set return value */
    ret_value=mesg;

done:
    if(ret_value==NULL) {
        if(mesg)
            H5FL_FREE(H5O_layout_t,mesg);
    } /* end if */
    FUNC_LEAVE_NOAPI(ret_value);
}
Пример #8
0
/*-------------------------------------------------------------------------
 * Function:	H5F__cache_superblock_deserialize
 *
 * Purpose:	Loads an object from the disk.
 *
 * Return:	Success:	Pointer to new object
 *		Failure:	NULL
 *
 * Programmer:	Quincey Koziol
 *		[email protected]
 *		July 18 2013
 *
 *-------------------------------------------------------------------------
 */
static void *
H5F__cache_superblock_deserialize(const void *_image, size_t len, void *_udata,
    hbool_t H5_ATTR_UNUSED *dirty)
{
    H5F_super_t         *sblock = NULL; /* File's superblock */
    H5F_superblock_cache_ud_t *udata = (H5F_superblock_cache_ud_t *)_udata; /* User data */
    const uint8_t	*image = (const uint8_t *)_image;       /* Pointer into raw data buffer */
    size_t              variable_size;  /* Variable size of superblock */
    unsigned            super_vers;     /* Superblock version */
    uint8_t             sizeof_addr;    /* Size of offsets in the file (in bytes) */
    uint8_t             sizeof_size;    /* Size of lengths in the file (in bytes) */
    H5F_super_t         *ret_value = NULL;      /* Return value */

    FUNC_ENTER_STATIC

    /* Check arguments */
    HDassert(image);
    HDassert(udata);
    HDassert(udata->f);

    /* Allocate space for the superblock */
    if(NULL == (sblock = H5FL_CALLOC(H5F_super_t)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    image += H5F_SIGNATURE_LEN;

    /* Superblock version */
    super_vers = *image++;
    if(super_vers > HDF5_SUPERBLOCK_VERSION_LATEST)
        HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad superblock version number")

    /* Record the superblock version */
    sblock->super_vers = super_vers;

    /* Sanity check */
    HDassert(((size_t)(image - (const uint8_t *)_image)) == H5F_SUPERBLOCK_FIXED_SIZE);
    HDassert(len >= H5F_SUPERBLOCK_FIXED_SIZE + 6);

    /* Determine the size of addresses & size of offsets, for computing the
     * variable-sized portion of the superblock.
     */
    if(super_vers < HDF5_SUPERBLOCK_VERSION_2) {
        sizeof_addr = image[4];
        sizeof_size = image[5];
    } /* end if */
    else {
        sizeof_addr = image[0];
        sizeof_size = image[1];
    } /* end else */
    if(sizeof_addr != 2 && sizeof_addr != 4 &&
            sizeof_addr != 8 && sizeof_addr != 16 && sizeof_addr != 32)
        HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number in an address")
    if(sizeof_size != 2 && sizeof_size != 4 &&
            sizeof_size != 8 && sizeof_size != 16 && sizeof_size != 32)
        HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number for object size")
    sblock->sizeof_addr = sizeof_addr;
    sblock->sizeof_size = sizeof_size;

    /* Determine the size of the variable-length part of the superblock */
    variable_size = (size_t)H5F_SUPERBLOCK_VARLEN_SIZE(super_vers, sizeof_addr, sizeof_size);
    HDassert(variable_size > 0);

    HDassert(len == (H5F_SUPERBLOCK_FIXED_SIZE + variable_size));

    /* Check for older version of superblock format */
    if(super_vers < HDF5_SUPERBLOCK_VERSION_2) {
	uint32_t    status_flags;	    /* File status flags	   */
	unsigned    sym_leaf_k;         /* Symbol table leaf node's 'K' value */
	unsigned    snode_btree_k;      /* B-tree symbol table internal node 'K' value */
	unsigned    chunk_btree_k;      /* B-tree chunk internal node 'K' value */

	/* Freespace version (hard-wired) */
	if(HDF5_FREESPACE_VERSION != *image++)
	    HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad free space version number")

	/* Root group version number (hard-wired) */
	if(HDF5_OBJECTDIR_VERSION != *image++)
	    HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad object directory version number")

	/* Skip over reserved byte */
	image++;

	/* Shared header version number (hard-wired) */
	if(HDF5_SHAREDHEADER_VERSION != *image++)
	    HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad shared-header format version number")

	/* Size of file addresses */
	sizeof_addr = *image++;
	if(sizeof_addr != 2 && sizeof_addr != 4 &&
		sizeof_addr != 8 && sizeof_addr != 16 && sizeof_addr != 32)
	    HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number in an address")
	sblock->sizeof_addr = sizeof_addr;
	udata->f->shared->sizeof_addr = sizeof_addr;  /* Keep a local copy also */

	/* Size of file sizes */
	sizeof_size = *image++;
	if(sizeof_size != 2 && sizeof_size != 4 &&
		sizeof_size != 8 && sizeof_size != 16 && sizeof_size != 32)
	    HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number for object size")
	sblock->sizeof_size = sizeof_size;
	udata->f->shared->sizeof_size = sizeof_size;  /* Keep a local copy also */

	/* Skip over reserved byte */
	image++;

	/* Various B-tree sizes */
	UINT16DECODE(image, sym_leaf_k);
	if(sym_leaf_k == 0)
	    HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, NULL, "bad symbol table leaf node 1/2 rank")
        udata->sym_leaf_k = sym_leaf_k;    /* Keep a local copy also */

        /* Need 'get' call to set other array values */
        UINT16DECODE(image, snode_btree_k);
        if(snode_btree_k == 0)
	    HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, NULL, "bad 1/2 rank for btree internal nodes")
	udata->btree_k[H5B_SNODE_ID] = snode_btree_k;

	/*
         * Delay setting the value in the property list until we've checked
         * for the indexed storage B-tree internal 'K' value later.
         */

        /* File status flags (not really used yet) */
        UINT32DECODE(image, status_flags);
        HDassert(status_flags <= 255);
        sblock->status_flags = (uint8_t)status_flags;
        if(sblock->status_flags & ~H5F_SUPER_ALL_FLAGS)
	    HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad flag value for superblock")

	/*
         * If the superblock version # is greater than 0, read in the indexed
         * storage B-tree internal 'K' value
         */
        if(super_vers > HDF5_SUPERBLOCK_VERSION_DEF) {
	    UINT16DECODE(image, chunk_btree_k);

	    /* Reserved bytes are present only in version 1 */
	    if(super_vers == HDF5_SUPERBLOCK_VERSION_1)
		image += 2;   /* reserved */
	} /* end if */
	else
	    chunk_btree_k = HDF5_BTREE_CHUNK_IK_DEF;
	udata->btree_k[H5B_CHUNK_ID] = chunk_btree_k;

	/* Remainder of "variable-sized" portion of superblock */
	H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->base_addr/*out*/);
	H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->ext_addr/*out*/);
	H5F_addr_decode(udata->f, (const uint8_t **)&image, &udata->stored_eof/*out*/);
	H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->driver_addr/*out*/);

	/* Allocate space for the root group symbol table entry */
	HDassert(!sblock->root_ent);
	if(NULL == (sblock->root_ent = (H5G_entry_t *)H5MM_calloc(sizeof(H5G_entry_t))))
	    HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't allocate space for root group symbol table entry")

	/* decode the root group symbol table entry */
	if(H5G_ent_decode(udata->f, (const uint8_t **)&image, sblock->root_ent) < 0)
	    HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, NULL, "can't decode root group symbol table entry")

	/* Set the root group address to the correct value */
	sblock->root_addr = sblock->root_ent->header;

	/* This step is for h5repart tool only. If user wants to change file driver
         *  from family to sec2 while using h5repart, set the driver address to
         *  undefined to let the library ignore the family driver information saved
         *  in the superblock.
         */
	if(udata->ignore_drvrinfo && H5F_addr_defined(sblock->driver_addr)) {
	    /* Eliminate the driver info */
	    sblock->driver_addr = HADDR_UNDEF;
            udata->drvrinfo_removed = TRUE;
	} /* end if */

	/* NOTE: Driver info block is decoded separately, later */

    } /* end if */
Пример #9
0
/*-------------------------------------------------------------------------
 * Function:    H5F_read_superblock
 *
 * Purpose:     Reads the superblock from the file or from the BUF. If
 *              ADDR is a valid address, then it reads it from the file.
 *              If not, then BUF must be non-NULL for it to read from the
 *              BUF.
 *
 * Return:      Success:        SUCCEED
 *              Failure:        FAIL
 *
 * Programmer:  Bill Wendling
 *              [email protected]
 *              Sept 12, 2003
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_entry_t *root_ent)
{
    haddr_t             stored_eoa;         /*relative end-of-addr in file  */
    haddr_t             eof;                /*end of file address           */
    uint8_t            *q;                  /*ptr into temp I/O buffer      */
    size_t              sizeof_addr = 0;
    size_t              sizeof_size = 0;
    const size_t        fixed_size = 24;    /*fixed sizeof superblock       */
    unsigned            sym_leaf_k = 0;
    size_t              variable_size;      /*variable sizeof superblock    */
    unsigned            btree_k[H5B_NUM_BTREE_ID];  /* B-tree internal node 'K' values */
    H5F_file_t         *shared = NULL;      /* shared part of `file'        */
    H5FD_t             *lf = NULL;          /* file driver part of `shared' */
    uint8_t            *p;                  /* Temporary pointer into encoding buffers */
    unsigned            i;                  /* Index variable               */
    unsigned            chksum;             /* Checksum temporary variable  */
    size_t              driver_size;        /* Size of driver info block, in bytes */
    char                driver_name[9];     /* Name of driver, for driver info block */
    unsigned            super_vers;         /* Super block version          */
    unsigned            freespace_vers;     /* Freespace info version       */
    unsigned            obj_dir_vers;       /* Object header info version   */
    unsigned            share_head_vers;    /* Shared header info version   */
    uint8_t             buf[H5F_SUPERBLOCK_SIZE];     /* Local buffer                 */
    H5P_genplist_t     *c_plist;            /* File creation property list  */
    herr_t              ret_value = SUCCEED;

    /* Decoding */
    FUNC_ENTER_NOAPI(H5F_read_superblock, FAIL)

    /* Short cuts */
    shared = f->shared;
    lf = shared->lf;

    /* Get the shared file creation property list */
    if (NULL == (c_plist = H5I_object(shared->fcpl_id)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")

    /* Read the superblock if it hasn't been read before. */
    if (HADDR_UNDEF == (shared->super_addr=H5F_locate_signature(lf,dxpl_id)))
        HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "unable to find file signature")
    if (H5FD_set_eoa(lf, shared->super_addr + fixed_size) < 0 ||
            H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, shared->super_addr, fixed_size, buf) < 0)
        HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "unable to read superblock")

    /* Signature, already checked */
    p = buf + H5F_SIGNATURE_LEN;

    /* Superblock version */
    super_vers = *p++;
    if (super_vers > HDF5_SUPERBLOCK_VERSION_MAX)
        HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad superblock version number")
    if (H5P_set(c_plist, H5F_CRT_SUPER_VERS_NAME, &super_vers) < 0)
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set superblock version")

    /* Freespace version */
    freespace_vers = *p++;
    if (HDF5_FREESPACE_VERSION != freespace_vers)
        HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad free space version number")
    if (H5P_set(c_plist, H5F_CRT_FREESPACE_VERS_NAME, &freespace_vers) < 0)
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to free space version")

    /* Root group version number */
    obj_dir_vers = *p++;
    if (HDF5_OBJECTDIR_VERSION != obj_dir_vers)
        HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad object directory version number")
    if (H5P_set(c_plist, H5F_CRT_OBJ_DIR_VERS_NAME, &obj_dir_vers) < 0)
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set object directory version")

    /* Skip over reserved byte */
    p++;

    /* Shared header version number */
    share_head_vers = *p++;
    if (HDF5_SHAREDHEADER_VERSION != share_head_vers)
        HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad shared-header format version number")
    if (H5P_set(c_plist, H5F_CRT_SHARE_HEAD_VERS_NAME, &share_head_vers) < 0)
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set shared-header format version")

    /* Size of file addresses */
    sizeof_addr = *p++;
    if (sizeof_addr != 2 && sizeof_addr != 4 &&
            sizeof_addr != 8 && sizeof_addr != 16 && sizeof_addr != 32)
        HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad byte number in an address")
    if (H5P_set(c_plist, H5F_CRT_ADDR_BYTE_NUM_NAME,&sizeof_addr) < 0)
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set byte number in an address")
    shared->sizeof_addr = sizeof_addr;  /* Keep a local copy also */

    /* Size of file sizes */
    sizeof_size = *p++;
    if (sizeof_size != 2 && sizeof_size != 4 &&
            sizeof_size != 8 && sizeof_size != 16 && sizeof_size != 32)
        HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad byte number for object size")
    if (H5P_set(c_plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &sizeof_size) < 0)
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set byte number for object size")
    shared->sizeof_size = sizeof_size;  /* Keep a local copy also */

    /* Skip over reserved byte */
    p++;

    /* Various B-tree sizes */
    UINT16DECODE(p, sym_leaf_k);
    if (sym_leaf_k == 0)
        HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, FAIL, "bad symbol table leaf node 1/2 rank")
    if (H5P_set(c_plist, H5F_CRT_SYM_LEAF_NAME, &sym_leaf_k) < 0)
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set rank for symbol table leaf nodes")
    shared->sym_leaf_k = sym_leaf_k;    /* Keep a local copy also */

    /* Need 'get' call to set other array values */
    if (H5P_get(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0)
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get rank for btree internal nodes")
    UINT16DECODE(p, btree_k[H5B_SNODE_ID]);
    if (btree_k[H5B_SNODE_ID] == 0)
        HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, FAIL, "bad 1/2 rank for btree internal nodes")
    /*
     * Delay setting the value in the property list until we've checked
     * for the indexed storage B-tree internal 'K' value later.
     */

    /* File consistency flags. Not really used yet */
    UINT32DECODE(p, shared->consist_flags);
    assert(((size_t)(p - buf)) == fixed_size);

    /* Decode the variable-length part of the superblock... */
    variable_size = (super_vers>0 ? 4 : 0) +    /* Potential indexed storage B-tree internal 'K' value */
                    H5F_SIZEOF_ADDR(f) +        /*base addr*/
                    H5F_SIZEOF_ADDR(f) +        /*global free list*/
                    H5F_SIZEOF_ADDR(f) +        /*end-of-address*/
                    H5F_SIZEOF_ADDR(f) +        /*reserved address*/
                    H5G_SIZEOF_ENTRY(f);        /*root group ptr*/
    assert(fixed_size + variable_size <= sizeof(buf));
    if (H5FD_set_eoa(lf, shared->super_addr + fixed_size+variable_size) < 0 ||
            H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, shared->super_addr + fixed_size, variable_size, p) < 0)
        HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read superblock")

    /*
     * If the superblock version # is greater than 0, read in the indexed
     * storage B-tree internal 'K' value
     */
    if (super_vers > 0) {
        UINT16DECODE(p, btree_k[H5B_ISTORE_ID]);
        p += 2;   /* reserved */
    }
    else
        btree_k[H5B_ISTORE_ID] = HDF5_BTREE_ISTORE_IK_DEF;

    /* Set the B-tree internal node values, etc */
    if (H5P_set(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0)
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set rank for btree internal nodes")
    HDmemcpy(shared->btree_k, btree_k, sizeof(unsigned) * (size_t)H5B_NUM_BTREE_ID);    /* Keep a local copy also */

    H5F_addr_decode(f, (const uint8_t **)&p, &shared->base_addr/*out*/);
    H5F_addr_decode(f, (const uint8_t **)&p, &shared->freespace_addr/*out*/);
    H5F_addr_decode(f, (const uint8_t **)&p, &stored_eoa/*out*/);
    H5F_addr_decode(f, (const uint8_t **)&p, &shared->driver_addr/*out*/);
    if (H5G_ent_decode(f, (const uint8_t **)&p, root_ent/*out*/) < 0)
        HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read root symbol entry")

    /*
     * Check if superblock address is different from base address and
     * adjust base address and "end of address" address if so.
     */
    if (!H5F_addr_eq(shared->super_addr,shared->base_addr)) {
        /* Check if the superblock moved earlier in the file */
        if (H5F_addr_lt(shared->super_addr, shared->base_addr))
            stored_eoa -= (shared->base_addr - shared->super_addr);
        else
            /* The superblock moved later in the file */
            stored_eoa += (shared->super_addr - shared->base_addr);

        shared->base_addr = shared->super_addr;
    } /* end if */

    /* Compute super block checksum */
    assert(sizeof(chksum) == sizeof(shared->super_chksum));
    for (q = (uint8_t *)&chksum, chksum = 0, i = 0; i < fixed_size + variable_size; ++i)
        q[i % sizeof(shared->super_chksum)] ^= buf[i];

    /* Set the super block checksum */
    shared->super_chksum = chksum;

    /* Decode the optional driver information block */
    if (H5F_addr_defined(shared->driver_addr)) {
        haddr_t drv_addr = shared->base_addr + shared->driver_addr;
        uint8_t dbuf[H5F_DRVINFOBLOCK_SIZE];     /* Local buffer                 */

        if (H5FD_set_eoa(lf, drv_addr + 16) < 0 ||
                H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, drv_addr, (size_t)16, dbuf) < 0)
            HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read driver information block")
        p = dbuf;

        /* Version number */
        if (HDF5_DRIVERINFO_VERSION != *p++)
            HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "bad driver information block version number")

        p += 3; /* reserved */

        /* Driver info size */
        UINT32DECODE(p, driver_size);

        /* Driver name and/or version */
        HDstrncpy(driver_name, (const char *)p, (size_t)8);
        driver_name[8] = '\0';
        p += 8; /* advance past name/version */

        /* Read driver information and decode */
        assert((driver_size + 16) <= sizeof(dbuf));
        if (H5FD_set_eoa(lf, drv_addr + 16 + driver_size) < 0 ||
                H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, drv_addr+16, driver_size, p) < 0)
            HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read file driver information")

        if (H5FD_sb_decode(lf, driver_name, p) < 0)
            HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to decode driver information")

        /* Compute driver info block checksum */
        assert(sizeof(chksum) == sizeof(shared->drvr_chksum));
        for (q = (uint8_t *)&chksum, chksum = 0, i = 0; i < (driver_size + 16); ++i)
            q[i % sizeof(shared->drvr_chksum)] ^= dbuf[i];

        /* Set the driver info block checksum */
        shared->drvr_chksum = chksum;
    } /* end if */
Пример #10
0
/*-------------------------------------------------------------------------
 * Function:	H5B2_cache_hdr_load
 *
 * Purpose:	Loads a B-tree header from the disk.
 *
 * Return:	Success:	Pointer to a new B-tree.
 *
 *		Failure:	NULL
 *
 * Programmer:	Quincey Koziol
 *		[email protected]
 *		Feb 1 2005
 *
 *-------------------------------------------------------------------------
 */
static H5B2_t *
H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void UNUSED *udata)
{
    const H5B2_class_t	*type = (const H5B2_class_t *) _type;   /* Type of B-tree */
    unsigned depth;                     /* Depth of B-tree */
    size_t node_size, rrec_size;        /* Size info for B-tree */
    uint8_t split_percent, merge_percent;      /* Split & merge %s for B-tree */
    H5B2_t		*bt2 = NULL;    /* B-tree info */
    size_t		size;           /* Header size */
    uint32_t            stored_chksum;  /* Stored metadata checksum value */
    uint32_t            computed_chksum; /* Computed metadata checksum value */
    H5WB_t              *wb = NULL;     /* Wrapped buffer for header data */
    uint8_t             hdr_buf[H5B2_HDR_BUF_SIZE]; /* Buffer for header */
    uint8_t		*hdr;           /* Pointer to header buffer */
    uint8_t		*p;             /* Pointer into raw data buffer */
    H5B2_t		*ret_value;     /* Return value */

    FUNC_ENTER_NOAPI(H5B2_cache_hdr_load, NULL)

    /* Check arguments */
    HDassert(f);
    HDassert(H5F_addr_defined(addr));
    HDassert(type);

    /* Allocate space for the B-tree data structure */
    if(NULL == (bt2 = H5FL_MALLOC(H5B2_t)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
    HDmemset(&bt2->cache_info, 0, sizeof(H5AC_info_t));

    /* Wrap the local buffer for serialized header info */
    if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
        HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, NULL, "can't wrap buffer")

    /* Compute the size of the serialized B-tree header on disk */
    size = H5B2_HEADER_SIZE(f);

    /* Get a pointer to a buffer that's large enough for header */
    if(NULL == (hdr = (uint8_t *)H5WB_actual(wb, size)))
        HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "can't get actual buffer")

    /* Read header from disk */
    if(H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, hdr) < 0)
	HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree header")

    /* Get temporary pointer to serialized header */
    p = hdr;

    /* Magic number */
    if(HDmemcmp(p, H5B2_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC))
	HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree header signature")
    p += H5_SIZEOF_MAGIC;

    /* Version */
    if(*p++ != H5B2_HDR_VERSION)
	HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree header version")

    /* B-tree type */
    if(*p++ != (uint8_t)type->id)
	HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "incorrect B-tree type")

    /* Node size (in bytes) */
    UINT32DECODE(p, node_size);

    /* Raw key size (in bytes) */
    UINT16DECODE(p, rrec_size);

    /* Depth of tree */
    UINT16DECODE(p, depth);

    /* Split & merge %s */
    split_percent = *p++;
    merge_percent = *p++;

    /* Root node pointer */
    H5F_addr_decode(f, (const uint8_t **)&p, &(bt2->root.addr));
    UINT16DECODE(p, bt2->root.node_nrec);
    H5F_DECODE_LENGTH(f, p, bt2->root.all_nrec);

    /* Metadata checksum */
    UINT32DECODE(p, stored_chksum);

    /* Sanity check */
    HDassert((size_t)(p - hdr) == size);

    /* Compute checksum on entire header */
    computed_chksum = H5_checksum_metadata(hdr, (size - H5B2_SIZEOF_CHKSUM), 0);

    /* Verify checksum */
    if(stored_chksum != computed_chksum)
	HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "incorrect metadata checksum for v2 B-tree header")

    /* Initialize shared B-tree info */
    if(H5B2_shared_init(f, bt2, type, depth, node_size, rrec_size, split_percent, merge_percent) < 0)
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't create shared B-tree info")

    /* Set return value */
    ret_value = bt2;

done:
    /* Release resources */
    if(wb && H5WB_unwrap(wb) < 0)
        HDONE_ERROR(H5E_BTREE, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
    if(!ret_value && bt2)
        (void)H5B2_cache_hdr_dest(f, bt2);

    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B2_cache_hdr_load() */ /*lint !e818 Can't make udata a pointer to const */