/* ************************************************************************** Author: Achim Gaedke Created: June 2004 ****************************************************************************/ #ifndef XML_STATES_H #define XML_STATES_H #include "states.h" #include "constants.h" #include #include #include /** \defgroup xmlstateinterface XML support for all state classes \ingroup states The state sequences consist of states and again sequences. A state is defined by a number of state_atom objects. This definition results in a file with nested sections, that is parsed into a tree formed by the state objects. The leaves of the tree are normaly state_atom objects. These state_atom objects define the state of a device. An example for a sequence definition is: \verbatim \endverbatim The first line of this code is a statement of xml conformity. (More about xml can be read at: http://www.w3.org/TR/REC-xml .) \n The second line defines a new subsequence of states by using the tag \. The "repeat" value 3 is the loop count. This line effects an instatiation of a state_sequent object. All information will be collected in this branch, it is closed on the last line by \. In this example the third line provides a %state tag corresponding to a state object. So this also line specifies the duration of this state in seconds. This section is closed with the eigth line containing \. A xml document can contain only one top-level-element, that is called root or document element. Applying the xml_state_reader it is not necessary to begin with a sequent element. \n A xml section (representing a state or sequence in our case) is opend by a tag with a name in angle braces like \ and is closed with an extra slash before the name \. Attributes can follow in the form name="value", attributes must be quoted (single or double quotes). If such a section has no contents there is a short form with a slash before the closing angle, e.g. \. \n Of course outside these tags, text can be supplied. By now, xml_state_reader ignores this text. Inside a %state section the definition of the state is collected. Implemented are ttlout, analogout and analogin. One element can occurr several times. How these states are merged is machine dependent. So a state sequence is defined by one sequent section, containing again serval state or sequent sections. The state sections must not contain other state sections or sequent sections. */ //@{ /** \brief gains state sequence from an xml event stream */ class xml_state_reader { state_atom* root; std::list pending_elements; XML_Parser parser; public: /** instantiates an expat xml parser object */ xml_state_reader(); /** frees the parser object */ ~xml_state_reader(); /** \brief parses xml file containing sequences of states the name of the file is the only parameter \return returns tree of states or NULL if an parse error occured */ state_atom* read_from_file(const std::string& filename); state_atom* read_from_dom(const XERCES_CPP_NAMESPACE_QUALIFIER DOMElement* e) { // to do work, work and work return NULL; } /** \brief parses a string containing sequences of states \return returns tree of states or NULL if an parse error occured */ state_atom* read_from_string(const std::string& data); /** \brief finds an attribute in the attributes array \return returns the pointer to the attributes value or NULL if not in the array */ const XML_Char* search_attribute(const XML_Char** atts, const XML_Char* attr) const; /** \brief looks for an attribute with different names the first alternative, that could be found is taken \return returns a pointer to the attributes value or NULL if nothing approprate is found */ const XML_Char* search_attributes(const XML_Char** atts, ...) const; /** create new states from xml tags and their attributes */ state_atom* state_factory(const XML_Char* name, const XML_Char** atts) const; /** start tag callback for expat parser */ void start_element(const XML_Char* name,const XML_Char** atts); /** end tag callback for expat parser */ void end_element(const XML_Char* name); }; /** \ingroup states the writer outputs states to xml files takes care of formating */ class xml_state_writer { public: /// have a stack std::list pending_elements; /// allow nice formating druing recursive operation size_t indent_offset; /// allow nice formating druing recursive operation size_t indent_increase; /// simple initialisation xml_state_writer(){ indent_offset=0; indent_increase=2; }; /** write states to a given output if add_header is !=0 a full xml document is given */ int write_states(FILE* output, const state_atom& states_to_write, int add_header=0, int indent_size=0); }; //@} #endif