I have a directory with multiple description files and want to store the information in a map to use later to implement a package manager.
Apparently, I read the files correctly, but when I try to filter the information, some things get lost. In most cases, the last line gets cut off, so when the last keyword is %DEPENDS%
and it has only one information, I cannot find that file in my dependencies map.
The description files look like the following:
%FILENAME%
zlib-1:1.2.11-4-x86_64.pkg.tar.xz
%NAME%
zlib
%BASE%
zlib
%VERSION%
1:1.2.11-4
%DESC%
Compression library implementing the deflate compression method found in gzip and PKZIP
%CSIZE%
83444
%ISIZE%
341567
%MD5SUM%
954e931d4bb8a1f1f2847b5fa07bf5da
%SHA256SUM%
43a17987d348e0b395cb6e28d2ece65fb3b5a0fe433714762780d18c0451c149
%PGPSIG%
iQEzBAABCAAdFiEEhs/8qRjPOvRxR1iAUeixSKmZnDQFAl3MRDoACgkQUeixSKmZnDTrWwgAjFovNb203v52oTBXrSxDoWFoCn9uEFfDVpXh/WWAsor5aEtqO8cHqeVUW+ttJdX4Zr0ETz9IVykFCuw5AixE6JSuVm7CIzKdR4JzzIwlU4Es0WDEG8gXAe9i+F8tgLuF92PhiCjxNFmBsdKFS5ISz9wAqdCAUoB+N1yWSeraz7NHkM5urdvnpYVReq9/TOrkjZrJzU45g9y1iuw/ZlpMO53LbsXwuiBE4EufQKEHKF5OgcrSBC4DRUliI9aI65jQ+a0unrxFb+bRjZDOIp1lEBbChQg4BIcE8YtNCIRDb6ztAMfoTOirdbJDbnrAjbIjZcPcvAHoz//vBRkkwCSADA==
%URL%
https://www.zlib.net/
%LICENSE%
custom
%ARCH%
x86_64
%BUILDDATE%
1573667866
%PACKAGER%
Evangelos Foutras <evangelos@foutrelis.com>
%DEPENDS%
glibc
I want to store all that information in a map so i have something like this:
std::map<std::string, std::vector<std::string>> data = {
{"FILENAME", {"zlib-1:1.2.11-4-x86_64.pkg.tar.xz"}},
{"NAME", {"zlib"}},
...,
{"DEPENDS", {"glibc"}}
}
I have a util class that looks more or less like this:
struct util
{
std::string path;
std::map<std::string, std::string> pkg_version;
std::map<std::string, std::vector<std::string>> pkg_dependencies;
std::map<std::string, std::vector<std::string>> pkg_virtual;
std::map<std::string, std::vector<std::string>> pkg_conflicts;
...
}
I have two methods to get all the information.
One to read all files and store the information line by line in a vector and one method to construct a map from the given vector and store the relevant information in pkg_dependencies
. The first one is actually the constructor of my util class.
util::util(std::string path_) :
path(path_)
{
for (const auto& dir_entry : std::filesystem::directory_iterator(path_))
{
std::string dir_path = dir_entry.path().string();
for (const auto& file_entry : std::filesystem::directory_iterator(dir_path))
{
std::string file_path = file_entry.path().string();
std::ifstream desc(file_path);
std::vector<std::string> content;
std::string line;
while (getline(desc, line))
{
if (line.size())
{
content.push_back(line);
}
}
desc.close();
parse_desc(content);
}
}
}
void util::parse_desc(std::vector<std::string> content)
{
std::string marker = "%";
std::map<std::string, std::vector<std::string>> mp;
std::string key;
std::vector<std::string> part_lines;
for (int i = content.size() - 1; i >= 0; --i)
{
bool check_front = content[i].substr(0, 1).compare(marker) == 0;
bool check_back = content[i].substr(content[i].size() - 1, content[i].size()).compare(marker) == 0;
if (check_front && check_back)
{
key = content[i].substr(1, content[i].size() - 2);
mp.insert(std::make_pair(key, part_lines));
part_lines.clear();
}
else
{
part_lines.push_back(content[i]);
}
}
...
if (mp.find("DEPENDS") != mp.end() && !(mp.find("DEPENDS")->second).empty())
{
pkg_dependencies.insert(std::make_pair(name, mp.find("DEPENDS")->second));
}
...
}
Yet in this example with zlib
, it cannot be found in pkg_dependencies
. I noticed that zlib
has only one dependency because it seems to cut off the last line in every file. After all, there are others with more than one dependency and the last one is always missing.
Currently, I start at the back of the vector and push_back the elements into part_lines
until I reach a keyword. Then I insert the keyword with the vector into my map.
I tried iterating over the vector from the beginning. So I find my key first and when I find the next one I first insert my information into the map and then define my new keyword and clear the vector. In case I am at the last element, push_back that element and then insert the information into the map.
Both attempts seem to cut off the last element, so the problem might be somewhere else.
This is the first time asking a question on here, so I do not know if I did a great job at explaining what precisely my problem is, and hope I provided enough information and the relevant code snippets.
Hopefully, someone can help me out.