Move hex-related functions into their own file
This commit is contained in:
parent
9b6f6a4bcc
commit
d1711a040b
|
@ -29,7 +29,7 @@ list(APPEND FLAGS -Werror -Wall -Wextra -Wshadow -Wpedantic -Wno-gnu-anonymous-s
|
||||||
add_link_options(${FLAGS})
|
add_link_options(${FLAGS})
|
||||||
|
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME} main.cpp numberhelper.cpp config.cpp settings.cpp models.cpp client.cpp servehelper.cpp timeutils.cpp hiredis_wrapper.cpp
|
add_executable(${PROJECT_NAME} main.cpp numberhelper.cpp hex.cpp config.cpp settings.cpp models.cpp client.cpp servehelper.cpp timeutils.cpp hiredis_wrapper.cpp
|
||||||
routes/home.cpp routes/css.cpp routes/user.cpp routes/status.cpp routes/tags.cpp routes/about.cpp routes/user_settings.cpp
|
routes/home.cpp routes/css.cpp routes/user.cpp routes/status.cpp routes/tags.cpp routes/about.cpp routes/user_settings.cpp
|
||||||
blankie/serializer.cpp blankie/escape.cpp)
|
blankie/serializer.cpp blankie/escape.cpp)
|
||||||
set_target_properties(${PROJECT_NAME}
|
set_target_properties(${PROJECT_NAME}
|
||||||
|
|
51
client.cpp
51
client.cpp
|
@ -2,6 +2,7 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
#include "hex.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "models.h"
|
#include "models.h"
|
||||||
#include "curlu_wrapper.h"
|
#include "curlu_wrapper.h"
|
||||||
|
@ -11,8 +12,6 @@ MastodonClient mastodon_client;
|
||||||
|
|
||||||
static void lowercase(std::string& str);
|
static void lowercase(std::string& str);
|
||||||
static void handle_post_server(Post& post, const std::string& host);
|
static void handle_post_server(Post& post, const std::string& host);
|
||||||
static std::string url_encode(const std::string& in);
|
|
||||||
static inline void hexencode(char c, char out[2]);
|
|
||||||
|
|
||||||
static void share_lock(CURL* curl, curl_lock_data data, curl_lock_access access, void* clientp);
|
static void share_lock(CURL* curl, curl_lock_data data, curl_lock_access access, void* clientp);
|
||||||
static void share_unlock(CURL* curl, curl_lock_data data, void* clientp);
|
static void share_unlock(CURL* curl, curl_lock_data data, void* clientp);
|
||||||
|
@ -90,7 +89,7 @@ std::optional<Account> MastodonClient::get_account_by_username(std::string host,
|
||||||
url.set(CURLUPART_SCHEME, "https");
|
url.set(CURLUPART_SCHEME, "https");
|
||||||
url.set(CURLUPART_HOST, host);
|
url.set(CURLUPART_HOST, host);
|
||||||
url.set(CURLUPART_PATH, "/api/v1/accounts/lookup");
|
url.set(CURLUPART_PATH, "/api/v1/accounts/lookup");
|
||||||
url.set(CURLUPART_QUERY, "acct="s + url_encode(username));
|
url.set(CURLUPART_QUERY, "acct="s + percent_encode(username));
|
||||||
try {
|
try {
|
||||||
Account account = this->_send_request("coyote:"s + host + ":@" + username, url);
|
Account account = this->_send_request("coyote:"s + host + ":@" + username, url);
|
||||||
account.same_server = host == account.server;
|
account.same_server = host == account.server;
|
||||||
|
@ -111,7 +110,7 @@ std::vector<Post> MastodonClient::get_pinned_posts(std::string host, const std::
|
||||||
CurlUrl url;
|
CurlUrl url;
|
||||||
url.set(CURLUPART_SCHEME, "https");
|
url.set(CURLUPART_SCHEME, "https");
|
||||||
url.set(CURLUPART_HOST, host);
|
url.set(CURLUPART_HOST, host);
|
||||||
url.set(CURLUPART_PATH, "/api/v1/accounts/"s + url_encode(account_id) + "/statuses");
|
url.set(CURLUPART_PATH, "/api/v1/accounts/"s + percent_encode(account_id) + "/statuses");
|
||||||
url.set(CURLUPART_QUERY, "pinned=true");
|
url.set(CURLUPART_QUERY, "pinned=true");
|
||||||
std::vector<Post> posts = this->_send_request("coyote:"s + host + ':' + account_id + ":pinned", url);
|
std::vector<Post> posts = this->_send_request("coyote:"s + host + ':' + account_id + ":pinned", url);
|
||||||
|
|
||||||
|
@ -129,7 +128,7 @@ std::vector<Post> MastodonClient::get_posts(const std::string& host, const std::
|
||||||
CurlUrl url;
|
CurlUrl url;
|
||||||
url.set(CURLUPART_SCHEME, "https");
|
url.set(CURLUPART_SCHEME, "https");
|
||||||
url.set(CURLUPART_HOST, host);
|
url.set(CURLUPART_HOST, host);
|
||||||
url.set(CURLUPART_PATH, "/api/v1/accounts/"s + url_encode(account_id) + "/statuses");
|
url.set(CURLUPART_PATH, "/api/v1/accounts/"s + percent_encode(account_id) + "/statuses");
|
||||||
url.set(CURLUPART_QUERY, sorting_parameters[sorting_method]);
|
url.set(CURLUPART_QUERY, sorting_parameters[sorting_method]);
|
||||||
if (max_id) {
|
if (max_id) {
|
||||||
url.set(CURLUPART_QUERY, "max_id="s + std::move(*max_id), CURLU_URLENCODE | CURLU_APPENDQUERY);
|
url.set(CURLUPART_QUERY, "max_id="s + std::move(*max_id), CURLU_URLENCODE | CURLU_APPENDQUERY);
|
||||||
|
@ -150,7 +149,7 @@ std::optional<Post> MastodonClient::get_post(const std::string& host, std::strin
|
||||||
CurlUrl url;
|
CurlUrl url;
|
||||||
url.set(CURLUPART_SCHEME, "https");
|
url.set(CURLUPART_SCHEME, "https");
|
||||||
url.set(CURLUPART_HOST, host);
|
url.set(CURLUPART_HOST, host);
|
||||||
url.set(CURLUPART_PATH, "/api/v1/statuses/"s + url_encode(std::move(id)));
|
url.set(CURLUPART_PATH, "/api/v1/statuses/"s + percent_encode(std::move(id)));
|
||||||
try {
|
try {
|
||||||
Post post = this->_send_request(std::nullopt, url);
|
Post post = this->_send_request(std::nullopt, url);
|
||||||
handle_post_server(post, host);
|
handle_post_server(post, host);
|
||||||
|
@ -170,7 +169,7 @@ PostContext MastodonClient::get_post_context(const std::string& host, std::strin
|
||||||
CurlUrl url;
|
CurlUrl url;
|
||||||
url.set(CURLUPART_SCHEME, "https");
|
url.set(CURLUPART_SCHEME, "https");
|
||||||
url.set(CURLUPART_HOST, host);
|
url.set(CURLUPART_HOST, host);
|
||||||
url.set(CURLUPART_PATH, "/api/v1/statuses/"s + url_encode(std::move(id)) + "/context");
|
url.set(CURLUPART_PATH, "/api/v1/statuses/"s + percent_encode(std::move(id)) + "/context");
|
||||||
PostContext context = this->_send_request(std::nullopt, url);
|
PostContext context = this->_send_request(std::nullopt, url);
|
||||||
|
|
||||||
for (Post& post : context.ancestors) {
|
for (Post& post : context.ancestors) {
|
||||||
|
@ -189,7 +188,7 @@ std::vector<Post> MastodonClient::get_tag_timeline(const std::string& host, cons
|
||||||
CurlUrl url;
|
CurlUrl url;
|
||||||
url.set(CURLUPART_SCHEME, "https");
|
url.set(CURLUPART_SCHEME, "https");
|
||||||
url.set(CURLUPART_HOST, host);
|
url.set(CURLUPART_HOST, host);
|
||||||
url.set(CURLUPART_PATH, "/api/v1/timelines/tag/"s + url_encode(tag));
|
url.set(CURLUPART_PATH, "/api/v1/timelines/tag/"s + percent_encode(tag));
|
||||||
if (max_id) {
|
if (max_id) {
|
||||||
url.set(CURLUPART_QUERY, "max_id="s + std::move(*max_id), CURLU_URLENCODE | CURLU_APPENDQUERY);
|
url.set(CURLUPART_QUERY, "max_id="s + std::move(*max_id), CURLU_URLENCODE | CURLU_APPENDQUERY);
|
||||||
}
|
}
|
||||||
|
@ -313,42 +312,6 @@ static void handle_post_server(Post& post, const std::string& host) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string url_encode(const std::string& in) {
|
|
||||||
std::string out;
|
|
||||||
char encoded[2];
|
|
||||||
size_t pos = 0;
|
|
||||||
size_t last_pos = 0;
|
|
||||||
|
|
||||||
out.reserve(in.size());
|
|
||||||
while ((pos = in.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", pos)) != std::string::npos) {
|
|
||||||
out.append(in, last_pos, pos - last_pos);
|
|
||||||
hexencode(in[pos], encoded);
|
|
||||||
out += '%';
|
|
||||||
out.append(encoded, 2);
|
|
||||||
pos++;
|
|
||||||
last_pos = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in.size() > last_pos) {
|
|
||||||
out.append(in, last_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void hexencode(char c, char out[2]) {
|
|
||||||
char nibble1 = (c >> 4) & 0xF;
|
|
||||||
char nibble2 = c & 0xF;
|
|
||||||
|
|
||||||
auto hexencode = [](char nibble) {
|
|
||||||
return static_cast<char>(nibble < 10
|
|
||||||
? '0' + nibble
|
|
||||||
: 'A' + nibble - 10);
|
|
||||||
};
|
|
||||||
out[0] = hexencode(nibble1);
|
|
||||||
out[1] = hexencode(nibble2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void share_lock(CURL* curl, curl_lock_data data, curl_lock_access access, void* clientp) {
|
static void share_lock(CURL* curl, curl_lock_data data, curl_lock_access access, void* clientp) {
|
||||||
(void)curl;
|
(void)curl;
|
||||||
(void)access;
|
(void)access;
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include "hex.h"
|
||||||
|
|
||||||
|
static void hex_encode(char c, char out[2]);
|
||||||
|
static inline char hex_decode(char nibble1, char nibble2);
|
||||||
|
|
||||||
|
|
||||||
|
std::string hex_encode(const char* in, size_t in_size) {
|
||||||
|
std::string out;
|
||||||
|
|
||||||
|
out.reserve(in_size * 2);
|
||||||
|
for (size_t i = 0; i < in_size; i++) {
|
||||||
|
char encoded[2];
|
||||||
|
hex_encode(in[i], encoded);
|
||||||
|
out.append(encoded, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string percent_encode(std::string_view in) {
|
||||||
|
std::string out;
|
||||||
|
char encoded[2];
|
||||||
|
size_t pos = 0;
|
||||||
|
size_t last_pos = 0;
|
||||||
|
|
||||||
|
out.reserve(in.size());
|
||||||
|
while ((pos = in.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", pos)) != std::string::npos) {
|
||||||
|
out.append(in, last_pos, pos - last_pos);
|
||||||
|
hex_encode(in[pos], encoded);
|
||||||
|
out += '%';
|
||||||
|
out.append(encoded, 2);
|
||||||
|
pos++;
|
||||||
|
last_pos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in.size() > last_pos) {
|
||||||
|
out.append(in, last_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> hex_decode(std::string_view in) {
|
||||||
|
if (in.size() % 2 != 0) {
|
||||||
|
throw std::invalid_argument("hex_decode(): hex string with an odd size passed");
|
||||||
|
}
|
||||||
|
std::vector<char> out;
|
||||||
|
|
||||||
|
out.reserve(in.size() / 2);
|
||||||
|
for (size_t i = 0; i < in.size(); i += 2) {
|
||||||
|
out.push_back(hex_decode(in[i], in[i + 1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hex_encode(char c, char out[2]) {
|
||||||
|
char nibble1 = (c >> 4) & 0xF;
|
||||||
|
char nibble2 = c & 0xF;
|
||||||
|
|
||||||
|
auto hex_encode = [](char nibble) {
|
||||||
|
return static_cast<char>(nibble < 10
|
||||||
|
? '0' + nibble
|
||||||
|
: 'A' + nibble - 10);
|
||||||
|
};
|
||||||
|
out[0] = hex_encode(nibble1);
|
||||||
|
out[1] = hex_encode(nibble2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char hex_decode(char nibble1, char nibble2) {
|
||||||
|
auto hex_decode = [](char nibble) {
|
||||||
|
if (nibble >= '0' && nibble <= '9') return nibble - '0';
|
||||||
|
if (nibble >= 'a' && nibble <= 'f') return nibble - 'a' + 10;
|
||||||
|
if (nibble >= 'A' && nibble <= 'F') return nibble - 'A' + 10;
|
||||||
|
throw std::invalid_argument("hex_decode(): invalid nibble");
|
||||||
|
};
|
||||||
|
|
||||||
|
return static_cast<char>((hex_decode(nibble1) << 4) | hex_decode(nibble2));
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
std::string hex_encode(const char* in, size_t in_size);
|
||||||
|
inline std::string hex_encode(const std::vector<char>& in) {
|
||||||
|
return hex_encode(in.data(), in.size());
|
||||||
|
}
|
||||||
|
std::string percent_encode(std::string_view in);
|
||||||
|
|
||||||
|
std::vector<char> hex_decode(std::string_view in);
|
Loading…
Reference in New Issue