XmlWriteContext.hxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef __XMLWRITECONTEXT_HXX__
00023 #define __XMLWRITECONTEXT_HXX__
00024
00025 #include <ostream>
00026 #include <string>
00027 #include "Assert.hxx"
00028
00029 namespace CLAM
00030 {
00043 class XmlWriteContext
00044 {
00045 public:
00046 XmlWriteContext(std::ostream & targetStream) :
00047 mTarget(targetStream)
00048 {
00049 CLAM_ASSERT(!sCurrentContext,
00050 "An XML generation context is already defined");
00051 sCurrentContext = this;
00052 mLastWasAContent=false;
00053 mElementInserted=false;
00054 mTagOpened=false;
00055 mCurrentLevel = 0;
00056 mUseIndentation=false;
00057 }
00058
00059 ~XmlWriteContext()
00060 {
00061 sCurrentContext = 0;
00062 }
00063
00064 static XmlWriteContext & CurrentContext()
00065 {
00066 CLAM_ASSERT(sCurrentContext,"XML generation context not created");
00067 return *sCurrentContext;
00068 }
00069
00070 std::ostream & GetTarget()
00071 {
00072 return mTarget;
00073 }
00074
00075 template <typename T>
00076 void InsertContent(const T & content)
00077 {
00078 if (mTagOpened) EndOpenTag();
00079 if (mElementInserted)
00080 NewIndentedLineIfEnabled();
00081 mTarget << content;
00082 mLastWasAContent = true;
00083 }
00084
00085 void OpenElement(const std::string & name)
00086 {
00087 if (mTagOpened) EndOpenTag();
00088 NewIndentedLineIfEnabled();
00089
00090 mTarget << std::string("<") << name;
00091 mTagOpened = true;
00092 mElementInserted = false;
00093 mLastWasAContent = false;
00094 mCurrentLevel++;
00095 }
00096
00097 void CloseElement(const std::string & name)
00098 {
00099 mCurrentLevel--;
00100 if (mLastWasAContent || mElementInserted)
00101 CloseFullElement(name);
00102 else
00103 CloseEmptyElement();
00104 mElementInserted = true;
00105 mLastWasAContent = false;
00106 }
00107
00108 template <typename T>
00109 void InsertAttribute(const std::string &name, const T & content)
00110 {
00111 CLAM_ASSERT(mTagOpened, "Appending attribute outside a tag");
00112 mTarget << std::string(" ") << name << std::string("='")
00113 << content << std::string("'");
00114 }
00115
00120 bool LastWasAContent()
00121 {
00122 return mLastWasAContent;
00123 }
00124
00128 bool ElementInserted()
00129 {
00130 return mElementInserted;
00131 }
00132
00133 unsigned int CurrentLevel()
00134 {
00135 return mCurrentLevel;
00136 }
00137
00138 void UseIndentation(bool useIt)
00139 {
00140 mUseIndentation = useIt;
00141 }
00142
00143 private:
00144
00145 void CloseFullElement(const std::string & name)
00146 {
00147 if (mElementInserted)
00148 NewIndentedLineIfEnabled();
00149
00150 mTarget << std::string("</") << name << std::string(">");
00151 }
00152
00153 void CloseEmptyElement()
00154 {
00155 CLAM_ASSERT(mTagOpened,"No open tag to close");
00156
00157 mTarget << std::string(" />");
00158 mTagOpened = false;
00159 }
00160
00161 void EndOpenTag()
00162 {
00163 CLAM_ASSERT(mTagOpened,"No open tag to close");
00164
00165 mTarget << std::string(">");
00166 mTagOpened = false;
00167 }
00168
00169 void NewIndentedLineIfEnabled()
00170 {
00171 if (!mUseIndentation) return;
00172
00173 if (mCurrentLevel!=0 || mLastWasAContent || mElementInserted)
00174 mTarget << std::string("\n");
00175 mTarget << std::string(mCurrentLevel,'\t');
00176 }
00177
00178 private:
00179
00180 std::ostream & mTarget;
00181 bool mLastWasAContent;
00182 bool mElementInserted;
00183 bool mTagOpened;
00184 bool mUseIndentation;
00185 unsigned int mCurrentLevel;
00186
00187 static XmlWriteContext * sCurrentContext;
00188
00189 };
00190
00191 }
00192
00193 #endif//__XMLWRITECONTEXT_HXX__
00194