00001
00005 #include <assert.h>
00006 #include <map>
00007 #include <sstream>
00008 #include "object.h"
00009
00010 const Object::id_t Object::NIL_ID;
00011
00012 typedef std::map<Object::id_t, _creator_t> _creator_map_t;
00013
00019 static _creator_map_t& _creator_map () {
00020 static _creator_map_t cmap;
00021 return cmap;
00022 }
00023
00025 inline static bool _creator_registered (const Object::id_t& id) {
00026 return _creator_map().find(id) != _creator_map().end();
00027 }
00028
00033 _register_creator::_register_creator (const Object::id_t& id, _creator_t cf) {
00034 assert(!_creator_registered(id));
00035 _creator_map()[id] = cf;
00036 }
00037
00061 bool Object::serialize (std::ostream& os, ver_list& vl) const {
00062 assert(vl.size() > 0);
00063 ver_list::const_iterator p = vl.begin();
00064 os << "# " << id() << " v" << *p;
00065 for (++p; p != vl.end(); ++p)
00066 os << '.' << *p;
00067 os << '\n';
00068 return true;
00069 }
00070
00071 static bool _get_id_ver (std::istream& is, Object::id_t& id,
00072 std::vector<UINT>& vl) {
00073 assert(vl.empty());
00074 const UINT ignore_size = 512;
00075
00076
00077 char c;
00078 if (!(is >> c)) return false;
00079 if (c != '#') {
00080 std::cerr << "_get_id_ver: Warning: # expected\n";
00081 is.ignore(ignore_size, '#');
00082 }
00083
00084
00085 char line[ignore_size];
00086 is.getline(line, ignore_size);
00087 std::istringstream iss(line);
00088
00089
00090 if (!(iss >> id)) {
00091 std::cerr << "_get_id_ver: Error: no class id?\n";
00092 return false;
00093 }
00094
00095
00096 vl.push_back(0);
00097 iss.ignore(ignore_size, 'v');
00098 UINT v;
00099 while (iss >> v) {
00100 assert(v > 0);
00101 vl.push_back(v);
00102 iss.ignore(1);
00103 }
00104 if (vl.size() == 1) {
00105 std::cerr << "_get_id_ver: Warning: pre-0.1 file format\n";
00106 if (id == "AdaBoost.M1") id = "AdaBoost";
00107 if (id.substr(0, 7) != "lemga::") id.insert(0, "lemga::");
00108 }
00109
00110 return true;
00111 }
00112
00117 Object* Object::create (std::istream& is) {
00118 id_t _id;
00119 ver_list vl;
00120 if (!_get_id_ver(is, _id, vl)) return 0;
00121 assert(vl[0] == 0);
00122
00123 if (_creator_registered(_id)) {
00124 Object* p = _creator_map()[_id]();
00125 bool loaded = p->unserialize(is, vl, _id);
00126 if (loaded && vl.size() == 1)
00127 return p;
00128 else if (loaded)
00129 std::cerr << _id << "::create: newer format encountered\n";
00130 delete p;
00131 } else
00132 std::cerr << "Class (" << _id << ") not regiestered\n";
00133
00134 return 0;
00135 }
00136
00137 std::istream& operator>> (std::istream& is, Object& obj) {
00138 Object::id_t id;
00139 Object::ver_list vl;
00140
00141
00142 if (!_get_id_ver(is, id, vl) || !obj.unserialize(is, vl, id)) {
00143 std::cerr << "operator>>: something wrong...\n";
00144 is.setstate(std::ios::badbit);
00145 } else if (vl.size() > 1) {
00146 std::cerr << "operator>>: newer format encountered\n";
00147 is.setstate(std::ios::badbit);
00148 }
00149 assert(vl[0] == 0);
00150
00151 return is;
00152 }