Created
April 18, 2016 00:01
-
-
Save dgodfrey206/9110784fb8f08ad1035b56ebae94e2b1 to your computer and use it in GitHub Desktop.
Morse code translator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <algorithm> | |
#include <streambuf> | |
#include <iostream> | |
#include <fstream> | |
#include <stdexcept> | |
#include <utility> | |
#include <string> | |
#include <vector> | |
#include <cctype> | |
#include <memory> | |
namespace parser { | |
class base_pair | |
{ | |
public: | |
using pair_type = std::pair<char, std::string>; | |
using key_type = pair_type::first_type; | |
using value_type = pair_type::second_type; | |
friend bool operator==(const base_pair&, key_type); | |
friend bool operator==(key_type, const base_pair&); | |
friend bool operator==(const value_type&, const base_pair&); | |
friend bool operator==(const base_pair&, const value_type&); | |
key_type get_first() | |
{ | |
return p.first; | |
} | |
value_type get_second() | |
{ | |
return p.second; | |
} | |
base_pair(key_type x, value_type y) : p(std::move(x), std::move(y)) { } | |
private: | |
pair_type p; | |
}; | |
class morse | |
{ | |
public: | |
static std::vector<base_pair> code_map; | |
}; | |
} | |
namespace parser { | |
std::vector<base_pair> morse::code_map {{'A', ".-"}, {'B', "-..."}, {'C', "-.-."}, {'D', "-.."}, | |
{'E', "."}, {'F', "..-."}, {'G', "--."}, {'H', "...."}, | |
{'I', ".."}, {'J', ".---"}, {'K', "-.-"}, {'L', ".-.."}, | |
{'M', "--"}, {'N', "-."}, {'O', "---"}, {'P', ".--."}, | |
{'Q', "--.-"}, {'R', ".-."}, {'S', "..."}, {'T', "-"}, | |
{'U', "..-"}, {'V', "...-"}, {'W', ".--"}, {'X', "-..-"}, | |
{'Y', "-.--"}, {'Z', "--.."}}; | |
bool operator==(const base_pair& lhs, base_pair::key_type c) | |
{ | |
return lhs.p.first == c; | |
} | |
bool operator==(base_pair::key_type c, const base_pair& rhs) | |
{ | |
return (rhs == c); | |
} | |
bool operator==(const base_pair& lhs, const base_pair::value_type& str) | |
{ | |
return lhs.p.second == str; | |
} | |
bool operator==(const base_pair::value_type& str, const base_pair& rhs) | |
{ | |
return (rhs == str); | |
} | |
} | |
namespace parser | |
{ | |
template<class Algorithm> | |
class algorithm; | |
template<> | |
class algorithm<morse> | |
{ | |
using value_type = base_pair::value_type; | |
using key_type = base_pair::key_type; | |
public: | |
static value_type from_alpha(base_pair::key_type); | |
static key_type to_alpha(base_pair::value_type); | |
}; | |
} | |
namespace parser | |
{ | |
algorithm<morse>::value_type algorithm<morse>::from_alpha(algorithm<morse>::key_type key) | |
{ | |
auto map = morse::code_map; | |
auto it = std::find(map.begin(), map.end(), std::toupper(key)); | |
if (it != map.end()) | |
return it->get_second(); | |
else throw std::invalid_argument("Could not find key"); | |
} | |
algorithm<morse>::key_type algorithm<morse>::to_alpha(base_pair::value_type val) | |
{ | |
auto map = morse::code_map; | |
auto it = std::find(map.begin(), map.end(), val); | |
if (it != map.end()) | |
return it->get_first(); | |
else throw std::invalid_argument("Could not find value"); | |
} | |
} | |
template<class Morse = parser::algorithm<parser::morse>> | |
class morse_code_buffer : public std::streambuf | |
{ | |
public: | |
typedef Morse parser_type; | |
morse_code_buffer(const std::string&, std::ios_base::openmode); | |
int_type overflow(int_type); | |
int sync(); | |
private: | |
std::filebuf out; | |
}; | |
using morse_int_type = morse_code_buffer<>::int_type; | |
template<> | |
morse_code_buffer<>::morse_code_buffer(const std::string& path, std::ios_base::openmode mode) | |
{ | |
out.open(path, mode); | |
} | |
template<> | |
int morse_code_buffer<>::sync() { | |
return out.pubsync(); | |
} | |
template<> | |
morse_int_type morse_code_buffer<>::overflow(morse_int_type c) | |
{ | |
using Morse = morse_code_buffer<>::parser_type; | |
if (c == traits_type::eof()) | |
return traits_type::eof(); | |
std::string m; | |
try { | |
m = Morse::from_alpha(static_cast<char_type>(c)); | |
} catch(...) { | |
return traits_type::eof(); | |
} | |
return out.sputn(m.data(), m.size()); | |
} | |
struct morse_code_ostream : private morse_code_buffer<>, std::ostream { | |
morse_code_ostream(std::string const& str) | |
: morse_code_buffer<>(str, std::ios_base::out) | |
, std::ostream(this) | |
{} | |
}; | |
struct morse_code_istream : private morse_code_buffer<>, std::istream { | |
morse_code_istream(std::string const& str) | |
: morse_code_buffer<>(str, std::ios_base::in) | |
, std::istream(this) | |
{} | |
}; | |
int main() | |
{ | |
morse_code_ostream file("out.txt"); | |
std::ifstream in("out.txt"); | |
std::string s; | |
in.tie(&file); | |
file << "ADSHIGFFFS"; | |
in >> s; | |
std::cout << s; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment