C++ Library to handle BagIt structures. BagIt is a standard format to create transfer packages for digital preservation purposes. See https://en.wikipedia.org/wiki/BagIt for details http://andreas-romeyke.de
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
3.8 KiB

#include "manifest.hpp"
#include <iostream>
#include <fstream>
#include <sstream>
#include <boost/filesystem.hpp>
//#include <filesystem> // c++17
//namespace fs = std::filesystem;
namespace fs = boost::filesystem;
using namespace std;
multimap<checksum_string_t,filename_t> Manifest::get_checksum_file_pairs(checksum_algorithms alg) {
string filename = this->manifest_algorithm_files[ alg ];
multimap<checksum_string_t,filename_t> checksum_file_pairs;
// cout << "using file " << filename << endl;
ifstream file;
file.open( filename );
if (file.is_open()) {
string line;
while (getline(file, line)) {
stringstream line_ss ( line );
string checksum;
string subfile;
line_ss >> checksum;
line_ss >> subfile;
checksum_file_pairs.insert( pair<checksum_string_t, filename_t>(checksum,subfile) );
// cout << "checksum="<<checksum<<" file="<<subfile<<endl;
}
file.close();
}
return checksum_file_pairs;
}
bool Manifest::validate( list<string> & log ) {
Checksum checksum;
bool is_valid = true;
for (map<checksum_algorithms,string>::iterator it=this->manifest_algorithm_files.begin(); it!=this->manifest_algorithm_files.end(); ++it) {
//cout << "validate using file '"<< (it->second) << "' (" << (it->first) << ")" <<endl;
multimap<checksum_string_t,filename_t>checksum_file_pairs = this->get_checksum_file_pairs( it->first );
for (multimap<checksum_string_t,filename_t>::iterator ch=checksum_file_pairs.begin(); ch!=checksum_file_pairs.end(); ++ch) {
string expected_checksum = ch->first;
string file = this->basedir + ch->second;
string calc_checksum = checksum.checksum_of_file( file, it->first );
//cout << "\t" << "file="<<file <<" expected:"<<expected_checksum << " found: " << calc_checksum << endl;
if (calc_checksum.empty()) {
log.push_back( "Bagit file '" + file + "', checksum '" + expected_checksum + "' is expected by file '" + it->second +"', but file was not found");
is_valid = false;
}
else if (0 != expected_checksum.compare( calc_checksum)) {
// cout << ( "Bagit file '" + file + "', checksum '" + expected_checksum + "' is expected, but found: '" + calc_checksum + "'") << endl;
log.push_back( "Bagit file '" + file + "', checksum '" + expected_checksum + "' is expected by file '" + it->second +"', but found: '" + calc_checksum + "'");
is_valid = false;
}
fs::path p{ file };
fs::file_status s = fs::status( p );
if (! fs::is_regular_file( p )) {
log.push_back("Bagit file '" + file + "' does not exists in '" + this->basedir + "'");
}
}
}
//cout << "MANIFEST validate, calling debug()" << endl;
//this->debug();
//cout << "MANIFEST validate, finished" << endl;
return is_valid;
}
void Manifest::debug() {
//cout << "DEBUG: basedir='"<<this->basedir<<"'"<<endl;
//cout << "DEBUG: list of manifest files:"<<endl;
for (map<checksum_algorithms,string>::iterator it=this->manifest_algorithm_files.begin(); it!=this->manifest_algorithm_files.end(); ++it) {
// cout << "DEBUG:\tvalidate using file '"<< (it->second) << "' (" << (it->first) << ")" <<endl;
}
//cout << "DEBUG" << endl;
}
list<string> Manifest::get_checksummed_files() {
list<string> files;
for (map<checksum_algorithms,string>::iterator it=this->manifest_algorithm_files.begin(); it!=this->manifest_algorithm_files.end(); ++it) {
multimap<checksum_string_t,filename_t>checksum_file_pairs = this->get_checksum_file_pairs( it->first );
for (multimap<checksum_string_t,filename_t>::iterator ch=checksum_file_pairs.begin(); ch!=checksum_file_pairs.end(); ++ch) {
string file = this->basedir + ch->second;
// cout << "MF: '" << file << "'" << endl;
files.push_back( file );
}
}
return files;
}
// vim: set tabstop=4 softtabstop=0 expandtab shiftwidth=4 smarttab