135 lines
3.2 KiB
C++
135 lines
3.2 KiB
C++
|
|
#pragma once
|
|
|
|
#if !defined(MIJIN_NET_CURL_WRAPPERS_HPP_INCLUDED)
|
|
#define MIJIN_NET_CURL_WRAPPERS_HPP_INCLUDED 1
|
|
|
|
#include <curl/curl.h>
|
|
|
|
#include "./url.hpp"
|
|
#include "../debug/assert.hpp"
|
|
#include "../internal/common.hpp"
|
|
#include "../types/result.hpp"
|
|
|
|
namespace curl
|
|
{
|
|
#if !MIJIN_WITH_EXCEPTIONS
|
|
struct [[nodiscard]] Error
|
|
{
|
|
CURLcode code = CURLE_OK;
|
|
|
|
[[nodiscard]]
|
|
bool isSuccess() const MIJIN_NOEXCEPT { return code == CURLE_OK; }
|
|
};
|
|
|
|
#define MIJIN_CURL_VERIFY_RESULT(curlResult) \
|
|
do \
|
|
{ \
|
|
if ((curlResult) != CURLE_OK) \
|
|
{ \
|
|
return Error{curlResult}; \
|
|
} \
|
|
} while (0)
|
|
#define MIJIN_CURL_RETURN_SUCCESS() return Error()
|
|
#else
|
|
using Error = void;
|
|
|
|
[[nodiscard]]
|
|
std::string curlCodeMessage(CURLcode code)
|
|
{
|
|
switch (code)
|
|
{
|
|
default:
|
|
return "Unknown CURL error.";
|
|
}
|
|
}
|
|
|
|
class CurlException : public std::runtime_error
|
|
{
|
|
private:
|
|
CURLcode code_;
|
|
public:
|
|
explicit CurlException(CURLcode code) MIJIN_NOEXCEPT: std::runtime_error(curlCodeMessage(code)), code_(code)
|
|
{}
|
|
|
|
[[nodiscard]]
|
|
constexpr CURLcode getCode() const MIJIN_NOEXCEPT
|
|
{ return code_; }
|
|
};
|
|
|
|
#define MIJIN_CURL_VERIFY_RESULT(curlResult) \
|
|
do \
|
|
{ \
|
|
if ((curlResult) != CURLE_OK) \
|
|
{ \
|
|
throw CurlException((curlResult)); \
|
|
} \
|
|
} while (0)
|
|
#define MIJIN_CURL_RETURN_SUCCESS() return
|
|
#endif
|
|
|
|
class CurlEasy
|
|
{
|
|
private:
|
|
CURL* handle_ = nullptr;
|
|
public:
|
|
CurlEasy() MIJIN_NOEXCEPT = default;
|
|
CurlEasy(const CurlEasy&) = delete;
|
|
CurlEasy(CurlEasy&& other) MIJIN_NOEXCEPT : handle_(std::exchange(other.handle_, nullptr)) {}
|
|
~CurlEasy() MIJIN_NOEXCEPT
|
|
{
|
|
reset();
|
|
}
|
|
|
|
CurlEasy& operator=(const CurlEasy&) = delete;
|
|
CurlEasy& operator=(CurlEasy&& other) MIJIN_NOEXCEPT
|
|
{
|
|
if (this == &other)
|
|
{
|
|
return *this;
|
|
}
|
|
reset();
|
|
handle_ = std::exchange(other.handle_, nullptr);
|
|
return *this;
|
|
}
|
|
|
|
MIJIN_ERROR_BOOL init() MIJIN_THROWS
|
|
{
|
|
reset();
|
|
handle_ = curl_easy_init();
|
|
if (handle_ != nullptr)
|
|
{
|
|
MIJIN_THROW_OR_RETURN_STD(false, "Error initializing CURL easy.");
|
|
}
|
|
MIJIN_RETURN_SUCCESS(true);
|
|
}
|
|
void reset() MIJIN_NOEXCEPT
|
|
{
|
|
if (handle_)
|
|
{
|
|
curl_easy_cleanup(handle_);
|
|
handle_ = nullptr;
|
|
}
|
|
}
|
|
|
|
Error setURL(const char* url) MIJIN_THROWS
|
|
{
|
|
const CURLcode result = curl_easy_setopt(handle_, CURLOPT_URL, url);
|
|
MIJIN_CURL_VERIFY_RESULT(result);
|
|
MIJIN_CURL_RETURN_SUCCESS();
|
|
}
|
|
|
|
Error setURL(const std::string& url) MIJIN_NOEXCEPT
|
|
{
|
|
return setURL(url.c_str());
|
|
}
|
|
|
|
Error setURL(const mijin::URL& url) MIJIN_NOEXCEPT
|
|
{
|
|
return setURL(url.getBase().c_str());
|
|
}
|
|
};
|
|
} // namespace curl
|
|
|
|
#endif // !defined(MIJIN_NET_CURL_WRAPPERS_HPP_INCLUDED)
|