| 120 | } |
| 121 | |
| 122 | void BitmapCopy(uint8_t* dst, size_t dst_offset, |
| 123 | const uint8_t* src, size_t src_offset, |
| 124 | size_t num_bits) { |
| 125 | DCHECK_GT(num_bits, 0); |
| 126 | |
| 127 | // Prohibit overlap in debug builds. |
| 128 | #ifndef NDEBUG |
| 129 | const uint8_t* src_start = src + (src_offset >> 3); |
| 130 | const uint8_t* src_end = src + ((src_offset + num_bits) >> 3); |
| 131 | uint8_t* dst_start = dst + (dst_offset >> 3); |
| 132 | uint8_t* dst_end = dst + ((dst_offset + num_bits) >> 3); |
| 133 | DCHECK(src_start >= dst_end || dst_start >= src_end) |
| 134 | << "Source and destination overlap"; |
| 135 | #endif |
| 136 | |
| 137 | // If the copy is entirely byte-aligned, we can use memcpy. |
| 138 | if ((src_offset & 7) == 0 && (dst_offset & 7) == 0 && (num_bits & 7) == 0) { |
| 139 | memcpy(dst + (dst_offset >> 3), |
| 140 | src + (src_offset >> 3), |
| 141 | BitmapSize(num_bits)); |
| 142 | return; |
| 143 | } |
| 144 | |
| 145 | // Otherwise, we fallback to a slower bit-by-bit copy. |
| 146 | // |
| 147 | // TODO(adar): this can be optimized using word-by-word operations. |
| 148 | for (size_t bit_num = 0; bit_num < num_bits; bit_num++) { |
| 149 | BitmapChange(dst, dst_offset + bit_num, BitmapTest(src, src_offset + bit_num)); |
| 150 | } |
| 151 | } |
| 152 | |
| 153 | string BitmapToString(const uint8_t *bitmap, size_t num_bits) { |
| 154 | string s; |