inmost_xml.h 8.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
#ifndef INMOST_XML_INCLUDED
#define INMOST_XML_INCLUDED

#include "inmost.h"

namespace INMOST
{  
  std::string CharToHex(char c);
#if defined(USE_MESH)
  std::string ReferenceToString(INMOST::HandleType h, int pos);
#endif
#if defined(USE_AUTODIFF)
13
  std::string VariableToString(INMOST::variable v);
14
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
15
  
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
    

  class XMLReader
  {
    class Interpreter
    {
      bool error_state;
      std::vector<std::string> Expand(const std::string & input) const;
      std::vector<std::string> MakePolish(const std::vector<std::string> & input);
      void Print(const std::vector<std::string> & polish) const;
      double Run(const std::vector<std::string> & polish);
    public:
      Interpreter();
      Interpreter(const Interpreter & b);
      Interpreter & operator = (Interpreter const & b);
      double Evaluate(const std::string & str);
      bool isError();
      void ClearError();
    };
    Interpreter intrp;
    struct Stream
    {
      std::string src;
      std::istream * s;
      int linebreak, linechar;
      int hadlinebreak, hadlinechar;
    };
    std::vector<Stream> inp;
    int verbose;
    enum State
    {
      Intro, //read tag or read tag contents
      WaitTag, //wait tag name or comment
      ReadTag, //reading in tag name
      ReadCommentExclamation, //skipping comments
      ReadCommentQuestion, //skipping comments
      WaitAttribute, //reading attribute name
      ReadAttribute,
      WaitAttributeValue, //read attribute value
      ReadAttributeValue,
      ReadAttributeValueQuote,
      EndTag, //tag ended read closing
      WaitCloseTag,
      ReadCloseTagSlash,
      ReadCloseTagName,

      WaitContentsOpen,
      WaitContents,
      ReadContents, //parse a word
      ReadContentsVector, // {0,1,2,3}
      ReadContentsQuotes, // "hello world"
      ReadContentsMultiplier, // 123*5
      ReadContentsMultiplierSkopes, // 123*(SetSize/2)
      EndContents,
      ReadVector,

