Mask represents the set of Data bytes that are worth mutating.
| 567 | |
| 568 | // Mask represents the set of Data bytes that are worth mutating. |
| 569 | size_t MutationDispatcher::MutateWithMask(uint8_t *Data, size_t Size, |
| 570 | size_t MaxSize, |
| 571 | const std::vector<uint8_t> &Mask) { |
| 572 | size_t MaskedSize = std::min(Size, Mask.size()); |
| 573 | // * Copy the worthy bytes into a temporary array T |
| 574 | // * Mutate T |
| 575 | // * Copy T back. |
| 576 | // This is totally unoptimized. |
| 577 | auto &T = MutateWithMaskTemp; |
| 578 | if (T.size() < Size) |
| 579 | T.resize(Size); |
| 580 | size_t OneBits = 0; |
| 581 | for (size_t I = 0; I < MaskedSize; I++) |
| 582 | if (Mask[I]) |
| 583 | T[OneBits++] = Data[I]; |
| 584 | |
| 585 | if (!OneBits) return 0; |
| 586 | assert(!T.empty()); |
| 587 | size_t NewSize = Mutate(T.data(), OneBits, OneBits); |
| 588 | assert(NewSize <= OneBits); |
| 589 | (void)NewSize; |
| 590 | // Even if NewSize < OneBits we still use all OneBits bytes. |
| 591 | for (size_t I = 0, J = 0; I < MaskedSize; I++) |
| 592 | if (Mask[I]) |
| 593 | Data[I] = T[J++]; |
| 594 | return Size; |
| 595 | } |
| 596 | |
| 597 | void MutationDispatcher::AddWordToManualDictionary(const Word &W) { |
| 598 | ManualDictionary.push_back( |
no test coverage detected