diff --git a/Makefile.am b/Makefile.am
index 9db11916..1a05dbb6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -7,12 +7,18 @@ AM_CXXFLAGS = $(BOOST_CPPFLAGS) $(COMMON_CXXFLAGS)
SUBDIRS = test
UTIL_FILES = \
+ adler.hpp \
+ adler.cpp \
annotations.hpp \
backtrace.hpp \
bitwise.cpp \
bitwise.hpp \
+ bsdsum.hpp \
+ bsdsum.cpp \
colour.cpp \
colour.hpp \
+ crc.cpp \
+ crc.hpp \
debug.cpp \
debug.hpp \
enable_if.hpp \
@@ -24,6 +30,7 @@ UTIL_FILES = \
extent.hpp \
fixed.cpp \
fixed.hpp \
+ fletcher.hpp \
float.cpp \
float.hpp \
fwd.hpp \
diff --git a/adler.cpp b/adler.cpp
new file mode 100644
index 00000000..8f844300
--- /dev/null
+++ b/adler.cpp
@@ -0,0 +1,30 @@
+/*
+ * This file is part of libgim.
+ *
+ * Waif is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * Waif is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with libgim. If not, see .
+ *
+ * Copyright 2010 Danny Robson
+ */
+
+#include "adler.hpp"
+
+#include "debug.hpp"
+#include "fletcher.hpp"
+
+static const unsigned MODULUS = 65521;
+
+uint32_t
+adler32 (const void* restrict _data, size_t _size)
+ { return fletcher<32, MODULUS, 1, 0> (_data, _size); }
+
diff --git a/adler.hpp b/adler.hpp
new file mode 100644
index 00000000..e76a9670
--- /dev/null
+++ b/adler.hpp
@@ -0,0 +1,28 @@
+/*
+ * This file is part of libgim.
+ *
+ * Waif is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * Waif is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with libgim. If not, see .
+ *
+ * Copyright 2010 Danny Robson
+ */
+
+#ifndef __UTIL_ADLER_HPP
+#define __UTIL_ADLER_HPP
+
+#include
+#include
+
+extern uint32_t adler32(const void* restrict, size_t);
+
+#endif
diff --git a/bsdsum.cpp b/bsdsum.cpp
new file mode 100644
index 00000000..016e32fb
--- /dev/null
+++ b/bsdsum.cpp
@@ -0,0 +1,35 @@
+/*
+ * This file is part of libgim.
+ *
+ * Waif is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * Waif is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with libgim. If not, see .
+ *
+ * Copyright 2010 Danny Robson
+ */
+
+#include "bsdsum.hpp"
+
+
+uint16_t
+bsdsum (const void *restrict _data, size_t size) {
+ const uint8_t *restrict data = static_cast (data);
+ uint16_t accum = 0;
+
+ for (size_t i = 0; i < size; ++i) {
+ accum = (accum >> 1) | ((accum & 0x1) << 15);
+ accum += data[i];
+ }
+
+ return accum;
+}
+
diff --git a/bsdsum.hpp b/bsdsum.hpp
new file mode 100644
index 00000000..c1d80e51
--- /dev/null
+++ b/bsdsum.hpp
@@ -0,0 +1,28 @@
+/*
+ * This file is part of libgim.
+ *
+ * Waif is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * Waif is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with libgim. If not, see .
+ *
+ * Copyright 2010 Danny Robson
+ */
+
+#ifndef __UTIL_BSDSUM_HPP
+#define __UTIL_BSDSUMP_HPP
+
+#include
+#include
+
+uint16_t bsdsum (const void *restrict, size_t);
+
+#endif
diff --git a/crc.cpp b/crc.cpp
new file mode 100644
index 00000000..8d26f0ed
--- /dev/null
+++ b/crc.cpp
@@ -0,0 +1,58 @@
+/*
+ * This file is part of libgim.
+ *
+ * libgim is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * libgim is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with libgim. If not, see .
+ *
+ * Copyright 2011 Danny Robson
+ */
+
+#include "crc.hpp"
+
+#include "debug.hpp"
+#include "endian.hpp"
+
+uint32_t
+crc32 (const void *restrict, size_t) {
+ not_implemented ();
+
+ /*
+ const uint8_t *restrict data = static_cast (_data);
+ static const uint32_t POLYNOMIAL = hton (static_cast(0x04C11DB7));
+
+ uint64_t bits = 0;
+ unsigned int i = 0;
+
+ if (size == 0)
+ return POLYNOMIAL;
+
+ switch (size) {
+ default: bits |= static_cast(data[3]) << 32U;
+ case 3: bits |= static_cast(data[2]) << 40U;
+ case 2: bits |= static_cast(data[1]) << 48U;
+ case 1: bits |= static_cast(data[0]) << 56U;
+ }
+
+ for (size_t i = 0; i < size; ++i) {
+ for (unsigned j = 0; j < 32; ++j) {
+ bool mix = bits 0x7000000000000000ULL;
+ bits <<= 1;
+
+ if (mix)
+ bits ^= POLYNOMIAL << 32;
+ }
+
+
+ }
+ */
+}
diff --git a/crc.hpp b/crc.hpp
new file mode 100644
index 00000000..f6979b12
--- /dev/null
+++ b/crc.hpp
@@ -0,0 +1,29 @@
+/*
+ * This file is part of libgim.
+ *
+ * libgim is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * libgim is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with libgim. If not, see .
+ *
+ * Copyright 2011 Danny Robson
+ */
+
+#ifndef __UTIL_CRC_HPP
+#define __UTIL_CRC_HPP
+
+#include
+#include
+
+uint32_t crc32 (const void *restrict, size_t);
+
+#endif
+
diff --git a/fletcher.hpp b/fletcher.hpp
new file mode 100644
index 00000000..a63ebcaa
--- /dev/null
+++ b/fletcher.hpp
@@ -0,0 +1,44 @@
+/*
+ * This file is part of libgim.
+ *
+ * Waif is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * Waif is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with libgim. If not, see .
+ *
+ * Copyright 2010 Danny Robson
+ */
+
+#ifndef __UTIL_FLETCHER_HPP
+#define __UTIL_FLETCHER_HPP
+
+#include "types.hpp"
+
+#include
+#include
+
+template
+typename bits_type::uint
+fletcher (const void *restrict _data, size_t size) {
+ const uint8_t *restrict data = static_cast (_data);
+ typename bits_type::uint A = INITIAL_A,
+ B = INITIAL_B;
+
+ for (size_t i = 0; i < size; ++i) {
+ A = (A + data[i]) % MODULUS;
+ B = (A + B) % MODULUS;
+ }
+
+ return (B << (BITS / 2)) | A;
+}
+
+#endif
+
diff --git a/test/.gitignore b/test/.gitignore
index 90d95a58..65f608cc 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -1,3 +1,4 @@
+/adler
/backtrace*
/float*
/hton*
diff --git a/test/Makefile.am b/test/Makefile.am
index f9b97c77..113d4bc1 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -9,6 +9,7 @@ AM_LDFLAGS = $(COMMON_LDFLAGS)
TEST_BIN = \
backtrace \
+ checksum \
float \
hton \
ip \
@@ -27,6 +28,9 @@ backtrace_CPPFLAGS = $(COMMON_CXXFLAGS)
backtrace_LDADD = $(builddir)/../libutil.la
backtrace_SOURCES = backtrace.cpp
+checksum_LDADD = $(builddir)/../libutil.la
+checksum_SOURCES = checksum.cpp
+
float_LDADD = $(builddir)/../libutil.la
float_SOURCES = float.cpp
diff --git a/test/checksum.cpp b/test/checksum.cpp
new file mode 100644
index 00000000..dbb6315c
--- /dev/null
+++ b/test/checksum.cpp
@@ -0,0 +1,32 @@
+
+#include "adler.hpp"
+#include "bsdsum.hpp"
+#include "types.hpp"
+
+#include
+#include
+
+using namespace std;
+
+static const char *ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+static const struct {
+ uint32_t adler;
+ uint16_t bsd;
+
+ const char *data;
+ size_t size;
+} TESTS[] = {
+ { 0xDF5B150C, 0x52FB, ALPHABET, strlen (ALPHABET) }
+};
+
+
+int
+main (int, char**) {
+ for (unsigned i = 0; i < elems (TESTS); ++i) {
+ check_eq (TESTS[i].adler, adler32 (TESTS[i].data, TESTS[i].size));
+ check_eq (TESTS[i].bsd, bsdsum (TESTS[i].data, TESTS[i].size));
+ }
+
+ return EXIT_SUCCESS;
+}