XmlWriteContext.hxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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                         // TODO: Change the temporary to normal insertion with the upgrade to 0.5.2
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                         // TODO: Change the temporary to normal insertion with the upgrade to 0.5.2
00150                         mTarget << std::string("</") << name << std::string(">");
00151                 }
00152 
00153                 void CloseEmptyElement()
00154                 {
00155                         CLAM_ASSERT(mTagOpened,"No open tag to close");
00156                         // TODO: Change the temporary to normal insertion with the upgrade to 0.5.2
00157                         mTarget << std::string(" />");
00158                         mTagOpened = false;
00159                 }
00160 
00161                 void EndOpenTag()
00162                 {
00163                         CLAM_ASSERT(mTagOpened,"No open tag to close");
00164                         // TODO: Change the temporary to normal insertion with the upgrade to 0.5.2
00165                         mTarget << std::string(">");
00166                         mTagOpened = false;
00167                 }
00168 
00169                 void NewIndentedLineIfEnabled()
00170                 {
00171                         if (!mUseIndentation) return;
00172                         // TODO: Change the temporary to normal insertion with the upgrade to 0.5.2
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 } // ns CLAM
00192 
00193 #endif//__XMLWRITECONTEXT_HXX__
00194 
Generated by  doxygen 1.6.3