CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/Alignment/Geners/src/AbsArchive.cc

Go to the documentation of this file.
00001 #include <cassert>
00002 #include <sstream>
00003 
00004 #include "Alignment/Geners/interface/AbsArchive.hh"
00005 #include "Alignment/Geners/interface/IOException.hh"
00006 
00007 namespace gs {
00008     AbsArchive::AbsArchive(const char* name)
00009         : name_(name ? name : ""),
00010           lastItemId_(0),
00011           lastItemLength_(0)
00012     {
00013     }
00014 
00015     void AbsArchive::addItemToReference(AbsReference& r,
00016                                         const unsigned long long id) const
00017     {
00018         r.addItemId(id);
00019     }
00020 }
00021 
00022 static std::string local_error_message(gs::AbsArchive& ar,
00023                                        const gs::AbsRecord& record,
00024                                        const char* failedAction)
00025 {
00026     std::ostringstream err;
00027     err << "In operator<<(gs::AbsArchive& ar, const gs::AbsRecord& record): "
00028         << "failed to " << failedAction << " to the archive \""
00029         << ar.name() << "\" for item with type \""
00030         << record.type().name() << "\", name \""
00031         << record.name() << "\", and category \""
00032         << record.category() << '"';
00033     return err.str();
00034 }
00035 
00036 gs::AbsArchive& operator<<(gs::AbsArchive& ar, const gs::AbsRecord& record)
00037 {
00038     // Do not reuse records
00039     if (record.id()) throw gs::IOInvalidArgument(
00040         "In operator<<(gs::AbsArchive& ar, const gs::AbsRecord& record): "
00041         "records can not be reused");
00042 
00043     // Get the relevant streams. Do not change the order
00044     // of the next three lines, some code which does
00045     // not implement compression may actually rely on
00046     // the fact that the "outputStream()" method
00047     // is called before "compressedStream()".
00048     std::ostream& os = ar.outputStream();
00049     std::streampos base = os.tellp();
00050     std::ostream& compressed = ar.compressedStream(os);
00051 
00052     // Write the data
00053     if (!record.writeData(compressed))
00054         throw gs::IOWriteFailure(local_error_message(ar, record, "write data"));
00055 
00056     const unsigned compressCode = ar.flushCompressedRecord(compressed);
00057     if (os.fail())
00058         throw gs::IOWriteFailure(local_error_message(
00059                                      ar, record, "transfer compressed data"));
00060 
00061     // Figure out the record length. Naturally, can't have negative length.
00062     std::streamoff off = os.tellp() - base;
00063     long long delta = off;
00064     assert(delta >= 0LL);
00065 
00066     // Add the record to the catalog
00067     const unsigned long long id = ar.addToCatalog(record, compressCode, delta);
00068     if (id == 0ULL)
00069         throw gs::IOWriteFailure(local_error_message(
00070                                      ar, record, "add catalog entry"));
00071 
00072     // Mark record as written and give feedback about item length
00073     record.itemId_ = id;
00074     record.itemLength_ = delta;
00075 
00076     // Same thing for the archive
00077     ar.lastItemId_ = id;
00078     ar.lastItemLength_ = delta;
00079 
00080     return ar;
00081 }