summaryrefslogtreecommitdiff
path: root/backend/slackpkg.cpp
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-06-17 12:46:59 +0200
committerEugen Wissner <belka@caraus.de>2026-06-17 12:46:59 +0200
commit93cacaa6fe0b18609bbd9be51702ae2fed1ad663 (patch)
tree9eb0b47d678c736144cafe34f435e9154e0aad5e /backend/slackpkg.cpp
parent1d8a03a7b9121bb2c61e8ec315920c452516afcf (diff)
downloadkatja-93cacaa6fe0b18609bbd9be51702ae2fed1ad663.tar.gz
Remove glib dependencyHEADmaster
Diffstat (limited to 'backend/slackpkg.cpp')
-rw-r--r--backend/slackpkg.cpp186
1 files changed, 72 insertions, 114 deletions
diff --git a/backend/slackpkg.cpp b/backend/slackpkg.cpp
index c240088..4119625 100644
--- a/backend/slackpkg.cpp
+++ b/backend/slackpkg.cpp
@@ -11,13 +11,14 @@ module;
#include <cstdint>
#include <cstddef>
#include <string.h>
-#include <gio/gio.h>
#include <curl/curl.h>
#include <string>
#include <regex>
#include <vector>
#include <forward_list>
#include <filesystem>
+#include <boost/algorithm/string.hpp>
+#include <fstream>
export module katja.slackpkg;
@@ -72,18 +73,16 @@ public:
CURL *curl = nullptr;
cache_entry source_dest;
std::forward_list<cache_entry> file_list;
- GFile *tmp_dir, *repo_tmp_dir;
/* Create the temporary directory for the repository */
- tmp_dir = g_file_new_for_path(tmpl.native().c_str());
- repo_tmp_dir = g_file_get_child(tmp_dir, this->name.c_str());
- g_file_make_directory(repo_tmp_dir, nullptr, nullptr);
+ std::filesystem::path tmp_dir = tmpl / this->name;
+ std::filesystem::create_directories(tmp_dir);
/* Download PACKAGES.TXT. These files are most important, break if some of them couldn't be found */
for (const std::string& current_priority : this->priority)
{
source_dest.first = this->mirror + current_priority + "/PACKAGES.TXT";
- source_dest.second = tmpl / this->name / "PACKAGES.TXT";
+ source_dest.second = tmp_dir / "PACKAGES.TXT";
if (get_file(&curl, source_dest.first.c_str(), std::nullopt) == CURLE_OK)
{
@@ -104,9 +103,6 @@ public:
}
}
out:
- g_object_unref(repo_tmp_dir);
- g_object_unref(tmp_dir);
-
if (curl)
{
curl_easy_cleanup(curl);
@@ -127,23 +123,19 @@ public:
void generate_cache(JobData *job_data, const std::filesystem::path& tmpl) noexcept
{
std::vector<std::string> pkg_tokens;
- char *query = nullptr, *filename = nullptr, *location = nullptr, *summary = nullptr, *line;
+ char *query = nullptr;
unsigned pkg_compressed = 0, pkg_uncompressed = 0;
std::uint8_t pkg_name_len;
- GString *desc;
- GFile *list_file;
- GFileInputStream *fin = nullptr;
- GDataInputStream *data_in = nullptr;
+ std::string desc, line, location;
sqlite3_stmt *insert_statement = nullptr, *update_statement = nullptr, *insert_default_statement = nullptr;
sqlite3_stmt *statement;
+ std::optional<std::string> filename, summary;
/* Check if the temporary directory for this repository exists, then the file metadata have to be generated */
std::filesystem::path packages_txt = tmpl / this->name / "PACKAGES.TXT";
- list_file = g_file_new_for_path(packages_txt.native().c_str());
- fin = g_file_read(list_file, nullptr, nullptr);
- g_object_unref(list_file);
+ std::ifstream data_in(packages_txt);
- if (!fin)
+ if (!data_in)
{
goto out;
}
@@ -201,64 +193,63 @@ public:
goto out;
}
- data_in = g_data_input_stream_new(G_INPUT_STREAM(fin));
- desc = g_string_new("");
+ desc = "";
sqlite3_exec(job_data->db, "BEGIN TRANSACTION", nullptr, nullptr, nullptr);
- while ((line = g_data_input_stream_read_line(data_in, nullptr, nullptr, nullptr)))
+ while (std::getline(data_in, line))
{
- if (!strncmp(line, "PACKAGE NAME: ", 15))
+ if (boost::starts_with(line, "PACKAGE NAME: "))
{
- filename = g_strdup(line + 15);
- if (this->is_blacklisted(filename))
+ filename = line.substr(15);
+ if (this->is_blacklisted(filename.value()))
{
- g_free(filename);
- filename = nullptr;
+ filename.reset();
}
}
- else if (filename && !strncmp(line, "PACKAGE LOCATION: ", 19))
+ else if (filename.has_value() && boost::starts_with(line, "PACKAGE LOCATION: "))
{
- location = g_strdup(line + 21); /* Exclude ./ at the path beginning */
+ location = line.substr(21); /* Exclude ./ at the path beginning */
}
- else if (filename && !strncmp(line, "PACKAGE SIZE (compressed): ", 28))
+ else if (filename.has_value() && boost::starts_with(line, "PACKAGE SIZE (compressed): "))
{
/* Remove the unit (kilobytes) */
- pkg_compressed = atoi(g_strndup(line + 28, strlen(line + 28) - 2)) * 1024;
+ std::from_chars(line.c_str() + 28, line.c_str() + line.size() - 2, pkg_compressed);
+ pkg_compressed *= 1024;
}
- else if (filename && !strncmp(line, "PACKAGE SIZE (uncompressed): ", 30))
+ else if (filename.has_value() && boost::starts_with(line, "PACKAGE SIZE (uncompressed): "))
{
/* Remove the unit (kilobytes) */
- pkg_uncompressed = atoi(g_strndup(line + 30, strlen(line + 30) - 2)) * 1024;
+ std::from_chars(line.c_str() + 30, line.c_str() + line.size() - 2, pkg_uncompressed);
+ pkg_uncompressed *= 1024;
}
- else if (filename && !g_strcmp0(line, "PACKAGE DESCRIPTION:"))
+ else if (filename.has_value() && boost::starts_with(line, "PACKAGE DESCRIPTION:"))
{
- g_free(line);
- line = g_data_input_stream_read_line(data_in, nullptr, nullptr, nullptr); /* Short description */
+ std::getline(data_in, line);
- summary = g_strstr_len(line, -1, "(");
- if (summary) /* Else summary = nullptr */
+ auto summary_position = line.find_first_of('(');
+ if (summary_position != std::string::npos) /* Else summary = nullptr */
{
- summary = g_strndup(summary + 1, strlen(summary) - 2); /* Without ( ) */
+ summary = line.substr(summary_position + 1, line.size() - summary_position - 2); /* Without ( ) */
}
- pkg_tokens = split_package_name(filename).value();
+ pkg_tokens = split_package_name(filename.value()).value();
pkg_name_len = pkg_tokens[0].size(); /* Description begins with pkg_name: */
}
- else if (filename && !strncmp(line, pkg_tokens[0].c_str(), pkg_name_len))
+ else if (filename.has_value() && boost::starts_with(line, pkg_tokens[0]))
{
- g_string_append(desc, line + pkg_name_len + 1);
+ desc += line.substr(pkg_name_len + 1);
}
- else if (filename && !g_strcmp0(line, ""))
+ else if (filename.has_value() && line == "")
{
- if (g_strcmp0(location, "patches/packages")) /* Insert a new package */
+ if (location != "patches/packages") /* Insert a new package */
{
/* Get the package group based on its location */
- const char *cat = g_strrstr(location, "/");
- if (cat)
+ auto category_position = location.find_last_of('/');
+ if (category_position != std::string::npos)
{
- ++cat;
statement = insert_statement;
- sqlite3_bind_text(insert_statement, 12, cat, -1, SQLITE_TRANSIENT);
+ sqlite3_bind_text(insert_statement, 12,
+ location.c_str() + category_position + 1, -1, SQLITE_TRANSIENT);
}
else
{
@@ -274,9 +265,10 @@ public:
sqlite3_bind_text(statement, 2, pkg_tokens[1].c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 3, pkg_tokens[2].c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 4, pkg_tokens[4].c_str(), -1, SQLITE_TRANSIENT);
- sqlite3_bind_text(statement, 5, location, -1, SQLITE_TRANSIENT);
- sqlite3_bind_text(statement, 6, summary, -1, SQLITE_TRANSIENT);
- sqlite3_bind_text(statement, 7, desc->str, -1, SQLITE_TRANSIENT);
+ sqlite3_bind_text(statement, 5, location.c_str(), -1, SQLITE_TRANSIENT);
+ sqlite3_bind_text(statement, 6,
+ summary.has_value() ? summary.value().c_str() : nullptr, -1, SQLITE_TRANSIENT);
+ sqlite3_bind_text(statement, 7, desc.c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_int(statement, 8, pkg_compressed);
sqlite3_bind_int(statement, 9, pkg_uncompressed);
sqlite3_bind_text(statement, 10, pkg_tokens[0].c_str(), -1, SQLITE_TRANSIENT);
@@ -286,20 +278,15 @@ public:
sqlite3_reset(statement);
/* Reset for the next package */
- g_free(filename);
- g_free(location);
- g_free(summary);
- filename = location = summary = nullptr;
- g_string_assign(desc, "");
+ summary.reset();
+ filename.reset();
+ location = "";
+ desc = "";
pkg_compressed = pkg_uncompressed = 0;
}
- g_free(line);
}
sqlite3_exec(job_data->db, "END TRANSACTION", nullptr, nullptr, nullptr);
- g_string_free(desc, true);
- g_object_unref(data_in);
-
/* Parse MANIFEST.bz2 */
for (const std::string& current_priority : this->priority)
{
@@ -310,11 +297,6 @@ public:
sqlite3_free(query);
sqlite3_finalize(insert_default_statement);
sqlite3_finalize(insert_statement);
-
- if (fin)
- {
- g_object_unref(fin);
- }
}
private:
@@ -335,13 +317,13 @@ private:
FILE *manifest;
int err, read_len;
unsigned pos;
- char buf[max_buf_size], *pkg_filename, *rest = nullptr, *start;
+ char buf[max_buf_size];
+ std::optional<std::string> rest;
std::filesystem::path path;
- char *full_name = nullptr;
- char **line, **lines;
+ std::vector<std::string> lines;
BZFILE *manifest_bz2;
- GRegex *pkg_expr = nullptr, *file_expr = nullptr;
- GMatchInfo *match_info;
+ std::regex pkg_expr, file_expr;
+ std::smatch match_info;
sqlite3_stmt *statement = nullptr;
path = tmpl / this->name / filename;
@@ -357,21 +339,13 @@ private:
}
/* Prepare regular expressions */
- pkg_expr = g_regex_new("^\\|\\|[[:blank:]]+Package:[[:blank:]]+.+\\/(.+)\\.(t[blxg]z$)?",
- static_cast<GRegexCompileFlags> (G_REGEX_OPTIMIZE | G_REGEX_DUPNAMES),
- static_cast<GRegexMatchFlags> (0),
- nullptr);
- file_expr = g_regex_new("^[-bcdlps][-r][-w][-xsS][-r][-w][-xsS][-r][-w]"
+ pkg_expr = std::regex("^\\|\\|[[:blank:]]+Package:[[:blank:]]+.+\\/(.+)\\.(t[blxg]z$)?",
+ std::regex::optimize);
+ file_expr = std::regex("^[-bcdlps][-r][-w][-xsS][-r][-w][-xsS][-r][-w]"
"[-xtT][[:space:]][^[:space:]]+[[:space:]]+"
"[[:digit:]]+[[:space:]][[:digit:]-]+[[:space:]]"
"[[:digit:]:]+[[:space:]](?!install\\/|\\.)(.*)",
- static_cast<GRegexCompileFlags> (G_REGEX_OPTIMIZE | G_REGEX_DUPNAMES),
- static_cast<GRegexMatchFlags> (0),
- nullptr);
- if (!(file_expr) || !(pkg_expr))
- {
- goto out;
- }
+ std::regex::optimize);
/* Prepare SQL statements */
if (sqlite3_prepare_v2(job_data->db,
@@ -393,66 +367,50 @@ private:
buf[read_len] = '\0';
/* Split the read text into lines */
- lines = g_strsplit(buf, "\n", 0);
- if (rest)
+ boost::split(lines, buf, boost::is_any_of("\n"));
+ if (rest.has_value())
{ /* Add to the first line rest characters from the previous read operation */
- start = lines[0];
- lines[0] = g_strconcat(rest, lines[0], nullptr);
- g_free(start);
- g_free(rest);
+ lines[0] = rest.value() + lines[0];
+ rest.reset();
}
if (err != BZ_STREAM_END) /* The last line can be incomplete */
{
- pos = g_strv_length(lines) - 1;
+ pos = lines.size() - 1;
rest = lines[pos];
- lines[pos] = nullptr;
}
- for (line = lines; *line; line++)
+ for (const auto& line : lines)
{
- if (g_regex_match(pkg_expr, *line, static_cast<GRegexMatchFlags> (0), &match_info))
+ std::optional<std::string> full_name;
+
+ if (std::regex_match(std::cbegin(line), std::cend(line), match_info, pkg_expr))
{
- if (g_match_info_get_match_count(match_info) > 2)
+ if (match_info.size() > 2)
{ /* If the extension matches */
- g_free(full_name);
- full_name = g_match_info_fetch(match_info, 1);
+ full_name = match_info.str(1);
}
else
{
- full_name = nullptr;
+ full_name.reset();
}
}
- g_match_info_free(match_info);
-
- match_info = nullptr;
- if (full_name && g_regex_match(file_expr, *line, static_cast<GRegexMatchFlags> (0), &match_info))
+ if (full_name.has_value()
+ && std::regex_match(std::cbegin(line), std::cend(line), match_info, file_expr))
{
- pkg_filename = g_match_info_fetch(match_info, 1);
- sqlite3_bind_text(statement, 1, full_name, -1, SQLITE_TRANSIENT);
- sqlite3_bind_text(statement, 2, pkg_filename, -1, SQLITE_TRANSIENT);
+ std::string pkg_filename = match_info.str(1);
+ sqlite3_bind_text(statement, 1, full_name.value().c_str(), -1, SQLITE_TRANSIENT);
+ sqlite3_bind_text(statement, 2, pkg_filename.c_str(), -1, SQLITE_TRANSIENT);
sqlite3_step(statement);
sqlite3_clear_bindings(statement);
sqlite3_reset(statement);
- g_free(pkg_filename);
}
- g_match_info_free(match_info);
}
- g_strfreev(lines);
}
sqlite3_exec(job_data->db, "END TRANSACTION", nullptr, nullptr, nullptr);
- g_free(full_name);
BZ2_bzReadClose(&err, manifest_bz2);
out:
sqlite3_finalize(statement);
- if (file_expr)
- {
- g_regex_unref(file_expr);
- }
- if (pkg_expr)
- {
- g_regex_unref(pkg_expr);
- }
fclose(manifest);
}
};