/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Alignment/Geners/src/BinaryFileArchive.cc
195 строк
7 KB
Cms Build
Clang-Format
08 май 2019, 15:16
08 май 2019, 15:16
7614b05
Код
Авторство
О чём код?
#include <sstream> #include "Alignment/Geners/interface/BinaryFileArchive.hh" #include "Alignment/Geners/interface/ContiguousCatalog.hh" #include "Alignment/Geners/interface/IOException.hh" #include "Alignment/Geners/interface/WriteOnlyCatalog.hh" #include "Alignment/Geners/interface/streamposIO.hh" #include "Alignment/Geners/interface/uriUtils.hh" namespace gs { BinaryFileArchive::BinaryFileArchive(const char *basename, const char *mode, const char *ann, const unsigned dataFileBufferSize, const unsigned catalogFileBufferSize) : BinaryArchiveBase(basename, mode), filebuf_(nullptr), catabuf_(nullptr), annotation_(ann ? std::string(ann) : std::string("")), dataFileName_(AbsArchive::name() + ".0.gsbd"), // binary data catalogFileName_(AbsArchive::name() + ".gsbmf"), // binary metafile dataFileURI_(localFileURI(dataFileName_.c_str())), lastpos_(0), jumppos_(0), catalogMergeLevel_(1), annotationsMerged_(false), streamFlushed_(true) { if (!modeValid()) return; try { // Get a new buffer for the data and open the data stream if (dataFileBufferSize) filebuf_ = new char[dataFileBufferSize]; dataStream_.rdbuf()->pubsetbuf(filebuf_, dataFileBufferSize); openDataFile(dataStream_, dataFileName_.c_str()); dataStream_.seekp(0, std::ios_base::end); // Get a new buffer for the catalog and open the catalog stream. // We may have to rewrite the complete catalog, so remove the flag // std::ios_base::app from the opening mode. if (catalogFileBufferSize) catabuf_ = new char[catalogFileBufferSize]; catStream_.rdbuf()->pubsetbuf(catabuf_, catalogFileBufferSize); catStream_.open(catalogFileName_.c_str(), openmode() & ~std::ios_base::app); if (!catStream_.is_open()) throw IOOpeningFailure("gs::BinaryFileArchive constructor", catalogFileName_); // Can we use a write-only catalog? if (openmode() & std::ios_base::in) { // Reading is allowed. Have to use in-memory catalog. // If the file data already exists, get the catalog in. if (isEmptyFile(catStream_)) setCatalog(new ContiguousCatalog()); else readCatalog<ContiguousCatalog>(); } else { // Yes, we can use a write-only catalog. // Is the catalog file empty? If so, write out // the stuff needed at the beginning of the file. // If not, assume that the necessary stuff is // already there. Note that in this case we will // not be able to add the annotation. if (isEmptyFile(catStream_)) { setCatalog(new WriteOnlyCatalog(catStream_)); writeCatalog(); } else { // Have to read in the catalog contents catStream_.close(); catStream_.clear(); catStream_.open(catalogFileName_.c_str(), openmode() | std::ios_base::in); if (!catStream_.is_open()) throw IOOpeningFailure("gs::BinaryFileArchive constructor", catalogFileName_); readCatalog<WriteOnlyCatalog>(); catStream_.seekp(0, std::ios_base::end); } } } catch (std::exception &e) { setCatalog(nullptr); releaseBuffers(); errorStream() << e.what(); } } void BinaryFileArchive::releaseBuffers() { if (dataStream_.is_open()) dataStream_.close(); if (catStream_.is_open()) catStream_.close(); catStream_.rdbuf()->pubsetbuf(nullptr, 0); dataStream_.rdbuf()->pubsetbuf(nullptr, 0); delete[] catabuf_; catabuf_ = nullptr; delete[] filebuf_; filebuf_ = nullptr; } BinaryFileArchive::~BinaryFileArchive() { flush(); releaseBuffers(); } void BinaryFileArchive::writeCatalog() { if (isOpen()) { if (!annotationsMerged_) { if (!annotation_.empty()) catalogAnnotations_.push_back(annotation_); annotationsMerged_ = true; } const unsigned compress = static_cast<unsigned>(compressionMode()); if (!writeBinaryCatalog(catStream_, compress, catalogMergeLevel_, catalogAnnotations_, *catalog())) { std::ostringstream os; os << "In BinaryFileArchive::writeCatalog: " << "failed to write catalog data to file " << catalogFileName_; throw IOWriteFailure(os.str()); } } } std::istream &BinaryFileArchive::plainInputStream(const unsigned long long id, unsigned *compressionCode, unsigned long long *length) { if (isOpen()) { assert(openmode() & std::ios_base::in); if (!id) throw gs::IOInvalidArgument("In gs::BinaryFileArchive::plainInputStream: invalid item id"); std::streampos pos; if (!catalog()->retrieveStreampos(id, compressionCode, length, &pos)) { std::ostringstream os; os << "In gs::BinaryFileArchive::plainInputStream: " << "failed to locate item with id " << id << "in the catalog stored in file " << catalogFileName_; throw gs::IOInvalidArgument(os.str()); } if (!streamFlushed_) { dataStream_.flush(); streamFlushed_ = true; } dataStream_.seekg(pos); } return dataStream_; } unsigned long long BinaryFileArchive::addToCatalog(const AbsRecord &record, const unsigned compressionCode, const unsigned long long itemLength) { unsigned long long id = 0; if (isOpen()) { id = catalog()->makeEntry(record, compressionCode, itemLength, ItemLocation(lastpos_, dataFileURI_.c_str())); if (id && injectMetadata()) { const CatalogEntry *entry = catalog()->lastEntryMade(); assert(entry); dataStream_.seekp(0, std::ios_base::end); std::streampos now = dataStream_.tellp(); if (entry->write(dataStream_)) { dataStream_.seekp(jumppos_); write_pod(dataStream_, now); dataStream_.seekp(0, std::ios_base::end); } else id = 0; } } return id; } std::ostream &BinaryFileArchive::plainOutputStream() { if (isOpen()) { assert(openmode() & std::ios_base::out); dataStream_.seekp(0, std::ios_base::end); if (injectMetadata()) { jumppos_ = dataStream_.tellp(); std::streampos catpos(0); write_pod(dataStream_, catpos); } lastpos_ = dataStream_.tellp(); streamFlushed_ = false; } return dataStream_; } void BinaryFileArchive::flush() { if (isOpen()) { if (!streamFlushed_) { dataStream_.flush(); streamFlushed_ = true; } if (openmode() & std::ios_base::out) { if (dynamic_cast<WriteOnlyCatalog *>(catalog()) == nullptr) writeCatalog(); catStream_.flush(); } } } } // namespace gs