Archiver
Instead of relying on a huge set of output files, RAMICES III bundles a number of core inputs and outputs into archives. These archives are tarballs, however instead of relying on external system calls, the Archiver module reads and writes files directly into the archive; effectively emulating the tar standard internally.
The Archive class grew out of a code snippet from the tar_to_stream project (provided under an MIT license). Some of this code appears verbatim in Archive::WriteFile, however the OOP approach and the reading functions were written for RAMICESIII.
Details
Basic Usage
//test.cpp
#include "Archive.h"
void ArchiveWriting(std::string archivePath)
{
Archive archive(archivePath,ArchiveMode::Write);
std::string fullFileData = "This is a complete file\nIt is already packaged up\nReady to be written\n";
archive.WriteFile("completeFile.txt",fullFileData);
archive.ActivateStream("streamedFile.txt");
archive << "This data is streamed in\n";
archive << "Bit by bit\n";
archive << "Like an fstream\n";
archive.DeactivateStream();
archive.ActivateStream("numericFile.txt");
for (int i = 0; i < 10; ++i)
{
archive << i << " " << 0.1*i << "\n";
}
} //archive passes out of scope, and closes itself, appending the necessary null-terminations
void ArchiveReading(std::string archivePath)
{
Archive archive; //default initialise
archive.Open(archivePath,ArchiveMode::Read); //delayed initialisation (for demonstration purposes!)
std::vector<std::string> fileList = archive.ListFiles();
// fileList = some permutation of {"completeFile.txt","streamedFile.txt","numericFile.txt"}
//see file list
std::cout << "The files in the archive are:\n";
for (auto file : fileList)
{
std::cout << "\t" << file <<"\n";
}
//basic string capture
std::cout << "\nThe contents of 'streamedFile.txt' are:\n";
//copy the file contents into a raw string stream
std::string contents = archive.GetText("streamedFile.txt");
std::cout << contents << "\n";
//per-file read in -- only output lines which have the letter 'o' in them
std::cout << "The following lines in `completeFile.txt' do not have 'o' in them:\n";
archive.ForLineIn("completeFile.txt",[&](auto line)
{
if (std::find(line.begin(),line.end(),'o') == line.end())
{
std::cout << "\t" <<line << "\n";
}
});
//numerical parsing
double value = 0;
archive.ForTabularLineIn<int,double>("numericFile.txt"," ",[&value](auto lineTuple)
{
int index = std::get<0>(lineTuple);
if (index % 2 == 0)
{
value += std::get<1>(lineTuple);
}
});
std::cout << "\nThe sum of even-indices in numericFile.txt is: " << value << "\n";
}
int main(int argc, char**argv)
{
Settings.Initialise(argc,argv);
ArchiveWriting("test.archive");
ArchiveReading("test.archive");
}
Gives the output:
#terminal output
The files in the archive are:
numericFile.txt
streamedFile.txt
completeFile.txt
The contents of streamedFile.txt are:
This data is streamed in
Bit by bit
Like an fstream
The following lines in completeFile.txt do not have o in them:
It is already packaged up
The sum of even-indices in numericFile.txt is: 2
Note that, as expected, the files in the archive are not in any guaranteed order (FILO order is common, but not mandated)