CMS 3D CMS Logo

FWXMLConfigParser.h
Go to the documentation of this file.
1 #ifndef Fireworks_Core_FWXMLConfigParser
2 #define Fireworks_Core_FWXMLConfigParser
3 #include <istream>
4 #include <iostream>
6 
8 
9 
34 {
35  enum STATES {
41  };
42 
43 public:
44  FWXMLConfigParser(std::istream &f)
45  : SimpleSAXParser(f),
48  {}
49 
51  void pushConfig(Attributes &attributes)
52  {
54  int version = 0;
55  for (size_t i = 0, e = attributes.size(); i != e; ++i)
56  {
57  Attribute &attr = attributes[i];
58  if (attr.key == "name")
59  name = attr.value;
60  else if (attr.key == "version")
61  {
62  char *endptr;
63  version = strtol(attr.value.c_str(), &endptr, 10);
64  if (endptr == attr.value.c_str())
65  throw ParserError("Version must be an integer.");
66  }
67  else
68  throw ParserError("Unexpected attribute " + attr.key);
69  }
70  m_configs.push_back(std::make_pair(name, new FWConfiguration(version)));
71  }
72 
73 
77  void startElement(const std::string &tag, Attributes &attributes) override
78  {
79  debug_config_state_machine("start", tag, m_state);
81  {
82  if (tag != "config")
83  throw ParserError("Expecting toplevel <config> tag");
84  pushConfig(attributes);
85  m_first.reset(m_configs.back().second);
87  }
88  else if (m_state == IN_PUSHED_CONFIG)
89  {
90  if (tag == "config")
91  pushConfig(attributes);
92  else if (tag == "string")
94  else
95  throw ParserError("Unexpected element " + tag);
96  }
97  else if (m_state == IN_POPPED_CONFIG)
98  {
99  if (tag != "config")
100  throw ParserError("Unexpected element " + tag);
101  pushConfig(attributes);
103  }
104  else
105  throw ParserError("Wrong opening tag found " + tag);
106  }
107 
116  void endElement(const std::string &tag) override
117  {
118  debug_config_state_machine("end", tag, m_state);
120  {
121  if (tag != "config")
122  throw ParserError("Wrong closing tag found " + tag);
123 
124  FWConfiguration *current = m_configs.back().second;
125  std::string key = m_configs.back().first;
126  m_configs.pop_back();
127  if (!m_configs.empty())
128  m_configs.back().second->addKeyValue(key, *current);
130  }
131  else if (m_state == IN_BEGIN_STRING && tag == "string")
132  {
133  m_configs.back().second->addValue("");
135  }
136  else if (m_state == IN_STORED_STRING && tag == "string")
138  else
139  throw ParserError("Wrong closing tag found " + tag);
140  }
141 
147  void data(const std::string &data) override
148  {
149  debug_config_state_machine("data", data, m_state);
150  // We ignore whitespace but complain about any text which is not
151  // in the <string> tag.
152  if (m_state == IN_BEGIN_STRING)
153  {
154  m_configs.back().second->addValue(data);
156  }
157  else if (strspn(data.c_str(), " \t\n") != data.size())
158  throw ParserError("Unexpected text " + data);
159  }
160 
165  {
166  return m_first.get();
167  }
168 
169 
170 void
171 debug_config_state_machine(const char *where, const std::string &tag, int state)
172 {
173 #ifdef FW_CONFIG_PARSER_DEBUG
174  static char *debug_states[] = {
175  "IN_BEGIN_DOCUMENT",
176  "IN_PUSHED_CONFIG",
177  "IN_POPPED_CONFIG",
178  "IN_BEGIN_STRING",
179  "IN_STORED_STRING"
180  };
181 
182  std::cerr << " " << where << " tag/data " << tag << "in state " << debug_states[state] << std::endl;
183 #endif
184 }
185 
186 private:
187  std::vector<std::pair<std::string, FWConfiguration *> > m_configs;
189  std::auto_ptr<FWConfiguration> m_first;
190  // unsigned int m_currentConfigVersion;
192 };
193 #endif
FWXMLConfigParser(std::istream &f)
std::string m_currentConfigName
std::vector< Attribute > Attributes
std::auto_ptr< FWConfiguration > m_first
std::vector< std::pair< std::string, FWConfiguration * > > m_configs
#define nullptr
FWConfiguration * config(void)
void pushConfig(Attributes &attributes)
void debug_config_state_machine(const char *where, const std::string &tag, int state)
double f[11][100]
void startElement(const std::string &tag, Attributes &attributes) override
void data(const std::string &data) override
void endElement(const std::string &tag) override