Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 10:39:05

0001 //=========================================================================
0002 // CatalogIO.hh
0003 //
0004 // The following functions provide an operational definition of
0005 // the "standard" binary catalog file format
0006 //
0007 // I. Volobouev
0008 // November 2010
0009 //=========================================================================
0010 
0011 #ifndef GENERS_CATALOGIO_HH_
0012 #define GENERS_CATALOGIO_HH_
0013 
0014 #include <iostream>
0015 
0016 #include "Alignment/Geners/interface/AbsCatalog.hh"
0017 
0018 namespace gs {
0019   struct CatalogFormat1 {
0020     enum { ID = 713265489 };
0021   };
0022 
0023   // In the following, it is assumed that the catalog is stored
0024   // in memory and that it has a stream dedicated to it. The
0025   // function returns "true" on success.
0026   //
0027   // Programs which make new catalogs should set "mergeLevel" to 1.
0028   // Programs which combine existing catalogs should add up the
0029   // merge levels of those catalogs to come up with the "mergeLevel".
0030   //
0031   // "annotations" are arbitrary strings (which should be just combined
0032   // when catalogs are merged).
0033   bool writeBinaryCatalog(std::ostream &os,
0034                           unsigned compressionCode,
0035                           unsigned mergeLevel,
0036                           const std::vector<std::string> &annotations,
0037                           const AbsCatalog &catalog,
0038                           unsigned formatId = CatalogFormat1::ID);
0039 
0040   // In the following, it is assumed that the Catalog class
0041   // has a "read" function which builds the catalog on the heap.
0042   // The "allowReadingByDifferentClass" parameter specifies
0043   // whether the catalog class is allowed to read something
0044   // written by another catalog class. This function returns NULL
0045   // pointer on failure. Note that the user must call "delete"
0046   // on the returned pointer at some point in the future.
0047   template <class Catalog>
0048   Catalog *readBinaryCatalog(std::istream &is,
0049                              unsigned *compressionCode,
0050                              unsigned *mergeLevel,
0051                              std::vector<std::string> *annotations,
0052                              bool allowReadingByDifferentClass,
0053                              unsigned formatId = CatalogFormat1::ID);
0054 }  // namespace gs
0055 
0056 #include <cassert>
0057 #include <sstream>
0058 
0059 #include "Alignment/Geners/interface/IOException.hh"
0060 #include "Alignment/Geners/interface/binaryIO.hh"
0061 
0062 namespace gs {
0063   template <class Catalog>
0064   Catalog *readBinaryCatalog(std::istream &is,
0065                              unsigned *compressionCode,
0066                              unsigned *mergeLevel,
0067                              std::vector<std::string> *annotations,
0068                              const bool allowReadingByDifferentClass,
0069                              const unsigned expectedformatId) {
0070     assert(compressionCode);
0071     assert(mergeLevel);
0072     assert(annotations);
0073 
0074     is.seekg(0, std::ios_base::beg);
0075 
0076     unsigned formatId = 0, endianness = 0;
0077     unsigned char sizelong = 0;
0078     read_pod(is, &formatId);
0079     read_pod(is, &endianness);
0080     read_pod(is, &sizelong);
0081 
0082     if (is.fail())
0083       throw IOReadFailure("In gs::readBinaryCatalog: input stream failure");
0084 
0085     if (endianness != 0x01020304 || formatId != expectedformatId || sizelong != sizeof(long))
0086       throw IOInvalidData(
0087           "In gs::readBinaryCatalog: not \"geners\" "
0088           "binary metafile or incompatible system "
0089           "architecture");
0090 
0091     read_pod(is, compressionCode);
0092     read_pod(is, mergeLevel);
0093     read_pod_vector(is, annotations);
0094     ClassId id(is, 1);
0095     Catalog *readback = nullptr;
0096 
0097     ClassId catId(ClassId::makeId<Catalog>());
0098     if (id.name() == catId.name())
0099       // The reading is done by the same class as the writing.
0100       // Make sure the "read" function gets the correct class version.
0101       readback = Catalog::read(id, is);
0102     else {
0103       if (!allowReadingByDifferentClass) {
0104         std::ostringstream os;
0105         os << "In gs::readBinarCatalog: incompatible "
0106            << "catalog class: written by \"" << id.name() << "\", but reading is attempted by \"" << catId.name()
0107            << '"';
0108         throw IOInvalidData(os.str());
0109       }
0110 
0111       // The reading is not done by the same class as the writing.
0112       // All bets are off, and it is up to the user to decide whether
0113       // this makes sense. However, to maintain compatibility with
0114       // version 1 archives, we need to pass this version to the
0115       // catalog read function.
0116       if (id.version() == 1)
0117         catId.setVersion(1);
0118 
0119       readback = Catalog::read(catId, is);
0120     }
0121 
0122     // Catalogs do not necessarily know their size in advance,
0123     // so that they might read until the end of file is encountered.
0124     // However, the eof flag on the stream can result in various
0125     // problems later (for example, in writing to the stream).
0126     // Remove this flag.
0127     if (is.eof() && !is.fail() && !is.bad()) {
0128       is.clear();
0129       is.seekg(0, std::ios_base::end);
0130     }
0131 
0132     return readback;
0133   }
0134 }  // namespace gs
0135 
0136 #endif  // GENERS_CATALOGIO_HH_