Advertisement
zamotivator

Untitled

Jan 23rd, 2013
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <climits>
  2. #include <cstring>
  3. #include <cstddef>
  4.  
  5. #define PREPARE_FIRST_COPY()                                            \
  6.     do {                                                                \
  7.         if (src_len >= (CHAR_BIT - dst_offset_modulo)) {                \
  8.             *dst     &= reverse_mask[dst_offset_modulo];                \
  9.             src_len -= CHAR_BIT - dst_offset_modulo;                    \
  10.         } else {                                                        \
  11.             *dst     &= reverse_mask[dst_offset_modulo]                 \
  12.                 | reverse_mask_xor[dst_offset_modulo + src_len + 1];    \
  13.             c       &= reverse_mask[dst_offset_modulo + src_len    ];   \
  14.             src_len = 0;                                                \
  15.         } } while (0)
  16.  
  17. /*
  18.   Copy of unaligned arrays.
  19.   http://stackoverflow.com/a/3535337/1454243
  20. */
  21. static int bitarray_copy(const unsigned char *src_org, int src_offset, int src_len, unsigned char *dst_org, int dst_offset)
  22. {
  23.     static const unsigned char mask[] =
  24.         { 0x55, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
  25.     static const unsigned char mask_xor[] =
  26.         { 0x55, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00 };
  27.     static const unsigned char reverse_mask[] =
  28.         { 0x55, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
  29.     static const unsigned char reverse_mask_xor[] =
  30.         { 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00 };
  31.  
  32.     if (src_len) {
  33.         const unsigned char *src;
  34.         unsigned char *dst;
  35.         int                  src_offset_modulo,
  36.             dst_offset_modulo;
  37.  
  38.         src = src_org + (src_offset / CHAR_BIT);
  39.         dst = dst_org + (dst_offset / CHAR_BIT);
  40.  
  41.         src_offset_modulo = src_offset % CHAR_BIT;
  42.         dst_offset_modulo = dst_offset % CHAR_BIT;
  43.  
  44.         if (src_offset_modulo == dst_offset_modulo) {
  45.             int              byte_len;
  46.             int              src_len_modulo;
  47.             if (src_offset_modulo) {
  48.                 unsigned char   c;
  49.  
  50.                 c = reverse_mask_xor[dst_offset_modulo]     & *src++;
  51.  
  52.                 PREPARE_FIRST_COPY();
  53.                 *dst++ |= c;
  54.             }
  55.  
  56.             byte_len = src_len / CHAR_BIT;
  57.             src_len_modulo = src_len % CHAR_BIT;
  58.  
  59.             if (byte_len) {
  60.                 memcpy(dst, src, byte_len);
  61.                 src += byte_len;
  62.                 dst += byte_len;
  63.             }
  64.             if (src_len_modulo) {
  65.                 *dst     &= reverse_mask_xor[src_len_modulo];
  66.                 *dst |= reverse_mask[src_len_modulo]     & *src;
  67.             }
  68.         } else {
  69.             int             bit_diff_ls,
  70.                 bit_diff_rs;
  71.             int             byte_len;
  72.             int             src_len_modulo;
  73.             unsigned char   c;
  74.             /*
  75.              * Begin: Line things up on destination.
  76.              */
  77.             if (src_offset_modulo > dst_offset_modulo) {
  78.                 bit_diff_ls = src_offset_modulo - dst_offset_modulo;
  79.                 bit_diff_rs = CHAR_BIT - bit_diff_ls;
  80.  
  81.                 c = *src++ << bit_diff_ls;
  82.                 c |= *src >> bit_diff_rs;
  83.                 c     &= reverse_mask_xor[dst_offset_modulo];
  84.             } else {
  85.                 bit_diff_rs = dst_offset_modulo - src_offset_modulo;
  86.                 bit_diff_ls = CHAR_BIT - bit_diff_rs;
  87.  
  88.                 c = *src >> bit_diff_rs     &
  89.                     reverse_mask_xor[dst_offset_modulo];
  90.             }
  91.             PREPARE_FIRST_COPY();
  92.             *dst++ |= c;
  93.  
  94.             /*
  95.              * Middle: copy with only shifting the source.
  96.              */
  97.             byte_len = src_len / CHAR_BIT;
  98.  
  99.             while (--byte_len >= 0) {
  100.                 c = *src++ << bit_diff_ls;
  101.                 c |= *src >> bit_diff_rs;
  102.                 *dst++ = c;
  103.             }
  104.  
  105.             /*
  106.              * End: copy the remaing bits;
  107.              */
  108.             src_len_modulo = src_len % CHAR_BIT;
  109.             if (src_len_modulo) {
  110.                 c = *src++ << bit_diff_ls;
  111.                 c |= *src >> bit_diff_rs;
  112.                 c     &= reverse_mask[src_len_modulo];
  113.  
  114.                 *dst     &= reverse_mask_xor[src_len_modulo];
  115.                 *dst |= c;
  116.             }
  117.         }
  118.     }
  119. }
  120.  
  121.  /**
  122.      * Copy a block of boolean values from a given valueIndex in a source buffer to a given valueIndex in a dst buffer.
  123.      * In each buffer, every byte stores up to eight boolean values.
  124.      * A valueIndex has a byte address = (valueIndex >> 3), and a bit address = (valueIndex & 7).
  125.      * For instance, the bit with valueIndex = 0 is stored at bit 0 of byte 0;
  126.      * the bit with valueIndex = 10 is stored at bit 2 of byte 1, and so on.
  127.      *
  128.      * @param[inout] dstData         the beginning of dst data buffer
  129.      * @param[in]    srcData         the beginning of the src data buffer
  130.      * @param[in]    valueIndexInDst the valueIndex in dst
  131.      * @param[in]    valueIndexInSrc the valueIndex in src
  132.      * @param[in]    length          how many bits to copy
  133.      */
  134. void copyRLEBoolValues(char* dstData, char* srcData, uint32_t valueIndexInDst, uint32_t valueIndexInSrc, position_t length)
  135. {
  136.     if (valueIndexInDst > 7 || valueIndexInSrc > 7) {
  137.         copyRLEBoolValues(dstData + (valueIndexInDst / 8),
  138.                           srcData + (valueIndexInSrc / 8),
  139.                           valueIndexInSrc % 8,
  140.                           valueIndexInDst % 8,
  141.                           length);
  142.     } else {
  143.         bitarray_copy(srcData, valueIndexInSrc, length, dstData, valueIndexInDst);
  144.     }
  145. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement