#include #include #include #include #include "charman.h" #include "utils.h" #include "zf_log.h" void CharMan::validate(void) { bool valid = true; for (int x = 0; x < text_offsets.size(); ++x) { int offset = text_offsets[x]; if (offset >= 0) { if (text[x] != work[offset]) { ZF_LOGE("validate: %d off %d [%c != %c]", x, offset, text[x], work[offset]); valid = false; } if ((text[x] != ' ') && (text[x] != buffer[offset])) { ZF_LOGE("validate: %d off %d [%c != %c]", x, offset, text[x], buffer[offset]); valid = false; } } } if (!valid) { ZF_LOGE("* NOT VALID* Somethings hosed."); } } void CharMan::regular_expressions(void) { std::regex words("[a-zA-Z']+([ ]{1,2}[a-zA-Z&-]+)+"); // I need position and length. for (auto it = std::sregex_iterator(this->text.begin(), this->text.end(), words); it != std::sregex_iterator(); ++it) { pos_len.push_back(std::make_pair(it->position(), it->length())); int pos = it->position(), len = it->length(); ZF_LOGD("pos %d len %d (%s)", pos, len, this->text.substr(pos, len).c_str()); } } char CharMan::get(int pos) { return this->text[pos]; } void CharMan::set(int pos, char ch) { this->text[pos] = ch; int idx = this->text_offsets[pos]; if (idx >= 0) { this->buffer[idx] = ch; this->work[idx] = ch; } } int CharMan::word_mangler(std::pair pos_len) { int pos = pos_len.first; int state = randrange(-1, 1); int count = 0; for (int p = 0; p < pos_len.second; ++p) { char c = this->get(pos + p); if (randint(pos_len.second) == p) break; switch (state) { case -1: if (islower(c)) { count++; this->set(pos + p, toupper(c)); } break; case 0: if (islower(c)) { count++; this->set(pos + p, toupper(c)); } else { if (isupper(c)) { count++; this->set(pos + p, tolower(c)); } } break; case 1: if (isupper(c)) { count++; this->set(pos + p, tolower(c)); } break; } } return count; } int CharMan::word_wrangler(std::pair pos_len) { int count = 0; int p; int len; if (pos_len.second < 4) return 0; p = randint(pos_len.second - 4) + 2; for (len = 0; len < 3; ++len) { if (!isalpha(this->get(pos_len.first + p + len))) break; } ZF_LOGD("Wrangler: %d, %d", p, len); if (len >= 2) { for (int x = 0; x < len / 2; x++) { char ch = this->get(pos_len.first + p + x); this->set(pos_len.first + p + x, this->get(pos_len.first + p + len - 1 - x)); this->set(pos_len.first + p + len - 1 - x, ch); } count++; } return count; } CharMan::CharMan(std::string &buffer, std::string &work, std::string &text, std::vector &text_offsets) : buffer(buffer), work(work), text(text), text_offsets(text_offsets) { /* this->buffer = buffer; this->work = work; this->text = text; this->text_offsets = text_offsets; */ this->mangle_count = 0; this->mangle_chars = 0; validate(); regular_expressions(); ZF_LOGD("Found %d word groups", (int)pos_len.size()); if (pos_len.size() > 0) { for (int i = 0; i < pos_len.size(); ++i) { if (random_activate(8)) { int c = word_mangler(pos_len[i]); if (c) { this->mangle_count++; this->mangle_chars += c; } } if (random_activate(4)) { if (word_wrangler(pos_len[i])) this->mangle_count++; } } } /* Display up to certain point. Print some characters slowly. Delay. ** This would require "need_render" ** */ }; CharMan::~CharMan() { ZF_LOGD("~CharMan"); validate(); }