object.cpp

Go to the documentation of this file.
00001 
00005 #include <assert.h>
00006 #include <map>
00007 #include <sstream>
00008 #include "object.h"
00009 
00010 const Object::id_t Object::empty_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     // get the comment char #
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     // get the rest of the line
00085     char line[ignore_size];
00086     is.getline(line, ignore_size);
00087     std::istringstream iss(line);
00088 
00089     // get the identity (class name)
00090     if (!(iss >> id)) {
00091         std::cerr << "_get_id_ver: Error: no class id?\n";
00092         return false;
00093     }
00094 
00095     // get the version
00096     iss.ignore(ignore_size, 'v');
00097     UINT v;
00098     while (iss >> v) {
00099         assert(v > 0);
00100         vl.push_back(v);
00101         iss.ignore(1);
00102     }
00103     if (vl.empty()) {
00104         std::cerr << "_get_id_ver: Warning: pre-0.1 file format\n";
00105         if (id == "AdaBoost.M1") id = "AdaBoost";
00106         if (id.substr(0, 7) != "lemga::") id.insert(0, "lemga::");
00107         vl.push_back(0);
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 
00122     if (_creator_registered(_id)) {
00123         Object* p = _creator_map()[_id]();
00124         p->unserialize(is, vl, _id);
00125         return p;
00126     }
00127 
00128     std::cerr << "Class (" << _id << ") not regiestered\n";
00129     return 0;
00130 }
00131 
00132 std::istream& operator>> (std::istream& is, Object& obj) {
00133     Object::id_t id;
00134     Object::ver_list vl;
00135 
00136     // unserialize() judges whether id and obj are compatible
00137     if (!_get_id_ver(is, id, vl) || !obj.unserialize(is, vl, id)) {
00138         std::cerr << "operator>>: something wrong...\n";
00139         is.setstate(std::ios::badbit);
00140     }
00141     assert(vl.empty() || vl[0] == 0);
00142 
00143     return is;
00144 }

Generated on Mon Jan 9 23:43:24 2006 for LEMGA by  doxygen 1.4.6