00001
00020 #include "Compat.h"
00021 #include <arpa/inet.h>
00022 #include <zlib.h>
00023 #include "Checksum.h"
00024
00025 namespace Hypertable {
00026
00027 #define HT_F32_DO1(buf,i) \
00028 sum1 += ((uint16_t)buf[i] << 8) | buf[i+1]; sum2 += sum1
00029 #define HT_F32_DO2(buf,i) HT_F32_DO1(buf,i); HT_F32_DO1(buf,i+2);
00030 #define HT_F32_DO4(buf,i) HT_F32_DO2(buf,i); HT_F32_DO2(buf,i+4);
00031 #define HT_F32_DO8(buf,i) HT_F32_DO4(buf,i); HT_F32_DO4(buf,i+8);
00032 #define HT_F32_DO16(buf,i) HT_F32_DO8(buf,i); HT_F32_DO8(buf,i+16);
00033
00034
00035
00036 uint32_t
00037 fletcher32(const void *data8, size_t len8) {
00038
00039
00040
00041 const uint8_t *data = (const uint8_t *)data8;
00042 uint32_t sum1 = 0xffff, sum2 = 0xffff;
00043 size_t len = len8 / 2;
00044
00045 while (len) {
00046
00047
00048
00049 unsigned tlen = len > 360 ? 360 : len;
00050 len -= tlen;
00051
00052 if (tlen >= 16) do {
00053 HT_F32_DO16(data, 0);
00054 data += 32;
00055 tlen -= 16;
00056 } while (tlen >= 16);
00057
00058 if (tlen != 0) do {
00059 HT_F32_DO1(data, 0);
00060 data += 2;
00061 } while (--tlen);
00062
00063 sum1 = (sum1 & 0xffff) + (sum1 >> 16);
00064 sum2 = (sum2 & 0xffff) + (sum2 >> 16);
00065 }
00066
00067
00068 if (len8 & 1) {
00069 sum1 += ((uint16_t)*data) << 8;
00070 sum2 += sum1;
00071 sum1 = (sum1 & 0xffff) + (sum1 >> 16);
00072 sum2 = (sum2 & 0xffff) + (sum2 >> 16);
00073 }
00074
00075
00076 sum1 = (sum1 & 0xffff) + (sum1 >> 16);
00077 sum2 = (sum2 & 0xffff) + (sum2 >> 16);
00078 return (sum2 << 16) | sum1;
00079 }
00080
00081 #define HT_F32A_DO1(buf, i) sum1 += ntohs(buf[i]); sum2 += sum1;
00082 #define HT_F32A_DO2(buf,i) HT_F32A_DO1(buf,i); HT_F32A_DO1(buf,i+1);
00083 #define HT_F32A_DO4(buf,i) HT_F32A_DO2(buf,i); HT_F32A_DO2(buf,i+2);
00084 #define HT_F32A_DO8(buf,i) HT_F32A_DO4(buf,i); HT_F32A_DO4(buf,i+4);
00085 #define HT_F32A_DO16(buf,i) HT_F32A_DO8(buf,i); HT_F32A_DO8(buf,i+8);
00086
00087 uint32_t
00088 fletcher32a(const uint16_t *data, size_t len) {
00089 uint32_t sum1 = 0xffff, sum2 = 0xffff;
00090
00091 while (len) {
00092
00093
00094
00095 unsigned tlen = len > 360 ? 360 : len;
00096 len -= tlen;
00097
00098 if (tlen >= 16) do {
00099 HT_F32A_DO16(data, 0);
00100 data += 16;
00101 tlen -= 16;
00102 } while (tlen >= 16);
00103
00104 if (tlen != 0) do {
00105 sum1 += ntohs(*data);
00106 ++data;
00107 sum2 += sum1;
00108 } while (--tlen);
00109
00110 sum1 = (sum1 & 0xffff) + (sum1 >> 16);
00111 sum2 = (sum2 & 0xffff) + (sum2 >> 16);
00112 }
00113
00114 sum1 = (sum1 & 0xffff) + (sum1 >> 16);
00115 sum2 = (sum2 & 0xffff) + (sum2 >> 16);
00116 return (sum2 << 16) | sum1;
00117 }
00118
00119
00120
00121
00122 #define MOD_ADLER 65521
00123
00124 inline uint32_t
00125 adler32_update_wp(uint32_t adler, const void *data8, size_t len) {
00126 const uint8_t *data = (const uint8_t *)data8;
00127 uint32_t a = adler & 0xffff, b = (adler >> 16) & 0xffff;
00128
00129 while (len) {
00130
00131
00132
00133 size_t tlen = len > 5550 ? 5550 : len;
00134 len -= tlen;
00135 do {
00136 a += *data++;
00137 b += a;
00138 } while (--tlen);
00139
00140 a = (a & 0xffff) + (a >> 16) * (65536 - MOD_ADLER);
00141 b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER);
00142 }
00143
00144
00145 if (a >= MOD_ADLER)
00146 a -= MOD_ADLER;
00147
00148
00149 b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER);
00150
00151 if (b >= MOD_ADLER)
00152 b -= MOD_ADLER;
00153
00154 return (b << 16) | a;
00155 }
00156
00157 uint32_t
00158 adler32_wp(const void *data, size_t len) {
00159 return adler32_update_wp(1, data, len);
00160 }
00161
00162 #define HT_A32_DO1(buf,i) a += buf[i]; b += a
00163 #define HT_A32_DO2(buf,i) HT_A32_DO1(buf,i); HT_A32_DO1(buf,i+1);
00164 #define HT_A32_DO4(buf,i) HT_A32_DO2(buf,i); HT_A32_DO2(buf,i+2);
00165 #define HT_A32_DO8(buf,i) HT_A32_DO4(buf,i); HT_A32_DO4(buf,i+4);
00166 #define HT_A32_DO16(buf,i) HT_A32_DO8(buf,i); HT_A32_DO8(buf,i+8);
00167
00168 inline uint32_t
00169 adler32_update(uint32_t adler, const void *data8, size_t len) {
00170 const uint8_t *data = (const uint8_t *)data8;
00171 uint32_t a = adler & 0xffff, b = (adler >> 16) & 0xffff;
00172
00173 while (len) {
00174 size_t tlen = len > 5552 ? 5552 : len;
00175 len -= tlen;
00176
00177 if (tlen >= 16) do {
00178 HT_A32_DO16(data, 0);
00179 data += 16;
00180 tlen -= 16;
00181 } while (tlen >= 16);
00182
00183 if (tlen != 0) do {
00184 a += *data++;
00185 b += a;
00186 } while (--tlen > 0);
00187
00188 a %= MOD_ADLER;
00189 b %= MOD_ADLER;
00190 }
00191 return (b << 16) | a;
00192 }
00193
00194 uint32_t
00195 adler32(const void *data, size_t len) {
00196 return adler32_update(1, data, len);
00197 }
00198
00199 uint32_t
00200 crc32(const void *data, size_t len) {
00201 uint32_t crc = ::crc32(0LL, Z_NULL, 0);
00202 return ::crc32(crc, (Bytef *)data, len);
00203 }
00204
00205 uint32_t
00206 crc32_update(uint32_t crc, const void *data, size_t len) {
00207 return ::crc32(crc, (Bytef *)data, len);
00208 }
00209
00210 }
00211
00212
00213