| #pragma once | #pragma once | ||||
| #include <cstdint> | #include <cstdint> | ||||
| #include <ctype.h> | |||||
| #include <string> | #include <string> | ||||
| #include <vector> | #include <vector> | ||||
| #include <iostream> | |||||
| #include <bitset> | |||||
| namespace codedweller { | namespace codedweller { | ||||
| class Roller32 { | class Roller32 { | ||||
| } | } | ||||
| }; | }; | ||||
| namespace roller{ | |||||
| static const unsigned char caseBit = 'A' ^ 'a'; | |||||
| static const unsigned char caseMask = ~caseBit; | |||||
| unsigned char applyCaseSensitivity(unsigned char byte, bool caseSensitive) { | |||||
| if (true==caseSensitive) return byte; | |||||
| if (false==isalpha(byte) && 0xFF != byte) return byte; | |||||
| unsigned char insensitiveByte = byte & caseMask; | |||||
| return insensitiveByte; | |||||
| } | |||||
| unsigned char appropriateBitMask(unsigned char byte, bool caseSensitive) { | |||||
| if (true==caseSensitive) return 0xff; | |||||
| if (false==isalpha(byte)) return 0xff; | |||||
| return caseMask; | |||||
| } | |||||
| template <class D, class T> | |||||
| void compute(D data, bool caseSensitive, T& matcher, T& masker) { | |||||
| size_t ingest = std::min(sizeof(matcher.value()), data.size()); | |||||
| for(size_t count = 0; count < ingest; count++) { | |||||
| unsigned char theByte = data.at(count); | |||||
| matcher.add(roller::applyCaseSensitivity(theByte, caseSensitive)); | |||||
| masker.add(roller::appropriateBitMask(theByte, caseSensitive)); | |||||
| } | |||||
| } | |||||
| } | |||||
| class RollerMatch32 { | class RollerMatch32 { | ||||
| private: | private: | ||||
| uint_fast32_t match; | uint_fast32_t match; | ||||
| uint_fast32_t mask; | uint_fast32_t mask; | ||||
| public: | public: | ||||
| RollerMatch32(const std::vector<unsigned char> pattern) { | |||||
| match = mask = 0; | |||||
| size_t ingest = std::min(sizeof(uint_fast32_t), pattern.size()); | |||||
| Roller32 matcher; | |||||
| Roller32 masker; | |||||
| for(size_t count = 0; count < ingest; count++) { | |||||
| matcher.add(pattern.at(count)); | |||||
| masker.add(0xFF); | |||||
| } | |||||
| RollerMatch32(const std::vector<unsigned char> pattern, bool caseSensitive=true) { | |||||
| Roller32 matcher, masker; | |||||
| roller::compute(pattern, caseSensitive, matcher, masker); | |||||
| match = matcher.value(); | match = matcher.value(); | ||||
| mask = masker.value(); | mask = masker.value(); | ||||
| } | } | ||||
| RollerMatch32(const std::string pattern) { | |||||
| match = mask = 0; | |||||
| size_t ingest = std::min(sizeof(uint_fast32_t), pattern.size()); | |||||
| Roller32 matcher; | |||||
| Roller32 masker; | |||||
| for(size_t count = 0; count < ingest; count++) { | |||||
| matcher.add(pattern.at(count)); | |||||
| masker.add(0xFF); | |||||
| } | |||||
| RollerMatch32(const std::string pattern, bool caseSensitive=true) { | |||||
| Roller32 matcher, masker; | |||||
| roller::compute(pattern, caseSensitive, matcher, masker); | |||||
| match = matcher.value(); | match = matcher.value(); | ||||
| mask = masker.value(); | mask = masker.value(); | ||||
| } | } | ||||
| uint_fast64_t mask; | uint_fast64_t mask; | ||||
| public: | public: | ||||
| RollerMatch64(const std::vector<unsigned char> pattern) { | |||||
| match = mask = 0; | |||||
| size_t ingest = std::min(sizeof(uint_fast64_t), pattern.size()); | |||||
| Roller64 matcher; | |||||
| Roller64 masker; | |||||
| for(size_t count = 0; count < ingest; count++) { | |||||
| matcher.add(pattern.at(count)); | |||||
| masker.add(0xFF); | |||||
| } | |||||
| RollerMatch64(const std::vector<unsigned char> pattern, bool caseSensitive=true) { | |||||
| Roller64 matcher, masker; | |||||
| roller::compute(pattern, caseSensitive, matcher, masker); | |||||
| match = matcher.value(); | match = matcher.value(); | ||||
| mask = masker.value(); | mask = masker.value(); | ||||
| } | } | ||||
| RollerMatch64(const std::string pattern) { | |||||
| match = mask = 0; | |||||
| size_t ingest = std::min(sizeof(uint_fast64_t), pattern.size()); | |||||
| Roller64 matcher; | |||||
| Roller64 masker; | |||||
| for(size_t count = 0; count < ingest; count++) { | |||||
| matcher.add(pattern.at(count)); | |||||
| masker.add(0xFF); | |||||
| } | |||||
| RollerMatch64(const std::string pattern, bool caseSensitive=true) { | |||||
| Roller64 matcher, masker; | |||||
| roller::compute(pattern, caseSensitive, matcher, masker); | |||||
| match = matcher.value(); | match = matcher.value(); | ||||
| mask = masker.value(); | mask = masker.value(); | ||||
| } | } | ||||
| return (match == (roller.value() & mask)); | return (match == (roller.value() & mask)); | ||||
| } | } | ||||
| }; | }; | ||||
| } | } | ||||