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
Wrap
C/C++ Source or Header
|
2008-01-23
|
13KB
|
240 lines
#ifndef K3DSDK_XML_H
#define K3DSDK_XML_H
// K-3D
// Copyright (c) 1995-2004, Timothy M. Shead
//
// Contact: tshead@k-3d.com
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
/** \file
\brief Declares the public API of k3dxml, an XML API designed to fit-in well with the Standard C++ Library
\author Tim Shead (tshead@k-3d.com)
*/
#include "string_cast.h"
#include <iosfwd>
#include <sstream>
#include <vector>
namespace k3d
{
namespace xml
{
/// Encapsulates an XML attribute with name and value
class attribute
{
public:
attribute() {}
attribute(const std::string& Name, const std::string& Value) : name(Name), value(Value) {}
attribute(const std::string& Name, const char* Value) : name(Name), value(Value) {}
template<typename T>
attribute(const std::string& Name, const T& Value) : name(Name), value(string_cast(Value)) {}
/// Stores the attribute name
std::string name;
/// Stores the attribute value
std::string value;
};
/// Encapsulates an XML element with name, text, child attributes, and child elements
class element
{
public:
element(){}
element(const std::string& Name) : name(Name) {}
template<typename T1>
element(const std::string& Name, const T1& A1) : name(Name) { push_back(A1); }
template<typename T1, typename T2>
element(const std::string& Name, const T1& A1, const T2& A2) : name(Name) { push_back(A1); push_back(A2); }
template<typename T1, typename T2, typename T3>
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); }
template<typename T1, typename T2, typename T3, typename T4>
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); }
template<typename T1, typename T2, typename T3, typename T4, typename T5>
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); }
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
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); }
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
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); }
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
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); }
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
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);}
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
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);}
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11>
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); }
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>
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); }
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>
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); }
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>
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); }
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>
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); }
void push_back(const std::string& Value) { text += Value; }
void push_back(const attribute& Value) { attributes.push_back(Value); }
void push_back(const element& Value) { children.push_back(Value); }
/// Searches for a child element by name, creating it if it isn't found
element& safe_element(const std::string& Name);
/// Searches for a child element, creating it from the match if it isn't found
element& safe_element(const element& Match);
/// Searches for a child element, creating it from the prototype if it isn't found
element& safe_element(const element& Match, const element& Prototype);
/// Appends a child attribute, returning a reference to the new child for convenience
attribute& append(const attribute& Child);
/// Appends a child element, returning a reference to the new child for convenience
element& append(const element& Child);
/// Stores the element name
std::string name;
/// Stores element text
std::string text;
/// Defines a collection of attributes
typedef std::vector<attribute> attributes_t;
/// Stores child attributes
attributes_t attributes;
/// Defines a collection of child elements
typedef std::vector<element> elements_t;
/// Stores child elements
elements_t children;
};
class same_name
{
public:
same_name(const std::string& Name) : name(name) {}
template<typename T>
bool operator()(const T& Val) { return Val.name == name; }
private:
const std::string name;
};
/// Sets an attribute on a child element, overwriting any existing attribute value
attribute& set_attribute(element& Element, const attribute& Child);
/*
/// Appends a child attribute to an element, returning a reference to the new child for convenience
attribute& append(element& Element, const attribute& Child);
/// Appends a child element to an element, returning a reference to the new child for convenience
element& append(element& Element, const element& Child);
*/
/// Searches for a child attribute by name, returning the child if found, else NULL
const attribute* find_attribute(const element& Element, const std::string& AttributeName);
/// Searches for a child attribute by name, returning the child if found, else NULL
attribute* find_attribute(element& Element, const std::string& AttributeName);
/// Searches for a child element by name, returning the child if found, else NULL
const element* find_element(const element& Element, const std::string& ElementName);
/// Searches for a child element by name, returning the child if found, else NULL
element* find_element(element& Element, const std::string& ElementName);
/// Searches for a child element by name, returning the child if found, else NULL
element* find_element(element& Element, const std::string& ElementName);
/// Returns the text value of an attribute as a string by name, or a default value if the attribute can't be found
const std::string attribute_text(const element& Element, const std::string& AttributeName, const std::string& DefaultValue = std::string());
/// Returns the text value of an attribute, converted to a specific type, or a default value if the attribute can't be found
template<typename T>
const T attribute_value(const element& Element, const std::string& AttributeName, const T& DefaultValue)
{
const attribute* const a = find_attribute(Element, AttributeName);
if(a)
return k3d::from_string<T>(a->value, DefaultValue);
return DefaultValue;
}
/// 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
const std::string element_text(const element& Element, const std::string& ElementName, const std::string& DefaultValue = std::string());
/// iostream-compatible manipulator that controls whether subsequent XML will be serialized with-or-without line breaks
struct single_line
{
single_line(bool Enable = true);
bool enable;
};
std::ostream& operator<<(std::ostream& Stream, const single_line& RHS);
/// Inserts an XML declaration <?xml version="1.0" ?> into a stream
struct declaration
{
};
std::ostream& operator<<(std::ostream& Stream, const declaration& RHS);
/// Serializes an XML attribute to a stream
std::ostream& operator<<(std::ostream& Stream, const attribute& RHS);
/// Serializes an XML document to a stream
std::ostream& operator<<(std::ostream& Stream, const element& RHS);
/// Extracts an XML document from a stream
std::istream& operator>>(std::istream& Stream, element& RHS);
/// Abstract interface used to provide feedback during long parsing operations
class progress
{
public:
virtual void show_activity() = 0;
protected:
progress() {}
progress(const progress&) {}
progress& operator=(const progress&) { return *this; }
virtual ~progress() {}
};
/// Convenience implementation of the progress interface for use when feedback is not required (Null Object Pattern)
class hide_progress :
public progress
{
public:
void show_activity() {}
};
/// Parses an XML document from a stream
void parse(element& Root, std::istream& InputStream, const std::string& StreamName, progress& Progress);
} // namespace xml
} // namespace k3d
#endif // !K3DSDK_XML_H