      EndOfFile, // end of file reached
      Failure //unexpected error
    } _state;
    Stream & get_Stream();
    const Stream & get_Stream() const;
    std::istream & get_iStream();
    const std::istream & get_iStream() const;
    //should not share the reference to the stream with another reader
    XMLReader(const XMLReader & other);
    XMLReader & operator =(XMLReader & other);
    char GetChar();
    //return one character back to the stream
    void RetChar();
    void SkipComments(State RetState);
    std::string StateName(State s) const;
  public:
88 89 90
	/// 2 - lot's of output
	/// 1 - output key steps, currently in ReadXML
	void SetVerbosity(int verbosity) {verbose =  verbosity;}
91 92 93 94
    void Report(const char * fmt, ...) const;
    XMLReader(std::string sourcename, std::istream & input);
    void PushStream(std::string file);
    void PopStream();
95 96 97 98
	//wait for '<' on input,
	//returns true and changes state to WaitTag if '<' encountered,
	//otherwise returns false
	bool ExpectOpenTag();
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
    //read in <TagName returns TagName
    std::string ReadOpenTag();
    //read > or /> skipping for attributes
    int ReadCloseTag();
    bool isTagFinish() const;
    //read </TagName> or fail
    bool ReadFinishTag(std::string TagName);
    //read next attribute name, check isTagEnded
    std::string AttributeName();
    //read value of the attribute after reading it's name
    std::string AttributeValue();
    // > or /> was reached, should close ReadCloseTag
    // to finalize
    bool isTagEnded() const;
    //read in <![CDATA[
    //Quick and dirty, rewrite with states!
    bool ReadOpenContents();
    //get next full word inside contents
    std::string GetContentsWord();
    //read ]]>
    bool ReadCloseContents();
    //]]> was reached, should call ReadCloseContents
    //to finalize
    bool isContentsEnded() const;
    bool isFailure() const;
    bool isEof() const;
    
#if defined(USE_MESH)
    INMOST::ElementType atoes(const char * _str);
    INMOST::ElementType atoe(const char * _str);
    std::pair<INMOST::ElementType,int> atoh(const char * _str);
    std::pair<std::string,std::pair<INMOST::ElementType,int> > atorh(const char * _str);
#endif
#if defined(USE_AUTODIFF)
133
    INMOST::variable atov(const char * _str);
134 135 136 137 138 139
#endif
    int EvaluateExpression(std::string expression);
    int ConvertMultiplier(std::string expression, int SetSize);
    void SplitValueMultiplier(std::string expression, std::string & value, std::string & multiplier);
    bool ParseBool(std::string word);
    void ParseCommaSeparated(std::string word, std::vector<std::string> & parsed, char symbol = ',');
140
#if defined(USE_MESH)
141 142 143 144 145
    void ParseReal(std::string word, std::vector<INMOST::Storage::real> & Vector, int & Repeat, int SetSize);
#if defined(USE_AUTODIFF)
    void ParseVariable(std::string word, std::vector<INMOST::Storage::var> & Vector, int & Repeat, int SetSize);
#endif
    void ParseInteger(std::string word, std::vector<INMOST::Storage::integer> & Vector, int & Repeat, int SetSize);
146
#endif
147
    void ParseBulk(std::string word, std::string & Vector, int & Repeat, int SetSize);
148
#if defined(USE_MESH)
149 150
    void ParseReference(std::string word, std::vector<std::pair<INMOST::ElementType,int> > & Vector, int & Repeat, int SetSize);
    void ParseRemoteReference(std::string word, std::vector< std::pair<std::string,std::pair<INMOST::ElementType,int> > > & Vector, int & Repeat, int SetSize);
151
#endif
152
    
Kirill Terekhov's avatar
Kirill Terekhov committed
153
	/// Structure for xml attribute.
154 155
    struct XMLAttrib
    {
Kirill Terekhov's avatar
Kirill Terekhov committed
156 157
      std::string name; //< Name of the attribute.
      std::string value; //< Value of the attribute.
158 159
    };

Kirill Terekhov's avatar
Kirill Terekhov committed
160
	/// Structure for xml tag with attributes.
161 162
    struct XMLTag
    {
Kirill Terekhov's avatar
Kirill Terekhov committed
163 164
      std::string name; //<Name of the XML tag.
      std::vector<XMLAttrib> attributes; //<List of attributes.
Kirill Terekhov's avatar
Kirill Terekhov committed
165
      int finish; //<Whether to close the tag.
166 167


Kirill Terekhov's avatar
Kirill Terekhov committed
168
	  ///This is data without ![CDATA[ wrap.
169
	  bool RawData() const {return finish == 5;}
Kirill Terekhov's avatar
Kirill Terekhov committed
170
	  ///This is data within ![CDATA[ wrap.
171
	  bool BlockData() const {return finish == 4;}
Kirill Terekhov's avatar
Kirill Terekhov committed
172
      ///Was not able to read the tag.
173
      bool Failure() const {return finish == 0;}
Kirill Terekhov's avatar
Kirill Terekhov committed
174
      ///Tag was red and have internal contents, can process the contents.
Kirill Terekhov's avatar
Kirill Terekhov committed
175
      bool Process() const {return finish == 1;}
Kirill Terekhov's avatar
Kirill Terekhov committed
176
	  ///Tag was red but do not have internal contents.
Kirill Terekhov's avatar
Kirill Terekhov committed
177
	  bool Stub() const {return finish == 2;}
Kirill Terekhov's avatar
Kirill Terekhov committed
178
      ///Tag was not red, finish of enclosing tag was encountered.
179
      bool Finalize() const {return finish == 3;}
Kirill Terekhov's avatar
Kirill Terekhov committed
180
	  ///Retrive attribute number n.
Kirill Terekhov's avatar
Kirill Terekhov committed
181
      const XMLAttrib & GetAttrib(int n) const {return attributes[n];}
Kirill Terekhov's avatar
Kirill Terekhov committed
182
	  ///Retrive attribute number n.
Kirill Terekhov's avatar
Kirill Terekhov committed
183
      XMLAttrib & GetAttrib(int n) {return attributes[n];}
Kirill Terekhov's avatar
Kirill Terekhov committed
184
	  ///Retrive number of attributes.
185
      int NumAttrib() const {return (int)attributes.size();}
Kirill Terekhov's avatar
Kirill Terekhov committed
186
	  ///Retrive the name of the tag.
187
	  std::string GetName() const {return name;}
188 189 190 191
    };

