00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #ifndef DATAUTILITIES_HPP_
00064 #define DATAUTILITIES_HPP_
00065
00066 #include "../internal/Utilities.hpp"
00067
00068 #include <boost/cstdint.hpp>
00069
00070 #include <memory>
00071 #include <string>
00072
00076 template<typename X> finline
00077 static X bitblk(size_t index, size_t length, bool value, if_uint(X)) {
00078 if (index == 0 && length >= sizeof(X) * 8) return value ? ~0 : 0;
00079 X x = ((((X) 1) << length) - 1) << index;
00080 return value ? x : ~x;
00081 }
00082
00086 template<typename X, bool value> finline
00087 static X bitblk(size_t index, size_t length, if_uint(X)) {
00088 return bitblk<X> (index, length, value);
00089 }
00090
00094 template<typename X, bool value> finline
00095 static X bitblk(size_t length, if_uint(X)) {
00096 if (length >= sizeof(X) * 8) return value ? ~0 : 0;
00097 return value ? (((X) 1 << length) - 1) : ~(((X) 1 << length) - 1);
00098 }
00099
00103 template<typename X, typename Y> finline
00104 static Y bitcpy(X src, size_t srcIdx, Y dst, size_t dstIdx, size_t len =
00105 sizeof(X) * 8, bool srcInvert = false, bool dstInvert = false,
00106 if_uint(X),if_uint (Y) ) {
00107 if (srcInvert) srcIdx = sizeof(X) * 8 - srcIdx - len;
00108 if (dstInvert) dstIdx = sizeof(Y) * 8 - dstIdx - len;
00109 Y value = ((Y) (src >> srcIdx)) << dstIdx;
00110 Y mask = bitblk<Y, 0> (dstIdx, len);
00111 return (dst & mask) | (value & ~mask);
00112 }
00113
00118 template<typename X> finline
00119 static void bitcpy(X* src, size_t srcIdx, X* dst, size_t dstIdx, size_t len) {
00120
00121
00122 const size_t w = sizeof(X) * 8;
00123
00124
00125 size_t dwp = dstIdx % w, swp = srcIdx % w;
00126 size_t idwp = w - dwp, iswp = w - swp;
00127 dst += dstIdx / w;
00128 src += srcIdx / w;
00129
00130
00131 if (dwp == 0 && swp == 0 && len % w == 0) {
00132 memcpy(dst, src, len / 8);
00133 return;
00134 }
00135
00136
00137 if ((dwp + len) <= w) {
00138 X fw = (src[0] << swp) | (src[1] >> iswp);
00139 *dst = bitcpy(fw, 0, *dst, dwp, len, true, true);
00140 return;
00141 }
00142
00143
00144 if (idwp != 0) {
00145 X fw = (src[0] << swp) | (src[1] >> iswp);
00146 *dst = (*dst & ~(((X) 1 << idwp) - 1)) | (fw >> dwp);
00147
00148
00149 dst++;
00150 src++;
00151 len -= idwp;
00152 swp = (swp + idwp) % w;
00153 iswp = w - swp;
00154 }
00155
00156 X a, b;
00157
00158
00159 if (swp == 0) {
00160 size_t numWords = len / w;
00161
00162 memcpy(dst, src, numWords * sizeof(X));
00163 src += numWords;
00164 dst += numWords;
00165 len = len % w;
00166 a = src[0], b = src[1];
00167 } else {
00168
00169 a = src[0], b = src[1];
00170 while (len >= w) {
00171 *dst = (a << swp) | (b >> iswp);
00172 dst++;
00173 src++;
00174 len -= w;
00175 a = b;
00176 b = *src;
00177 }
00178 }
00179
00180
00181 X lw = (a << swp) | (b >> iswp), lm = (((X) 1 << (w - len)) - 1);
00182 *dst = (*dst & lm) | (lw & ~lm);
00183 }
00184
00188 template<typename X, typename Y> finline
00189 static void bitcpy(X* src, size_t srcIdx, Y& dst, size_t dstIdx, size_t len =
00190 sizeof(Y) * 8, if_uint(Y),if_uint (X) ) {
00191
00192
00193 const size_t w = sizeof(X) * 8;
00194
00195
00196 size_t swp = srcIdx % w, iswp = w - swp;
00197 src += srcIdx / w;
00198
00199
00200 dst &= bitblk<Y,0>(dstIdx,len);
00201
00202
00203 X a = src[0], b = src[1];
00204 Y value = 0;
00205 src++;
00206 while (len >= w) {
00207 X x = (a << swp) | (b >> iswp);
00208 value <<= w;
00209 value |= x;
00210 src++;
00211 len -= w;
00212 a = b; b = *src;
00213 }
00214
00215
00216 if ( len> 0 ) {
00217 value <<= len;
00218 value |= (((a << swp) | (b >> iswp)) >> (w - len)) & ((1 << len)-1);
00219 }
00220
00221
00222 dst |= (value << dstIdx);
00223 }
00224
00228
00229 template<typename X> finline
00230 static void bitcpy(X src, size_t srcIdx, X* dst, size_t dstIdx, size_t len =
00231 sizeof(X) * 8, bool srcInvert = false, if_uint(X)) {
00232
00233
00234 if (srcInvert) srcIdx = sizeof(X) * 8 - srcIdx - len;
00235
00236
00237 const size_t w = sizeof(X) * 8;
00238
00239
00240 size_t dwp = dstIdx % w;
00241 dst += dstIdx / w;
00242
00243
00244 if (dwp == 0 && srcIdx == 0 && len == w) {
00245 *dst = src;
00246 } else
00247
00248
00249 if ((dwp + len) <= w) {
00250 *dst = bitcpy(src, srcIdx, *dst, dwp, len, false, true);
00251
00252
00253 } else {
00254 size_t idwp = w - dwp;
00255 src >>= srcIdx;
00256 X mask1 = ~((1 << idwp) - 1);
00257 dst[0] = (dst[0] & mask1) | ((src >> (len - idwp)) & ~mask1);
00258 X mask2 = (1 << (w - len + idwp)) - 1;
00259 dst[1] = (dst[1] & mask2) | ((src << (w - len + idwp)) & ~mask2);
00260 }
00261 }
00262
00266
00267 template<typename Y, typename X> finline
00268 static void bitcpy(Y src, size_t srcIdx, X* dst, size_t dstIdx, size_t len =
00269 sizeof(Y) * 8, bool srcInvert = false, if_uint(X),if_uint (Y) ) {
00270
00271 if (sizeof(Y) <= sizeof(X)) {
00272
00273 if (srcInvert)
00274 srcIdx = sizeof(Y) * 8 - srcIdx - len + (sizeof(X)-sizeof(Y))*8;
00275 bitcpy((X)src,srcIdx,dst,dstIdx,len,false);
00276 } else {
00277
00278 if (srcInvert) srcIdx = sizeof(Y) * 8 - srcIdx - len;
00279 src >>= srcIdx;
00280
00281 const size_t dw = sizeof(X)*8;
00282 while (len >= dw) {
00283 X word = (X)(src >> (len-dw));
00284 bitcpy(word,0,dst,dstIdx,dw);
00285 dstIdx += dw;
00286 len -= dw;
00287 }
00288 X word = (X)src;
00289 bitcpy(word,0,dst,dstIdx,len);
00290 }
00291 }
00292
00296 template<typename T, typename X> finline
00297 static T bitget(X* src, size_t idx, size_t len = sizeof(T) * 8, if_uint(X),if_uint (T) ) {
00298 T x = 0;
00299 bitcpy(src, idx, x, 0, len );
00300 return x;
00301 }
00302
00306 template<typename T, typename X> finline
00307 static T bitget(X src, size_t idx, size_t len = sizeof(T) * 8, if_uint(X),if_uint (T) ) {
00308 T x = 0;
00309 bitcpy(src, idx, x, 0, len );
00310 return x;
00311 }
00312
00316 template<typename X> finline
00317 static bool bitget(X* src, size_t index, if_uint(X)) {
00318 uint8_t x = 0;
00319 bitcpy(src, index, x, 0, 1);
00320 return x != 0;
00321 }
00322
00326 template<typename X> finline
00327 static bool bitget(X src, size_t index, if_uint(X)) {
00328 uint8_t x = 0;
00329 x = bitcpy(src, index, x, 0, 1);
00330 return x != 0;
00331 }
00332
00336 template<typename T, typename X> finline
00337 static void bitset(T src, X* dst, size_t index, if_uint(X),if_uint (T) ) {
00338 bitcpy(src,0,dst,index);
00339 }
00340
00344 template<typename X> finline
00345 static void bitset(bool src, X* dst, size_t index, if_uint(X) ) {
00346 bitcpy(src != 0, 0, dst, index, 1);
00347 }
00348
00352 template<typename X> finline
00353 static X bitset(bool src, X dst, size_t index, if_uint(X)) {
00354 return bitcpy(src != 0, 0, dst, index, 1);
00355 }
00356
00360 template<typename X> finline
00361 static X bitrev(X src, if_uint(X) ) {
00362 const size_t width = sizeof(X) * 8;
00363 X dst = 0;
00364 for (size_t i = 0; i < width; i++)
00365 dst = bitset(bitget(src, i), dst, width - i - 1);
00366 return dst;
00367 }
00368
00372 template<typename X> finline
00373 static void bitrev(X* src, size_t len, if_uint(X) ) {
00374 for (size_t i = 0; i < len / 2; i++) {
00375 bool b0 = bitget(src, i);
00376 bool b1 = bitget(src, len - i - 1);
00377 bitset(b1, src, i);
00378 bitset(b0, src, len - i - 1);
00379 }
00380 }
00381
00385 template<typename X> finline
00386 static X switch_endian(X src, if_uint(X) ) {
00387 if (sizeof(X) == 1) return src;
00388 X ret = 0;
00389 for (size_t i = 0; i < sizeof(X); i++) {
00390 ret <<= 8;
00391 ret |= src & 0xFF;
00392 src >>= 8;
00393 }
00394 return ret;
00395 }
00396
00400 template<typename X> finline
00401 static std::string bitstr(X src, int log2base = 4, if_uint(X)) {
00402 const size_t word_width = sizeof(src) * 8;
00403 const char digit[37] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
00404
00405 std::string str;
00406 for (int i = word_width - log2base, j = 0; i >= 0; i -= log2base, j++)
00407 str.append(1, digit[(src >> i) & ((1 << log2base) - 1)]);
00408 return str;
00409 }
00410
00414 template<typename X> finline
00415 static std::string bitstr(X* src, size_t len, int log2base = 4, bool dot =
00416 false, if_uint(X)) {
00417 std::string str;
00418 for (size_t i = 0; i < len / 8 / sizeof(X); i++) {
00419 if (i != 0 && dot) str.append(".");
00420 str.append(bitstr(src[i], log2base));
00421 }
00422 return str;
00423 }
00424
00425 #endif