1 Star 0 Fork 0

submodule/hdf5

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
H5FDonion_history.c 11.71 KB
一键复制 编辑 原始数据 按行查看 历史
Larry Knox 提交于 2022-11-02 05:02 +08:00 . Update copyright headers (#2184)
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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 COPYING file, which can be found at the root of the source code *
* distribution tree, or in https://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Onion Virtual File Driver (VFD)
*
* Purpose: Code for the onion file's history
*/
/* This source code file is part of the H5FD driver module */
#include "H5FDdrvr_module.h"
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5FDprivate.h" /* File drivers */
#include "H5FDonion.h" /* Onion file driver */
#include "H5FDonion_priv.h" /* Onion file driver internals */
/*-----------------------------------------------------------------------------
* Function: H5FD__onion_write_history
*
* Purpose: Read and decode the history information from `raw_file` at
* `addr` .. `addr + size` (taken from history header), and store
* the decoded information in the structure at `history_out`.
*
* Returns: SUCCEED/FAIL
*-----------------------------------------------------------------------------
*/
herr_t
H5FD__onion_ingest_history(H5FD_onion_history_t *history_out, H5FD_t *raw_file, haddr_t addr, haddr_t size)
{
unsigned char *buf = NULL;
uint32_t sum = 0;
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE;
HDassert(history_out);
HDassert(raw_file);
/* Set early so we can clean up properly on errors */
history_out->record_locs = NULL;
if (H5FD_get_eof(raw_file, H5FD_MEM_DRAW) < (addr + size))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "header indicates history beyond EOF");
if (NULL == (buf = H5MM_malloc(sizeof(char) * size)))
HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate buffer space");
if (H5FD_set_eoa(raw_file, H5FD_MEM_DRAW, (addr + size)) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't modify EOA");
if (H5FD_read(raw_file, H5FD_MEM_DRAW, addr, size, buf) < 0)
HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "can't read history from file");
if (H5FD__onion_history_decode(buf, history_out) != size)
HGOTO_ERROR(H5E_VFL, H5E_CANTDECODE, FAIL, "can't decode history (initial)");
sum = H5_checksum_fletcher32(buf, size - 4);
if (history_out->checksum != sum)
HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "checksum mismatch between buffer and stored");
if (history_out->n_revisions > 0)
if (NULL == (history_out->record_locs =
H5MM_calloc(history_out->n_revisions * sizeof(H5FD_onion_record_loc_t))))
HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate record pointer list");
if (H5FD__onion_history_decode(buf, history_out) != size)
HGOTO_ERROR(H5E_VFL, H5E_CANTDECODE, FAIL, "can't decode history (final)");
done:
H5MM_xfree(buf);
if (ret_value < 0)
H5MM_xfree(history_out->record_locs);
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5FD__onion_ingest_history() */
/*-----------------------------------------------------------------------------
* Function: H5FD__onion_write_history
*
* Purpose: Encode and write history to file at the given address.
*
* Returns: Success: Number of bytes written to destination file (always non-zero)
* Failure: 0
*-----------------------------------------------------------------------------
*/
uint64_t
H5FD__onion_write_history(H5FD_onion_history_t *history, H5FD_t *file, haddr_t off_start,
haddr_t filesize_curr)
{
uint32_t _sum = 0; /* Required by the API call but unused here */
uint64_t size = 0;
unsigned char *buf = NULL;
uint64_t ret_value = 0;
FUNC_ENTER_PACKAGE;
if (NULL == (buf = H5MM_malloc(H5FD_ONION_ENCODED_SIZE_HISTORY +
(H5FD_ONION_ENCODED_SIZE_RECORD_POINTER * history->n_revisions))))
HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, 0, "can't allocate buffer for updated history")
if (0 == (size = H5FD__onion_history_encode(history, buf, &_sum)))
HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, 0, "problem encoding updated history")
if ((size + off_start > filesize_curr) && (H5FD_set_eoa(file, H5FD_MEM_DRAW, off_start + size) < 0))
HGOTO_ERROR(H5E_VFL, H5E_CANTSET, 0, "can't modify EOA for updated history")
if (H5FD_write(file, H5FD_MEM_DRAW, off_start, size, buf) < 0)
HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, 0, "can't write history as intended")
ret_value = size;
done:
H5MM_xfree(buf);
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5FD__onion_write_history() */
/*-----------------------------------------------------------------------------
* Function: H5FD__onion_history_decode
*
* Purpose: Attempt to read a buffer and store it as a history
* structure.
*
* Implementation must correspond with
* H5FD__onion_history_encode().
*
* MUST BE CALLED TWICE:
* On the first call, n_records in the destination structure must
* be zero, and record_locs be NULL.
*
* If the buffer is well-formed, the destination structure is
* tentatively populated with fixed-size values, and the number of
* bytes read are returned.
*
* Prior to the second call, the user must allocate space for
* record_locs to hold n_records record-pointer structs.
*
* Then the decode operation is called a second time, and all
* components will be populated (and again number of bytes read is
* returned).
*
* Return: Success: Number of bytes read from buffer
* Failure: 0
*-----------------------------------------------------------------------------
*/
size_t H5_ATTR_NO_OPTIMIZE
H5FD__onion_history_decode(unsigned char *buf, H5FD_onion_history_t *history)
{
uint32_t ui32 = 0;
uint32_t sum = 0;
uint64_t ui64 = 0;
uint64_t n_revisions = 0;
uint8_t *ui8p = NULL;
unsigned char *ptr = NULL;
size_t ret_value = 0;
FUNC_ENTER_PACKAGE;
HDassert(buf != NULL);
HDassert(history != NULL);
HDassert(H5FD_ONION_HISTORY_VERSION_CURR == history->version);
if (HDstrncmp((const char *)buf, H5FD_ONION_HISTORY_SIGNATURE, 4))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "invalid signature")
if (H5FD_ONION_HISTORY_VERSION_CURR != buf[4])
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "invalid version")
ptr = buf + 8;
HDmemcpy(&ui64, ptr, 8);
ui8p = (uint8_t *)&ui64;
UINT64DECODE(ui8p, n_revisions);
ptr += 8;
if (0 == history->n_revisions) {
history->n_revisions = n_revisions;
ptr += H5FD_ONION_ENCODED_SIZE_RECORD_POINTER * n_revisions;
}
else {
if (history->n_revisions != n_revisions)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0,
"history argument suggests different revision count than encoded buffer")
if (NULL == history->record_locs)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "list is NULL -- cannot populate")
for (uint64_t i = 0; i < n_revisions; i++) {
H5FD_onion_record_loc_t *rloc = &history->record_locs[i];
/* Decode into appropriately sized types, then do a checked
* assignment to the struct value. We don't have access to
* the H5F_t struct for this file, so we can't use the
* offset/length macros in H5Fprivate.h.
*/
uint64_t record_size;
uint64_t phys_addr;
HDmemcpy(&ui64, ptr, 8);
ui8p = (uint8_t *)&ui64;
UINT64DECODE(ui8p, phys_addr);
H5_CHECKED_ASSIGN(rloc->phys_addr, haddr_t, phys_addr, uint64_t);
ptr += 8;
HDmemcpy(&ui64, ptr, 8);
ui8p = (uint8_t *)&ui64;
UINT64DECODE(ui8p, record_size);
H5_CHECKED_ASSIGN(rloc->record_size, hsize_t, record_size, uint64_t);
ptr += 8;
HDmemcpy(&ui32, ptr, 4);
ui8p = (uint8_t *)&ui32;
UINT32DECODE(ui8p, rloc->checksum);
ptr += 4;
}
}
sum = H5_checksum_fletcher32(buf, (size_t)(ptr - buf));
HDmemcpy(&ui32, ptr, 4);
ui8p = (uint8_t *)&ui32;
UINT32DECODE(ui8p, history->checksum);
ptr += 4;
if (sum != history->checksum)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "checksum mismatch")
ret_value = (size_t)(ptr - buf);
done:
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5FD__onion_history_decode() */
/*-----------------------------------------------------------------------------
* Function: H5FD__onion_history_encode
*
* Purpose: Write history structure to the given buffer.
* All multi-byte elements are stored in little-endian word order.
*
* Implementation must correspond with
* H5FD__onion_history_decode().
*
* The destination buffer must be sufficiently large to hold the
* encoded contents.
* (Hint: `sizeof(history struct) +
* sizeof(record-pointer-struct) * n_records)` guarantees
* ample/excess space.)
*
* Return: Number of bytes written to buffer.
* The checksum of the generated buffer contents (excluding the
* checksum itself) is stored in the pointer `checksum`).
*-----------------------------------------------------------------------------
*/
size_t
H5FD__onion_history_encode(H5FD_onion_history_t *history, unsigned char *buf, uint32_t *checksum)
{
unsigned char *ptr = buf;
size_t vers_u32 = (uint32_t)history->version; /* pad out unused bytes */
FUNC_ENTER_PACKAGE_NOERR;
HDassert(history != NULL);
HDassert(H5FD_ONION_HISTORY_VERSION_CURR == history->version);
HDassert(buf != NULL);
HDassert(checksum != NULL);
HDmemcpy(ptr, H5FD_ONION_HISTORY_SIGNATURE, 4);
ptr += 4;
UINT32ENCODE(ptr, vers_u32);
UINT64ENCODE(ptr, history->n_revisions);
if (history->n_revisions > 0) {
HDassert(history->record_locs != NULL);
for (uint64_t i = 0; i < history->n_revisions; i++) {
H5FD_onion_record_loc_t *rloc = &history->record_locs[i];
/* Do a checked assignment from the struct value into appropriately
* sized types. We don't have access to the H5F_t struct for this
* file, so we can't use the offset/length macros in H5Fprivate.h.
*/
uint64_t phys_addr;
uint64_t record_size;
H5_CHECKED_ASSIGN(phys_addr, uint64_t, rloc->phys_addr, haddr_t);
H5_CHECKED_ASSIGN(record_size, uint64_t, rloc->record_size, hsize_t);
UINT64ENCODE(ptr, phys_addr);
UINT64ENCODE(ptr, record_size);
UINT32ENCODE(ptr, rloc->checksum);
}
}
*checksum = H5_checksum_fletcher32(buf, (size_t)(ptr - buf));
UINT32ENCODE(ptr, *checksum);
FUNC_LEAVE_NOAPI((size_t)(ptr - buf));
} /* end H5FD__onion_history_encode() */
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/submodule_xiaohu/hdf5.git
git@gitee.com:submodule_xiaohu/hdf5.git
submodule_xiaohu
hdf5
hdf5
architecture_docs

搜索帮助