RCFProto

- Main Page
- Classes
- Files

- File List

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 util {
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 util
112
113
114 #endif // ! INCLUDE_UTIL_SCAN_HPP