| @@ -0,0 +1,122 @@ | |||
| // roller.hpp | |||
| // Copyright (C) 2022 MicroNeil Research Corporation. | |||
| // | |||
| // This software is released under the MIT license. See LICENSE.TXT. | |||
| // | |||
| // Roller is a naive rolling hash system for rapid string searches. | |||
| // Roller32 accommodates matches up to 4 bytes. | |||
| // Roller64 accommodates matches up to 8 bytes. | |||
| #pragma once | |||
| #include <cstdint> | |||
| #include <string> | |||
| #include <vector> | |||
| namespace codedweller { | |||
| class Roller32 { | |||
| private: | |||
| uint_fast32_t roller; | |||
| public: | |||
| Roller32() : roller(0) {} | |||
| uint_fast32_t value() const { return roller; } | |||
| uint_fast32_t add(uint8_t byte) { | |||
| roller = roller << 8 | byte; | |||
| return roller; | |||
| } | |||
| }; | |||
| class Roller64 { | |||
| private: | |||
| uint_fast64_t roller; | |||
| public: | |||
| Roller64() : roller(0) {} | |||
| uint_fast64_t value() const { return roller; } | |||
| uint_fast64_t add(uint8_t byte) { | |||
| roller = roller << 8 | byte; | |||
| return roller; | |||
| } | |||
| }; | |||
| class RollerMatch32 { | |||
| private: | |||
| uint_fast32_t match; | |||
| uint_fast32_t mask; | |||
| 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); | |||
| } | |||
| match = matcher.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); | |||
| } | |||
| match = matcher.value(); | |||
| mask = masker.value(); | |||
| } | |||
| bool matches(const Roller32 roller) { | |||
| return (match == (roller.value() & mask)); | |||
| } | |||
| }; | |||
| class RollerMatch64 { | |||
| private: | |||
| uint_fast64_t match; | |||
| uint_fast64_t mask; | |||
| 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); | |||
| } | |||
| match = matcher.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); | |||
| } | |||
| match = matcher.value(); | |||
| mask = masker.value(); | |||
| } | |||
| bool matches(const Roller64 roller) { | |||
| return (match == (roller.value() & mask)); | |||
| } | |||
| }; | |||
| } | |||