libutil++  1.9.3
 All Classes Functions Variables
Nullable.cpp
1 /*
2 ** libutil++
3 ** $Id: Nullable.cpp 1653 2016-02-28 19:54:59Z sella $
4 ** Copyright (c) 2011-2016 Digital Genesis, LLC. All Rights Reserved.
5 ** Released under the LGPL Version 2.1 License.
6 ** http://www.digitalgenesis.com
7 */
8 
9 static const char rcsid[] __attribute__((used)) = "$Id: Nullable.cpp 1653 2016-02-28 19:54:59Z sella $";
10 
11 #include "Nullable.h"
12 #include "../util/CommonMacro.h"
13 
14 using namespace sella::variant;
15 
16 Nullable::Nullable() throw () :
17  value()
18 { }
19 
20 Nullable::Nullable(std::shared_ptr<void> &value) throw () :
21  value(value)
22 { }
23 
24 Nullable::Nullable(std::shared_ptr<void> &&value) throw () :
25  value(std::move(value))
26 { }
27 
28 Nullable::~Nullable() throw () { }
29 
30 void Nullable::shrink_to_fit() throw () {
31 }
32 
33 bool Nullable::isNull() const throw () {
34  return (this->value == NULL);
35 }
36 
37 std::vector<std::string> Nullable::tokenize(const std::string &value, const boost::regex &pattern) const throw (TypeCastException) {
38  std::vector<std::string> tokens;
39  boost::smatch match;
40 
41  if (UNLIKELY(!boost::regex_match(value, match, pattern))) {
42  if (value.at(0) == '[') {
43  THROW(TypeCastException, "unable to tokenize vector '%s'", value.c_str());
44  } else if (value.at(0) == '{') {
45  THROW(TypeCastException, "unable to tokenize object '%s'", value.c_str());
46  } else {
47  THROW(TypeCastException, "unable to tokenize '%s'", value.c_str());
48  }
49  }
50 
51  const std::string &data = match[1].str();
52 
53  auto begin = data.begin();
54 
55  bool str = false;
56  bool esc = false;
57 
58  for (auto it = data.begin(), end = data.end(); it != end; ++it) {
59  switch (*it) {
60  case '\\':
61  if (!esc) {
62  esc = true;
63 
64  continue;
65  }
66  break;
67 
68  case '"':
69  if (str && !esc) {
70  tokens.push_back(std::string(begin, it + 1));
71  begin = it + 1;
72 
73  str = false;
74  } else if (!esc) {
75  begin = it;
76 
77  str = true;
78  }
79  break;
80 
81  case ' ': case '\t': case '\r': case '\n': case '\f':
82  if (!str) {
83  if (begin != it) {
84  tokens.push_back(std::string(begin, it));
85  }
86  begin = it + 1;
87  }
88  break;
89 
90  case '[': case ']': case '{': case '}': case ',': case ':':
91  if (!str) {
92  if (begin != it) {
93  tokens.push_back(std::string(begin, it));
94  }
95  tokens.push_back(std::string(1, *it));
96  begin = it + 1;
97  }
98  break;
99 
100  default:
101  if (!str && end == std::next(it)) {
102  tokens.push_back(std::string(begin, end));
103  }
104  }
105 
106  if (esc) {
107  esc = false;
108  }
109  }
110 
111  return tokens;
112 }
113 
114 /*
115 ** vim: noet ts=3 sw=3
116 */