00001 #ifndef PHX_XML_DESCRIPTION_H
00002 #define PHX_XML_DESCRIPTION_H
00003
00004 #include <Phx/PhxConfig.h>
00005 #include <Phx/PhxTypes.h>
00006 #include <Phx/Util/PhxXml.h>
00007 #include <sstream>
00008 #include <map>
00009 #include <vector>
00010 #include <set>
00011
00018 namespace Phx {
00019
00038 class XmlDescriptionNode {
00039
00040 public:
00047 class AttribSpec {
00048 public:
00054 AttribSpec(const String& name) : mName(name), mIndex("") {}
00055
00065 AttribSpec(const String& name, const String& index) :
00066 mName(name), mIndex(index) {}
00067
00068
00070 const String& name(void) const { return mName; }
00071
00075 const String& index(void) const { return mIndex; }
00076
00077 private:
00078 String mName, mIndex;
00079 };
00080
00081 private:
00082
00083 struct AttribSpecComp {
00084 bool operator()(const AttribSpec& lhs, const AttribSpec& rhs) const {
00085 if (lhs.name() < rhs.name()) return true;
00086 if (lhs.name() > rhs.name()) return false;
00087 return lhs.index() < rhs.index();
00088 }
00089 };
00090 public:
00091
00095 typedef std::set<AttribSpec, AttribSpecComp> AttribSpecSet;
00096
00104 XmlDescriptionNode(XmlNode* node);
00105
00112 XmlDescriptionNode(const String& descType);
00113
00118 XmlDescriptionNode(const XmlDescriptionNode& node);
00119
00125 const XmlDescriptionNode& operator=(const XmlDescriptionNode& rhs);
00126
00130 const String& type(void) const { return mType; }
00131
00136 void type(const String& type) { mType = type; }
00137
00150 void file(const String& file) { mFile = file; }
00151
00157 const String& file(void) const { return mFile; }
00158
00165 uint32_t attributeCount(void) const
00166 { return (uint32_t)(mAttributes.size()+mChildren.size()); }
00167
00188 AttribSpecSet attributes(const String& name = "") const;
00189
00209 XmlDescriptionNode* childAttribute(const AttribSpec& attrib);
00210
00211 const XmlDescriptionNode* childAttribute(const AttribSpec& attrib) const;
00212
00246 XmlDescriptionNode childAttributeSubstitute(const AttribSpec& attrib) const;
00247
00260 void childAttribute(const AttribSpec& attrib, const XmlDescriptionNode* node);
00261
00274 void childAttribute(const AttribSpec& attrib, const XmlDescriptionNode& node);
00275
00288 String stringAttributeDefault(const AttribSpec& attrib, const String& defaultValue = "") const;
00289
00298 String stringAttribute(const AttribSpec& attrib) const {
00299 return stringAttributeDefault(attrib);
00300 }
00301
00310 void stringAttribute(const AttribSpec& attrib, const String& value);
00311
00312 float floatAttribute(const AttribSpec& attrib) const {
00313 return floatAttributeDefault(attrib, 0.0f);
00314 }
00315 double doubleAttribute(const AttribSpec& attrib) const {
00316 return doubleAttributeDefault(attrib, 0.0f);
00317 }
00318 uint64_t uint64Attribute(const AttribSpec& attrib) const {
00319 return uint64AttributeDefault(attrib, 0);
00320 }
00321 uint32_t uint32Attribute(const AttribSpec& attrib) const {
00322 return uint32AttributeDefault(attrib, 0);
00323 }
00324 uint16_t uint16Attribute(const AttribSpec& attrib) const {
00325 return uint16AttributeDefault(attrib, 0);
00326 }
00327 uint8_t uint8Attribute(const AttribSpec& attrib) const {
00328 return uint8AttributeDefault(attrib, 0);
00329 }
00330 int64_t int64Attribute(const AttribSpec& attrib) const {
00331 return int64AttributeDefault(attrib, 0);
00332 }
00333 int32_t int32Attribute(const AttribSpec& attrib) const {
00334 return int32AttributeDefault(attrib, 0);
00335 }
00336 int16_t int16Attribute(const AttribSpec& attrib) const {
00337 return int16AttributeDefault(attrib, 0);
00338 }
00339 int8_t int8Attribute(const AttribSpec& attrib) const {
00340 return int8AttributeDefault(attrib, 0);
00341 }
00342 bool boolAttribute(const AttribSpec& attrib) const {
00343 return boolAttributeDefault(attrib, false);
00344 }
00345
00346 float floatAttributeDefault(const AttribSpec& attrib, float defaultValue) const;
00347 double doubleAttributeDefault(const AttribSpec& attrib, double defaultValue) const;
00348 uint64_t uint64AttributeDefault(const AttribSpec& attrib, uint64_t defaultValue) const;
00349 uint32_t uint32AttributeDefault(const AttribSpec& attrib, uint32_t defaultValue) const;
00350 uint16_t uint16AttributeDefault(const AttribSpec& attrib, uint16_t defaultValue) const;
00351 uint8_t uint8AttributeDefault(const AttribSpec& attrib, uint8_t defaultValue) const;
00352 int64_t int64AttributeDefault(const AttribSpec& attrib, int64_t defaultValue) const;
00353 int32_t int32AttributeDefault(const AttribSpec& attrib, int32_t defaultValue) const;
00354 int16_t int16AttributeDefault(const AttribSpec& attrib, int16_t defaultValue) const;
00355 int8_t int8AttributeDefault(const AttribSpec& attrib, int8_t defaultValue) const;
00356 bool boolAttributeDefault(const AttribSpec& attrib, bool defaultValue) const;
00357
00358 void floatAttribute(const AttribSpec& attrib, float value);
00359 void doubleAttribute(const AttribSpec& attrib, double value);
00360 void uint64Attribute(const AttribSpec& attrib, uint64_t value);
00361 void uint32Attribute(const AttribSpec& attrib, uint32_t value);
00362 void uint16Attribute(const AttribSpec& attrib, uint16_t value);
00363 void uint8Attribute(const AttribSpec& attrib, uint8_t value);
00364 void int64Attribute(const AttribSpec& attrib, int64_t value);
00365 void int32Attribute(const AttribSpec& attrib, int32_t value);
00366 void int16Attribute(const AttribSpec& attrib, int16_t value);
00367 void int8Attribute(const AttribSpec& attrib, int8_t value);
00368 void boolAttribute(const AttribSpec& attrib, bool value);
00369
00370 private:
00371
00372
00373 void clearChildren(void);
00374 void deleteChild(const AttribSpec& attrib);
00375
00376
00377 template <typename T>
00378 T readAttribute(const AttribSpec& attrib, T defaultVal) const {
00379 T value = defaultVal;
00380 AttribStringMapType::const_iterator itr = mAttributes.find(attrib);
00381
00382 if (itr != mAttributes.end()) {
00383 std::istringstream istr(itr->second);
00384 istr >> value;
00385 if (!istr.bad() && !istr.fail()) {
00386 return value;
00387 } else {
00388 std::clog << "Failure while parsing attribute "
00389 << attrib.name() << ":" << attrib.index() << std::endl;
00390 }
00391 }
00392
00393 return value;
00394 }
00395
00396
00397 template <typename T>
00398 void writeAttribute(const AttribSpec& attrib, T value) {
00399 std::stringstream stream;
00400 stream << value;
00401 if (stream.good()) {
00402 stringAttribute(attrib, stream.str());
00403 } else {
00404 std::clog << "Failure while writing attribute "
00405 << attrib.name() << ":" << attrib.index() << std::endl;
00406 }
00407 }
00408
00409
00410
00411
00412
00413
00414
00415 void print(std::ostream& os) const;
00416
00417
00418 XmlDescriptionNode substituteFile(const XmlDescriptionNode& node) const;
00419
00420
00421
00422 String mType;
00423 String mFile;
00424
00425 typedef std::map<AttribSpec,String, AttribSpecComp> AttribStringMapType;
00426 typedef std::map<AttribSpec, XmlDescriptionNode*, AttribSpecComp> AttribChildMapType;
00427 AttribStringMapType mAttributes;
00428 AttribChildMapType mChildren;
00429
00430 friend std::ostream& operator<<(std::ostream& os, const XmlDescriptionNode& node);
00431 };
00432
00436 std::ostream& operator<<(std::ostream& os, const XmlDescriptionNode& node);
00437
00441 std::ostream& operator<<(std::ostream& os, const XmlDescriptionNode::AttribSpec& attrib);
00442
00443 };
00444
00445 #endif