summaryrefslogtreecommitdiffstats
path: root/src/H5Zfletcher32.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Zfletcher32.c')
-rw-r--r--src/H5Zfletcher32.c161
1 files changed, 161 insertions, 0 deletions
diff --git a/src/H5Zfletcher32.c b/src/H5Zfletcher32.c
new file mode 100644
index 0000000..bd4c68f
--- /dev/null
+++ b/src/H5Zfletcher32.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright © 1999-2001 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Raymond Lu<slu@ncsa.uiuc.edu>
+ * Jan 3, 2003
+ */
+#include "H5private.h"
+#include "H5Eprivate.h"
+#include "H5MMprivate.h"
+#include "H5Zprivate.h"
+
+#ifdef H5_HAVE_FILTER_FLETCHER32
+
+#define FLETCHER_LEN 4
+
+/* Interface initialization */
+#define PABLO_MASK H5Z_fletcher32_mask
+#define INTERFACE_INIT NULL
+static int interface_initialize_g = 0;
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_filter_fletcher32_compute
+ *
+ * Purpose: Implement an Fletcher32 Checksum using 1's complement.
+ *
+ * Return: Success: Fletcher32 value
+ *
+ * Failure: Can't fail
+ *
+ * Programmer: Raymond Lu
+ * Jan 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static unsigned int H5Z_filter_fletcher32_compute(unsigned short *buf, size_t len)
+{
+ size_t count = len;
+ register unsigned int s1 = 0;
+ register unsigned int s2 = 0;
+ unsigned short *src = buf;
+
+ FUNC_ENTER_NOINIT(H5Z_filter_fletcher32_compute);
+
+ /* Compute checksum */
+ while(count > 1) {
+ s1 += *src++;
+ if(s1 & 0xFFFF0000) { /*Wrap around carry if occurred*/
+ s1 &= 0xFFFF;
+ s1++;
+ }
+ s2 += s1;
+ if(s2 & 0xFFFF0000) { /*Wrap around carry if occurred*/
+ s2 &= 0xFFFF;
+ s2++;
+ }
+ count -= 2;
+ }
+
+ if(count==1) {
+ s1 += *(unsigned char*)src;
+ if(s1 & 0xFFFF0000) { /*Wrap around carry if occurred*/
+ s1 &= 0xFFFF;
+ s1++;
+ }
+ s2 += s1;
+ if(s2 & 0xFFFF0000) { /*Wrap around carry if occurred*/
+ s2 &= 0xFFFF;
+ s2++;
+ }
+ }
+
+ FUNC_LEAVE_NOAPI((s2 << 16) + s1);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_filter_fletcher32
+ *
+ * Purpose: Implement an I/O filter of Fletcher32 Checksum
+ *
+ * Return: Success: size of data plus the size of Fletcher32 value
+ *
+ * Failure: 0
+ *
+ * Programmer: Raymond Lu
+ * Jan 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5Z_filter_fletcher32 (unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
+ size_t nbytes, size_t *buf_size, void **buf)
+{
+ size_t ret_value = 0;
+ void *outbuf = NULL;
+
+ unsigned char *src = (unsigned char*)(*buf);
+ unsigned int fletcher = 0;
+
+ FUNC_ENTER_NOAPI(H5Z_filter_fletcher32, 0);
+
+ assert(sizeof(unsigned int)==4);
+
+ if (flags & H5Z_FLAG_REVERSE) { /* Read */
+ size_t src_nbytes = nbytes;
+ unsigned int origin_fletcher;
+
+ /* Do checksum if it's enabled for read; otherwise skip it
+ * to save performance. */
+ if (!(flags & H5Z_FLAG_SKIP_EDC)) { /* Read */
+ unsigned char *tmp_src;
+
+ src_nbytes -= FLETCHER_LEN;
+ tmp_src=src+src_nbytes;
+ UINT32DECODE(tmp_src, origin_fletcher);
+
+ /* Compute checksum */
+ fletcher = H5Z_filter_fletcher32_compute((unsigned short*)src,src_nbytes);
+
+ if(origin_fletcher != fletcher)
+ HGOTO_ERROR(H5E_STORAGE, H5E_READERROR, 0, "data error detected by Fletcher32 checksum");
+ }
+
+ *buf_size = nbytes - FLETCHER_LEN;
+ ret_value = *buf_size;
+ } else { /* Write */
+ unsigned char *dst;
+
+ /* Compute checksum */
+ fletcher = H5Z_filter_fletcher32_compute((unsigned short*)src,nbytes);
+
+ if (NULL==(dst=outbuf=H5MM_malloc(nbytes+FLETCHER_LEN)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "unable to allocate Fletcher32 checksum destination buffer");
+
+ /* Copy raw data */
+ HDmemcpy((void*)dst, (void*)(*buf), nbytes);
+
+ /* Append checksum to raw data */
+ dst += nbytes;
+ UINT32ENCODE(dst, fletcher);
+
+ *buf_size = nbytes + FLETCHER_LEN;
+ H5MM_xfree(*buf);
+ *buf = outbuf;
+ outbuf = NULL;
+ ret_value = *buf_size;
+ }
+
+done:
+ if(outbuf)
+ H5MM_xfree(outbuf);
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+#endif /* H5_HAVE_FILTER_FLETCHER32 */