////////////////////////////////////////////////// // expat [XMLEntity.cpp] ////////////////////////////////////////////////// #include "XMLEntity.h" #include #include XMLEntity::XMLEntity(const char *name, const char **atts) { _parent = NULL; _children = new vector; _name = strdup(name); _atts = NULL; _character_data = NULL; _is_complete = false; SetAttributes(atts); } XMLEntity::~XMLEntity() { // delete all children (depth first) for (vector::iterator i=_children->begin(); i != _children->end(); ++i) { delete *i; } // delete self delete _children; free(_name); // delete attributes if (_atts != NULL) { for (int i=0; i<(CountAttributes() + 2); ++i) { free(_atts[i]); } free(_atts); } free(_character_data); } XMLEntity *XMLEntity::Parent() { return _parent; } XMLEntity *XMLEntity::Child(int index) { return (*_children)[index]; } XMLEntity *XMLEntity::Child(const char *name) { if (name) { for (int i=0; iName(), name)) return Child(i); } return NULL; } const char *XMLEntity::Name() { return _name; } const char *XMLEntity::Attribute(const char *key) { if (_atts) for(int i=0; _atts[i] && *_atts[i]; i+=2) if (!strcasecmp(_atts[i], key)) return _atts[i+1]; return NULL; } const char *XMLEntity::AttributeKey(int index) { return _atts[index << 1]; } const char *XMLEntity::AttributeValue(int index) { return _atts[(index << 1) + 1]; } const char *XMLEntity::CharacterData() { if (_character_data && *_character_data) return _character_data; else return ""; } const char *XMLEntity::ChildData(const char *name) { XMLEntity *child = Child(name); // if the child exists if (child) return child->Data(); return NULL; } const char *XMLEntity::Data() { return CharacterData(); } char *XMLEntity::ToString(bool encoded, int level) { // piece together text-version XML from XMLEntity string text = ""; // assemble indent size string indent = ""; string character_data = EscapeText(CharacterData()); for(int i=0; i 0) { text += "\n"; for (int i=0; i < CountChildren(); ++i) { char *str = Child(i)->ToString(encoded, level + 1); if (str) { text += str; free(str); } } text += indent; } // closing tag if (CountChildren() > 0 || character_data.size() > 0) { text += ""; } // end text += "\n"; // possible point of memory leak - needs resolution return strdup(text.c_str()); } char *XMLEntity::StartToString(__attribute__((unused)) bool encoded) { // piece together text-version XML from XMLEntity string text = ""; // starting tag text += "<"; text += Name(); // attributes for(int i=0; i < CountAttributes(); ++i) { text += " "; text += AttributeKey(i); text += "="; text += "\""; text += EscapeText(AttributeValue(i)); text += "\""; } text += ">"; // possible point of memory leak - needs resolution return strdup(text.c_str()); } char *XMLEntity::EndToString() { // piece together text-version XML from XMLEntity string text = ""; // closing tag text += ""; // possible point of memory leak - needs resolution return strdup(text.c_str()); } int XMLEntity::CountChildren() { return _children->size(); } int XMLEntity::CountAttributes() { if (!_atts) return 0; int i = 0; for(i=0; _atts[i] != NULL; i+=2); return (i >> 1); } bool XMLEntity::IsCompleted() { return _is_complete; } void XMLEntity::SetName(const char *new_name) { if (_name) { free(_name); _name = NULL; } _name = strdup(new_name); } void XMLEntity::SetParent(XMLEntity *entity) { _parent = entity; } void XMLEntity::AddChild(XMLEntity *entity) { // automatically set parent of target child entity->SetParent(this); // add child _children->push_back(entity); } void XMLEntity::AddChild(const char *name, const char **atts, const char *data) { XMLEntity *entity = new XMLEntity(name, atts); entity->SetCharacterData(data); AddChild(entity); } void XMLEntity::RemoveChild(const char *name) { for (vector::iterator i=_children->begin(); i != _children->end(); ++i) { if (!strcasecmp((*i)->Name(), name)) { delete *i; _children->erase(i); return; } } } void XMLEntity::RemoveChild(XMLEntity *entity) { for (vector::iterator i=_children->begin(); i != _children->end(); ++i) if ((*i) == entity) { delete *i; _children->erase(i); return; } } void XMLEntity::RemoveSelf() { if(Parent()) { Parent()->RemoveChild(this); } else { delete this; } } void XMLEntity::SetAttributes(const char **atts) { // delete attributes if (_atts != NULL) { for (int i=0; i<(CountAttributes() + 2); ++i) { delete[] _atts[i]; } delete[] _atts; _atts = NULL; } if (atts == NULL) return; // initialize attributes int i; for (i=0; atts[i] && *atts[i] && atts[i+1]; i+=2); if (i > 0) { _atts = (char **)malloc((i+2) * sizeof(char *)); for(int j=0; j", replacement)) != string::npos) { text.replace(replacement++, 1, ">"); } return text; } string XMLEntity::DeEscapeText(string text) { size_t replacement; replacement = 0; while ((replacement = text.find("&", replacement)) != string::npos) { text.replace(replacement++, 5, "&"); } replacement = 0; while ((replacement = text.find("<", replacement)) != string::npos) { text.replace(replacement++, 4, "<"); } replacement = 0; while ((replacement = text.find(">", replacement)) != string::npos) { text.replace(replacement++, 4, ">"); } return text; }