Main Page | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Namespace Members | Data Fields | Globals

writeobj.cpp

Go to the documentation of this file.
00001 // See ../../license.txt for license information.
00002 //
00003 // writeobj.cpp
00004 //
00005 // NOTES
00006 //              A concrete subclass of object_writer which dumps an object.
00007 //
00008 //      We write the objects like this:
00009 //
00010 /*
00011         object ::=  
00012                 object-start
00013                         sub-object-list
00014                 object-end
00015                 
00016         object-start ::=
00017                 "<" TAGNAME ["(" attr-list ")"] ">"
00018 
00019         object-end ::=
00020                 "</" TAGNAME ">"
00021 
00022         sub-object-list ::=
00023                 (data-object | object)*
00024 
00025         data-object ::=
00026                 "<" TAGNAME ">" data "</" TAGNAME ">"
00027                  
00028         attr-list ::= 
00029                 [attr-pair ([", " attr-pair])*]
00030                                 
00031         attr-pair ::=
00032                 name "=" value
00033 */
00034 // 21-Jul-2003  phamilton  Created
00035 //
00036 
00037 #define PERSIST_IN_LIBRARY_SOURCE
00038 #include "writeobj.hpp"
00039 
00040 using namespace ph::persist::xml;
00041 
00042 bool writeobj::start(const std::string &tagname)
00043 /*
00044         The input to start and end is "TAGNAME". The state table for the
00045         tree must start from TAGNAME and work out.
00046 */
00047 {
00048         // write out the XML declaration at the top.
00049         if (_start)
00050         {
00051                 *_stream << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" << std::endl << std::endl;
00052                 _start = false;
00053         }
00054         
00055         // Close off the previous tag (if there is one).
00056         if (!_tagname.empty())
00057         {
00058                 if (_data.empty())
00059                 {
00060                         //      object ::=  
00061                         //              object-start
00062                         //                      ...
00063                         object_start();
00064                         _tabs++;
00065                 }
00066                 else
00067                         data_object();
00068         }
00069         
00070         // and get started for the next tag.
00071         _attrs.clear();
00072         _tagname = tagname;
00073         _data = "";
00074         
00075         return true;
00076 }
00077 
00078 bool writeobj::end(const std::string &tagname)
00079 {
00080         // close off the current tag (if there is one).
00081         if (_tagname.empty())
00082         {
00083                 /*
00084                         object ::=  
00085                                         ...
00086                                 object-end
00087                 */
00088                 // there was no accumulated tagname, just unnest,
00089                 _tabs--;
00090                 object_end(tagname);
00091         }
00092         else
00093         {
00094                 if (_data.empty())
00095                 {
00096                         /*
00097                                 object ::=  
00098                                         object-start
00099                                                 ...
00100                                         object-end
00101                         */
00102                         // the last tag had no data, so the last one was an object.
00103                         object_start();
00104                         object_end(tagname);
00105                 }
00106                 else
00107                         data_object();
00108         }
00109                 
00110         _attrs.clear();
00111         _tagname = "";
00112         _data = "";
00113         
00114         return true;
00115 }
00116 
00117 bool writeobj::attr(const std::string &name, const std::string &value)
00118 {
00119         if (_tagname.empty())
00120         {
00121                 *_console << "bad state detected in attr(). _tagname should not be empty." << std::endl;
00122                 return false;
00123         }
00124         if (!_data.empty())
00125         {
00126                 *_console << "bad state detected in attr(). _data should be empty." << std::endl;
00127                 return false;
00128         }
00129         // and save this attribute.
00130         _attrs[name] = value;
00131         return true;
00132 }
00133 
00134 bool writeobj::data(const std::string &d)
00135 {
00136         if (!_data.empty())
00137         {
00138                 *_console << "bad state detected in data(). _data should be empty." << std::endl;
00139                 return false;
00140         }
00141         // and save this data.
00142         _data = d;
00143         return true;
00144 }
00145 
00146 void writeobj::object_start()
00147 /*
00148         object-start ::=
00149                 "<" TAGNAME ["(" attr-list ")"] ">"
00150 
00151         attr-list ::= 
00152                 [attr-pair ([", " attr-pair])*]
00153                                 
00154         attr-pair ::=
00155                 name "=" "\"" value "\""
00156 */
00157 {
00158         if (_tagname.empty())
00159         {
00160                 *_console << "bad state detected in object_decl(). _tagname should not be empty." << std::endl;
00161                 return;
00162         }
00163         tabs();
00164         *_stream << "<" << _tagname;
00165         if (!_attrs.empty())
00166         {
00167                 *_stream << " ";
00168                 // how about a std::for_each for this guy. What would be the best way?
00169                 for (std::map<std::string, std::string>::iterator i=_attrs.begin(); i != _attrs.end(); i++)
00170                 {
00171                         if (i != _attrs.begin())
00172                                 *_stream << ", ";
00173                         *_stream << i->first << "=\"" << i->second << "\"";
00174                 }
00175         }
00176         *_stream << ">";
00177         cr();
00178 }
00179 
00180 void writeobj::object_end(const std::string &tagname)
00181 /*
00182         object-end ::=
00183                 "</" TAGNAME ">"
00184 */
00185 {
00186         tabs();
00187         *_stream << "</" << tagname << ">";
00188         cr();
00189 }
00190 
00191 void writeobj::data_object()
00192 /*
00193         data-object ::=
00194                 "<" TAGNAME ">" data "</" TAGNAME ">"
00195 */
00196 {
00197         tabs(); *_stream << "<" << _tagname << ">" << _data << "</" << _tagname << ">"; cr();
00198 }
00199 
00200 void writeobj::tabs()
00201 {
00202         for (int i=0; i<_tabs; i++)
00203                 *_stream << "  ";
00204 }
00205 
00206 void writeobj::cr()
00207 {
00208         *_stream << std::endl;
00209 }
00210 

Generated on Wed Apr 5 22:03:27 2006 for cppxmlobj by  doxygen 1.4.3