// ObjStreamTest.hpp // Concrete implementation of ObjStream to test that abstract base. #include "ObjStream.hpp" #include "ObjException.hpp" #include "ObjData.hpp" #include "ObjTable.hpp" string header = "Begin"; string trailer = "End"; class TestStream : public ObjStream { public: // Constructor from an istream TestStream(istream& strm) : ObjStream(strm) { string tmp; in_stream() >> tmp; if ( tmp != header ) throw ObjReadError(); if ( in_state() != 0 ) throw ObjReadError(); } // Constructor from an ostream TestStream(ostream& strm) : ObjStream(strm) { out_stream() << header << std::endl; } // Destructor. ~TestStream() { if ( out_enabled() ) out_stream() << std::endl << trailer; if ( in_enabled() ) { string tmp; in_stream() >> tmp; if ( tmp != trailer ) throw ObjReadError(); } } // Read an object. string read_data() { if ( ! in_enabled() ) throw ObjReadError(); // Read the object type. string otype; in_stream() >> otype; ObjData data(otype); // Read the object name. string oname; string brace; in_stream() >> oname >> brace; assert( brace == "{" ); assert( ! ObjTable::has_object_name(oname) ); if ( ObjTable::has_object_name(oname) ) throw ObjReadError(); // Read the attributes. while ( true ) { // type string type; in_stream() >> type; if ( type == "}" ) break; // name string aname; string eq; in_stream() >> aname >> eq; assert( eq == "=" ); // value if ( type == "int" ) { int i; in_stream() >> i; data.add_int(aname,i); #ifdef ObjData_supports_lists } else if ( type == "int_list" ) { int i; ObjData::IntList vals; char ch = ' '; in_stream().get(ch); while ( ch != '\n' ) { if ( ch == ' ' ) break; in_stream() >> i; vals.push_back(i); in_stream().get(ch); } data.add_int_list(aname,vals); #endif } else if ( type == "double" ) { double d; in_stream() >> d; data.add_double(aname,d); #ifdef ObjData_supports_lists } else if ( type == "double_list" ) { double val; ObjData::DoubleList vals; char ch = ' '; in_stream().get(ch); while ( ch != '\n' ) { if ( ch == ' ' ) break; in_stream() >> val; vals.push_back(val); in_stream().get(ch); } data.add_double_list(aname,vals); #endif } else if ( type == "bool" ) { bool b; in_stream() >> b; data.add_bool(aname,b); #ifdef ObjData_supports_lists } else if ( type == "bool_list" ) { bool val; ObjData::BoolList vals; char ch = ' '; in_stream().get(ch); while ( ch != '\n' ) { if ( ch == ' ' ) break; in_stream() >> val; vals.push_back(val); in_stream().get(ch); } data.add_bool_list(aname,vals); #endif } else if ( type == "string" ) { char quote = '"'; char c; // Find opening quote. in_stream() >> c; assert( c == quote ); string s; in_stream().get(c); while ( c != quote ) { s += c; in_stream().get(c); } data.add_string(aname,s); #ifdef ObjData_supports_lists } else if ( type == "string_list" ) { char quote = '"'; string val; ObjData::StringList vals; char ch = ' '; in_stream().get(ch); while ( ch != '\n' ) { if ( ch == ' ' ) break; char c; in_stream() >> c; assert( c == quote ); string s; in_stream().get(c); while ( c != quote ) { s += c; in_stream().get(c); } vals.push_back(s); in_stream().get(ch); } data.add_string_list(aname,vals); #endif } else if ( type == "bare_pointer" ) { string oname; in_stream() >> oname; ObjData::BarePtr pobj = 0; if ( oname != "0" ) { assert( ObjTable::has_object_name(oname) ); if ( ! ObjTable::has_object_name(oname) ) throw ObjReadError(); ObjTable::get_object(oname, pobj); } data.add_bare_pointer(aname, pobj); #ifdef ObjData_supports_lists } else if ( type == "bare_ptr_list" ) { ObjData::BarePtr val; ObjData::BarePtrList vals; char ch = ' '; in_stream().get(ch); while ( ch != '\n' ) { if ( ch == ' ' ) break; string oname; in_stream() >> oname; assert( ObjTable::has_object_name(oname) ); if ( ! ObjTable::has_object_name(oname) ) throw ObjReadError(); ObjTable::get_object(oname, val); vals.push_back(val); in_stream().get(ch); } data.add_bare_ptr_list(aname,vals); #endif } else if ( type == "share_pointer" ) { string oname; in_stream() >> oname; ObjData::SharePtr pobj; if ( oname != "0" ) { assert( ObjTable::has_object_name(oname) ); if ( ! ObjTable::has_object_name(oname) ) throw ObjReadError(); ObjTable::get_object(oname, pobj); } data.add_share_pointer(aname, pobj); #ifdef ObjData_supports_lists } else if ( type == "share_ptr_list" ) { ObjData::SharePtr val; ObjData::SharePtrList vals; char ch = ' '; in_stream().get(ch); while ( ch != '\n' ) { if ( ch == ' ' ) break; string oname; in_stream() >> oname; assert( ObjTable::has_object_name(oname) ); if ( ! ObjTable::has_object_name(oname) ) throw ObjReadError(); ObjTable::get_object(oname, val); vals.push_back(val); in_stream().get(ch); } data.add_share_ptr_list(aname,vals); #endif } else { assert( false ); } } // Create the object. int count = ObjTable::get_object_count(); ObjTable::new_object(oname,data); assert( ObjTable::get_object_count() == ++count ); assert( ObjTable::has_object_name(oname) ); return oname; } // Write an object. void write_data(string name, const ObjData& data) { if ( ! out_enabled() ) throw ObjWriteError(); out_stream() << std::endl << data.get_object_type() << " " << name << " {" << std::endl; const ObjData::NameList& names = data.get_names(); for ( ObjData::NameList::const_iterator iname=names.begin(); iname!=names.end(); ++iname ) { string aname = *iname; out_stream() << " "; // Write type. switch ( data.get_type(aname) ) { case ObjData::INT: out_stream() << "int"; break; case ObjData::DOUBLE: out_stream() << "double"; break; case ObjData::BOOL: out_stream() << "bool"; break; case ObjData::STRING: out_stream() << "string"; break; case ObjData::BARE_PTR: out_stream() << "bare_pointer"; break; case ObjData::SHARE_PTR: out_stream() << "share_pointer"; break; #ifdef ObjData_supports_lists case ObjData::INT_LIST: out_stream() << "int_list"; break; case ObjData::DOUBLE_LIST: out_stream() << "double_list"; break; case ObjData::BOOL_LIST: out_stream() << "bool_list"; break; case ObjData::STRING_LIST: out_stream() << "string_list"; break; case ObjData::BARE_PTR_LIST: out_stream() << "bare_ptr_list"; break; case ObjData::SHARE_PTR_LIST: out_stream() << "share_ptr_list"; break; #endif default: assert(false); } // Write name. out_stream() << " " << aname << " = "; // Write value. switch ( data.get_type(aname) ) { case ObjData::INT: out_stream() << data.get_int(aname); break; #ifdef ObjData_supports_lists case ObjData::INT_LIST: { ObjData::IntList vals; for ( ObjData::IntList::const_iterator ival=vals.begin(); ival!=vals.end(); ++ival ) { out_stream() << *ival << ' '; } } break; #endif case ObjData::DOUBLE: out_stream() << data.get_double(aname); break; #ifdef ObjData_supports_lists case ObjData::DOUBLE_LIST: { ObjData::DoubleList vals; for ( ObjData::DoubleList::const_iterator ival=vals.begin(); ival!=vals.end(); ++ival ) { out_stream() << *ival << ' '; } } break; #endif case ObjData::BOOL: out_stream() << data.get_bool(aname); break; #ifdef ObjData_supports_lists case ObjData::BOOL_LIST: { ObjData::BoolList vals; for ( ObjData::BoolList::const_iterator ival=vals.begin(); ival!=vals.end(); ++ival ) { out_stream() << *ival << ' '; } } break; #endif case ObjData::BARE_PTR: { const ObjType* pobj = data.get_bare_pointer(aname); if ( pobj == 0 ) out_stream() << '0'; else out_stream() << ObjTable::get_object_name(pobj); } break; #ifdef ObjData_supports_lists case ObjData::BARE_PTR_LIST: { ObjData::BarePtrList vals; for ( ObjData::BarePtrList::const_iterator ival=vals.begin(); ival!=vals.end(); ++ival ) { { const ObjType* pobj = *ival; if ( pobj == 0 ) out_stream() << '0'; else out_stream() << ObjTable::get_object_name(pobj); } out_stream() << ' '; } } break; #endif case ObjData::SHARE_PTR: { const ObjType* pobj = data.get_share_pointer(aname).pointer(); if ( pobj == 0 ) out_stream() << '0'; else out_stream() << ObjTable::get_object_name(pobj); } break; #ifdef ObjData_supports_lists case ObjData::SHARE_PTR_LIST: { ObjData::SharePtrList vals; for ( ObjData::SharePtrList::const_iterator ival=vals.begin(); ival!=vals.end(); ++ival ) { { const ObjType* pobj = ival->pointer(); if ( pobj == 0 ) out_stream() << '0'; else out_stream() << ObjTable::get_object_name(pobj); } out_stream() << ' '; } } break; #endif case ObjData::STRING: out_stream() << '"'<< data.get_string(aname) << '"'; break; #ifdef ObjData_supports_lists case ObjData::STRING_LIST: { ObjData::StringList vals; for ( ObjData::StringList::const_iterator ival=vals.begin(); ival!=vals.end(); ++ival ) { out_stream() << '"' << *ival << '\" '; } } break; #endif default: assert(false); } out_stream() << std::endl; } out_stream() << "}" << std::endl; } };