/*------------------------------------------------------------------------- * Function: H5O_ginfo_encode * * Purpose: Encodes a message. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * [email protected] * Aug 30 2005 * *------------------------------------------------------------------------- */ static herr_t H5O_ginfo_encode(H5F_t UNUSED *f, hbool_t UNUSED disable_shared, uint8_t *p, const void *_mesg) { const H5O_ginfo_t *ginfo = (const H5O_ginfo_t *) _mesg; unsigned char flags; /* Flags for encoding group info */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* check args */ HDassert(p); HDassert(ginfo); /* Message version */ *p++ = H5O_GINFO_VERSION; /* The flags for the group info */ flags = ginfo->store_link_phase_change ? H5O_GINFO_STORE_PHASE_CHANGE : 0; flags |= ginfo->store_est_entry_info ? H5O_GINFO_STORE_EST_ENTRY_INFO : 0; *p++ = flags; /* Store the max. # of links to store compactly & the min. # of links to store densely */ if(ginfo->store_link_phase_change) { UINT16ENCODE(p, ginfo->max_compact) UINT16ENCODE(p, ginfo->min_dense) } /* end if */ /* Estimated # of entries & name lengths */ if(ginfo->store_est_entry_info) { UINT16ENCODE(p, ginfo->est_num_entries) UINT16ENCODE(p, ginfo->est_name_len) } /* end if */ FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_ginfo_encode() */
/*------------------------------------------------------------------------- * Function: H5O_efl_encode * * Purpose: Encodes a message. * * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke * Tuesday, November 25, 1997 * *------------------------------------------------------------------------- */ static herr_t H5O_efl_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const void *_mesg) { const H5O_efl_t *mesg = (const H5O_efl_t *)_mesg; size_t u; /* Local index variable */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_efl_encode) /* check args */ HDassert(f); HDassert(mesg); HDassert(p); /* Version */ *p++ = H5O_EFL_VERSION; /* Reserved */ *p++ = 0; *p++ = 0; *p++ = 0; /* Number of slots */ HDassert(mesg->nalloc > 0); UINT16ENCODE(p, mesg->nused); /*yes, twice*/ HDassert(mesg->nused > 0 && mesg->nused <= mesg->nalloc); UINT16ENCODE(p, mesg->nused); /* Heap address */ HDassert(H5F_addr_defined(mesg->heap_addr)); H5F_addr_encode(f, &p, mesg->heap_addr); /* Encode file list */ for(u = 0; u < mesg->nused; u++) { /* * The name should have been added to the heap when the dataset was * created. */ HDassert(mesg->slot[u].name_offset); H5F_ENCODE_LENGTH(f, p, mesg->slot[u].name_offset); H5F_ENCODE_LENGTH(f, p, mesg->slot[u].offset); H5F_ENCODE_LENGTH(f, p, mesg->slot[u].size); } /* end for */ FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_efl_encode() */
/**************************************************************** ** ** test_metadata(): Main meta-data encode/decode testing routine. ** ****************************************************************/ void test_metadata(void) { int16_t ei16 = TEST_INT16_VALUE; /* variables to hold the values to encode */ uint16_t eu16 = TEST_UINT16_VALUE; int32_t ei32 = TEST_INT32_VALUE; uint32_t eu32 = TEST_UINT32_VALUE; int16_t di16; /* variables to hold the decoded values */ uint16_t du16; int32_t di32; uint32_t du32; uint8_t *p; /* pointer into the buffer being en/de-coded */ /* Output message about test being performed */ MESSAGE(5, ("Testing Metadata Encoding/decoding\n")); /* Start by encoding the values above */ p = encode_buffer; INT16ENCODE(p, ei16); /* Encode the int16 value */ UINT16ENCODE(p, eu16); /* Encode the uint16 value */ INT32ENCODE(p, ei32); /* Encode the int32 value */ UINT32ENCODE(p, eu32); /* Encode the uint32 value */ /* Check if we got what we asked for */ if (HDmemcmp(encode_buffer, compar_buffer, sizeof(compar_buffer)) != 0) { unsigned u; /* local counting variable */ for (u = 0; u < sizeof(compar_buffer); u++) { if (compar_buffer[u] != encode_buffer[u]) TestErrPrintf("Error encoding meta-data at offset %u, wanted: %u, got: %u\n", (unsigned) u, (unsigned) compar_buffer[u], (unsigned) encode_buffer[u]); } /* end for */ } /* end if */ /* Test decoding macros */ p = encode_buffer; INT16DECODE(p, di16); /* Decode the int16 value */ UINT16DECODE(p, du16); /* Decode the uint16 value */ INT32DECODE(p, di32); /* Decode the int32 value */ UINT32DECODE(p, du32); /* Decode the uint32 value */ /* Check the values decoded */ if (di16 != TEST_INT16_VALUE) TestErrPrintf("Error decoding int16 meta-data wanted: %d, got: %d " "at %s:%d\n", (int) TEST_INT16_VALUE, (int) di16, __FILE__, __LINE__); if (du16 != TEST_UINT16_VALUE) TestErrPrintf("Error decoding uint16 meta-data wanted: %u, got: %u " "at %s:%d\n", (unsigned) TEST_UINT16_VALUE, (unsigned) du16, __FILE__, __LINE__); if (di32 != TEST_INT32_VALUE) TestErrPrintf("Error decoding int32 meta-data wanted: %ld, got: %ld " "at %s:%d\n", (long) TEST_INT32_VALUE, (long) di32, __FILE__, __LINE__); if (du32 != TEST_UINT32_VALUE) TestErrPrintf("Error decoding uint32 meta-data wanted: %lu, got: %lu " "at %s:%d\n", (unsigned long) TEST_UINT32_VALUE, (unsigned long) du32, __FILE__, __LINE__); } /* test_metadata() */
/*------------------------------------------------------------------------- * Function: H5O_drvinfo_encode * * Purpose: Encode a v1 B-tree 'K' value message. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Mar 1, 2007 * *------------------------------------------------------------------------- */ static herr_t H5O_drvinfo_encode(H5F_t H5_ATTR_UNUSED *f, hbool_t H5_ATTR_UNUSED disable_shared, uint8_t *p, const void *_mesg) { const H5O_drvinfo_t *mesg = (const H5O_drvinfo_t *)_mesg; FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ HDassert(f); HDassert(p); HDassert(mesg); /* Store version, driver name, buffer length, & encoded buffer */ *p++ = H5O_DRVINFO_VERSION; HDmemcpy(p, mesg->name, 8); p += 8; HDassert(mesg->len <= 65535); UINT16ENCODE(p, mesg->len); HDmemcpy(p, mesg->buf, mesg->len); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_drvinfo_encode() */
/*------------------------------------------------------------------------- * Function: H5O_ainfo_encode * * Purpose: Encodes a message. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * [email protected] * Mar 6 2007 * *------------------------------------------------------------------------- */ static herr_t H5O_ainfo_encode(H5F_t *f, hbool_t H5_ATTR_UNUSED disable_shared, uint8_t *p, const void *_mesg) { const H5O_ainfo_t *ainfo = (const H5O_ainfo_t *)_mesg; unsigned char flags; /* Flags for encoding attribute info */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* check args */ HDassert(f); HDassert(p); HDassert(ainfo); /* Message version */ *p++ = H5O_AINFO_VERSION; /* The flags for the attribute indices */ flags = ainfo->track_corder ? H5O_AINFO_TRACK_CORDER : 0; flags = (unsigned char)(flags | (ainfo->index_corder ? H5O_AINFO_INDEX_CORDER : 0)); *p++ = flags; /* Max. creation order value for the object */ if(ainfo->track_corder) UINT16ENCODE(p, ainfo->max_crt_idx); /* Address of fractal heap to store "dense" attributes */ H5F_addr_encode(f, &p, ainfo->fheap_addr); /* Address of v2 B-tree to index names of attributes */ H5F_addr_encode(f, &p, ainfo->name_bt2_addr); /* Address of v2 B-tree to index creation order of attributes, if they are indexed */ if(ainfo->index_corder) H5F_addr_encode(f, &p, ainfo->corder_bt2_addr); else HDassert(!H5F_addr_defined(ainfo->corder_bt2_addr)); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_ainfo_encode() */
/*------------------------------------------------------------------------- * Function: H5O_layout_encode * * Purpose: Encodes a message. * * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke * Wednesday, October 8, 1997 * * Note: * Quincey Koziol, 2004-5-21 * We write out version 3 messages by default now. * * 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. * * Quincey Koziol, 2004-5-21 * Added version number 3 case to straighten out problems with contiguous * layout's sizes (was encoding them as 4-byte values when they were * really n-byte values (where n usually is 8)) and additionally clean up * the information written out. * *------------------------------------------------------------------------- */ static herr_t H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const void *_mesg) { const H5O_layout_t *mesg = (const H5O_layout_t *) _mesg; unsigned u; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_layout_encode) /* check args */ HDassert(f); HDassert(mesg); HDassert(p); /* Message version */ *p++ = (uint8_t)H5O_LAYOUT_VERSION_3; /* Layout class */ *p++ = mesg->type; /* Write out layout class specific information */ switch(mesg->type) { case H5D_COMPACT: /* Size of raw data */ UINT16ENCODE(p, mesg->storage.u.compact.size); /* Raw data */ if(mesg->storage.u.compact.size > 0) { if(mesg->storage.u.compact.buf) HDmemcpy(p, mesg->storage.u.compact.buf, mesg->storage.u.compact.size); else HDmemset(p, 0, mesg->storage.u.compact.size); p += mesg->storage.u.compact.size; } /* end if */ break; case H5D_CONTIGUOUS: H5F_addr_encode(f, &p, mesg->storage.u.contig.addr); H5F_ENCODE_LENGTH(f, p, mesg->storage.u.contig.size); break; case H5D_CHUNKED: /* Number of dimensions */ HDassert(mesg->u.chunk.ndims > 0 && mesg->u.chunk.ndims <= H5O_LAYOUT_NDIMS); *p++ = (uint8_t)mesg->u.chunk.ndims; /* B-tree address */ H5F_addr_encode(f, &p, mesg->storage.u.chunk.idx_addr); /* Dimension sizes */ for(u = 0; u < mesg->u.chunk.ndims; u++) UINT32ENCODE(p, mesg->u.chunk.dim[u]); break; default: HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "Invalid layout class") } /* end switch */ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_layout_encode() */
/*-------------------------------------------------------------------------- NAME H5O_attr_encode PURPOSE Encode a simple attribute message USAGE herr_t H5O_attr_encode(f, raw_size, p, mesg) H5F_t *f; IN: pointer to the HDF5 file struct const uint8 *p; IN: the raw information buffer const void *mesg; IN: Pointer to the simple datatype struct RETURNS Non-negative on success/Negative on failure DESCRIPTION This function encodes the native memory form of the attribute message in the "raw" disk form. * * Modifications: * Robb Matzke, 17 Jul 1998 * Added padding for alignment. * * Robb Matzke, 20 Jul 1998 * Added a version number at the beginning. * * Raymond Lu, 8 April 2004 * For data space, changed the operation on H5S_simple_t to * H5S_extent_t * --------------------------------------------------------------------------*/ static herr_t H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg) { const H5A_t *attr = (const H5A_t *) mesg; size_t name_len; /* Attribute name length */ unsigned version; /* Attribute version */ hbool_t type_shared; /* Flag to indicate that a shared datatype is used for this attribute */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_encode); /* check args */ assert(f); assert(p); assert(attr); /* Check whether datatype is shared */ if(H5T_committed(attr->dt)) type_shared = TRUE; else type_shared = FALSE; /* Check which version to write out */ if(type_shared) version = H5O_ATTR_VERSION_NEW; /* Write out new version if shared datatype */ else version = H5O_ATTR_VERSION; /* Encode Version */ *p++ = version; /* Set attribute flags if version >1 */ if(version>H5O_ATTR_VERSION) *p++ = (type_shared ? H5O_ATTR_FLAG_TYPE_SHARED : 0 ); /* Set flags for attribute */ else *p++ = 0; /* Reserved, for version <2 */ /* * Encode the lengths of the various parts of the attribute message. The * encoded lengths are exact but we pad each part except the data to be a * multiple of eight bytes (in the first version). */ name_len = HDstrlen(attr->name)+1; UINT16ENCODE(p, name_len); UINT16ENCODE(p, attr->dt_size); UINT16ENCODE(p, attr->ds_size); /* * Write the name including null terminator padded to the correct number * of bytes. */ HDmemcpy(p, attr->name, name_len); HDmemset(p+name_len, 0, H5O_ALIGN(name_len)-name_len); if(version < H5O_ATTR_VERSION_NEW) p += H5O_ALIGN(name_len); else p += name_len; /* encode the attribute datatype */ if(type_shared) { H5O_shared_t sh_mesg; /* Reset shared message information */ HDmemset(&sh_mesg,0,sizeof(H5O_shared_t)); /* Get shared message information from datatype */ if ((H5O_MSG_DTYPE->get_share)(f, attr->dt, &sh_mesg/*out*/)<0) HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode shared attribute datatype"); /* Encode shared message information for datatype */ if((H5O_MSG_SHARED->encode)(f,p,&sh_mesg)<0) HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode shared attribute datatype"); } /* end if */ else { /* Encode datatype information */ if((H5O_MSG_DTYPE->encode)(f,p,attr->dt)<0) HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute datatype"); } /* end else */ if(version < H5O_ATTR_VERSION_NEW) { HDmemset(p+attr->dt_size, 0, H5O_ALIGN(attr->dt_size)-attr->dt_size); p += H5O_ALIGN(attr->dt_size); } /* end if */ else p += attr->dt_size; /* encode the attribute dataspace */ if((H5O_MSG_SDSPACE->encode)(f,p,&(attr->ds->extent))<0) HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute dataspace"); if(version < H5O_ATTR_VERSION_NEW) { HDmemset(p+attr->ds_size, 0, H5O_ALIGN(attr->ds_size)-attr->ds_size); p += H5O_ALIGN(attr->ds_size); } /* end if */ else p += attr->ds_size; /* Store attribute data */ if(attr->data) HDmemcpy(p,attr->data,attr->data_size); else HDmemset(p,0,attr->data_size); done: FUNC_LEAVE_NOAPI(ret_value); }
/*------------------------------------------------------------------------- * Function: H5B2_cache_hdr_flush * * Purpose: Flushes a dirty B-tree header to disk. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * [email protected] * Feb 1 2005 * Changes: JRM -- 8/21/06 * Added the flags_ptr parameter. This parameter exists to * allow the flush routine to report to the cache if the * entry is resized or renamed as a result of the flush. * *flags_ptr is set to H5C_CALLBACK__NO_FLAGS_SET on entry. * *------------------------------------------------------------------------- */ static herr_t H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_t *bt2, unsigned UNUSED * flags_ptr) { H5WB_t *wb = NULL; /* Wrapped buffer for header data */ uint8_t hdr_buf[H5B2_HDR_BUF_SIZE]; /* Buffer for header */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5B2_cache_hdr_flush, FAIL) /* check arguments */ HDassert(f); HDassert(H5F_addr_defined(addr)); HDassert(bt2); if (bt2->cache_info.is_dirty) { H5B2_shared_t *shared; /* Shared B-tree information */ uint8_t *hdr; /* Pointer to header buffer */ uint8_t *p; /* Pointer into raw data buffer */ size_t size; /* Header size on disk */ uint32_t metadata_chksum; /* Computed metadata checksum value */ /* Get the pointer to the shared B-tree info */ shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared); HDassert(shared); /* Wrap the local buffer for serialized header info */ if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf)))) HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "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, FAIL, "can't get actual buffer") /* Get temporary pointer to serialized header */ p = hdr; /* Magic number */ HDmemcpy(p, H5B2_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC); p += H5_SIZEOF_MAGIC; /* Version # */ *p++ = H5B2_HDR_VERSION; /* B-tree type */ *p++ = shared->type->id; /* Node size (in bytes) */ UINT32ENCODE(p, shared->node_size); /* Raw key size (in bytes) */ UINT16ENCODE(p, shared->rrec_size); /* Depth of tree */ UINT16ENCODE(p, shared->depth); /* Split & merge %s */ H5_CHECK_OVERFLOW(shared->split_percent, /* From: */ unsigned, /* To: */ uint8_t); *p++ = (uint8_t)shared->split_percent; H5_CHECK_OVERFLOW(shared->merge_percent, /* From: */ unsigned, /* To: */ uint8_t); *p++ = (uint8_t)shared->merge_percent; /* Root node pointer */ H5F_addr_encode(f, &p, bt2->root.addr); UINT16ENCODE(p, bt2->root.node_nrec); H5F_ENCODE_LENGTH(f, p, bt2->root.all_nrec); /* Compute metadata checksum */ metadata_chksum = H5_checksum_metadata(hdr, (size - H5B2_SIZEOF_CHKSUM), 0); /* Metadata checksum */ UINT32ENCODE(p, metadata_chksum); /* Write the B-tree header. */ HDassert((size_t)(p - hdr) == size); if(H5F_block_write(f, H5FD_MEM_BTREE, addr, size, dxpl_id, hdr) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree header to disk") bt2->cache_info.is_dirty = FALSE; } /* end if */