Use a unified string-to-number function

This commit is contained in:
blankie 2023-04-07 22:13:25 +07:00
parent 5c594b6301
commit b414bfbf13
Signed by: blankie
GPG Key ID: CC15FC822C7F61F5
7 changed files with 44 additions and 61 deletions

View File

@ -23,7 +23,8 @@ 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 misc.cpp config.cpp servehelper.cpp pixivclient.cpp blankie/serializer.cpp blankie/escape.cpp blankie/murl.cpp add_executable(${PROJECT_NAME} main.cpp misc.cpp config.cpp servehelper.cpp numberhelper.cpp pixivclient.cpp
blankie/serializer.cpp blankie/escape.cpp blankie/murl.cpp
routes/home.cpp routes/css.cpp routes/users/common.cpp routes/users/users.cpp routes/users/illustrations.cpp) routes/home.cpp routes/css.cpp routes/users/common.cpp routes/users/users.cpp routes/users/illustrations.cpp)
set_target_properties(${PROJECT_NAME} set_target_properties(${PROJECT_NAME}
PROPERTIES PROPERTIES

View File

@ -3,6 +3,7 @@
#include <climits> #include <climits>
#include "murl.h" #include "murl.h"
#include "../numberhelper.h"
#define UNRESERVED "[\\w\\d\\-._~]" #define UNRESERVED "[\\w\\d\\-._~]"
#define PCT_ENCODED "%[\\da-f]{2}" #define PCT_ENCODED "%[\\da-f]{2}"
@ -30,7 +31,6 @@
"(?:#" FRAGMENT ")?" "(?:#" FRAGMENT ")?"
static std::regex url_regex(HTTP_HTTPS_URL, std::regex::icase); static std::regex url_regex(HTTP_HTTPS_URL, std::regex::icase);
static inline int to_int(const std::string& str);
static void handle_segment(std::vector<std::string>& segments, const std::string& str, size_t offset, size_t length); static void handle_segment(std::vector<std::string>& segments, const std::string& str, size_t offset, size_t length);
namespace blankie { namespace blankie {
@ -122,21 +122,6 @@ std::string normalize_path(const std::string& str) {
}; // namespace murl }; // namespace murl
}; // namespace blankie }; // namespace blankie
static inline int to_int(const std::string& str) {
char* endptr;
long res = strtol(str.c_str(), &endptr, 10);
if (res > INT_MAX) {
throw std::overflow_error(str + " is too big");
} else if (res < INT_MIN) {
throw std::underflow_error(str + " is too small");
} else if (endptr[0] != '\0') {
throw std::invalid_argument(str + " has trailing text");
}
return static_cast<int>(res);
}
static void handle_segment(std::vector<std::string>& segments, const std::string& str, size_t offset, size_t length) { static void handle_segment(std::vector<std::string>& segments, const std::string& str, size_t offset, size_t length) {
if (length == 2 && str[offset] == '.' && str[offset + 1] == '.') { if (length == 2 && str[offset] == '.' && str[offset + 1] == '.') {
if (segments.empty()) { if (segments.empty()) {

31
numberhelper.cpp Normal file
View File

@ -0,0 +1,31 @@
#include <climits>
#include <stdexcept>
#include "numberhelper.h"
unsigned long long to_ull(const std::string& str) {
char* endptr;
errno = 0;
unsigned long long ret = strtoull(str.c_str(), &endptr, 10);
if (ret > ULLONG_MAX && errno == ERANGE) {
throw std::overflow_error(str + " is too big");
} else if (endptr[0] != '\0') {
throw std::invalid_argument(str + " has trailing text");
}
return ret;
}
int to_int(const std::string& str) {
char* endptr;
long ret = strtol(str.c_str(), &endptr, 10);
if (ret > INT_MAX) {
throw std::overflow_error(str + " is too big");
} else if (ret < INT_MIN) {
throw std::underflow_error(str + " is too small");
} else if (endptr[0] != '\0') {
throw std::invalid_argument(str + " has trailing text");
}
return static_cast<int>(ret);
}

7
numberhelper.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
#include <string>
#include <cstdlib>
unsigned long long to_ull(const std::string& str);
int to_int(const std::string& str);

View File

@ -1,12 +1,12 @@
#include <regex> #include <regex>
#include "numberhelper.h"
#include "blankie/murl.h" #include "blankie/murl.h"
#include "pixivclient.h" #include "pixivclient.h"
static inline std::optional<std::string> get_1920x960_cover_image(blankie::murl::Url url); static inline std::optional<std::string> get_1920x960_cover_image(blankie::murl::Url url);
static inline std::optional<std::string> get_original_cover_image(blankie::murl::Url url); static inline std::optional<std::string> get_original_cover_image(blankie::murl::Url url);
static inline std::optional<std::string> get_original_profile_picture(blankie::murl::Url url); static inline std::optional<std::string> get_original_profile_picture(blankie::murl::Url url);
static inline uint64_t to_ull(const std::string& str);
PixivClient::PixivClient() { PixivClient::PixivClient() {
this->_www_pixiv_net_client.set_keep_alive(true); this->_www_pixiv_net_client.set_keep_alive(true);
@ -130,17 +130,3 @@ static inline std::optional<std::string> get_original_profile_picture(blankie::m
url.path = sm.str(1) + sm.str(2); url.path = sm.str(1) + sm.str(2);
return url.to_string(); return url.to_string();
} }
static inline uint64_t to_ull(const std::string& str) {
char* endptr;
errno = 0;
unsigned long long res = strtoull(str.c_str(), &endptr, 10);
if (endptr[0] != '\0') {
throw std::invalid_argument(str + " contains trailing data");
} else if (res == ULLONG_MAX && errno == ERANGE) {
throw std::overflow_error(str + " overflows uint64_t");
}
return res;
}

View File

@ -1,11 +1,11 @@
#include <utility> #include <utility>
#include "../routes.h" #include "../routes.h"
#include "../../numberhelper.h"
#include "../../servehelper.h" #include "../../servehelper.h"
#include "../../pixivclient.h" #include "../../pixivclient.h"
#include "common.h" #include "common.h"
static inline uint64_t to_ull(const std::string& str);
static Element generate_pager(size_t page, size_t items, size_t items_per_page); static Element generate_pager(size_t page, size_t items, size_t items_per_page);
static inline Element generate_content(const std::vector<uint64_t>& illust_ids, size_t page, size_t items_per_page); static inline Element generate_content(const std::vector<uint64_t>& illust_ids, size_t page, size_t items_per_page);
@ -48,19 +48,6 @@ void user_illustrations_route(const httplib::Request& req, httplib::Response& re
serve(req, res, config, user.display_name + " illustrations", std::move(body)); serve(req, res, config, user.display_name + " illustrations", std::move(body));
} }
static inline uint64_t to_ull(const std::string& str) {
char* endptr;
errno = 0;
uint64_t res = strtoull(str.c_str(), &endptr, 10);
if (res == ULLONG_MAX && errno == ERANGE) {
throw std::overflow_error(str + " is too big");
} else if (endptr[0] != '\0') {
throw std::invalid_argument(str + " contains trailing text or is not an integer");
}
return res;
}
static Element generate_pager(size_t page, size_t items, size_t items_per_page) { static Element generate_pager(size_t page, size_t items, size_t items_per_page) {
using namespace std::string_literals; using namespace std::string_literals;

View File

@ -1,10 +1,9 @@
#include "../routes.h" #include "../routes.h"
#include "../../numberhelper.h"
#include "../../servehelper.h" #include "../../servehelper.h"
#include "../../pixivclient.h" #include "../../pixivclient.h"
#include "common.h" #include "common.h"
static inline uint64_t to_ull(const std::string& str);
void users_route(const httplib::Request& req, httplib::Response& res, const Config& config, PixivClient& pixiv_client) { void users_route(const httplib::Request& req, httplib::Response& res, const Config& config, PixivClient& pixiv_client) {
uint64_t user_id = to_ull(req.matches[1].str()); uint64_t user_id = to_ull(req.matches[1].str());
User user; User user;
@ -26,16 +25,3 @@ void users_route(const httplib::Request& req, httplib::Response& res, const Conf
} }
serve(req, res, config, user.display_name + " (@" + user.username + ')', generate_user_header(user, config)); serve(req, res, config, user.display_name + " (@" + user.username + ')', generate_user_header(user, config));
} }
static inline uint64_t to_ull(const std::string& str) {
char* endptr;
errno = 0;
uint64_t res = strtoull(str.c_str(), &endptr, 10);
if (res == ULLONG_MAX && errno == ERANGE) {
throw std::overflow_error(str + " is too big");
} else if (endptr[0] != '\0') {
throw std::invalid_argument(str + " contains trailing text or is not an integer");
}
return res;
}