#include "ATOOLS/Org/My_File.H" #include "ATOOLS/Org/Shell_Tools.H" #include "ATOOLS/Org/Exception.H" #include "ATOOLS/Org/CXXFLAGS_PACKAGES.H" #include "ATOOLS/Org/My_MPI.H" #include "ATOOLS/Org/libzippp.h" #include #include #include #include #include #define PTS long unsigned int using namespace libzippp; namespace ATOOLS { typedef std::pair > ZipArchive_Ref; typedef std::map ZipArchive_Map; typedef std::pair Zip_Entry; typedef std::map ZipEntry_Map; ZipArchive_Map s_ziparchives; ZipEntry_Map s_zipfiles; } using namespace ATOOLS; std::ostream &ATOOLS::operator<<(std::ostream &ostr,const fom::code &code) { switch (code) { case fom::temporary: return ostr<<"temporary"; case fom::permanent: return ostr<<"permanent"; case fom::unknown: return ostr<<"unknown"; } return ostr; } namespace ATOOLS { template <> std::ostream & operator<<(std::ostream &ostr, const My_File &file) { return ostr<<"("<<(&*file)<<") [input] { m_path = "< std::ostream & operator<<(std::ostream &ostr, const My_File &file) { return ostr<<"("<<(&*file)<<") [output] { m_path = "< bool My_File::OpenDB(std::string file) { std::string path(file); #ifdef USING__MPI if (mpi->Rank()) { s_ziparchives[path]=ZipArchive_Ref(NULL,std::vector()); int size; mpi->Bcast(&size,1,MPI_INT); for (int i=0;iBcast(&length,1,MPI_INT); char *message = new char[length+1]; mpi->Bcast(message,length+1,MPI_CHAR); std::string name, content; for (int p=0;p()); int res=zf->open(ZipArchive::WRITE); const std::vector &entries=zf->getEntries(); int size=entries.size(); #ifdef USING__MPI mpi->Bcast(&size,1,MPI_INT); #endif for(std::vector::const_iterator it=entries.begin();it!=entries.end();++it) { std::string name=path+it->getName(); std::string content=it->readAsText(); s_ziparchives[path].second.push_back(name); s_zipfiles[name]=Zip_Entry(content,0); #ifdef USING__MPI int length(name.length()+content.length()+1); content=name+'\n'+content; mpi->Bcast(&length,1,MPI_INT); mpi->Bcast(&content[0],length+1,MPI_CHAR); #endif } return true; } template bool My_File::CloseDB(std::string file,int mode) { #ifdef USING__MPI if (mpi->Rank()) { int success; mpi->Bcast(&success,1,MPI_INT); return success; } #endif std::string path(file); while (file.length() && file.back()=='/') file.pop_back(); file+=".zip"; ZipArchive_Map::iterator ait(s_ziparchives.find(path)); if (ait==s_ziparchives.end()) { int success(false); #ifdef USING__MPI mpi->Bcast(&success,1,MPI_INT); #endif return success; } ZipArchive *zf(ait->second.first); const std::vector &files(ait->second.second); for (size_t i(0);isecond.second<0) zf->deleteEntry(fn); if (zit->second.second>0) { char *tmp = new char[zit->second.first.length()+1]; strcpy(tmp,zit->second.first.c_str()); zf->addData(fn,tmp,strlen(tmp)); } zit->second.second=0; } if (mode) s_zipfiles.erase(zit); } if (mode) s_ziparchives.erase(ait); if (zf) { zf->close(); if (mode) delete zf; else zf->open(ZipArchive::WRITE); } int success(true); #ifdef USING__MPI mpi->Bcast(&success,1,MPI_INT); #endif return success; } template My_File::My_File(const std::string &path, const std::string &file): m_path(path), m_file(file), m_mode(fom::permanent) {} template My_File::~My_File() { Close(); } template FileType *My_File::operator()() const { return p_file.get(); } template FileType *My_File::operator->() const { return p_file.get(); } template FileType &My_File::operator*() const { return *p_file; } template bool My_File::FileInDB(const std::string &name) { return s_zipfiles.find(name)!=s_zipfiles.end(); } template bool My_File::CopyInDB(std::string oldfile, std::string newfile) { if (!FileExists(oldfile)) return false; My_In_File infile(oldfile); if (!infile.Open()) return false; My_Out_File outfile(newfile); if (!outfile.Open()) return false; *outfile< bool My_File::Open() { if (m_path=="" && m_file=="") { p_file = std::make_shared(); return false; } Close(); p_file = std::make_shared(); std::ifstream *is=dynamic_cast(p_file.get()); std::ofstream *os=dynamic_cast(p_file.get()); if (is) { p_stream = std::make_shared(); ZipEntry_Map::const_iterator zit= s_zipfiles.find(m_path+m_file); if (zit!=s_zipfiles.end()) { (*p_stream)<second.first; } else { #ifdef USING__MPI if (mpi->Rank()) { int fsize; mpi->Bcast(&fsize,1,MPI_INT); if (fsize<0) return false; char *content = new char[fsize+1]; mpi->Bcast(content,fsize+1,MPI_CHAR); (*p_stream)<Bcast(&fsize,1,MPI_INT); #endif return false; } msg_IODebugging()<str()); fsize=content.length(); mpi->Bcast(&fsize,1,MPI_INT); mpi->Bcast(&content[0],fsize+1,MPI_CHAR); } #endif } msg_IODebugging()<<"}\n"; p_file->copyfmt(*p_stream); p_file->clear(p_stream->rdstate()); is->std::ios::rdbuf(p_stream->rdbuf()); is->seekg(0); return true; } if (os) { p_stream = std::make_shared(); os->std::ios::rdbuf(p_stream->rdbuf()); os->seekp(0); return true; } return false; } template bool My_File::Close() { if (p_file == nullptr) return false; auto os = dynamic_cast(p_file.get()); if (os) { bool indb(false); for (ZipArchive_Map::iterator zit(s_ziparchives.begin()); zit!=s_ziparchives.end();++zit) if ((m_path+m_file).find(zit->first)==0) { ZipEntry_Map::iterator fit(s_zipfiles.find(m_path+m_file)); if (fit!=s_zipfiles.end()) fit->second=Zip_Entry(p_stream->str(),2); else { s_zipfiles[m_path+m_file]=Zip_Entry(p_stream->str(),2); zit->second.second.push_back(m_path+m_file); } indb=true; break; } #ifdef USING__MPI if (mpi->Rank()==0) #endif if (!indb) { std::ofstream file(m_path+m_file); file<str(); } } p_file->close(); p_stream.reset(); p_file.reset(); return true; } template void My_File::SetPath(const std::string &path) { m_path=path; } template void My_File::SetFile(const std::string &file) { m_file=file; } template void My_File::SetMode(const fom::code &mode) { m_mode=mode; } template const std::string &My_File::Path() const { return m_path; } template const std::string &My_File::File() const { return m_file; } template const fom::code &My_File::Mode() const { return m_mode; } namespace ATOOLS { template class My_In_File; template class My_Out_File; }