charman.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #include <ctype.h>
  2. #include <regex>
  3. #include <string>
  4. #include <vector>
  5. #include "charman.h"
  6. #include "utils.h"
  7. #include "zf_log.h"
  8. void CharMan::validate(void) {
  9. bool valid = true;
  10. for (int x = 0; x < text_offsets.size(); ++x) {
  11. int offset = text_offsets[x];
  12. if (offset >= 0) {
  13. if (text[x] != work[offset]) {
  14. ZF_LOGE("validate: %d off %d [%c != %c]", x, offset, text[x],
  15. work[offset]);
  16. valid = false;
  17. }
  18. if ((text[x] != ' ') && (text[x] != buffer[offset])) {
  19. ZF_LOGE("validate: %d off %d [%c != %c]", x, offset, text[x],
  20. buffer[offset]);
  21. valid = false;
  22. }
  23. }
  24. }
  25. if (!valid) {
  26. ZF_LOGE("* NOT VALID* Somethings hosed.");
  27. }
  28. }
  29. void CharMan::regular_expressions(void) {
  30. std::regex words("[a-zA-Z']+([ ]{1,2}[a-zA-Z&-]+)+");
  31. // I need position and length.
  32. for (auto it =
  33. std::sregex_iterator(this->text.begin(), this->text.end(), words);
  34. it != std::sregex_iterator(); ++it) {
  35. pos_len.push_back(std::make_pair(it->position(), it->length()));
  36. int pos = it->position(), len = it->length();
  37. ZF_LOGD("pos %d len %d (%s)", pos, len,
  38. this->text.substr(pos, len).c_str());
  39. }
  40. }
  41. char CharMan::get(int pos) { return this->text[pos]; }
  42. void CharMan::set(int pos, char ch) {
  43. this->text[pos] = ch;
  44. int idx = this->text_offsets[pos];
  45. if (idx >= 0) {
  46. this->buffer[idx] = ch;
  47. this->work[idx] = ch;
  48. }
  49. }
  50. int CharMan::word_mangler(std::pair<int, int> pos_len) {
  51. int pos = pos_len.first;
  52. int state = randrange(-1, 1);
  53. int count = 0;
  54. for (int p = 0; p < pos_len.second; ++p) {
  55. char c = this->get(pos + p);
  56. if (randint(pos_len.second) == p)
  57. break;
  58. switch (state) {
  59. case -1:
  60. if (islower(c)) {
  61. count++;
  62. this->set(pos + p, toupper(c));
  63. }
  64. break;
  65. case 0:
  66. if (islower(c)) {
  67. count++;
  68. this->set(pos + p, toupper(c));
  69. } else {
  70. if (isupper(c)) {
  71. count++;
  72. this->set(pos + p, tolower(c));
  73. }
  74. }
  75. break;
  76. case 1:
  77. if (isupper(c)) {
  78. count++;
  79. this->set(pos + p, tolower(c));
  80. }
  81. break;
  82. }
  83. }
  84. return count;
  85. }
  86. int CharMan::word_wrangler(std::pair<int, int> pos_len) {
  87. int count = 0;
  88. int p;
  89. int len;
  90. if (pos_len.second < 4)
  91. return 0;
  92. p = randint(pos_len.second - 4) + 2;
  93. for (len = 0; len < 3; ++len) {
  94. if (!isalpha(this->get(pos_len.first + p + len)))
  95. break;
  96. }
  97. ZF_LOGD("Wrangler: %d, %d", p, len);
  98. if (len >= 2) {
  99. for (int x = 0; x < len / 2; x++) {
  100. char ch = this->get(pos_len.first + p + x);
  101. this->set(pos_len.first + p + x,
  102. this->get(pos_len.first + p + len - 1 - x));
  103. this->set(pos_len.first + p + len - 1 - x, ch);
  104. }
  105. count++;
  106. }
  107. return count;
  108. }
  109. CharMan::CharMan(std::string &buffer, std::string &work, std::string &text,
  110. std::vector<int> &text_offsets)
  111. : buffer(buffer), work(work), text(text), text_offsets(text_offsets) {
  112. /*
  113. this->buffer = buffer;
  114. this->work = work;
  115. this->text = text;
  116. this->text_offsets = text_offsets;
  117. */
  118. this->mangle_count = 0;
  119. this->mangle_chars = 0;
  120. validate();
  121. regular_expressions();
  122. ZF_LOGD("Found %d word groups", (int)pos_len.size());
  123. if (pos_len.size() > 0) {
  124. for (int i = 0; i < pos_len.size(); ++i) {
  125. if (random_activate(8)) {
  126. int c = word_mangler(pos_len[i]);
  127. if (c) {
  128. this->mangle_count++;
  129. this->mangle_chars += c;
  130. }
  131. }
  132. if (random_activate(4)) {
  133. if (word_wrangler(pos_len[i]))
  134. this->mangle_count++;
  135. }
  136. }
  137. }
  138. /*
  139. Display up to certain point.
  140. Print some characters slowly. Delay.
  141. ** This would require "need_render" **
  142. */
  143. };
  144. CharMan::~CharMan() {
  145. ZF_LOGD("~CharMan");
  146. validate();
  147. }