From acb1e54c63014380419d65e4d04bd69f5f348d03 Mon Sep 17 00:00:00 2001 From: J Ninja Date: Wed, 26 Jun 2019 22:11:01 -0700 Subject: [PATCH 1/2] Refactor and accessor changes. --- src/hexagram.cc | 4 +- src/hexagram.h | 8 +++- src/lexer.h | 23 ++++++++++ src/main.cc | 7 +-- src/parser.h | 34 ++++++++++++++ src/translator.cc | 115 +++++++--------------------------------------- src/translator.h | 4 +- src/util.h | 83 +++++++++++++++++++++++++++++++++ 8 files changed, 172 insertions(+), 106 deletions(-) create mode 100644 src/lexer.h create mode 100644 src/parser.h create mode 100644 src/util.h diff --git a/src/hexagram.cc b/src/hexagram.cc index 596ade1..3f8813b 100644 --- a/src/hexagram.cc +++ b/src/hexagram.cc @@ -23,12 +23,12 @@ const char* TRIGRAMS[NUM_TRIGRAMS][NUM_TRIGRAM_LINES] = [ EARTH ] = { BROKEN, BROKEN, BROKEN } }; -Trigram Hexagram::lower() +Trigram Hexagram::lower() const { return this->_lower; } -Trigram Hexagram::upper() +Trigram Hexagram::upper() const { return this->_upper; } diff --git a/src/hexagram.h b/src/hexagram.h index ab958b9..6b4da61 100644 --- a/src/hexagram.h +++ b/src/hexagram.h @@ -18,8 +18,12 @@ class Hexagram _upper(upper), _lower(lower), _value(value) {} - Trigram upper(); - Trigram lower(); + Hexagram(const Hexagram& hexagram) : + _upper(hexagram.upper()), + _lower(hexagram.lower()), + _value(hexagram.value()) {} + Trigram upper()const; + Trigram lower() const; unsigned value() const; bool operator <(const Hexagram& hexagram) const; string str(); diff --git a/src/lexer.h b/src/lexer.h new file mode 100644 index 0000000..0604539 --- /dev/null +++ b/src/lexer.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include + +using std::vector; +using std::string; + +namespace Lexer +{ + vector strip_lines(const string& encoded_or_fname) + { + vector lines; + std::stringstream ss(encoded_or_fname); + string line = ""; + + while (std::getline(ss, line, '\n')) + lines.push_back(line); + + return lines; + } +} diff --git a/src/main.cc b/src/main.cc index 74d7bd4..476a9eb 100644 --- a/src/main.cc +++ b/src/main.cc @@ -5,6 +5,7 @@ #include "translator.h" +using std::cerr; using std::cout; using std::endl; @@ -56,12 +57,12 @@ int main(int argc, char** argv) po::notify(vm); } catch(po::error& e) { - std::cerr << "ERROR: " << e.what() << std::endl << std::endl; - std::cerr << desc << std::endl; + cerr << "ERROR: " << e.what() << std::endl << std::endl; + cerr << desc << std::endl; return ERROR_IN_COMMAND_LINE; } } catch(std::exception& e) { - std::cerr << "Unhandled Exception reached the top of main: " + cerr << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit" << std::endl; return ERROR_UNHANDLED_EXCEPTION; diff --git a/src/parser.h b/src/parser.h new file mode 100644 index 0000000..fd42f6d --- /dev/null +++ b/src/parser.h @@ -0,0 +1,34 @@ +#pragma once + +#include + +#include "hexagram.h" + +using std::vector; + +namespace Parser +{ + static vector lines_to_hexagrams(const vector& lines) + { + vector continuous_hexagrams(NUM_HEXAGRAM_LINES); + int i = 0; + for (const string& line : lines) { + i = i % NUM_HEXAGRAM_LINES == 0 ? 0 : i; + continuous_hexagrams[i] += line; + i += 1; + } + + vector hexagrams; + for (size_t offset = 0; offset < continuous_hexagrams[0].length(); offset += HEXAGRAM_WIDTH) { + string hexagram = ""; + for (const string& line : continuous_hexagrams) { + for (size_t j = offset; j < offset + HEXAGRAM_WIDTH; j++) + hexagram += line[j]; + hexagram += "\n"; + } + hexagrams.push_back(hexagram); + } + + return hexagrams; + } +} diff --git a/src/translator.cc b/src/translator.cc index ebcd0e4..8180c47 100644 --- a/src/translator.cc +++ b/src/translator.cc @@ -1,29 +1,17 @@ #include "translator.h" -#include #include #include -#include #include -#include -#include - -#include -#include -#include -#include #include "hexagram.h" +#include "lexer.h" +#include "parser.h" -using namespace boost::archive::iterators; - -using std::cerr; -using std::cout; using std::endl; using std::ifstream; using std::map; using std::pair; -using std::vector; static size_t MAX_WIDTH = 80; static string B64_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -38,55 +26,24 @@ static void build_keymap() } } -static string b64_encode(string msg) -{ - std::stringstream os; - typedef base64_from_binary> base64_text; - - std::copy( - base64_text(msg.c_str()), - base64_text(msg.c_str() + msg.size()), - std::ostream_iterator(os)); - return os.str(); -} - -static string b64_decode(const string& msg) -{ - typedef transform_width>, 8, 6> ItBinaryT; - string output = ""; - string padded = msg; - - try { - size_t num_pad_chars((4 - msg.size() % 4) % 4); - padded.append(num_pad_chars, '='); - size_t pad_chars(std::count(padded.begin(), padded.end(), '=')); - std::replace(padded.begin(), padded.end(), '=', 'A'); - std::string output(ItBinaryT(padded.begin()), ItBinaryT(padded.end())); - output.erase(output.end() - pad_chars, output.end()); - return output; - } catch (std::exception const& e) { - cerr << "Exception caught: " << e.what() << endl; - } - - return output; -} - -string build_hexagram_output(vector& hexagrams, const string& delimiter) +string build_hexagram_output(const vector& hexagrams, const string& delimiter) { string repr = ""; vector continuous_hexagrams(NUM_HEXAGRAM_LINES); size_t offset = 0; size_t line_pos = 0; - for (Hexagram& hexagram: hexagrams) { + for (const Hexagram& hexagram: hexagrams) { if (line_pos >= MAX_WIDTH) { - for (int i = 0; i < NUM_HEXAGRAM_LINES; i++) + for (int i = 0; i < NUM_HEXAGRAM_LINES; i++) { continuous_hexagrams.push_back(""); + } + offset += NUM_HEXAGRAM_LINES; line_pos = 0; } - string h = hexagram.str(); + string h = Hexagram(hexagram).str(); size_t pos = 0; string token; @@ -99,29 +56,25 @@ string build_hexagram_output(vector& hexagrams, const string& delimite line_pos += HEXAGRAM_WIDTH; } - for (const string& line: continuous_hexagrams) + for (const string& line: continuous_hexagrams) { repr += line + "\n"; + } return repr; } -static int random_generator(int i) -{ - return std::rand() % i; -} - string Translator::encode(const string& input, bool shuffle) { if (shuffle) { std::srand(unsigned(std::time(0))); - std::random_shuffle(B64_CHARACTERS.begin(), B64_CHARACTERS.end(), random_generator); + std::random_shuffle(B64_CHARACTERS.begin(), B64_CHARACTERS.end(), Util::Random::random_generator); cout << "KEY: " << B64_CHARACTERS << endl; build_keymap(); } else { build_keymap(); } - string b64_encoded = b64_encode(input); + string b64_encoded = Util::Base64::b64_encode(input); vector hexagrams; for (const char& c : b64_encoded) { @@ -131,43 +84,7 @@ string Translator::encode(const string& input, bool shuffle) return build_hexagram_output(hexagrams, "\n"); } -static vector strip_lines(const string& encoded_or_fname) -{ - vector lines; - std::stringstream ss(encoded_or_fname); - string line = ""; - - while (std::getline(ss, line, '\n')) - lines.push_back(line); - - return lines; -} - -static vector lines_to_hexagrams(const vector& lines) -{ - vector continuous_hexagrams(NUM_HEXAGRAM_LINES); - int i = 0; - for (const string& line : lines) { - i = i % NUM_HEXAGRAM_LINES == 0 ? 0 : i; - continuous_hexagrams[i] += line; - i += 1; - } - - vector hexagrams; - for (size_t offset = 0; offset < continuous_hexagrams[0].length(); offset += HEXAGRAM_WIDTH) { - string hexagram = ""; - for (const string& line : continuous_hexagrams) { - for (size_t j = offset; j < offset + HEXAGRAM_WIDTH; j++) - hexagram += line[j]; - hexagram += "\n"; - } - hexagrams.push_back(hexagram); - } - - return hexagrams; -} - -string Translator::decode(const string& input, string key) +string Translator::decode(const string& input, const string& key) { if (key != "") { B64_CHARACTERS = key; @@ -175,18 +92,20 @@ string Translator::decode(const string& input, string key) } else { build_keymap(); } - vector hexagrams = lines_to_hexagrams(strip_lines(input)); + + vector hexagrams = Parser::lines_to_hexagrams(Lexer::strip_lines(input)); string b64 = ""; for (const string& hexagram: hexagrams) { map::iterator it; for (it = KEYMAP.begin(); it != KEYMAP.end(); it++) { string hex_str = it->second.str(); + if (hex_str != "" && hex_str == hexagram) { b64 += it->first; } } } - return b64_decode(b64); + return Util::Base64::b64_decode(b64); } diff --git a/src/translator.h b/src/translator.h index 403c7cb..7ecde64 100644 --- a/src/translator.h +++ b/src/translator.h @@ -2,10 +2,12 @@ #include +#include "util.h" + using std::string; namespace Translator { string encode(const string& input, bool shuffle = false); - string decode(const string& input, string key = ""); + string decode(const string& input, const string& key = ""); } diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..9639d2a --- /dev/null +++ b/src/util.h @@ -0,0 +1,83 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include +#include + +using namespace boost::archive::iterators; +using std::cerr; +using std::cout; +using std::endl; +using std::string; + +namespace Util +{ + namespace Random + { + int random_generator(int i) + { + return std::rand() % i; + } + } + + namespace Base64 + { + string b64_encode(const string& msg) + { + std::stringstream os; + typedef base64_from_binary> base64_text; + + std::copy( + base64_text(msg.c_str()), + base64_text(msg.c_str() + msg.size()), + std::ostream_iterator(os)); + return os.str(); + } + + string b64_decode(const string& msg) + { + typedef transform_width>, 8, 6> ItBinaryT; + string output = ""; + string padded = msg; + + try { + size_t num_pad_chars((4 - msg.size() % 4) % 4); + padded.append(num_pad_chars, '='); + size_t pad_chars(std::count(padded.begin(), padded.end(), '=')); + std::replace(padded.begin(), padded.end(), '=', 'A'); + std::string output(ItBinaryT(padded.begin()), ItBinaryT(padded.end())); + output.erase(output.end() - pad_chars, output.end()); + return output; + } catch (std::exception const& e) { + cerr << "Exception caught: " << e.what() << endl; + } + + return output; + } + } + + namespace String + { + const char* ws = " \t\n\r\f\v"; + + inline string& rtrim(const std::string& s, const char* t = ws) + { + return string(s).erase(s.find_last_not_of(t) + 1); + } + + inline string& ltrim(const string& s, const char* t = ws) + { + return string(s).erase(0, s.find_first_not_of(t)); + } + + inline string& trim(const string& s, const char* t = ws) + { + return ltrim(rtrim(s, t), t); + } + } +} From 94033fa95a4e54ce538de6a733d85ad9388e8ace Mon Sep 17 00:00:00 2001 From: J Ninja Date: Wed, 26 Jun 2019 22:32:10 -0700 Subject: [PATCH 2/2] Refactor/structure and tightening of accessors. --- CMakeLists.txt | 5 ++-- src/CMakeLists.txt | 2 +- src/translator.cc | 16 +++++++---- src/util.cc | 69 ++++++++++++++++++++++++++++++++++++++++++++ src/util.h | 71 +++++----------------------------------------- 5 files changed, 91 insertions(+), 72 deletions(-) create mode 100644 src/util.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 5909823..c47c3dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ -cmake_minimum_required(VERSION 2.6) -project(iching) +cmake_minimum_required(VERSION 3.1) +project(iching VERSION 1.0.0 LANGUAGES CXX) add_subdirectory(src) +#add_subdirectory(tests) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4e7e21f..0fdde31 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,7 +2,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -Wextra -g") find_package(Boost 1.66 COMPONENTS system program_options REQUIRED) include_directories(${Boost_INCLUDE_DIR}) -add_executable(iching main.cc hexagram.cc translator.cc) +add_executable(iching main.cc hexagram.cc translator.cc util.cc) target_link_libraries(iching LINK_PUBLIC ${Boost_LIBRARIES}) install(TARGETS iching RUNTIME DESTINATION bin) diff --git a/src/translator.cc b/src/translator.cc index 8180c47..a84a1f8 100644 --- a/src/translator.cc +++ b/src/translator.cc @@ -1,26 +1,29 @@ #include "translator.h" +#include #include #include +#include #include #include "hexagram.h" #include "lexer.h" #include "parser.h" +using std::cout; using std::endl; using std::ifstream; using std::map; using std::pair; static size_t MAX_WIDTH = 80; -static string B64_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static map KEYMAP; +string BASE64_CHARACTER_ORDERING = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static void build_keymap() { int i = 0; - for (const char& c : B64_CHARACTERS) { + for (const char& c : BASE64_CHARACTER_ORDERING) { KEYMAP.insert(pair(c, HEXAGRAMS[i])); i += 1; } @@ -67,8 +70,11 @@ string Translator::encode(const string& input, bool shuffle) { if (shuffle) { std::srand(unsigned(std::time(0))); - std::random_shuffle(B64_CHARACTERS.begin(), B64_CHARACTERS.end(), Util::Random::random_generator); - cout << "KEY: " << B64_CHARACTERS << endl; + std::random_shuffle( + BASE64_CHARACTER_ORDERING.begin(), + BASE64_CHARACTER_ORDERING.end(), + Util::Random::random_generator); + cout << "KEY: " << BASE64_CHARACTER_ORDERING << endl; build_keymap(); } else { build_keymap(); @@ -87,7 +93,7 @@ string Translator::encode(const string& input, bool shuffle) string Translator::decode(const string& input, const string& key) { if (key != "") { - B64_CHARACTERS = key; + BASE64_CHARACTER_ORDERING = key; build_keymap(); } else { build_keymap(); diff --git a/src/util.cc b/src/util.cc new file mode 100644 index 0000000..b9916ff --- /dev/null +++ b/src/util.cc @@ -0,0 +1,69 @@ +#include "util.h" + +#include +#include +#include + +#include +#include +#include +#include + +using namespace boost::archive::iterators; +using std::cerr; +using std::cout; +using std::endl; + +int Util::Random::random_generator(int i) +{ + return std::rand() % i; +} + +string & Util::String::rtrim(const string& s, const char* t) +{ + + return string(s).erase(s.find_last_not_of(t) + 1); +} + +string & Util::String::ltrim(const string& s, const char* t) +{ + return string(s).erase(0, s.find_first_not_of(t)); +} + +string & Util::String::trim(const string& s, const char* t) +{ + return Util::String::ltrim(Util::String::rtrim(s, t), t); +} + +string Util::Base64::b64_decode(const string& msg) +{ + typedef transform_width>, 8, 6> ItBinaryT; + string output = ""; + string padded = msg; + + try { + size_t num_pad_chars((4 - msg.size() % 4) % 4); + padded.append(num_pad_chars, '='); + size_t pad_chars(std::count(padded.begin(), padded.end(), '=')); + std::replace(padded.begin(), padded.end(), '=', 'A'); + std::string output(ItBinaryT(padded.begin()), ItBinaryT(padded.end())); + output.erase(output.end() - pad_chars, output.end()); + return output; + } catch (std::exception const& e) { + cerr << "Exception caught: " << e.what() << endl; + } + + return output; +} + +string Util::Base64::b64_encode(const string& msg) +{ + std::stringstream os; + typedef base64_from_binary> base64_text; + + std::copy( + base64_text(msg.c_str()), + base64_text(msg.c_str() + msg.size()), + std::ostream_iterator(os)); + return os.str(); +} diff --git a/src/util.h b/src/util.h index 9639d2a..a36389e 100644 --- a/src/util.h +++ b/src/util.h @@ -1,83 +1,26 @@ #pragma once -#include -#include -#include +#include -#include -#include -#include -#include - -using namespace boost::archive::iterators; -using std::cerr; -using std::cout; -using std::endl; using std::string; namespace Util { namespace Random { - int random_generator(int i) - { - return std::rand() % i; - } + int random_generator(int i); } namespace Base64 { - string b64_encode(const string& msg) - { - std::stringstream os; - typedef base64_from_binary> base64_text; - - std::copy( - base64_text(msg.c_str()), - base64_text(msg.c_str() + msg.size()), - std::ostream_iterator(os)); - return os.str(); - } - - string b64_decode(const string& msg) - { - typedef transform_width>, 8, 6> ItBinaryT; - string output = ""; - string padded = msg; - - try { - size_t num_pad_chars((4 - msg.size() % 4) % 4); - padded.append(num_pad_chars, '='); - size_t pad_chars(std::count(padded.begin(), padded.end(), '=')); - std::replace(padded.begin(), padded.end(), '=', 'A'); - std::string output(ItBinaryT(padded.begin()), ItBinaryT(padded.end())); - output.erase(output.end() - pad_chars, output.end()); - return output; - } catch (std::exception const& e) { - cerr << "Exception caught: " << e.what() << endl; - } - - return output; - } + string b64_encode(const string& msg); + string b64_decode(const string& msg); } namespace String { - const char* ws = " \t\n\r\f\v"; - - inline string& rtrim(const std::string& s, const char* t = ws) - { - return string(s).erase(s.find_last_not_of(t) + 1); - } - - inline string& ltrim(const string& s, const char* t = ws) - { - return string(s).erase(0, s.find_first_not_of(t)); - } - - inline string& trim(const string& s, const char* t = ws) - { - return ltrim(rtrim(s, t), t); - } + inline string& rtrim(const string& s, const char* t = " \t\n\r\f\v"); + inline string& ltrim(const string& s, const char* t = " \t\n\r\f\v"); + inline string& trim(const string& s, const char* t = " \t\n\r\f\v"); } }