#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct File;
struct Archive {
virtual std::vector<File*> fileList() = 0;
};
struct File {
File(std::string name_) : name(name_) {}
virtual void extract() = 0;
std::string name;
};
// ---- zip ----
struct ZipFile;
struct ZipArchive: public Archive {
void extractFile(ZipFile& file);
virtual std::vector<File*> fileList();
};
struct ZipFile: public File {
ZipArchive* archive;
virtual void extract() { archive->extractFile(*this); }
ZipFile(std::string name_, ZipArchive* archive_) : File(name_), archive(archive_) {}
};
// had to postpone it to have ZipFile defined
void ZipArchive::extractFile(ZipFile& file) {
cout << "Extracting file " << file.name << " from zip archive " << endl;
}
std::vector<File*> ZipArchive::fileList() {
// memory leak here for simplicity
return std::vector<File*>(1, new ZipFile("test", this));
}
// ---- tar ----
struct TarFile;
struct TarArchive: public Archive {
void extractFile(TarFile& file);
virtual std::vector<File*> fileList();
};
struct TarFile: public File {
TarArchive* archive;
virtual void extract() { archive->extractFile(*this); }
TarFile(std::string name_, TarArchive* archive_) : File(name_), archive(archive_) {}
};
// had to postpone it to have ZipFile defined
void TarArchive::extractFile(TarFile& file) {
cout << "Extracting file " << file.name << " from tar archive " << endl;
}
std::vector<File*> TarArchive::fileList() {
// memory leak here for simplicity
return std::vector<File*>(1, new TarFile("test-tar", this));
}
int main() {
ZipArchive archive;
archive.fileList()[0]->extract();
TarArchive archive2;
archive2.fileList()[0]->extract();
return 0;
}