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
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
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
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
00118 return IOManager::getStreamer(className, (*version_map.find(className)).second );
00119 }
00120 } else {
00121
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 }