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

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

AltStyle によって変換されたページ (->オリジナル) /