RCFProto
 All Classes Functions Typedefs
Scan.hpp
1 
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2013, Delta V Software. All rights reserved.
6 // http://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF
12 // under GPL terms.
13 //
14 // Version: 2.0
15 // Contact: support <at> deltavsoft.com
16 //
17 //******************************************************************************
18 
19 #ifndef INCLUDE_UTIL_SCAN_HPP
20 #define INCLUDE_UTIL_SCAN_HPP
21 
22 #include <sstream>
23 #include <string>
24 #include <utility>
25 #include <vector>
26 
27 namespace RCF {
28 
29  class Scan {
30  public:
31  Scan( std::string s, std::string format ) : i_(0), ok_(true)
32  {
33  int n = 0;
34  std::string::size_type pos = 0;
35  std::string::size_type prev_pos = 0;
36  std::string::size_type npos = std::string::npos;
37 
38  // Extract format string literals
39  std::vector< std::pair<std::string, std::string> > literals;
40  while(pos != npos) {
41  n++;
42  std::string specifier1 = makeSpecifier(n);
43  std::string specifier2 = makeSpecifier(n+1);
44  pos = format.find(specifier1, prev_pos);
45  std::string literal1 = (pos == npos) ? format.substr(prev_pos) : format.substr(prev_pos, pos - prev_pos);
46  if (pos != npos) pos += specifier1.length();
47  prev_pos = pos;
48  pos = format.find(specifier2, prev_pos);
49  std::string literal2 = (pos == npos) ? format.substr(prev_pos) : format.substr(prev_pos, pos - prev_pos);
50  literals.push_back( std::make_pair( literal1, literal2 ) );
51  }
52 
53  // Extract arg string values
54  pos = 0;
55  for (std::vector< std::pair<std::string, std::string> >::iterator it = literals.begin(); it != literals.end(); it++) {
56  if (pos != npos && pos == s.find( (*it).first, pos)) {
57  std::string::size_type a = pos + (*it).first.length();
58  std::string::size_type b = s.find( (*it).second, a );
59  values_.push_back( s.substr( a , (b == a) ? npos : b-a ) );
60  pos = b;
61  }
62  else {
63  ok_ = false;
64  }
65 
66  }
67 
68  }
69 
70  template<typename T> Scan &operator()(T &t)
71  {
72  std::istringstream istr( getNextValue() );
73  istr >> t;
74  return *this;
75  }
76 
77  operator bool() const
78  {
79  return ok();
80  }
81 
82  bool ok() const
83  {
84  return ok_;
85  }
86 
87  private:
88 
89  std::string makeSpecifier( int n )
90  {
91  std::ostringstream ostr;
92  ostr << "%" << n;
93  return ostr.str();
94  }
95 
96  std::string getNextValue()
97  {
98  if (i_<values_.size())
99  return values_[ i_++ ];
100  else {
101  ok_ = false;
102  return "";
103  }
104  }
105 
106  std::vector<std::string> values_;
107  unsigned int i_;
108  bool ok_;
109  };
110 
111 } // namespace RCF
112 
113 #endif // ! INCLUDE_UTIL_SCAN_HPP