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
00073 template<typename X> finline
00074 static X shr( const X& value, unsigned int bits ) {
00075 return (sizeof(X)*8 == bits) ? 0 : (value >> bits);
00076 }
00077
00078 template<typename X> finline
00079 static X shl( const X& value, unsigned int bits ) {
00080 return (sizeof(X)*8 == bits) ? 0 : (value << bits);
00081 }
00082
00086 template<typename X> finline
00087 static X bitblk(size_t index, size_t length, bool value, if_uint(X)) {
00088 if (index == 0 && length >= sizeof(X) * 8) return value ? ~0 : 0;
00089 X x = shl(( shl( ((X) 1), length) - 1), index);
00090 return value ? x : ~x;
00091 }
00092
00096 template<typename X, bool value> finline
00097 static X bitblk(size_t index, size_t length, if_uint(X)) {
00098 return bitblk<X> (index, length, value);
00099 }
00100
00104 template<typename X, bool value> finline
00105 static X bitblk(size_t length, if_uint(X)) {
00106 if (length >= sizeof(X) * 8) return value ? ~0 : 0;
00107 return value ? (((X) 1 << length) - 1) : ~(((X) 1 << length) - 1);
00108 }
00109
00113 template<typename X, typename Y> finline
00114 static Y bitcpy(X src, size_t srcIdx, Y dst, size_t dstIdx, size_t len =
00115 sizeof(X) * 8, bool srcInvert = false, bool dstInvert = false,
00116 if_uint(X),if_uint (Y) ) {
00117 if (srcInvert) srcIdx = sizeof(X) * 8 - srcIdx - len;
00118 if (dstInvert) dstIdx = sizeof(Y) * 8 - dstIdx - len;
00119 Y value = ((Y)shr(src, srcIdx)) << dstIdx;
00120 Y mask = bitblk<Y, 0> (dstIdx, len);
00121 return (dst & mask) | (value & ~mask);
00122 }
00123
00128 template<typename X> finline
00129 static void bitcpy(X* src, size_t srcIdx, X* dst, size_t dstIdx, size_t len) {
00130
00131
00132 const size_t w = sizeof(X) * 8;
00133
00134
00135 size_t dwp = dstIdx % w, swp = srcIdx % w;
00136 size_t idwp = w - dwp, iswp = w - swp;
00137 dst += dstIdx / w;
00138 src += srcIdx / w;
00139
00140
00141 if (dwp == 0 && swp == 0 && len % w == 0) {
00142 memcpy(dst, src, len / 8);
00143 return;
00144 }
00145
00146
00147 if ((dwp + len) <= w) {
00148 X fw = shl(src[0],swp) | shr(src[1],iswp);
00149 *dst = bitcpy(fw, 0, *dst, dwp, len, true, true);
00150 return;
00151 }
00152
00153
00154 if (idwp != 0) {
00155 X fw = shl(src[0],swp) | shr(src[1],iswp);
00156 *dst = (*dst & ~(((X) 1 << idwp) - 1)) | shr(fw,dwp);
00157
00158
00159 dst++;
00160 src++;
00161 len -= idwp;
00162 swp = (swp + idwp) % w;
00163 iswp = w - swp;
00164 }
00165
00166 X a, b;
00167
00168
00169 if (swp == 0) {
00170 size_t numWords = len / w;
00171
00172 memcpy(dst, src, numWords * sizeof(X));
00173 src += numWords;
00174 dst += numWords;
00175 len = len % w;
00176 a = src[0], b = src[1];
00177 } else {
00178
00179 a = src[0], b = src[1];
00180 while (len >= w) {
00181 *dst = shl(a,swp) | shr(b,iswp);
00182 dst++;
00183 src++;
00184 len -= w;
00185 a = b;
00186 b = *src;
00187 }
00188 }
00189
00190
00191 X lw = shl(a,swp) | shr(b,iswp), lm = (shl((X) 1,(w - len)) - 1);
00192 *dst = (*dst & lm) | (lw & ~lm);
00193 }
00194
00195
00196
00200 template<typename X, typename Y> finline
00201 static void bitcpy(X* src, size_t srcIdx, Y& dst, size_t dstIdx, size_t len =
00202 sizeof(Y) * 8, if_uint(Y),if_uint (X) ) {
00203
00204
00205 const size_t w = sizeof(X) * 8;
00206
00207
00208 size_t swp = srcIdx % w, iswp = w - swp;
00209 src += srcIdx / w;
00210
00211
00212 dst &= bitblk<Y,0>(dstIdx,len);
00213
00214
00215 X a = src[0], b = src[1];
00216 Y value = 0;
00217 src++;
00218 while (len >= w) {
00219 X x = shl(a,swp) | shr(b,iswp);
00220 value <<= w;
00221 value |= x;
00222 src++;
00223 len -= w;
00224 a = b; b = *src;
00225 }
00226
00227
00228 if ( len> 0 ) {
00229 value <<= len;
00230 value |= ((shl(a,swp) | shr(b,iswp)) >> (w - len)) & (shl(1,len)-1);
00231 }
00232
00233
00234 dst |= (value << dstIdx);
00235 }
00236
00240
00241 template<typename X> finline
00242 static void bitcpy(X src, size_t srcIdx, X* dst, size_t dstIdx, size_t len =
00243 sizeof(X) * 8, bool srcInvert = false, if_uint(X)) {
00244
00245
00246 if (srcInvert) srcIdx = sizeof(X) * 8 - srcIdx - len;
00247
00248
00249 const size_t w = sizeof(X) * 8;
00250
00251
00252 size_t dwp = dstIdx % w;
00253 dst += dstIdx / w;
00254
00255
00256 if (dwp == 0 && srcIdx == 0 && len == w) {
00257 *dst = src;
00258 } else
00259
00260
00261 if ((dwp + len) <= w) {
00262 *dst = bitcpy(src, srcIdx, *dst, dwp, len, false, true);
00263
00264
00265 } else {
00266 size_t idwp = w - dwp;
00267 src >>= srcIdx;
00268 X mask1 = ~(shl(1,idwp) - 1);
00269 dst[0] = (dst[0] & mask1) | (shr(src,(len - idwp)) & ~mask1);
00270 X mask2 = shl(1,(w - len + idwp)) - 1;
00271 dst[1] = (dst[1] & mask2) | (shl(src, (w - len + idwp)) & ~mask2);
00272 }
00273 }
00274
00278
00279 template<typename Y, typename X> finline
00280 static void bitcpy(Y src, size_t srcIdx, X* dst, size_t dstIdx, size_t len =
00281 sizeof(Y) * 8, bool srcInvert = false, if_uint(X),if_uint (Y) ) {
00282
00283 if (sizeof(Y) <= sizeof(X)) {
00284
00285 if (srcInvert)
00286 srcIdx = sizeof(Y) * 8 - srcIdx - len + (sizeof(X)-sizeof(Y))*8;
00287 bitcpy((X)src,srcIdx,dst,dstIdx,len,false);
00288 } else {
00289
00290 if (srcInvert) srcIdx = sizeof(Y) * 8 - srcIdx - len;
00291 src = shr(src, srcIdx);
00292
00293 const size_t dw = sizeof(X)*8;
00294 while (len >= dw) {
00295 X word = (X)shr(src,(len-dw));
00296 bitcpy(word,0,dst,dstIdx,dw);
00297 dstIdx += dw;
00298 len -= dw;
00299 }
00300 X word = (X)src;
00301 bitcpy(word,0,dst,dstIdx,len);
00302 }
00303 }
00304
00308 template<typename T, typename X> finline
00309 static T bitget(X* src, size_t idx, size_t len = sizeof(T) * 8, if_uint(X),if_uint (T) ) {
00310 T x = 0;
00311 bitcpy(src, idx, x, 0, len );
00312 return x;
00313 }
00314
00318 template<typename T, typename X> finline
00319 static T bitget(X src, size_t idx, size_t len = sizeof(T) * 8, if_uint(X),if_uint (T) ) {
00320 T x = 0;
00321 bitcpy(src, idx, x, 0, len );
00322 return x;
00323 }
00324
00328 template<typename X> finline
00329 static bool bitget(X* src, size_t index, if_uint(X)) {
00330 uint8_t x = 0;
00331 bitcpy(src, index, x, 0, 1);
00332 return x != 0;
00333 }
00334
00338 template<typename X> finline
00339 static bool bitget(X src, size_t index, if_uint(X)) {
00340 uint8_t x = 0;
00341 x = bitcpy(src, index, x, 0, 1);
00342 return x != 0;
00343 }
00344
00348 template<typename T, typename X> finline
00349 static void bitset(T src, X* dst, size_t index, if_uint(X),if_uint (T) ) {
00350 bitcpy(src,0,dst,index);
00351 }
00352
00356 template<typename X> finline
00357 static void bitset(bool src, X* dst, size_t index, if_uint(X) ) {
00358 bitcpy(src != 0, 0, dst, index, 1);
00359 }
00360
00364 template<typename X> finline
00365 static X bitset(bool src, X dst, size_t index, if_uint(X)) {
00366 return bitcpy(src != 0, 0, dst, index, 1);
00367 }
00368
00372 template<typename X> finline
00373 static X bitrev(X src, if_uint(X) ) {
00374 const size_t width = sizeof(X) * 8;
00375 X dst = 0;
00376 for (size_t i = 0; i < width; i++)
00377 dst = bitset(bitget(src, i), dst, width - i - 1);
00378 return dst;
00379 }
00380
00384 template<typename X> finline
00385 static void bitrev(X* src, size_t len, if_uint(X) ) {
00386 for (size_t i = 0; i < len / 2; i++) {
00387 bool b0 = bitget(src, i);
00388 bool b1 = bitget(src, len - i - 1);
00389 bitset(b1, src, i);
00390 bitset(b0, src, len - i - 1);
00391 }
00392 }
00393
00397 template<typename X> finline
00398 static X switch_endian(X src, if_uint(X) ) {
00399 if (sizeof(X) == 1) return src;
00400 X ret = 0;
00401 for (size_t i = 0; i < sizeof(X); i++) {
00402 ret <<= 8;
00403 ret |= src & 0xFF;
00404 src >>= 8;
00405 }
00406 return ret;
00407 }
00408
00412 template<typename X> finline
00413 static std::string bitstr(X src, int log2base = 4, if_uint(X)) {
00414 const size_t word_width = sizeof(src) * 8;
00415 const char digit[37] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
00416
00417 std::string str;
00418 for (int i = word_width - log2base, j = 0; i >= 0; i -= log2base, j++)
00419 str.append(1, digit[(src >> i) & ((1 << log2base) - 1)]);
00420 return str;
00421 }
00422
00426 template<typename X> finline
00427 static std::string bitstr(X* src, size_t len, int log2base = 4, bool dot =
00428 false, if_uint(X)) {
00429 std::string str;
00430 for (size_t i = 0; i < len / 8 / sizeof(X); i++) {
00431 if (i != 0 && dot) str.append(".");
00432 str.append(bitstr(src[i], log2base));
00433 }
00434 return str;
00435 }
00436
00437 #endif