All pastes #172730 Raw Edit

Mine

public cpp v1 · immutable
·published 2006-09-16 08:46 UTC
rendered paste body
namespace xml{	class element	{	public:		std::string name;		std::string text;		std::map<std::string, std::string> attributes;		std::list<element> children;		element *parent;		element()		{		}		element(std::istream &s)		{			load(s);		}		void load(std::istream &s)		{			parent = 0;			text.clear();			attributes.clear();			children.clear();			element *open_element = this;			std::string tmp_tagname;			std::string tmp_attrname;			std::string tmp_attrvalue;			std::map<std::string, std::string> tmp_attributes;			int open_tags = 0; // A counter for open tags to establish blocks.			unsigned char cur = 0; // Bit field with any of the following flags...			static const unsigned char cur_intag	= 0x1; // Currently processing a tag.			static const unsigned char cur_foundroot = 0x2; // We found at least the root element.			static const unsigned char cur_ent		= 0x4; // Currently processing a character entity.			static const unsigned char cur_attr		= 0x8; // Currently processing an attribute.			static const unsigned char cur_str		= 0x10; // Currently processing an attribute value within quotes.			static const unsigned char cur_pastname	= 0x20; // The tag name was already found.			static const unsigned char cur_closing = 0x40; // We found a forward slash before the tag name.//			static const unsigned char cur_attr		= 0x10; // Currently assigning an attribute.			while(open_tags || !(cur & cur_foundroot)) // Continue until we have found and closed the root element.			{				char c = s.get();				if(!(cur & cur_str)) // If we are not in a string.				{					// Conclusion: Syntactic stuff is OK.					if(c == '<') // Start tag					{						cur |= cur_intag; // Set in-tag flag.												continue;					}					if(c == '>') // End tag					{						if(cur & cur_closing) // If we found a slash before the tag name.						{							// Conclusion: This is a closing tag.							open_element = open_element->parent; // Step back up to parent element.							open_tags--; // One step closer to closing the root element.						}						else						{							// Conclusion: This is an opening tag for a new child element.							open_element->name = tmp_tagname;							open_element->children.resize(open_element->children.size()+1); // Create child element in open element							element *tmp = open_element; // Save open element							open_element = &*children.begin(); // Set open element to new child							open_element->parent = tmp; // Set child's parent							open_element->attributes = tmp_attributes;							tmp_attributes.clear();							open_tags++; // One step further from closing the root element.							cur |= cur_foundroot; // Set found-root-element flag.						}						cur &= ~cur_pastname;						cur &= ~cur_intag; // Clear in-tag flag.						cur &= ~cur_closing; // Clear tag-is-closing flag.						tmp_tagname.clear(); // Clear tag name buffer.						continue;					}					if(c == '/') // If this character is a forward slash.					{						if(cur & cur_intag) // If we're in a tag.						{							if(!(cur & cur_pastname)) // If we haven't passed the tag name yet.							{								// Conclusion: This is a closing tag.								cur |= cur_closing; // Set tag-is-closing flag.							}						}						continue;					}					if(c == '=') // If this character is an equal sign.					{						if(cur & cur_intag) // If inside a tag.						{							// Conclusion: This must be an attribute assignment operator.							cur |= cur_attr; // Set currently-assigning-attribute flag.						}						continue;					}				}				if(c == '"') // If this character is a quote mark.				{					if(cur & cur_intag) // If inside a tag.					{						if(cur & cur_attr) // If currently assigning an attribute.						{							if(cur & cur_str) // If already reading in a string.							{								// Conclusion: This is a closing quote mark for an attribute value.								tmp_attributes[tmp_attrname] = tmp_attrvalue;								tmp_attrname.clear();								tmp_attrvalue.clear();								cur &= ~cur_str; // Clear currently-reading-string flag.								cur &= ~cur_attr;  // Clear currently-assigning-attribute flag.							}							else							{								cur |= cur_str; // Set the currently-reading-string flag.							}						}					}				}				// What to expect inside a tag changes with whitespace.				else if(std::isspace(c)) // If this character is whitespace.				{					if(cur & cur_intag) // If inside a tag					{						if(tmp_tagname.size()) // If tag name buffer is not empty.						{							// Conclusion: We are past the tag name and now reading attributes.							cur |= cur_pastname; // Set currently-past-name flag.						}					}				}				else				{					// Conclusion: This character must be contents.					if(cur & cur_intag) // If inside a tag.					{						if(cur & cur_pastname) // If past the tag name						{							// Conclusion: Reading in attributes.							if(cur & cur_str) // If inside a string.							{								tmp_attrvalue += c;							}							else							{								// Append this character to the attribute name buffer.								tmp_attrname += c;							}						}						else						{							// Conclusion: We are still reading in the name.							tmp_tagname += c; // Append character to temporary tag name buffer.						}					}					else // Not inside a tag					{						// Conclusion: Basic text contents of element.						open_element->text += c; // Append this character to the element's text buffer.					}				}			}		}	};}