home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Multimedia / k3d-setup-0.7.11.0.exe / include / k3d / k3dsdk / xml.h < prev   
C/C++ Source or Header  |  2008-01-23  |  13KB  |  240 lines

  1. #ifndef K3DSDK_XML_H
  2. #define K3DSDK_XML_H
  3.  
  4. // K-3D
  5. // Copyright (c) 1995-2004, Timothy M. Shead
  6. //
  7. // Contact: tshead@k-3d.com
  8. //
  9. // This program is free software; you can redistribute it and/or
  10. // modify it under the terms of the GNU General Public
  11. // License as published by the Free Software Foundation; either
  12. // version 2 of the License, or (at your option) any later version.
  13. //
  14. // This program is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17. // General Public License for more details.
  18. //
  19. // You should have received a copy of the GNU General Public
  20. // License along with this program; if not, write to the Free Software
  21. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  22.  
  23. /** \file
  24.         \brief Declares the public API of k3dxml, an XML API designed to fit-in well with the Standard C++ Library
  25.         \author Tim Shead (tshead@k-3d.com)
  26. */
  27.  
  28. #include "string_cast.h"
  29.  
  30. #include <iosfwd>
  31. #include <sstream>
  32. #include <vector>
  33.  
  34. namespace k3d
  35. {
  36.  
  37. namespace xml
  38. {
  39.  
  40. /// Encapsulates an XML attribute with name and value
  41. class attribute
  42. {
  43. public:
  44.     attribute() {}
  45.     attribute(const std::string& Name, const std::string& Value) : name(Name), value(Value) {}
  46.     attribute(const std::string& Name, const char* Value) : name(Name), value(Value) {}
  47.  
  48.     template<typename T>
  49.     attribute(const std::string& Name, const T& Value) : name(Name), value(string_cast(Value)) {}
  50.  
  51.     /// Stores the attribute name
  52.     std::string name;
  53.     /// Stores the attribute value
  54.     std::string value;
  55. };
  56.  
  57. /// Encapsulates an XML element with name, text, child attributes, and child elements
  58. class element
  59. {
  60. public:
  61.     element(){}
  62.  
  63.     element(const std::string& Name) : name(Name) {}
  64.     
  65.     template<typename T1>    
  66.     element(const std::string& Name, const T1& A1) : name(Name) { push_back(A1); }
  67.  
  68.     template<typename T1, typename T2>
  69.     element(const std::string& Name, const T1& A1, const T2& A2) : name(Name) { push_back(A1); push_back(A2); }
  70.  
  71.     template<typename T1, typename T2, typename T3>
  72.     element(const std::string& Name, const T1& A1, const T2& A2, const T3& A3) : name(Name) { push_back(A1); push_back(A2); push_back(A3); }
  73.     
  74.     template<typename T1, typename T2, typename T3, typename T4>
  75.     element(const std::string& Name, const T1& A1, const T2& A2, const T3& A3, const T4& A4) : name(Name) { push_back(A1); push_back(A2); push_back(A3); push_back(A4); }
  76.  
  77.     template<typename T1, typename T2, typename T3, typename T4, typename T5>
  78.     element(const std::string& Name, const T1& A1, const T2& A2, const T3& A3, const T4& A4, const T5& A5) : name(Name) { push_back(A1); push_back(A2); push_back(A3); push_back(A4); push_back(A5); }
  79.  
  80.     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
  81.     element(const std::string& Name, const T1& A1, const T2& A2, const T3& A3, const T4& A4, const T5& A5, const T6& A6) : name(Name) { push_back(A1); push_back(A2); push_back(A3); push_back(A4); push_back(A5); push_back(A6); }
  82.  
  83.     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
  84.     element(const std::string& Name, const T1& A1, const T2& A2, const T3& A3, const T4& A4, const T5& A5, const T6& A6, const T7& A7) : name(Name) { push_back(A1); push_back(A2); push_back(A3); push_back(A4); push_back(A5); push_back(A6); push_back(A7); }
  85.  
  86.     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
  87.     element(const std::string& Name, const T1& A1, const T2& A2, const T3& A3, const T4& A4, const T5& A5, const T6& A6, const T7& A7, const T8& A8) : name(Name) { push_back(A1); push_back(A2); push_back(A3); push_back(A4); push_back(A5); push_back(A6); push_back(A7); push_back(A8); }
  88.     
  89.     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
  90.     element(const std::string& Name, const T1& A1, const T2& A2, const T3& A3, const T4& A4, const T5& A5, const T6& A6, const T7& A7, const T8& A8, const T9& A9) : name(Name) { push_back(A1); push_back(A2); push_back(A3); push_back(A4); push_back(A5); push_back(A6); push_back(A7); push_back(A8); push_back(A9);}
  91.  
  92.     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
  93.     element(const std::string& Name, const T1& A1, const T2& A2, const T3& A3, const T4& A4, const T5& A5, const T6& A6, const T7& A7, const T8& A8, const T9& A9, const T10& A10) : name(Name) { push_back(A1); push_back(A2); push_back(A3); push_back(A4); push_back(A5); push_back(A6); push_back(A7); push_back(A8); push_back(A9); push_back(A10);}
  94.  
  95.     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11>
  96.     element(const std::string& Name, const T1& A1, const T2& A2, const T3& A3, const T4& A4, const T5& A5, const T6& A6, const T7& A7, const T8& A8, const T9& A9, const T10& A10, const T11& A11) : name(Name) { push_back(A1); push_back(A2); push_back(A3); push_back(A4); push_back(A5); push_back(A6); push_back(A7); push_back(A8); push_back(A9); push_back(A10); push_back(A11); }
  97.  
  98.     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12>
  99.     element(const std::string& Name, const T1& A1, const T2& A2, const T3& A3, const T4& A4, const T5& A5, const T6& A6, const T7& A7, const T8& A8, const T9& A9, const T10& A10, const T11& A11, const T12& A12) : name(Name) { push_back(A1); push_back(A2); push_back(A3); push_back(A4); push_back(A5); push_back(A6); push_back(A7); push_back(A8); push_back(A9); push_back(A10); push_back(A11); push_back(A12); }
  100.  
  101.     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13>
  102.     element(const std::string& Name, const T1& A1, const T2& A2, const T3& A3, const T4& A4, const T5& A5, const T6& A6, const T7& A7, const T8& A8, const T9& A9, const T10& A10, const T11& A11, const T12& A12, const T13& A13) : name(Name) { push_back(A1); push_back(A2); push_back(A3); push_back(A4); push_back(A5); push_back(A6); push_back(A7); push_back(A8); push_back(A9); push_back(A10); push_back(A11); push_back(A12); push_back(A13); }
  103.  
  104.     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13, typename T14>
  105.     element(const std::string& Name, const T1& A1, const T2& A2, const T3& A3, const T4& A4, const T5& A5, const T6& A6, const T7& A7, const T8& A8, const T9& A9, const T10& A10, const T11& A11, const T12& A12, const T13& A13, const T14& A14) : name(Name) { push_back(A1); push_back(A2); push_back(A3); push_back(A4); push_back(A5); push_back(A6); push_back(A7); push_back(A8); push_back(A9); push_back(A10); push_back(A11); push_back(A12); push_back(A13); push_back(A14); }
  106.  
  107.     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13, typename T14, typename T15>
  108.     element(const std::string& Name, const T1& A1, const T2& A2, const T3& A3, const T4& A4, const T5& A5, const T6& A6, const T7& A7, const T8& A8, const T9& A9, const T10& A10, const T11& A11, const T12& A12, const T13& A13, const T14& A14, const T15& A15) : name(Name) { push_back(A1); push_back(A2); push_back(A3); push_back(A4); push_back(A5); push_back(A6); push_back(A7); push_back(A8); push_back(A9); push_back(A10); push_back(A11); push_back(A12); push_back(A13); push_back(A14); push_back(A15); }
  109.  
  110.     void push_back(const std::string& Value) { text += Value; }
  111.     void push_back(const attribute& Value) { attributes.push_back(Value); }
  112.     void push_back(const element& Value) { children.push_back(Value); }
  113.     
  114.     /// Searches for a child element by name, creating it if it isn't found
  115.     element& safe_element(const std::string& Name);
  116.     /// Searches for a child element, creating it from the match if it isn't found
  117.     element& safe_element(const element& Match);
  118.     /// Searches for a child element, creating it from the prototype if it isn't found
  119.     element& safe_element(const element& Match, const element& Prototype);
  120.  
  121.     /// Appends a child attribute, returning a reference to the new child for convenience
  122.     attribute& append(const attribute& Child);
  123.     /// Appends a child element, returning a reference to the new child for convenience
  124.     element& append(const element& Child);
  125.  
  126.     /// Stores the element name
  127.     std::string name;
  128.     /// Stores element text
  129.     std::string text;
  130.  
  131.     /// Defines a collection of attributes
  132.     typedef std::vector<attribute> attributes_t;
  133.     /// Stores child attributes
  134.     attributes_t attributes;
  135.     /// Defines a collection of child elements
  136.     typedef std::vector<element> elements_t;
  137.     /// Stores child elements
  138.     elements_t children;
  139. };
  140.  
  141. class same_name
  142. {
  143. public:
  144.     same_name(const std::string& Name) : name(name) {}
  145.  
  146.     template<typename T>
  147.     bool operator()(const T& Val) { return Val.name == name; }
  148.  
  149. private:
  150.     const std::string name;
  151. };
  152.  
  153. /// Sets an attribute on a child element, overwriting any existing attribute value
  154. attribute& set_attribute(element& Element, const attribute& Child);
  155. /*
  156. /// Appends a child attribute to an element, returning a reference to the new child for convenience
  157. attribute& append(element& Element, const attribute& Child);
  158. /// Appends a child element to an element, returning a reference to the new child for convenience
  159. element& append(element& Element, const element& Child);
  160. */
  161.  
  162. /// Searches for a child attribute by name, returning the child if found, else NULL
  163. const attribute* find_attribute(const element& Element, const std::string& AttributeName);
  164. /// Searches for a child attribute by name, returning the child if found, else NULL
  165. attribute* find_attribute(element& Element, const std::string& AttributeName);
  166. /// Searches for a child element by name, returning the child if found, else NULL
  167. const element* find_element(const element& Element, const std::string& ElementName);
  168. /// Searches for a child element by name, returning the child if found, else NULL
  169. element* find_element(element& Element, const std::string& ElementName);
  170. /// Searches for a child element by name, returning the child if found, else NULL
  171. element* find_element(element& Element, const std::string& ElementName);
  172.  
  173. /// Returns the text value of an attribute as a string by name, or a default value if the attribute can't be found
  174. const std::string attribute_text(const element& Element, const std::string& AttributeName, const std::string& DefaultValue = std::string());
  175. /// Returns the text value of an attribute, converted to a specific type, or a default value if the attribute can't be found
  176. template<typename T>
  177. const T attribute_value(const element& Element, const std::string& AttributeName, const T& DefaultValue)
  178. {
  179.     const attribute* const a = find_attribute(Element, AttributeName);
  180.     if(a)
  181.         return k3d::from_string<T>(a->value, DefaultValue);
  182.     
  183.     return DefaultValue;
  184. }
  185.  
  186. /// Returns the text value of a child element as a string by name, or a default value if the child element can't be found
  187. const std::string element_text(const element& Element, const std::string& ElementName, const std::string& DefaultValue = std::string());
  188.  
  189. /// iostream-compatible manipulator that controls whether subsequent XML will be serialized with-or-without line breaks
  190. struct single_line
  191. {
  192.     single_line(bool Enable = true);
  193.     bool enable;
  194. };
  195. std::ostream& operator<<(std::ostream& Stream, const single_line& RHS);
  196.  
  197. /// Inserts an XML declaration <?xml version="1.0" ?> into a stream
  198. struct declaration
  199. {
  200. };
  201. std::ostream& operator<<(std::ostream& Stream, const declaration& RHS);
  202.  
  203. /// Serializes an XML attribute to a stream
  204. std::ostream& operator<<(std::ostream& Stream, const attribute& RHS);
  205. /// Serializes an XML document to a stream
  206. std::ostream& operator<<(std::ostream& Stream, const element& RHS);
  207. /// Extracts an XML document from a stream
  208. std::istream& operator>>(std::istream& Stream, element& RHS);
  209.  
  210. /// Abstract interface used to provide feedback during long parsing operations
  211. class progress
  212. {
  213. public:
  214.     virtual void show_activity() = 0;
  215.  
  216. protected:
  217.     progress() {}
  218.     progress(const progress&) {}
  219.     progress& operator=(const progress&) { return *this; }
  220.     virtual ~progress() {}
  221. };
  222.  
  223. /// Convenience implementation of the progress interface for use when feedback is not required (Null Object Pattern)
  224. class hide_progress :
  225.     public progress
  226. {
  227. public:
  228.     void show_activity() {}
  229. };
  230.  
  231. /// Parses an XML document from a stream
  232. void parse(element& Root, std::istream& InputStream, const std::string& StreamName, progress& Progress);
  233.  
  234. } // namespace xml
  235.  
  236. } // namespace k3d
  237.  
  238. #endif // !K3DSDK_XML_H
  239.  
  240.