// StdObjStream_t.cpp #include "StdObjStream.hpp" #include #include #include #include #include #include #include #include #include "ObjTable.hpp" #include "ObjTableTest.hpp" using std::cout; using std::cerr; using std::endl; using std::list; using std::string; using std::istringstream; using std::ostringstream; using std::abs; using std::numeric_limits; // For MSVC++, qualify with typedef instead of bare template. typedef numeric_limits DoubleNumericLimits; // Function is_equal returns true if values are exactly the same // or differ by a very small amount. We set that small amount to // be twice the machine precision. Values differing by one tick // will return true, those differing by three or more will return // false. The behavior for those differing by two depends on the value // and the platform. inline bool is_equal(double x1, double x2) { if ( x1 == 0.0 ) return x2 == 0.0; if ( x2 == 0.0 ) return false; double eps = DoubleNumericLimits::epsilon(); // 1 tick = 0.5, 2tick = 1, ... // Choose an intermediate value double maxdif = 0.7*eps; double num = x1 - x2; double den = x1 + x2; #ifdef NT_MSVCPP double rat = fabs(num/den); #else double rat = abs(num/den); #endif return rat < maxdif; } // Check a double by reading it from an object stream. // If define is true, the first define it. // Return true if it is ok. bool check_double(string name, double value, bool define =false) { string lists = " refs=int( ) lens=double( ) isrefs=bool( ) "; lists += "paras=string( ) figs=*( ) tabs=@( )\n"; string double_base = " number=1 start=false text=\"\" prev=*0 first=@0\n"; #ifdef ObjData_supports_lists double_base += lists; #endif ostringstream ostr; if ( define ) { ostr << name << " = " << value; if ( ostr.str().find(".") == string::npos ) ostr << '.'; ostr << '\n'; assert( ostr.str().find(".") != string::npos ); } ostr << "[ page_" << name << " Page\n" << double_base << " length=$" << name << "\n]"; string strg = ostr.str(); cout << "Checking double " << name << " has value " << value << endl; cout << strg << endl; istringstream istr(strg); StdObjStream objstr(istr); string oname = objstr.read_object(); assert( oname == "page_"+name ); const Page* ppage; ObjTable::get_object(oname,ppage); bool check = is_equal( ppage->length(), value ); return check; } //********************************************************************** int main( ) { string component = "StdObjStream"; string ok_prefix = component + " (I): "; string error_prefix = component + " test (E): "; cout << ok_prefix << "---------- Testing component " + component + ". ----------" << endl; // Make sure assert is enabled. bool assert_flag = false; assert ( ( assert_flag = true, assert_flag ) ); if ( ! assert_flag ) { cerr << "Assert is disabled" << endl; return 1; } //******************************************************************** cout << ok_prefix << "Create input data." << endl; string istrg; istrg += "OBS_GLOBAL_DEBUG=true\n"; istrg += "OBSNAME = input1\n"; istrg += "# Skip this comment.\n"; istrg += "\n"; istrg += "OBSINCLUDE = inp.obs\n"; istrg += "[ figure1 Figure ]\n"; istrg += "\n"; istrg += "OBSDEBUG=false\n"; istrg += "[ table1 Table ]\n"; istrg += "\n"; istrg += "[ page1 Page number = $num length=$length\n"; istrg += " start =true text=\"page one\" \n"; istrg += " prev=*0 first= @0 \n"; #ifdef ObjData_supports_lists istrg += " refs = int( 2 4 ) \n"; istrg += " lens = double( 2.2 4.4 ) \n"; istrg += " isrefs = bool( true ) \n"; istrg += " paras = string( \"Intro\" \"page i\" ) \n"; istrg += " figs = *( 0 ) \n"; istrg += " tabs = @( 0 ) \n"; #endif istrg += "]\n"; istrg += "[ page2 Page number= 2 length = 22.2 start=false"; istrg += " text=\"'two'\" prev=*page1 first = @page1 \n"; #ifdef ObjData_supports_lists istrg += " refs = int( 1 2 3 ) \n"; istrg += " lens = double( 1.1 3.3 ) \n"; istrg += " isrefs = bool( false ) \n"; istrg += " paras = string( \"Contents\" \"page ii\" ) \n"; istrg += " figs = *( figure1 ) \n"; istrg += " tabs = @( table1 ) \n"; #endif istrg += "]\n"; cout << istrg << endl; //******************************************************************** cout << ok_prefix << "Create input stream." << endl; istringstream isstr(istrg); StdObjStream istr(isstr); //******************************************************************** cout << ok_prefix << "Read input stream." << endl; assert( ObjTable::get_object_count() == 0 ); Page::BPtr pb1(0); Page::SPtr ps1(0); { assert( istr.read_object() == "figure1" ); assert( istr.read_object() == "table1" ); assert( istr.read_object() == "page1" ); assert( ObjTable::get_object_count() == 3 ); assert( ObjTable::has_object_name("page1") ); Ptr ppage; ObjTable::get_object("page1", ppage); set refs; refs.insert(2); refs.insert(4); vector lens; lens.push_back(2.2); lens.push_back(4.4); list isrefs; isrefs.push_back(true); vector paras; paras.push_back( "Intro" ); paras.push_back( "page i" ); FigureList figs; figs.insert(0); TableList tabs; tabs.push_back( TablePtr(0) ); Page expect(1,11.1,true,"page one",pb1,ps1 #ifdef ObjData_supports_lists ,refs,lens,isrefs,paras,figs,tabs #endif ); cout << expect << endl; cout << *ppage << endl; assert( *ppage == expect ); ps1 = ppage; pb1 = ps1.pointer(); } Page::BPtr pb2; Page::SPtr ps2; { assert( istr.read_object() == "page2" ); assert( ObjTable::get_object_count() == 4 ); assert( ObjTable::has_object_name("page2") ); Ptr ppage; ObjTable::get_object("page2", ppage); #ifdef ObjData_supports_lists set refs; refs.insert(1); refs.insert(2); refs.insert(3); vector lens; lens.push_back(1.1); lens.push_back(3.3); list isrefs; isrefs.push_back(false); vector paras; paras.push_back("Contents"); paras.push_back("page ii"); FigureList figs; const Figure* pfig; ObjTable::get_object("figure1",pfig); figs.insert(pfig); TableList tabs; TablePtr ptab; ObjTable::get_object("table1",ptab); tabs.push_back(ptab); #endif Page page(2,22.2,false,"'two'",pb1,ps1 #ifdef ObjData_supports_lists ,refs,lens,isrefs,paras,figs,tabs #endif ); cout << *ppage << endl; cout << page << endl; assert( *ppage == page); ps2 = ppage; pb2 = ps2.pointer(); } cout < refs; refs.insert(3); refs.insert(6); refs.insert(9); vector lens; lens.push_back(2.2); lens.push_back(4.4); list isrefs; isrefs.push_back(false); isrefs.push_back(true); vector paras; FigureList figs; TableList tabs; #endif Page page3(3,33,false," three",pb1,ps2 #ifdef ObjData_supports_lists ,refs,lens,isrefs,paras,figs,tabs #endif ); ostr.write_object("Page_3",page3); cout << osstr.str() << endl; //******************************************************************** cout << ok_prefix << "Read back output stream." << endl; istringstream iosstr(osstr.str()); StdObjStream iostr(iosstr); string temp = osstr.str(); cout << temp << endl; { assert( iostr.read_object() == "Page_3" ); assert( ObjTable::get_object_count() == 5 ); assert( ObjTable::has_object_name("Page_3") ); Ptr ppage; ObjTable::get_object("Page_3", ppage); cout << *ppage << endl; assert( *ppage == page3 ); } //******************************************************************** cout << ok_prefix << "Check symbols." << endl; assert( check_double( "PI", acos(-1.0) ) ); assert( check_double( "TWOPI", 2.0*acos(-1.0) ) ); assert( check_double( "PI2", 0.5*acos(-1.0) ) ); assert( check_double( "X", 123.456, true ) ); //******************************************************************** cout << ok_prefix << "------------- All tests passed. -------------" << endl; return 0; //******************************************************************** }