XMLFileOutput.h

Go to the documentation of this file.
00001 /*
00002  *  BEEN: Benchmarking Environment
00003  *  ==============================
00004  *
00005  *  File author: Branislav Repcek
00006  *
00007  *  GNU Lesser General Public License Version 2.1
00008  *  ---------------------------------------------
00009  *  Copyright (C) 2004-2006 Distributed Systems Research Group,
00010  *  Faculty of Mathematics and Physics, Charles University in Prague
00011  *
00012  *  This library is free software; you can redistribute it and/or
00013  *  modify it under the terms of the GNU Lesser General Public
00014  *  License version 2.1, as published by the Free Software Foundation.
00015  *
00016  *  This library is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  *  Lesser General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU Lesser General Public
00022  *  License along with this library; if not, write to the Free Software
00023  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00024  *  MA  02111-1307  USA
00025  */
00026 
00034 #ifndef XML_FILE_OUTPUT_INCLUDED
00035 #define XML_FILE_OUTPUT_INCLUDED
00036 
00037 #include <vector>
00038 #include "UnicodeString.h"
00039 
00040 namespace hwdet
00041 {
00042 
00044 #ifdef UNICODE
00045     const Char DefaultEncoding[] = TXT("UTF-16");
00046 #else
00047 #ifdef _WINDOWS
00048     const Char DefaultEncoding[] = TXT("WINDOWS-1252");
00049 #else
00050     const Char DefaultEncoding[] = TXT("US-ASCII");
00051 #endif
00052 #endif
00053 
00059     template< typename T > String inline ConvertToXMLString(const T &value)
00060     {
00061         StringStream stream;
00062 
00063         stream << value;
00064 
00065         return stream.str();
00066     }
00067 
00073     String inline ConvertToXMLString(const String &value)
00074     {
00075         StringStream stream;
00076 
00077         const String chars = TXT("&\'\"<>");
00078         const String reps[] = {TXT("&amp;"), TXT("&apos;"), TXT("&quot;"), TXT("&lt;"), TXT("&gt;")};
00079 
00080         String::const_iterator end = value.end();
00081 
00082         for (String::const_iterator it = value.begin(); it != end; ++it)
00083         {
00084             size_t index = chars.find(*it);
00085             if (index == chars.npos)
00086             {
00087                 stream << (Char) *it;
00088             }
00089             else
00090             {
00091                 stream << reps[index];
00092             }
00093         }
00094 
00095         return stream.str();
00096     }
00097 
00102     class XMLElement
00103     {
00104     public:
00109         XMLElement(void) :
00110         name(TXT("(undefined)")),
00111         depth(0),
00112         parent(NULL) 
00113         {
00114         }
00115 
00120         XMLElement(const Char *elem_name) :
00121         name(elem_name),
00122         depth(0),
00123         parent(NULL) 
00124         {
00125         }
00126 
00131         XMLElement(const String &elem_name) :
00132         name(elem_name),
00133         depth(0),
00134         parent(NULL) 
00135         {
00136         }
00137 
00142         virtual ~XMLElement(void)
00143         {
00144             std::vector< XMLElement * >::const_iterator end = nodes.end();
00145 
00146             for (std::vector< XMLElement * >::const_iterator it = nodes.begin(); it != end; ++it)
00147             {
00148                 delete *it;
00149             }
00150         }
00151 
00156         virtual String GetNodeName(void) const
00157         {
00158             return name;
00159         }
00160 
00167         void AddSubNode(XMLElement *new_node)
00168         {
00169             if (new_node == NULL)
00170             {
00171                 return;
00172             }
00173 
00174             new_node->SetNodeParent(this);
00175             nodes.push_back(new_node);
00176         }
00177 
00183         XMLElement *GetSubNode(const size_t index) const
00184         {
00185             if (index < nodes.size())
00186             {
00187                 return nodes[index];
00188             }
00189             else
00190             {
00191                 return NULL;
00192             }
00193         }
00194 
00199         size_t GetSubNodeCount(void) const
00200         {
00201             return nodes.size();
00202         }
00203 
00210         virtual String GetNodeValueString(void)
00211         {
00212             StringStream stream;
00213 
00214             std::vector< XMLElement * >::const_iterator end = nodes.end();
00215 
00216             for (std::vector< XMLElement * >::const_iterator it = nodes.begin(); it != end; ++it)
00217             {
00218                 (*it)->AppendToStream(stream);
00219             }
00220 
00221             return stream.str();
00222         }
00223 
00228         virtual void AppendToStream(OStream &stream) const
00229         {
00230             for (size_t i = 0; i < depth; ++i)
00231             {
00232                 stream << TXT("\t");
00233             }
00234 
00235             stream << TXT("<") << GetNodeName() << TXT(">") << std::endl;
00236             
00237             std::vector< XMLElement * >::const_iterator end = nodes.end();
00238             for (std::vector< XMLElement * >::const_iterator it = nodes.begin(); it != end; ++it)
00239             {
00240                 (*it)->AppendToStream(stream);
00241             }
00242             
00243             for (size_t i = 0; i < depth; ++i)
00244             {
00245                 stream << TXT("\t");
00246             }
00247 
00248             stream << TXT("</") << GetNodeName() << TXT(">") << std::endl;
00249         }
00250 
00251     protected:
00252 
00254         String                     name;
00255 
00257         std::vector< XMLElement* > nodes;
00258 
00260         size_t                     depth;
00261 
00263         XMLElement                 *parent;
00264 
00271         void SetNodeDepth(size_t nd)
00272         {
00273             depth = nd;
00274             std::vector< XMLElement * >::iterator end = nodes.end();
00275 
00276             for (std::vector< XMLElement * >::iterator it = nodes.begin(); it != end; ++it)
00277             {
00278                 (*it)->SetNodeDepth(depth + 1);
00279             }
00280         }
00281 
00288         void SetNodeParent(XMLElement *e)
00289         {
00290             parent = e;
00291 
00292             if (e != NULL)
00293             {
00294                 SetNodeDepth(e->depth + 1);
00295             }
00296             else
00297             {
00298                 SetNodeDepth(0);
00299             }
00300         }
00301     };
00302 
00305     template< typename T >
00306     class XMLValueElement : public XMLElement
00307     {
00308     public:
00314         XMLValueElement(const Char *elem_name, const T elem_value) :
00315         XMLElement(elem_name),
00316         value(elem_value) 
00317         {
00318         }
00319 
00325         XMLValueElement(const String &elem_name, const T elem_value) :
00326         XMLElement(elem_name),
00327         value(elem_value) 
00328         {
00329         }
00330 
00333         virtual ~XMLValueElement(void)
00334         {
00335         }
00336 
00341         T GetNodeValue(void) const
00342         {
00343             return value;
00344         }
00345 
00350         void SetNodeValue(T new_value)
00351         {
00352             value = new_value;
00353         }
00354 
00359         String GetNodeValueString(void) const
00360         {
00361             return ConvertToXMLString(value);
00362         }
00363 
00368         virtual void AppendToStream(OStream &stream) const
00369         {
00370             for (size_t i = 0; i < depth; ++i)
00371             {
00372                 stream << TXT("\t");
00373             }
00374 
00375             stream << TXT("<") << GetNodeName() << TXT(">") << GetNodeValueString() << 
00376                       TXT("</") << GetNodeName() << TXT(">") << std::endl;
00377         }
00378 
00379     protected:
00381         T           value;
00382     };
00383 
00386     class XMLOutputFile
00387     {
00388     public:
00395         XMLOutputFile(const Char *enc = NULL) :
00396         root_node(NULL),
00397         encoding(TXT("")) 
00398         {
00399             if (enc != NULL)
00400             {
00401                 encoding = String(enc);
00402             }
00403         }
00404 
00412         XMLOutputFile(XMLElement *root_elem, const Char *enc = DefaultEncoding) :
00413         root_node(root_elem),
00414         encoding(enc)
00415         {
00416         }
00417 
00422         ~XMLOutputFile(void)
00423         {
00424         }
00425 
00431         bool Write(OStream &stream) const
00432         {
00433             if (encoding != String(TXT("")))
00434             {
00435                 stream << TXT("<?xml version=\"1.0\" encoding=\"") << encoding << TXT("\"?>") << std::endl;
00436             }
00437             else
00438             {
00439                 stream << TXT("<?xml version=\"1.0\"?>") << std::endl;
00440             }
00441 
00442             root_node->AppendToStream(stream);
00443 
00444             return true;
00445         }
00446 
00454         bool Write(String file_name) const
00455         {
00456             if (root_node == NULL)
00457             {
00458                 return false;
00459             }
00460 
00461             OFStream file;
00462 
00463 #if defined(_MSC_VER) && (_MSC_VER < 1400) && defined(UNICODE) && defined(_WINDOWS)
00464             // this is provided for older versions of Visual Studio which do not support wide char
00465             // strings as file names
00466             file.open(Win_UnicodeToANSI(file_name).c_str(), std::ios_base::out);
00467 #else
00468             file.open(file_name.c_str(), std::ios_base::out);
00469 #endif
00470 
00471             if (file.is_open())
00472             {
00473                 if (encoding != String(TXT("")))
00474                 {
00475                     file << TXT("<?xml version=\"1.0\" encoding=\"") << encoding << TXT("\"?>") << std::endl;
00476                 }
00477                 else
00478                 {
00479                     file << TXT("<?xml version=\"1.0\"?>") << std::endl;
00480                 }
00481 
00482                 root_node->AppendToStream(file);
00483                 file.close();
00484 
00485                 return true;
00486             }
00487 
00488             return false;
00489         }
00490 
00495         void SetRootNode(XMLElement *elem)
00496         {
00497             root_node = elem;
00498         }
00499 
00502         void ClearRootNode(void)
00503         {
00504             delete root_node;
00505             root_node = NULL;
00506         }
00507         
00512         String GetEncoding(void) const
00513         {
00514             return encoding;
00515         }
00516 
00517     private:
00519         XMLElement  *root_node;
00520 
00522         String      encoding;
00523     };
00524 
00525 } // namespace hwdet
00526 
00527 #endif

Generated on Tue Dec 19 17:43:52 2006 for Detector for Windows by  doxygen 1.4.7