IOManagerStreamerVersioned.cpp

00001 #include "IOManagerStreamerVersioned.h"
00002 #include "../Streamer.h"
00003 #include "../Serializable.h"
00004 #include <cstdlib>
00005 #include "../SctNames.h"
00006 
00007 using std::string;
00008 
00009 namespace Sct {
00010   namespace Archive {
00011     
00012     IOManagerStreamerVersioned::IOManagerStreamerVersioned() {
00013     }
00014     
00015     IOManagerStreamerVersioned::VersionMap& IOManagerStreamerVersioned::getReadVersionMap(){
00016       static VersionMap read_version_map;
00017       return read_version_map;
00018     }
00019     
00020     void IOManagerStreamerVersioned::writeClassName(OStream& os, const string& classname) const{
00021       setReadMode(false);
00022       //std::cout << "writing classname " << classname << std::endl;
00023       unsigned version = IOManager::getStreamer(classname).getVersion();
00024       string mapname = getMapName(classname, version);
00025       IOManager::writeClassName(os, mapname);
00026     }
00027     
00028     string IOManagerStreamerVersioned::readClassName(IStream& is) const{
00029       setReadMode(true);
00030       string tmp = IOManager::readClassName(is);
00031       //std::cout << tmp << std::endl;
00032       unsigned slash=tmp.rfind("/");
00033       if (slash==string::npos){
00034     throw StreamCorruptedException(string("Not a classname/version pair: `")+tmp+ "'",__FILE__,__LINE__);
00035       }
00036       std::istringstream iss(tmp.substr(slash+1));
00037       unsigned version; 
00038       iss >> version;
00039       string classname = tmp.substr(0,slash);
00040       getReadVersionMap()[classname]=version;
00041       return classname;
00042     }
00043 
00044     void IOManagerStreamerVersioned::readImpl(IStream& in, Streamable& ob, const std::string& className) const{
00045       setReadMode(true);
00046       string readclassname = readClassName(in);
00047       if (readclassname != className){
00048     std::ostringstream oss;
00049     oss << "Expected a " << className << "but got a " << readclassname;
00050     throw StreamCorruptedException(oss.str(), __FILE__, __LINE__);
00051       }
00052       getStreamer(className).read(in, ob, *this);
00053     }
00054     
00055     void IOManagerStreamerVersioned::writeImpl(OStream& out, const Streamable& ob, const std::string& className) const{
00056       setReadMode(false);
00057       writeClassName(out, className);
00058       getStreamer(className).write(out, ob, *this);
00059     }
00060     
00061     void IOManagerStreamerVersioned::readImpl(IStream& in, Streamable& ob, bool bReadClassName) const {
00062       setReadMode(true);
00063       string checkname = readClassName(in);
00064       if (checkname != ob.getClassName()){
00065     std::ostringstream oss;
00066     oss << "Was expecting a `" << ob.getClassName() 
00067         << "' but got a `" << checkname << "'";
00068     throw StreamCorruptedException(oss.str(), __FILE__, __LINE__);
00069       }
00070       Streamer& s = getStreamer(ob.getClassName());
00071       s.read(in, ob, *this);
00072      }
00073     
00074     shared_ptr<Streamable> IOManagerStreamerVersioned::readImpl(IStream& in, const string& className) const {
00075       setReadMode(true);
00076       string checkname = readClassName(in);
00077       if (checkname != className){
00078     std::ostringstream oss;
00079     oss << "Was expecting a `" << className 
00080         << "' but got a `" << checkname << "'";
00081     throw StreamCorruptedException(oss.str(), __FILE__, __LINE__);
00082       }
00083       Streamer& s = getStreamer(className);
00084       return s.read(in, *this);
00085     }
00086     
00087     shared_ptr<Streamable> IOManagerStreamerVersioned::readImpl(IStream& in) const {
00088       setReadMode(true);
00089       string className = readClassName(in);
00090       Streamer& s = getStreamer(className);
00091       return s.read(in, *this);
00092      }
00093 
00094     void IOManagerStreamerVersioned::writeImpl(OStream& out, const Streamable& ob, bool bWriteClassName) const {
00095       setReadMode(false);
00096       Streamer& s = getStreamer(ob.getClassName());
00097       writeClassName(out, ob.getClassName());
00098       s.write(out, ob, *this);
00099     }
00100 
00101     Streamer& IOManagerStreamerVersioned::getStreamer(const string& className) const{
00102       if (readMode()){
00103     // hope we know it already!
00104     VersionMap version_map = getReadVersionMap();
00105     if (version_map.find(className)==version_map.end()){
00106       std::ostringstream oss;
00107       oss << "I know about the following " << version_map.size() << "streamer/version pairs :" << std::endl;
00108       for (VersionMap::const_iterator it=version_map.begin();
00109            it!=version_map.end();
00110            ++it){
00111         oss << (*it).first <<  "/" << (*it).second << std::endl;
00112       }
00113       string diag = oss.str();
00114       SctNames::Mrs() << "SCT_IO" << MRS_TEXT(diag) << MRS_DIAGNOSTIC << ENDM;
00115       throw NoSuchStreamerException(className, "IOManagerStreamerVersioned dosen't know what version to use for Streamer", __FILE__, __LINE__);
00116     } else {
00117       // good- found the read streamer.
00118       return IOManager::getStreamer(className, (*version_map.find(className)).second );
00119     } 
00120       } else {
00121     // in write mode write streamer
00122     return IOManager::getStreamer(className);
00123       }
00124     }
00125 
00126     void IOManagerStreamerVersioned::setReadMode(bool mode) const{
00127       boost::recursive_mutex::scoped_lock lock (getMutex());
00128       m_read_mode=mode;
00129     }
00130     
00131     bool IOManagerStreamerVersioned::readMode() const{
00132       boost::recursive_mutex::scoped_lock lock (getMutex());
00133       return m_read_mode;
00134     }
00135     boost::recursive_mutex& IOManagerStreamerVersioned::getMutex() const{
00136       return m_access;
00137     }
00138 
00139   }
00140 }

Generated on Mon Feb 6 14:01:21 2006 for SCT DAQ/DCS Software - C++ by  doxygen 1.4.6