diff options
Diffstat (limited to 'src/H5Zfletcher32.c')
-rw-r--r-- | src/H5Zfletcher32.c | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/src/H5Zfletcher32.c b/src/H5Zfletcher32.c new file mode 100644 index 0000000..4cd77ef --- /dev/null +++ b/src/H5Zfletcher32.c @@ -0,0 +1,164 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Raymond Lu <slu@ncsa.uiuc.edu> + * Jan 3, 2003 + */ + +#include "H5Zmodule.h" /* This source code file is part of the H5Z module */ + + +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fprivate.h" /* File access */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Zpkg.h" /* Data filters */ + +/* Local function prototypes */ +static size_t H5Z_filter_fletcher32 (unsigned flags, size_t cd_nelmts, + const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf); + +/* This message derives from H5Z */ +const H5Z_class2_t H5Z_FLETCHER32[1] = {{ + H5Z_CLASS_T_VERS, /* H5Z_class_t version */ + H5Z_FILTER_FLETCHER32, /* Filter id number */ + 1, /* encoder_present flag (set to true) */ + 1, /* decoder_present flag (set to true) */ + "fletcher32", /* Filter name for debugging */ + NULL, /* The "can apply" callback */ + NULL, /* The "set local" callback */ + H5Z_filter_fletcher32, /* The actual filter function */ +}}; + +#define FLETCHER_LEN 4 + + +/*------------------------------------------------------------------------- + * Function: H5Z_filter_fletcher32 + * + * Purpose: Implement an I/O filter of Fletcher32 Checksum + * + * Return: Success: Size of buffer filtered + * Failure: 0 + * + * Programmer: Raymond Lu + * Jan 3, 2003 + * + * Modifications: + * Raymond Lu + * July 8, 2005 + * There was a bug in the calculating code of the Fletcher32 + * checksum in the library before v1.6.3. The checksum + * value wasn't consistent between big-endian and little-endian + * systems. This bug was fixed in Release 1.6.3. However, + * after fixing the bug, the checksum value is no longer the + * same as before on little-endian system. We'll check both + * the correct checksum and the wrong checksum to be consistent + * with Release 1.6.2 and before. + *------------------------------------------------------------------------- + */ +static size_t +H5Z_filter_fletcher32 (unsigned flags, size_t H5_ATTR_UNUSED cd_nelmts, const unsigned H5_ATTR_UNUSED cd_values[], + size_t nbytes, size_t *buf_size, void **buf) +{ + void *outbuf = NULL; /* Pointer to new buffer */ + unsigned char *src = (unsigned char*)(*buf); + uint32_t fletcher; /* Checksum value */ + uint32_t reversed_fletcher; /* Possible wrong checksum value */ + uint8_t c[4]; + uint8_t tmp; + size_t ret_value = 0; /* Return value */ + + FUNC_ENTER_NOAPI(0) + + HDassert(sizeof(uint32_t)>=4); + + if (flags & H5Z_FLAG_REVERSE) { /* Read */ + /* Do checksum if it's enabled for read; otherwise skip it + * to save performance. */ + if (!(flags & H5Z_FLAG_SKIP_EDC)) { + unsigned char *tmp_src; /* Pointer to checksum in buffer */ + size_t src_nbytes = nbytes; /* Original number of bytes */ + uint32_t stored_fletcher; /* Stored checksum value */ + + /* Get the stored checksum */ + src_nbytes -= FLETCHER_LEN; + tmp_src=src+src_nbytes; + UINT32DECODE(tmp_src, stored_fletcher); + + /* Compute checksum (can't fail) */ + fletcher = H5_checksum_fletcher32(src, src_nbytes); + + /* The reversed checksum. There was a bug in the calculating code of + * the Fletcher32 checksum in the library before v1.6.3. The checksum + * value wasn't consistent between big-endian and little-endian systems. + * This bug was fixed in Release 1.6.3. However, after fixing the bug, + * the checksum value is no longer the same as before on little-endian + * system. We'll check both the correct checksum and the wrong + * checksum to be consistent with Release 1.6.2 and before. + */ + HDmemcpy(c, &fletcher, (size_t)4); + + tmp = c[1]; + c[1] = c[0]; + c[0] = tmp; + + tmp = c[3]; + c[3] = c[2]; + c[2] = tmp; + + HDmemcpy(&reversed_fletcher, c, (size_t)4); + + /* Verify computed checksum matches stored checksum */ + if(stored_fletcher != fletcher && stored_fletcher != reversed_fletcher) + HGOTO_ERROR(H5E_STORAGE, H5E_READERROR, 0, "data error detected by Fletcher32 checksum") + } + + /* Set return values */ + /* (Re-use the input buffer, just note that the size is smaller by the size of the checksum) */ + ret_value = nbytes-FLETCHER_LEN; + } else { /* Write */ + unsigned char *dst; /* Temporary pointer to destination buffer */ + + /* Compute checksum (can't fail) */ + fletcher = H5_checksum_fletcher32(src, nbytes); + + if (NULL == (outbuf = H5MM_malloc(nbytes + FLETCHER_LEN))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "unable to allocate Fletcher32 checksum destination buffer") + + dst = (unsigned char *) outbuf; + + /* Copy raw data */ + HDmemcpy((void*)dst, (void*)(*buf), nbytes); + + /* Append checksum to raw data for storage */ + dst += nbytes; + UINT32ENCODE(dst, fletcher); + + /* Free input buffer */ + H5MM_xfree(*buf); + + /* Set return values */ + *buf_size = nbytes + FLETCHER_LEN; + *buf = outbuf; + outbuf = NULL; + ret_value = *buf_size; + } + +done: + if(outbuf) + H5MM_xfree(outbuf); + FUNC_LEAVE_NOAPI(ret_value) +} + |