/////////////////////////////////////////////////////////////////////// // persist.cpp - provides persist interface and a template-based // // ver 2.0 function to read objects from persistent store // // // // Language: Visual C++, ver 6.0, SP 5 // // Platform: Dell Dimension 8100, Win 2000 Pro, SP 2 // // Application: CSE691/791 - SWM&A Demonstration // // Author: Jim Fawcett, CST 2-187, Syracuse Univ // // (315) 443-3948, jfawcett@twcny.rr.com // /////////////////////////////////////////////////////////////////////// #include "persist.h" #include "creatable.h" #include using namespace std; //----< write object to persistant store >--------------------- void persist::write(std::ostream &toStore) const { toStore << classID() << std::endl; do_write(toStore); } //----< read object from persistant store >-------------------- void persist::read(std::istream &fromStore) { if(fromStore.good()) do_read(fromStore); } //----< test stub >-------------------------------------------- #ifdef TEST_PERSIST /////////////////////////////////////////////////////////////// // user class is an abstract base // it provides the protocol show(std::ostream &out) class user : public persist { public: virtual ~user() { } virtual void show(std::ostream &out) = 0; }; // /////////////////////////////////////////////////////////////// // user1 class implements user interface // it stores and displays an int and a double class user1 : public user, public creator { public: user1() { /////////////////////////////////////////////////// // register this object's create() in objFactory objFactory factory; factory.reg(id(),user1::create); } user1(int x, double y) : _x(x), _y(y) { /////////////////////////////////////////////////// // register this object's create() in objFactory objFactory factory; factory.reg(id(),user1::create); } void show(std::ostream &out) { out << "\n " << id(); out << ":: (_x,_y) = (" << _x << ", " << _y << ')'; } int& getInt() { return _x; } double& getDouble() { return _y; } ///////////////////////////////////////////////////////// // these two functions could be used instead of // inheriting from creator // // static user* create() { return new user1(0,0); } // static classID id() { return "user1"; } // protected: virtual void do_write(std::ostream &toStore) const { toStore << id() << std::endl; toStore << _x << std::endl; toStore << _y << std::endl; } virtual void do_read(std::istream &fromStore) { if(fromStore.good()) { fromStore >> _x; fromStore >> _y; } } private: int _x; double _y; }; // /////////////////////////////////////////////////////////////// // class user2 implements the user interface // it stores and displays a string class user2 : public user, public creator { public: user2() { /////////////////////////////////////////////////// // register this object's create() in objFactory objFactory factory; factory.reg(id(),user2::create); } user2(const std::string &str) : _str(str) { /////////////////////////////////////////////////// // register this object's create() in objFactory objFactory factory; factory.reg(id(),user2::create); } void show(std::ostream &out) { out << "\n " << id(); out << "::_str = " << _str; } std::string& getStr() { return _str; } protected: virtual void do_write(std::ostream &toStore) const { toStore << id() << std::endl; toStore << _str << std::endl; } virtual void do_read(std::istream &fromStore) { if(fromStore.good()) { std::getline(fromStore,_str,'\n'); if(_str.size() == 0) std::getline(fromStore,_str,'\n'); } } private: std::string _str; }; // void main() { std::cout << "\n Test persist class, storing into file Objects.db " << "\n ==================================================\n"; /////////////////////////////////////////////////////////// // write several objects into object storage std::cout << "\n create and store several objects from user hierarchy " << "\n ------------------------------------------------------"; std::ofstream toStore; toStore.open("..\\objects.db"); user1 first1(-2,3.5); first1.show(std::cout); toStore << first1; first1.getInt() = 14; first1.getDouble() = 3.1415927; first1.show(std::cout); toStore << first1; user2 second("this is second"); second.show(std::cout); toStore << second; second.getStr() = "another second"; second.show(std::cout); toStore << second; toStore.close(); std::cout << "\n"; // ///////////////////////////////////////////////////////////// // read objects back from object storage std::cout << "\n read objects back polymorphically " << "\n -----------------------------------"; std::ifstream fromStore; fromStore.open("..\\objects.db"); if(!fromStore.good()) { std::cout << "\n --- can't open objects.db ---\n\n"; return; } do { ////////////////////////////////////////////// // polymorphic read user *pUser = readObject(fromStore); if(pUser) { //////////////////////////////////////////// // polymorphic call pUser->show(std::cout); delete pUser; } else break; } while(1); std::cout << "\n\n"; std::cout << "\n here's what is stored in objects.db " << "\n -------------------------------------\n"; /////////////////////////////////////////////////////////// // clear stream, seek back to beginning, and stream to cout fromStore.clear(); fromStore.seekg(0,ios::beg); cout << fromStore.rdbuf() << "\n\n"; } #endif