This fixes the crash and the unrequested printf of the downloaded json
This commit is contained in:
parent
666d25c4d1
commit
fb49c84899
5 changed files with 109 additions and 41 deletions
|
@ -21,6 +21,7 @@ link_directories(
|
||||||
add_executable(${PROJECT_NAME}
|
add_executable(${PROJECT_NAME}
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
src/WordReference.cpp
|
src/WordReference.cpp
|
||||||
|
src/HttpReader.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(${PROJECT_NAME}
|
target_link_libraries(${PROJECT_NAME}
|
||||||
${Boost_LIBRARIES}
|
${Boost_LIBRARIES}
|
||||||
|
|
86
wordref/src/HttpReader.cpp
Normal file
86
wordref/src/HttpReader.cpp
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
WordReferenceCLI, a c++ program to access WordReference.com.
|
||||||
|
Copyright (C) 2013 King_DuckZ
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.hpp"
|
||||||
|
#include "HttpReader.hpp"
|
||||||
|
#include <curl/curl.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
///------------------------------------------------------------------------
|
||||||
|
///------------------------------------------------------------------------
|
||||||
|
extern "C" int readCurlHelper(char* parData, size_t parSize, size_t parNmemb, void* parBuffer) {
|
||||||
|
std::string* const that = static_cast<std::string*>(parBuffer);
|
||||||
|
const size_t dataLen = parSize * parNmemb;
|
||||||
|
that->reserve(that->size() + dataLen);
|
||||||
|
const size_t effectiveWrite = std::min(dataLen, that->capacity() - that->size());
|
||||||
|
that->append(parData, effectiveWrite);
|
||||||
|
return effectiveWrite;
|
||||||
|
}
|
||||||
|
} //unnamed namespace
|
||||||
|
|
||||||
|
struct HttpReader::LocalData {
|
||||||
|
explicit LocalData ( CURL* parCurl ) : curl(parCurl), headers(nullptr) {}
|
||||||
|
|
||||||
|
CURL* const curl;
|
||||||
|
struct curl_slist* headers;
|
||||||
|
};
|
||||||
|
|
||||||
|
///----------------------------------------------------------------------------
|
||||||
|
///----------------------------------------------------------------------------
|
||||||
|
HttpReader::HttpReader() :
|
||||||
|
m_localData(new LocalData(curl_easy_init()))
|
||||||
|
{
|
||||||
|
if (m_localData->curl) {
|
||||||
|
curl_slist_append(m_localData->headers, "Accept: application/json");
|
||||||
|
curl_slist_append(m_localData->headers, "Content-Type: application/json");
|
||||||
|
curl_slist_append(m_localData->headers, "charset: utf-8");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw std::runtime_error("Can't create the CURL object, curl_easy_init() failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///----------------------------------------------------------------------------
|
||||||
|
///----------------------------------------------------------------------------
|
||||||
|
HttpReader::~HttpReader() noexcept {
|
||||||
|
if (m_localData->curl)
|
||||||
|
curl_easy_cleanup(m_localData->curl);
|
||||||
|
curl_slist_free_all(m_localData->headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
///----------------------------------------------------------------------------
|
||||||
|
///----------------------------------------------------------------------------
|
||||||
|
std::string HttpReader::GetPage (const std::string& parAddress) const {
|
||||||
|
std::string localString;
|
||||||
|
|
||||||
|
curl_easy_setopt(m_localData->curl, CURLOPT_FOLLOWLOCATION, 1L); //Tell curl to follow redirection when needed
|
||||||
|
curl_easy_setopt(m_localData->curl, CURLOPT_HTTPHEADER, m_localData->headers);
|
||||||
|
curl_easy_setopt(m_localData->curl, CURLOPT_URL, parAddress.c_str());
|
||||||
|
curl_easy_setopt(m_localData->curl, CURLOPT_HTTPGET, 1);
|
||||||
|
curl_easy_setopt(m_localData->curl, CURLOPT_WRITEFUNCTION, &readCurlHelper);
|
||||||
|
curl_easy_setopt(m_localData->curl, CURLOPT_WRITEDATA, &localString);
|
||||||
|
|
||||||
|
const CURLcode res = curl_easy_perform(m_localData->curl);
|
||||||
|
if (CURLE_OK != res) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "Error during the CURL request: " << curl_easy_strerror(res);
|
||||||
|
throw std::runtime_error(oss.str());
|
||||||
|
}
|
||||||
|
return localString;
|
||||||
|
}
|
17
wordref/src/HttpReader.hpp
Normal file
17
wordref/src/HttpReader.hpp
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef idC90956E8210D439AA5E2801D9E9FD799
|
||||||
|
#define idC90956E8210D439AA5E2801D9E9FD799
|
||||||
|
|
||||||
|
class HttpReader {
|
||||||
|
public:
|
||||||
|
HttpReader ( void );
|
||||||
|
~HttpReader ( void ) noexcept;
|
||||||
|
|
||||||
|
std::string GetPage ( const std::string& parAddress ) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct LocalData;
|
||||||
|
|
||||||
|
const std::unique_ptr<LocalData> m_localData;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -18,10 +18,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#include "main.hpp"
|
#include "main.hpp"
|
||||||
#include "WordReference.hpp"
|
#include "WordReference.hpp"
|
||||||
|
#include "HttpReader.hpp"
|
||||||
|
#include "libjson.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <boost/algorithm/string/trim_all.hpp>
|
#include <boost/algorithm/string/trim_all.hpp>
|
||||||
#include <curl/curl.h>
|
|
||||||
#include "libjson.h"
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const char* ApiVersion = "0.8";
|
const char* ApiVersion = "0.8";
|
||||||
|
@ -54,43 +54,6 @@ namespace {
|
||||||
return parWord;
|
return parWord;
|
||||||
}
|
}
|
||||||
|
|
||||||
///-------------------------------------------------------------------------
|
|
||||||
///-------------------------------------------------------------------------
|
|
||||||
void DownloadHttpPage (const std::string& parAddress, std::string& parDest) {
|
|
||||||
struct CurlAuto {
|
|
||||||
CurlAuto ( void ) : curl(curl_easy_init()) {}
|
|
||||||
~CurlAuto ( void ) { if (curl) curl_easy_cleanup(curl); }
|
|
||||||
CURL* const curl;
|
|
||||||
};
|
|
||||||
|
|
||||||
CurlAuto curl;
|
|
||||||
if (curl.curl) {
|
|
||||||
curl_easy_setopt(curl.curl, CURLOPT_URL, parAddress.c_str());
|
|
||||||
//Tell curl to follow redirection when needed
|
|
||||||
curl_easy_setopt(curl.curl, CURLOPT_FOLLOWLOCATION, 1L);
|
|
||||||
|
|
||||||
const CURLcode res = curl_easy_perform(curl.curl);
|
|
||||||
if (CURLE_OK == res) {
|
|
||||||
char* reading;
|
|
||||||
const CURLcode res = curl_easy_getinfo(curl.curl, CURLINFO_CONTENT_TYPE, &reading);
|
|
||||||
if (CURLE_OK != res or not reading) {
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "Error while requesting http page: " << curl_easy_strerror(res);
|
|
||||||
throw std::runtime_error(oss.str());
|
|
||||||
}
|
|
||||||
parDest = reading;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "Error during the CURL request: " << curl_easy_strerror(res);
|
|
||||||
throw std::runtime_error(oss.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw std::runtime_error("Error initializing CURL");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///-------------------------------------------------------------------------
|
///-------------------------------------------------------------------------
|
||||||
///-------------------------------------------------------------------------
|
///-------------------------------------------------------------------------
|
||||||
JSONNode QueryJSon (const std::string& parFrom, const std::string& parTo, const std::string& parKey, const std::string& parWord) {
|
JSONNode QueryJSon (const std::string& parFrom, const std::string& parTo, const std::string& parKey, const std::string& parWord) {
|
||||||
|
@ -98,8 +61,8 @@ namespace {
|
||||||
oss << "http://api.wordreference.com/" << ApiVersion << "/"
|
oss << "http://api.wordreference.com/" << ApiVersion << "/"
|
||||||
<< parKey << "/json/" << parFrom << parTo << "/" << GetCleanWord(parWord);
|
<< parKey << "/json/" << parFrom << parTo << "/" << GetCleanWord(parWord);
|
||||||
|
|
||||||
std::string jsonResponse;
|
HttpReader http;
|
||||||
DownloadHttpPage(oss.str(), jsonResponse);
|
std::string jsonResponse(http.GetPage(oss.str()));
|
||||||
return libjson::parse(libjson::to_json_string(jsonResponse));
|
return libjson::parse(libjson::to_json_string(jsonResponse));
|
||||||
}
|
}
|
||||||
} //unnamed namespace
|
} //unnamed namespace
|
||||||
|
|
|
@ -23,5 +23,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue