commit
3f69e0243e
4 changed files with 307 additions and 0 deletions
@ -0,0 +1,25 @@ |
|||
#ifndef DICTCC_DESV_INCLUDED |
|||
#define DICTCC_DESV_INCLUDED |
|||
|
|||
// Dictcc API
|
|||
#include "dict.h" |
|||
|
|||
namespace dictcc |
|||
{ |
|||
class desv : public dict |
|||
{ |
|||
// TODO: Implement specifics of the language here.
|
|||
public: |
|||
desv(); |
|||
~desv() |
|||
{} |
|||
}; |
|||
|
|||
desv::desv() |
|||
{ |
|||
d_suburl = "desv"; |
|||
} |
|||
|
|||
} // namespace dictcc
|
|||
|
|||
#endif // DICTCC_DESV_INCLUDED
|
@ -0,0 +1,179 @@ |
|||
// STD
|
|||
#include <string> |
|||
#include <sstream> |
|||
#include <iostream> |
|||
#include <utility> |
|||
#include <functional> |
|||
#include <vector> |
|||
// Curl
|
|||
#include <curlpp/cURLpp.hpp> |
|||
#include <curlpp/Easy.hpp> |
|||
#include <curlpp/Options.hpp> |
|||
// Boost
|
|||
#include <boost/algorithm/string.hpp> |
|||
// Dictcc API
|
|||
#include "types.h" |
|||
#include "exceptions.h" |
|||
|
|||
#ifndef DICTCC_DICT_INCLUDED |
|||
#define DICTCC_DICT_INCLUDED |
|||
|
|||
namespace dictcc |
|||
{ |
|||
/*! \brief Base dictionary class.
|
|||
*/ |
|||
class dict |
|||
{ |
|||
protected: |
|||
static const std::string URL_HTTPS; |
|||
static const std::string URL_REST; |
|||
static const std::string QUERYA; |
|||
static const std::string QUERYB; |
|||
static const std::string QUERYC; |
|||
static const std::string SEPERATOR; |
|||
|
|||
protected: |
|||
/*! \brief Word list corresponding to one language.
|
|||
*/ |
|||
word_list_t d_wordsl0; |
|||
/*! \brief Word list corresponding to one language.
|
|||
*/ |
|||
word_list_t d_wordsl1; |
|||
curlpp::Easy d_request; |
|||
curlpp::Cleanup d_cleaner; |
|||
lang_t d_langs; |
|||
std::string d_suburl; |
|||
|
|||
protected: |
|||
void parse_answer(const std::ostringstream& os, const std::string& query, word_list_t& vec); |
|||
|
|||
protected: |
|||
dict(){} |
|||
|
|||
public: |
|||
static dict* create(const std::string langs); |
|||
virtual ~dict(){} |
|||
|
|||
public: |
|||
search_t search(std::string word); |
|||
static std::string langs2str(const lang_t& lt); |
|||
static lang_t str2langs(const std::string& str); |
|||
}; |
|||
|
|||
const std::string dict::URL_HTTPS = "https://"; |
|||
const std::string dict::URL_REST = ".dict.cc/?s="; |
|||
const std::string dict::QUERYA = "c1Arr = new Array"; |
|||
const std::string dict::QUERYB = "c2Arr = new Array"; |
|||
const std::string dict::QUERYC = ");"; |
|||
const std::string dict::SEPERATOR = "\",\""; |
|||
|
|||
void dict::parse_answer(const std::ostringstream& os, const std::string& query, word_list_t& vec) |
|||
{ |
|||
std::string page = os.str(); |
|||
auto lstart = page.find(query); |
|||
auto lend = page.find(QUERYC, lstart); |
|||
// No results found -> throw an exception
|
|||
if(lstart == -1) |
|||
throw(dict_no_results(__FILE__, __LINE__)); |
|||
lstart += query.size(); |
|||
// Scroll to the first character
|
|||
while( (page[lstart] == '\"') || (page[lstart] == ',') || (page[lstart] == '(') ) |
|||
lstart++; |
|||
// Scroll to the last character
|
|||
while( (page[lstart] == '\"') || (page[lstart] == ',') || (page[lstart] == '(') ) |
|||
lend--; |
|||
// Get the line.
|
|||
std::string line = page.substr(lstart, lend-lstart); |
|||
// Split it.
|
|||
boost::split(vec, line, boost::is_any_of(SEPERATOR), boost::token_compress_on); |
|||
// Last element is always empty.
|
|||
vec.pop_back(); |
|||
// Make sure, that the string termination is present.
|
|||
for (std::string& str : vec) { |
|||
if (str[str.size()-1] != '\0' ) { |
|||
str.append("\0"); |
|||
} |
|||
} |
|||
} |
|||
|
|||
search_t dict::search(std::string word) |
|||
{ |
|||
std::ostringstream answer; |
|||
// Perform HTTP request with SSL below.
|
|||
try { |
|||
std::string dict_req = URL_HTTPS + d_suburl + URL_REST + word; |
|||
curlpp::options::Url url(dict_req); |
|||
d_request.setOpt(url); |
|||
answer << d_request; |
|||
} catch(curlpp::RuntimeError &e) { |
|||
std::ostringstream ss; |
|||
ss << e.what() << "(curlpp::RuntimeError)."; |
|||
throw(dict_libcurl_error(__FILE__, __LINE__, ss.str())); |
|||
} catch(curlpp::LogicError &e) { |
|||
std::ostringstream ss; |
|||
ss << e.what() << "(curlpp::LogicError)."; |
|||
throw(dict_libcurl_error(__FILE__, __LINE__, ss.str())); |
|||
} |
|||
// Convert request into word lists language one and language two respectively.
|
|||
try { |
|||
parse_answer(answer, QUERYA, d_wordsl0); |
|||
parse_answer(answer, QUERYB, d_wordsl1); |
|||
} catch (dict_no_results& e) { |
|||
// The parsing might go wrong.
|
|||
e << std::string("Could not find ") + std::string("\"") + word + std::string("\"."); |
|||
throw; |
|||
} |
|||
// Return a pair of references
|
|||
return std::make_pair(&d_wordsl0, &d_wordsl1); |
|||
} |
|||
|
|||
inline std::string dict::langs2str(const lang_t& lt) |
|||
{ |
|||
// TODO: Add new languages here.
|
|||
std::vector<std::string> str = {"DESV", "DEEN"}; |
|||
if (lt >= str.size()) { |
|||
throw(dict_lang_error(__FILE__, __LINE__)); |
|||
} |
|||
return str[lt]; |
|||
} |
|||
|
|||
inline lang_t dict::str2langs(const std::string& str) |
|||
{ |
|||
if (str == "DESV") { |
|||
return DESV; |
|||
} else if ( str == "DEEN") { |
|||
return DEEN; |
|||
} else { |
|||
throw(dict_lang_error(__FILE__, __LINE__)); |
|||
} |
|||
} |
|||
|
|||
class desv : public dict |
|||
{ |
|||
// TODO: Implement specifics of the language here.
|
|||
public: |
|||
desv(); |
|||
~desv() |
|||
{} |
|||
}; |
|||
|
|||
desv::desv() |
|||
{ |
|||
d_suburl = "desv"; |
|||
} |
|||
|
|||
dict* dict::create(const std::string langs) |
|||
{ |
|||
lang_t l = str2langs(langs); |
|||
// TODO: Add new languages here
|
|||
switch (l) { |
|||
case DESV: |
|||
return new desv; |
|||
break; |
|||
default: |
|||
throw(dict_lang_error(__FILE__, __LINE__)); |
|||
} |
|||
} |
|||
} // namespace dictcc
|
|||
|
|||
#endif // DICTCC_DICT_INCLUDED
|
@ -0,0 +1,77 @@ |
|||
#include <string> |
|||
#include <sstream> |
|||
|
|||
#ifndef DICTCC_EXCEPTIONS_INCLUDED |
|||
#define DICTCC_EXCEPTIONS_INCLUDED |
|||
|
|||
namespace dictcc |
|||
{ |
|||
/*! \brief Exception class to be thrown if there is a general problem with the dictionary.
|
|||
*/ |
|||
class dict_exception : public std::exception |
|||
{ |
|||
private: |
|||
std::string d_file; |
|||
int d_line; |
|||
|
|||
protected: |
|||
std::string d_msg; |
|||
|
|||
public: |
|||
dict_exception(const std::string file, const int line, const std::string msg) |
|||
: d_msg(msg), d_file(file), d_line(line) |
|||
{ |
|||
std::ostringstream os; |
|||
os << d_file << ": " << d_line << ": " << d_msg; |
|||
d_msg = os.str(); |
|||
} |
|||
/*! \brief Get the exception identifier.
|
|||
*/ |
|||
const char* what() const noexcept |
|||
{ |
|||
return d_msg.c_str(); |
|||
}; |
|||
/*! \brief Get the naked file where the exception happened.
|
|||
*/ |
|||
std::string file() const noexcept {return d_file;} |
|||
/*! \brief Get line where the exception happened.
|
|||
*/ |
|||
int line() const noexcept {return d_line;} |
|||
}; |
|||
|
|||
/*! \brief Exception class to be thrown if no results have been found for a search.
|
|||
*/ |
|||
class dict_no_results : public dict_exception |
|||
{ |
|||
public: |
|||
dict_no_results(const std::string file, const int line, const std::string msg = "") |
|||
: dict_exception(file, line, msg) {} |
|||
/*! \brief Change message content of a exception, that has been thrown.
|
|||
*/ |
|||
void operator<<(const std::string& new_msg) noexcept |
|||
{ |
|||
this->d_msg += new_msg; |
|||
} |
|||
}; |
|||
|
|||
/*! \brief Exception class to be thrown if there is a libcurl issue.
|
|||
*/ |
|||
class dict_libcurl_error : public dict_exception |
|||
{ |
|||
public: |
|||
dict_libcurl_error(const std::string file, const int line, const std::string msg) |
|||
: dict_exception(file, line, msg) {} |
|||
}; |
|||
|
|||
/*! \brief Exception class to be thrown if there is a libcurl issue.
|
|||
*/ |
|||
class dict_lang_error : public dict_exception |
|||
{ |
|||
public: |
|||
dict_lang_error(const std::string file, const int line, const std::string msg = "Language is not supported.") |
|||
: dict_exception(file, line, msg) {} |
|||
}; |
|||
|
|||
} // namespace dictcc
|
|||
|
|||
#endif // DICTCC_EXCEPTIONS_INCLUDED
|
@ -0,0 +1,26 @@ |
|||
#include <string> |
|||
#include <utility> |
|||
#include <functional> |
|||
#include <vector> |
|||
|
|||
#ifndef DICTCC_TYPES_INCLUDED |
|||
#define DICTCC_TYPES_INCLUDED |
|||
|
|||
namespace dictcc |
|||
{ |
|||
/*! \brief List of words in one language.
|
|||
*/ |
|||
typedef std::vector<std::string> word_list_t; |
|||
/*! \brief Pair of two word lists with corresponding word/sentence pairs (translations) resulting from a search string.
|
|||
*/ |
|||
typedef std::pair<word_list_t*, word_list_t*> search_t; |
|||
/*! \brief Supported language pairs.
|
|||
*/ |
|||
typedef enum |
|||
{ |
|||
DESV, |
|||
DEEN |
|||
} lang_t; |
|||
} // namespace dictcc
|
|||
|
|||
#endif // DICTCC_TYPES_INCLUDED
|
Loading…
Reference in new issue