    XMLTag OpenTag();
    bool CloseTag(XMLTag & tag);
192

Kirill Terekhov's avatar
Kirill Terekhov committed
193
	/// Structure defining entire XML file.
194 195
	struct XMLTree
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
196 197 198
		XMLTag tag; //< tag information, such as name and attributes.
		std::vector<XMLTree> children; //< Children inside XML tag.
		std::string contents; //< Text inside of the tag.
199

Kirill Terekhov's avatar
Kirill Terekhov committed
200 201 202
		///Return next occurance of XML tag with the specified
		///name. Returns NumChildren() if not found.
		int FindChild(std::string name, int offset = -1) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
203 204 205
		///Return next occurance of XML attribute with the specified
		///name. Returns NumAttrib() if not found.
		int FindAttrib(std::string name, int offset = -1) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
206
		///Retrive a child of current XML tag with number n.
207
		const XMLTree & GetChild(int n) const {return children[n];}
Kirill Terekhov's avatar
Kirill Terekhov committed
208
		///Retrive a child of current XML tag with name
Kirill Terekhov's avatar
Kirill Terekhov committed
209 210 211 212 213
		///Returns NULL if not found.
		const XMLTree * GetChild(std::string name) const;
		///Retrive a child of current XML tag with attribute
		///Returns NULL if not found.
		const XMLTree * GetChildWithAttrib(std::string name, std::string value) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
214
		///Retrive number of children.
215
		int NumChildren() const {return (int)children.size();}
Kirill Terekhov's avatar
Kirill Terekhov committed
216
		///Retrive attribute of current XML tag with number n.
Kirill Terekhov's avatar
Kirill Terekhov committed
217
		const XMLAttrib & GetAttrib(int n) const {return tag.GetAttrib(n);}
Kirill Terekhov's avatar
Kirill Terekhov committed
218
		///Retrive attribute of current XML tag with name.
Kirill Terekhov's avatar
Kirill Terekhov committed
219 220
		///Returns NULL if not found.
		const std::string & GetAttrib(std::string name) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
221
		///Retrive number of attributes.
Kirill Terekhov's avatar
Kirill Terekhov committed
222
		int NumAttrib() const {return tag.NumAttrib();}
Kirill Terekhov's avatar
Kirill Terekhov committed
223
		///Retrive the name of the tag.
224
		std::string GetName() const {return tag.GetName();}
Kirill Terekhov's avatar
Kirill Terekhov committed
225
		///Retrive contents of the tag.
226 227 228 229 230 231 232 233 234
		const std::string & GetContents() const {return contents;}
	};


private:
	std::string ReadUntil(std::string stop);
	int ReadXMLSub(XMLTree & root);
public:
	/// Read entire XML file into structure,
Kirill Terekhov's avatar
Kirill Terekhov committed
235 236
	/// it may be more efficient to read the file incrementially, depending on the size.
	/// See mesh_xml_file.cpp for incremential read.
237
	XMLTree ReadXML();
238
  };
Kirill Terekhov's avatar
Kirill Terekhov committed
239 240

  void WriteXML(const XMLReader::XMLTree & t, std::ostream & output, int offset = 0);
Dmitry Bagaev's avatar
Dmitry Bagaev committed
241 242 243

	typedef std::vector<XMLReader::XMLTree>::iterator xml_reader_tree_iterator_t;
	typedef std::vector<XMLReader::XMLAttrib>::iterator xml_reader_attrib_iterator_t;
244 245 246 247
}


#endif //INMOST_XML_INCLUDED