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; +}