root/trunk/whisperlib/common/base/parse.h

Revision 7, 8.2 kB (checked in by whispercastorg, 2 years ago)

version 0.2.0

Line 
1 // Copyright (c) 2009, Whispersoft s.r.l.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Whispersoft s.r.l. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Author: Mihai Ianculescu
31
32 //
33 // We have here a bunch of utility classes for parsing stuff from strings.
34 //
35
36 #ifndef __COMMON_BASE_PARSE_H__
37 #define __COMMON_BASE_PARSE_H__
38
39 #include <string>
40 #include <whisperlib/common/base/strutil.h>
41 #include <whisperlib/common/base/log.h>
42
43 // our namespace
44 namespace parsable {
45
46 class Parsable {
47  public:
48   Parsable() : set_(false) {}
49   virtual ~Parsable() {}
50
51   bool IsSet() const { return set_; }
52   void Reset() { set_ = false; }
53
54   virtual bool Parse(const char* in,
55                      const char** next,
56                      char terminator = '\0') = 0;
57   virtual string ToString() const = 0;
58
59  protected:
60   bool set_;
61 };
62
63 template<typename TTraits> class TParsable : public Parsable {
64  public:
65   TParsable() {
66   }
67   explicit TParsable(const TParsable<TTraits>& other) {
68     value_ = other.value_;
69     set_ = other.set_;
70   }
71   explicit TParsable(typename TTraits::RType value) {
72     TTraits::Assign(value_, value);
73     set_ = true;
74   }
75
76   operator const typename TTraits::LType& () const {
77     return value_;
78   }
79   const typename TTraits::LType& Value() const {
80     return value_;
81   }
82
83   const typename TTraits::LType&
84   operator=(const typename TTraits::LType& value) {
85     value_ = value;
86     set_ = true;
87     return value_;
88   }
89
90   bool operator ==(const TParsable<TTraits>& other) const {
91     if (IsSet()) {
92       if (other.IsSet()) {
93         return Value() == other.Value();
94       }
95       return false;
96     }
97     return !other.IsSet();
98   }
99   // a not set parsable is never equal to a specific value
100   bool operator ==(typename TTraits::RType other) const {
101     if (IsSet()) {
102       return Value() == other;
103     }
104     return false;
105   }
106   bool operator <(const TParsable<TTraits>& other) const {
107     if (IsSet()) {
108       if (other.IsSet()) {
109         return Value() < other.Value();
110       }
111       return false;
112     }
113     return other.IsSet();
114   }
115   // a not set parsable is always less than a specific value
116   bool operator <(typename TTraits::RType other) const {
117     if (IsSet()) {
118       return Value() < other;
119     }
120     return true;
121   }
122
123   virtual bool Parse(const char* in,
124                      const char** next,
125                      char terminator = '\0') {
126     if (TTraits::Parse(value_, in, next, terminator)) {
127       set_ = true;
128       return true;
129     }
130     return false;
131   }
132
133   virtual string ToString() const {
134     return TTraits::ToString(value_);
135   }
136
137  private:
138   typename TTraits::LType value_;
139 };
140
141 template<typename T>
142 class TSimpleTraits {
143  public:
144   typedef T RType;
145   typedef T LType;
146
147   static void Assign(T& value, T from) {
148     value = from;
149   }
150   static T Return(const T& value) {
151     return value;
152   }
153 };
154
155 // string
156 class TStringTraits {
157  public:
158   typedef const char* RType;
159   typedef string LType;
160
161   static void Assign(string& value, const char* from) {
162     value = (from != NULL) ? from : "";
163   }
164   static const char* Return(const string& value) {
165     return value.c_str();
166   }
167   static bool Parse(string& value,
168                     const char* in,
169                     const char** next,
170                     char terminator) {
171     CHECK_NOT_NULL(in);
172     value = in;
173     if (next != NULL) {
174       *next = const_cast<char*>(in + value.size());
175     }
176     return true;
177   }
178   static string ToString(const string& value) {
179     return value;
180   }
181 };
182
183 typedef TParsable<TStringTraits> String;
184
185 // bool
186 class TBooleanTraits : public TSimpleTraits<bool> {
187  public:
188   static bool Parse(bool& value,
189                     const char* in,
190                     const char** next,
191                     char terminator) {
192     CHECK_NOT_NULL(in);
193
194     char* _next = const_cast<char*>(in);
195     value = true;
196     if (*in != '\0') {
197       if (strutil::StrCasePrefix(in, "true")) {
198         value = true;
199         _next += 4;
200       } else if (strutil::StrCasePrefix(in, "false")) {
201         value = false;
202         _next += 5;
203       } else if (strutil::StrCasePrefix(in, "on")) {
204         value = true;
205         _next += 2;
206       } else if (strutil::StrCasePrefix(in, "off")) {
207         value = false;
208         _next += 3;
209       } else if (strutil::StrCasePrefix(in, "yes")) {
210         value = true;
211         _next += 3;
212       } else if (strutil::StrCasePrefix(in, "no")) {
213         value = false;
214         _next += 2;
215       } else if (strutil::StrCasePrefix(in, "1")) {
216         value = true;
217         _next += 1;
218       } else if (strutil::StrCasePrefix(in, "0")) {
219         value = false;
220         _next += 1;
221       } else {
222         return false;
223       }
224
225       if (*_next != terminator)
226         return false;
227     }
228
229     if (next != NULL) {
230       *next = _next;
231     }
232     return true;
233   }
234   static string ToString(const bool& value) {
235     return value ? "1" : "0";
236   }
237 };
238 typedef TParsable<TBooleanTraits> Boolean;
239
240 // generic integer type
241 template <typename TIntegerType>
242 class TIntegerTraits : public TSimpleTraits<TIntegerType> {
243  public:
244   static bool Parse(TIntegerType& value,
245                     const char* in,
246                     const char** next,
247                     char terminator) {
248     char* _next;
249     value = DoParse(in, &_next);
250     if ( _next != in ) {
251       if ( *_next != terminator ) {
252         return false;
253       }
254       if ( next != NULL ) {
255         *next = _next;
256       }
257       return true;
258     }
259     return false;
260   }
261   static string ToString(const TIntegerType& value);
262
263  protected:
264   static TIntegerType DoParse(const char* in, char** next);
265 };
266
267 // int32
268 template<> inline
269 int32 TIntegerTraits<int32>::DoParse(const char* in, char** next) {
270   return static_cast<int32>((strtol(in, next, 10)));
271 }
272 template<> inline
273 string TIntegerTraits<int32>::ToString(const int32& value) {
274   return strutil::IntToString(value);
275 }
276 typedef TParsable<TIntegerTraits<int32> > Int32;
277
278 // uint32
279 template<> inline
280 uint32 TIntegerTraits<uint32>::DoParse(const char* in,
281                                        char** next) {
282   return static_cast<uint32>(strtoul(in, next, 10));
283 }
284 template<> inline
285 string TIntegerTraits<uint32>::ToString(const uint32& value) {
286   return strutil::UintToString(value);
287 }
288 typedef TParsable<TIntegerTraits<uint32> > UInt32;
289
290 // int64
291 template<> inline
292 int64 TIntegerTraits<int64>::DoParse(const char* in, char** next) {
293   return static_cast<int64>(strtoll(in, next, 10));
294 }
295 template<> inline
296 string TIntegerTraits<int64>::ToString(const int64& value) {
297   return strutil::Int64ToString(value);
298 }
299 typedef TParsable<TIntegerTraits<int64> > Int64;
300
301 // uint64
302 template<> inline
303 uint64 TIntegerTraits<uint64>::DoParse(const char* in,
304                                        char** next) {
305   return static_cast<uint64>(strtoull(in, next, 10));
306 }
307 template<> inline
308 string TIntegerTraits<uint64>::ToString(const uint64& value) {
309   return strutil::Uint64ToString(value);
310 }
311 typedef TParsable<TIntegerTraits<uint64> > UInt64;
312
313 }   // namespace parsable
314
315 #endif  // __COMMON_BASE_PARSE_H__
Note: See TracBrowser for help on using the browser.