diff --git a/wordref/src/HttpReader.cpp b/wordref/src/HttpReader.cpp
index c3fb30e..5a7f2a5 100644
--- a/wordref/src/HttpReader.cpp
+++ b/wordref/src/HttpReader.cpp
@@ -20,6 +20,8 @@ along with this program. If not, see .
#include "HttpReader.hpp"
#include
#include
+#include
+#include
namespace {
///------------------------------------------------------------------------
@@ -32,6 +34,30 @@ namespace {
that->append(parData, effectiveWrite);
return effectiveWrite;
}
+
+ std::string GetCleanWord (CURL* parCurl, std::wstring parWord) __attribute__((pure));
+
+ ///-------------------------------------------------------------------------
+ ///-------------------------------------------------------------------------
+ std::string GetCleanWord (CURL* parCurl, std::wstring parWord) {
+ class CurlFree {
+ public:
+ CurlFree ( void ) noexcept = default;
+ void operator() ( char* parDele ) const { curl_free(parDele); }
+ };
+
+ boost::algorithm::trim_all(parWord);
+ const size_t maxMultibSize = parWord.size() * 4 + 1;
+ const std::unique_ptr memForMultib(new char[maxMultibSize]);
+
+ const size_t wctombsRet = std::wcstombs(memForMultib.get(), parWord.c_str(), maxMultibSize);
+ if (EILSEQ == wctombsRet)
+ throw std::runtime_error("Can't convert received string to multibyte, wcstombs() failed");
+
+ const std::unique_ptr urlEncoded(curl_easy_escape(parCurl, memForMultib.get(), static_cast(wctombsRet)));
+ std::string retVal(urlEncoded.get());
+ return retVal;
+ }
} //unnamed namespace
struct HttpReader::LocalData {
@@ -84,3 +110,15 @@ std::string HttpReader::GetPage (const std::string& parAddress) const {
}
return localString;
}
+
+///-----------------------------------------------------------------------------
+///-----------------------------------------------------------------------------
+std::string HttpReader::UrlEncode (const wchar_t* parWord) {
+ return GetCleanWord(m_localData->curl, parWord);
+}
+
+///-----------------------------------------------------------------------------
+///-----------------------------------------------------------------------------
+std::string HttpReader::UrlEncode (const std::wstring& parWord) {
+ return GetCleanWord(m_localData->curl, parWord);
+}
diff --git a/wordref/src/HttpReader.hpp b/wordref/src/HttpReader.hpp
index 53f06e0..41b1057 100644
--- a/wordref/src/HttpReader.hpp
+++ b/wordref/src/HttpReader.hpp
@@ -7,6 +7,8 @@ public:
~HttpReader ( void ) noexcept;
std::string GetPage ( const std::string& parAddress ) const;
+ std::string UrlEncode ( const wchar_t* parWord ) __attribute__((pure));
+ std::string UrlEncode ( const std::wstring& parWord ) __attribute__((pure));
private:
struct LocalData;
diff --git a/wordref/src/WordReference.cpp b/wordref/src/WordReference.cpp
index 9131cd9..bb52388 100644
--- a/wordref/src/WordReference.cpp
+++ b/wordref/src/WordReference.cpp
@@ -21,7 +21,6 @@ along with this program. If not, see .
#include "HttpReader.hpp"
#include "libjson.h"
#include
-#include
namespace {
const char* ApiVersion = "0.8";
@@ -44,25 +43,14 @@ namespace {
std::pair("tr", "Turkish")
};
- std::string GetCleanWord (std::string parWord) __attribute__((pure));
-
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
- std::string GetCleanWord (std::string parWord) {
- boost::algorithm::trim_all(parWord);
- std::replace(parWord.begin(), parWord.end(), ' ', '+');
- return parWord;
- }
-
- ///-------------------------------------------------------------------------
- ///-------------------------------------------------------------------------
- JSONNode QueryJSon (const std::string& parFrom, const std::string& parTo, const std::string& parKey, const std::string& parWord) {
+ JSONNode QueryJSon (HttpReader& parHttp, const std::string& parFrom, const std::string& parTo, const std::string& parKey, const std::wstring& parWord) {
std::ostringstream oss;
oss << "http://api.wordreference.com/" << ApiVersion << "/"
- << parKey << "/json/" << parFrom << parTo << "/" << GetCleanWord(parWord);
+ << parKey << "/json/" << parFrom << parTo << "/" << parHttp.UrlEncode(parWord);
- HttpReader http;
- std::string jsonResponse(http.GetPage(oss.str()));
+ std::string jsonResponse(parHttp.GetPage(oss.str()));
return libjson::parse(libjson::to_json_string(jsonResponse));
}
@@ -112,6 +100,7 @@ ErrBadLanguage::ErrBadLanguage (std::string&& parMessage) :
///-----------------------------------------------------------------------------
///-----------------------------------------------------------------------------
WordReference::WordReference (const char* parFrom, const char* parTo, const char* parApiKey) :
+ m_httpReader(new HttpReader),
m_langFrom(parFrom),
m_langTo(parTo),
m_apiKey(parApiKey)
@@ -128,6 +117,11 @@ WordReference::WordReference (const char* parFrom, const char* parTo, const char
}
}
+///-----------------------------------------------------------------------------
+///-----------------------------------------------------------------------------
+WordReference::~WordReference() {
+}
+
///-----------------------------------------------------------------------------
///-----------------------------------------------------------------------------
const std::string& WordReference::GetLanguageCode (WordReferenceLangDirection parDir) const {
@@ -143,24 +137,6 @@ const std::string& WordReference::GetLanguageName (WordReferenceLangDirection pa
return SupportedLanguages.at(GetLanguageCode(parDir));
}
-///-----------------------------------------------------------------------------
-///-----------------------------------------------------------------------------
-std::string WordReference::GetHttpLink (const char* parWord) {
- std::ostringstream oss;
- oss << "http://www.wordreference.com/redirect/translation.aspx?w=";
- oss << GetCleanWord(parWord) << "&dict=" << m_langFrom << m_langTo;
- return oss.str();
-}
-
-///-----------------------------------------------------------------------------
-///-----------------------------------------------------------------------------
-std::string WordReference::GetHttpLink (const std::string& parWord) {
- std::ostringstream oss;
- oss << "http://www.wordreference.com/redirect/translation.aspx?w=";
- oss << GetCleanWord(parWord) << "&dict=" << m_langFrom << m_langTo;
- return oss.str();
-}
-
///-----------------------------------------------------------------------------
///-----------------------------------------------------------------------------
std::string WordReference::GetApiVersion() {
@@ -169,8 +145,8 @@ std::string WordReference::GetApiVersion() {
///-----------------------------------------------------------------------------
///-----------------------------------------------------------------------------
-void WordReference::Translate (const std::string& parWord, std::wostream& parStream) {
- JSONNode root = QueryJSon(m_langFrom, m_langTo, m_apiKey, parWord);
+void WordReference::Translate (const std::wstring& parWord, std::wostream& parStream) {
+ JSONNode root = QueryJSon(*m_httpReader, m_langFrom, m_langTo, m_apiKey, parWord);
for (JSONNode::const_iterator itCur = root.begin(), itCurEND = root.end(); itCur != itCurEND; ++itCur) {
const std::wstring nodeName(libjson::to_std_wstring(itCur->name()));
if (itCur->type() == JSON_NODE and nodeName.compare(0, 4, L"term") == 0) {
@@ -181,3 +157,21 @@ void WordReference::Translate (const std::string& parWord, std::wostream& parStr
}
}
}
+
+///-----------------------------------------------------------------------------
+///-----------------------------------------------------------------------------
+std::string WordReference::GetHttpLink (const wchar_t* parWord) {
+ std::ostringstream oss;
+ oss << "http://www.wordreference.com/redirect/translation.aspx?w=";
+ oss << m_httpReader->UrlEncode(parWord) << "&dict=" << m_langFrom << m_langTo;
+ return oss.str();
+}
+
+///-----------------------------------------------------------------------------
+///-----------------------------------------------------------------------------
+std::string WordReference::GetHttpLink (const std::wstring& parWord) {
+ std::ostringstream oss;
+ oss << "http://www.wordreference.com/redirect/translation.aspx?w=";
+ oss << m_httpReader->UrlEncode(parWord) << "&dict=" << m_langFrom << m_langTo;
+ return oss.str();
+}
diff --git a/wordref/src/WordReference.hpp b/wordref/src/WordReference.hpp
index 71c131a..3ac396e 100644
--- a/wordref/src/WordReference.hpp
+++ b/wordref/src/WordReference.hpp
@@ -19,6 +19,8 @@ along with this program. If not, see .
#ifndef id75A4E59ADE4649F7A4A56F91C5886405
#define id75A4E59ADE4649F7A4A56F91C5886405
+class HttpReader;
+
enum WordReferenceLangDirection {
WordRefLangFrom,
WordRefLangTo
@@ -34,17 +36,19 @@ public:
class WordReference {
public:
+ WordReference ( void ) = delete;
WordReference ( const char* parFrom, const char* parTo, const char* parApiKey );
- ~WordReference ( void ) = default;
+ ~WordReference ( void );
const std::string& GetLanguageCode ( WordReferenceLangDirection parDir ) const;
const std::string& GetLanguageName ( WordReferenceLangDirection parDir ) const;
- std::string GetHttpLink ( const char* parWord );
- std::string GetHttpLink ( const std::string& parWord );
static std::string GetApiVersion ( void );
- void Translate ( const std::string& parWord, std::wostream& parStream );
+ std::string GetHttpLink ( const wchar_t* parWord );
+ std::string GetHttpLink ( const std::wstring& parWord );
+ void Translate ( const std::wstring& parWord, std::wostream& parStream );
private:
+ const std::unique_ptr m_httpReader;
std::string m_langFrom;
std::string m_langTo;
std::string m_apiKey;
diff --git a/wordref/src/main.cpp b/wordref/src/main.cpp
index 8b0408b..4c6924a 100644
--- a/wordref/src/main.cpp
+++ b/wordref/src/main.cpp
@@ -102,8 +102,9 @@ int main (int parArgc, const char* const parArgv[]) {
}
WordReference wref("en", "it", DefApiKey);
- wref.Translate("house", std::wcout);
+ wref.Translate(L"house", std::wcout);
- std::wcout << wref.GetHttpLink("north face") << L"\nWritten by King_DuckZ; © WordReference.com" << std::endl;
+ std::cout << wref.GetHttpLink(L"north face") << "\n";
+ std::wcout << L"Written by King_DuckZ; © WordReference.com" << std::endl;
return 0;
}