cisst-saw
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cmnStreamRawParser.h
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */
3 
4 /*
5 
6  Author(s): Peter Kazanzides
7 
8  (C) Copyright 2009-2014 Johns Hopkins University (JHU), All Rights Reserved.
9 
10 --- begin cisst license - do not edit ---
11 
12 This software is provided "as is" under an open source license, with
13 no warranty. The complete license can be found in license.txt and
14 http://www.cisst.org/cisst/license.txt.
15 
16 --- end cisst license ---
17 
18 */
19 
20 
25 #pragma once
26 
27 #ifndef _cmnStreamRawParser_h
28 #define _cmnStreamRawParser_h
29 
30 #include <iostream>
31 #include <string>
32 #include <set>
33 #include <functional>
34 
36 #include <cisstCommon/cmnLogger.h>
37 
38 #include <cisstCommon/cmnExport.h>
39 
95 {
96  class EntryBase {
97  protected:
98  std::string key;
99  char delimiter;
100  bool required;
101  bool valid;
102  public:
103  EntryBase(const std::string &name, char delim = ' ', bool req = true) :
104  key(name), delimiter(delim), required(req), valid(false) {}
105  virtual ~EntryBase() {}
106 
107  std::string GetKey() const { return key; }
108  bool isRequired() const { return required; }
109  bool isValid() const { return valid; }
110  void SetValid(bool val) { valid = val; }
111 
112  // Following should be implemented in the derived classes
113  virtual bool Parse(std::istream &CMN_UNUSED(inputStream)) { return false; }
114  virtual void ToStream(std::ostream & outputStream) const { outputStream << key << " (default)"; }
115  };
116 
117  template <class _elementType>
118  class Entry : public EntryBase {
119  _elementType *valuePtr;
120  public:
121  Entry(const std::string &name, _elementType &data, char delim = ' ', bool req = true) :
122  EntryBase(name, delim, req), valuePtr(&data) {}
123  ~Entry() {}
124 
125  bool Parse(std::istream &inputStream) {
126  if (valid) CMN_LOG_INIT_WARNING << "cmnStreamRawParser: duplicate entry for " << key << std::endl;
127  if (valuePtr) {
128  try {
129  cmnData<_elementType>::DeSerializeText(*valuePtr, inputStream, delimiter);
130  valid = true;
131  }
132  catch (const std::runtime_error &) {
133  valid = false;
134  }
135  }
136  return valid;
137  }
138 
139  void ToStream(std::ostream & outputStream) const {
140  outputStream << key << " ";
141  if (valuePtr && valid) {
142  try {
143  cmnData<_elementType>::SerializeText(*valuePtr, outputStream, delimiter);
144  }
145  catch (const std::runtime_error &e) {
146  outputStream << "(invalid: " << e.what() << ")";
147  }
148  }
149  else
150  outputStream << "(invalid)";
151  }
152  };
153 
154  template <class _elementType>
155  class EntryStreamable : public EntryBase {
156  _elementType *valuePtr;
157  public:
158  EntryStreamable(const std::string &name, _elementType &data, bool req = true) :
159  EntryBase(name, ' ', req), valuePtr(&data) {}
160  ~EntryStreamable() {}
161 
162  bool Parse(std::istream &inputStream) {
163  if (valid) CMN_LOG_INIT_WARNING << "cmnStreamRawParser: duplicate entry for " << key << std::endl;
164  if (valuePtr)
165  inputStream >> *valuePtr;
166  valid = inputStream.good();
167  return valid;
168  }
169 
170  void ToStream(std::ostream & outputStream) const {
171  outputStream << key << " ";
172  if (valuePtr && valid)
173  outputStream << *valuePtr;
174  else
175  outputStream << "(invalid)";
176  }
177  };
178 
179  // Comparison operator for std::set
180  struct KeyListLess: public std::binary_function<const cmnStreamRawParser::EntryBase*, const cmnStreamRawParser::EntryBase*, bool>
181  {
182  result_type operator()(first_argument_type p1, second_argument_type p2) const
183  {
184  return p1->GetKey() < p2->GetKey();
185  }
186  };
187 
188  typedef std::set<cmnStreamRawParser::EntryBase *, KeyListLess> KeyListType;
189  KeyListType KeyList;
190 
191 public:
194 
201  template <class _elementType>
202  bool AddEntry(const std::string &name, _elementType &data, char delim = ' ', bool req = true)
203  {
204  cmnStreamRawParser::EntryBase *newEntry = new Entry<_elementType>(name, data, delim, req);
205  bool result = KeyList.insert(newEntry).second;
206  if (!result) delete newEntry; // if not inserted, delete entry
207  return result;
208  }
209 
217  template <class _elementType>
218  bool AddEntryStreamable(const std::string &name, _elementType &data, bool req = true)
219  {
220  cmnStreamRawParser::EntryBase *newEntry = new EntryStreamable<_elementType>(name, data, req);
221  bool result = KeyList.insert(newEntry).second;
222  if (!result) delete newEntry; // if not inserted, delete entry
223  return result;
224  }
225 
227  void SetAllValid(bool val = true);
228 
231  bool Parse(std::istream & inputStream);
232 
234  bool IsValid(const std::string &name) const;
235 
238  void ToStream(std::ostream & outputStream) const;
239 };
240 
241 #endif // _cmnStreamRawParser_h
#define CISST_EXPORT
Definition: cmnExportMacros.h:50
#define CMN_UNUSED(argument)
Definition: cmnPortability.h:479
Declaration of cmnLogger amd macros for human readable logging.
static void SerializeText(const DataType &data, std::ostream &outputStream, const char delimiter= ',')
bool AddEntryStreamable(const std::string &name, _elementType &data, bool req=true)
Definition: cmnStreamRawParser.h:218
cmnStreamRawParser()
Definition: cmnStreamRawParser.h:192
Macros to export the symbols of cisstCommon (in a Dll).
Definition: cmnStreamRawParser.h:94
static void DeSerializeText(DataType &data, std::istream &inputStream, const char delimiter= ',')
#define CMN_LOG_INIT_WARNING
Definition: cmnLogger.h:163
bool AddEntry(const std::string &name, _elementType &data, char delim= ' ', bool req=true)
Definition: cmnStreamRawParser.h:202