00001 #include "IOManager.h"
00002 #include "Streamer.h"
00003 #include "Streamable.h"
00004 #include "Serializable.h"
00005 #include "IStream.h"
00006 #include "OStream.h"
00007 #include "SctNames.h"
00008 #include "LogicErrors.h"
00009 #include <sstream>
00010
00011 using namespace std;
00012
00013 namespace Sct {
00014
00015 typedef map<string, shared_ptr<Streamer> > StreamerMap;
00016
00017 bool IOManager::addToMap(const string& className, std::auto_ptr<Streamer> auto_s) throw() {
00018 shared_ptr<Streamer> s (auto_s);
00019 const unsigned version=s->getVersion();
00020 string mapName = getMapName(className, version);
00021
00022 StreamerMap& default_map = getMap();
00023 StreamerMap& full_map = getFullVersionMap();
00024
00025 if (full_map.find(mapName) != full_map.end()){
00026 string message = "IoManager:: WARNING duplicate entry for streamer/version = ";
00027 message += mapName;
00028 Sct::LogicError e(message, __FILE__, __LINE__);
00029 e.sendToMrs();
00030 ostringstream oss;
00031 oss << "Known streamers:" << endl;
00032 for (StreamerMap::const_iterator it=full_map.begin();
00033 it!=full_map.end();
00034 ++it){
00035 oss << (*it).first << endl;
00036 }
00037 string diag = oss.str();
00038 SctNames::Mrs() << "SCT_IO" << MRS_TEXT(diag) << MRS_DIAGNOSTIC << ENDM;
00039 return false;
00040 } else {
00041 full_map[mapName]=s;
00042
00043
00044 StreamerMap::iterator previous = default_map.find(className);
00045 if (previous==default_map.end() || (*previous).second->getVersion() < version){
00046
00047 default_map[className]=s;
00048 }
00049
00050 }
00051 return true;
00052 }
00053
00054
00055 StreamerMap& IOManager::getFullVersionMap() throw(){
00056 static StreamerMap full_map;
00057 return full_map;
00058 }
00059
00060 StreamerMap& IOManager::getMap() throw() {
00061 static StreamerMap default_map;
00062 return default_map;
00063 }
00064
00065 Streamer& IOManager::getStreamer(const string& className) const {
00066 const StreamerMap& default_map = getMap();
00067 if (default_map.find(className) == default_map.end()) {
00068 ostringstream oss;
00069 oss << "Known streamers:" << endl;
00070 for (StreamerMap::const_iterator it=default_map.begin();
00071 it!=default_map.end();
00072 ++it){
00073 oss << (*it).first << endl;
00074 }
00075 string diag = oss.str();
00076 SctNames::Mrs() << "SCT_IO" << MRS_TEXT(diag) << MRS_DIAGNOSTIC << ENDM;
00077 throw NoSuchStreamerException(className, "IOManager can't find a Streamer", __FILE__, __LINE__);
00078 }
00079 return *(*default_map.find(className)).second;
00080 }
00081
00082 Streamer& IOManager::getStreamer(const string& className, const unsigned version) const {
00083 const StreamerMap& full_map = getFullVersionMap();
00084 std::string mapName = getMapName(className, version);
00085
00086 StreamerMap::const_iterator it = full_map.find(mapName);
00087 if (it==full_map.end()){
00088 ostringstream oss;
00089 oss << "Known streamer/versions:" << endl;
00090 for (StreamerMap::const_iterator it=full_map.begin();
00091 it!=full_map.end();
00092 ++it){
00093 oss << (*it).first << endl;
00094 }
00095 string diag = oss.str();
00096
00097 SctNames::Mrs() << "SCT_IO" << MRS_TEXT(diag) << MRS_DIAGNOSTIC << ENDM;
00098 throw NoSuchStreamerException(className,string("IOManager can'f find a Streamer")+mapName, __FILE__, __LINE__);
00099 } else {
00100 return *(*it).second;
00101 }
00102 }
00103
00104
00105 std::string IOManager::getMapName(const std::string& classname, const unsigned version) throw() {
00106 ostringstream oss;
00107 oss << classname << "/" << version;
00108 return oss.str();
00109 }
00110
00111 void IOManager::writeImpl(OStream& out, const Streamable& ob, bool bWriteClassName) const {
00112 Streamer& s = getStreamer(ob.getClassName());
00113 if (bWriteClassName) writeClassName(out, ob.getClassName());
00114 s.write(out, ob, *this);
00115 }
00116
00117 void IOManager::writeImpl(OStream& out, const Streamable& ob, const char* className) const {
00118 writeImpl(out, ob, string(className) );
00119 }
00120
00121 void IOManager::writeImpl(OStream& out, const Streamable& ob, const string& className) const {
00122 Streamer& s = getStreamer(className);
00123 s.write(out, ob, *this);
00124 }
00125
00126 shared_ptr<Streamable> IOManager::readImpl(IStream& in) const {
00127 string className = readClassName(in);
00128 Streamer& s = getStreamer(className);
00129 return s.read(in, *this);
00130 }
00131
00132 void IOManager::readImpl(IStream& in, Streamable& ob, const string& className) const{
00133 Streamer& s = getStreamer(className);
00134 s.read(in, ob, *this);
00135 }
00136
00137 shared_ptr<Streamable> IOManager::readImpl(IStream& in, const string& className) const {
00138 Streamer& s = getStreamer(className);
00139 return s.read(in, *this);
00140 }
00141
00142 void IOManager::readImpl(IStream& in, Streamable& ob, const char* className) const{
00143 readImpl(in, ob, string(className));
00144 }
00145
00146 shared_ptr<Streamable> IOManager::readImpl(IStream& in, const char* className) const {
00147 return readImpl(in, string(className));
00148 }
00149
00150
00151 void IOManager::readImpl(IStream& in, Streamable& ob, bool bReadClassName) const {
00152 if (bReadClassName) {
00153 string className = readClassName(in);
00154 if (className != ob.getClassName()) {
00155 string str = "Can't read: ";
00156 str += ob.getClassName();
00157 str += " from stream because stream contains a: ";
00158 str += className;
00159 throw StreamCorruptedException(str, __FILE__, __LINE__);
00160 }
00161 }
00162 Streamer& s = getStreamer(ob.getClassName());
00163 s.read(in, ob, *this);
00164 }
00165
00166 void IOManager::writeClassName(OStream& out, const string& className) const {
00167 out << "SctClassName:" + className;
00168 }
00169
00170 string IOManager::readClassName(IStream& in) const {
00171 string className = "";
00172 in >> className;
00173 if (className.find("SctClassName:") == 0) {
00174 return className.substr(13);
00175 }
00176 throw StreamCorruptedException("Read string but it wasn't a className. Got: `" + className + "'", __FILE__, __LINE__);
00177 }
00178
00179
00180
00181 }