Goby v2
moos_string.h
1 // Copyright 2009-2018 Toby Schneider (http://gobysoft.org/index.wt/people/toby)
2 // GobySoft, LLC (2013-)
3 // Massachusetts Institute of Technology (2007-2014)
4 // Community contributors (see AUTHORS file)
5 //
6 //
7 // This file is part of the Goby Underwater Autonomy Project Libraries
8 // ("The Goby Libraries").
9 //
10 // The Goby Libraries are free software: you can redistribute them and/or modify
11 // them under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 2.1 of the License, or
13 // (at your option) any later version.
14 //
15 // The Goby Libraries are distributed in the hope that they will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with Goby. If not, see <http://www.gnu.org/licenses/>.
22 
23 #ifndef MOOSSTRING20110527H
24 #define MOOSSTRING20110527H
25 
26 #include "goby/moos/moos_header.h"
27 
28 #include "goby/common/time.h"
29 #include "goby/util/as.h"
30 
31 namespace goby
32 {
33 namespace moos
34 {
35 inline std::ostream& operator<<(std::ostream& os, const CMOOSMsg& msg)
36 {
37  os << "[[CMOOSMsg]]"
38  << " Key: " << msg.GetKey() << " Type: " << (msg.IsDouble() ? "double" : "string")
39  << " Value: "
40  << (msg.IsDouble() ? goby::util::as<std::string>(msg.GetDouble()) : msg.GetString())
41  << " Time: " << goby::util::as<boost::posix_time::ptime>(msg.GetTime())
42  << " Community: " << msg.GetCommunity()
43  << " Source: " << msg.m_sSrc // no getter in CMOOSMsg!!!
44  << " Source Aux: " << msg.GetSourceAux();
45  return os;
46 }
47 
57 inline bool val_from_string(std::string& out, const std::string& str, const std::string& key)
58 {
59  // str: foo=1,bar={2,3,4,5},pig=3,cow=yes
60  // two cases:
61  // key: bar
62  // key: pig
63 
64  out.erase();
65 
66  // deal with foo=bar,o=bar problem when looking for "o=" since
67  // o is contained in foo
68 
69  // ok: beginning of string, end of string, comma right before start_pos
70  int match = 0;
71  std::string::size_type start_pos = 0;
72  while (match == 0 ||
73  !(start_pos == 0 || start_pos == std::string::npos || str[start_pos - 1] == ','))
74  {
75  // str: foo=1,bar={2,3,4,5},pig=3,cow=yes
76  // start_pos ^ ^
77  boost::iterator_range<std::string::const_iterator> result =
78  boost::ifind_nth(str, std::string(key + "="), match);
79  start_pos = (result) ? result.begin() - str.begin() : std::string::npos;
80  ++match;
81  }
82 
83  if (start_pos != std::string::npos)
84  {
85  // chopped: bar={2,3,4,5},pig=3,cow=yes
86  // chopped: pig=3,cow=yes
87  std::string chopped = str.substr(start_pos);
88 
89  // chopped: bar={2,3,4,5},pig=3,cow=yes
90  // equal_pos ^
91  // chopped: pig=3,cow=yes
92  // equal_pos ^
93  std::string::size_type equal_pos = chopped.find("=");
94 
95  // check for array
96  bool is_array = (equal_pos + 1 < chopped.length() && chopped[equal_pos + 1] == '{');
97 
98  if (equal_pos != std::string::npos)
99  {
100  // chopped_twice: ={2,3,4,5},pig=3,cow=yes
101  // chopped_twice: =pig=3,cow=yes
102  std::string chopped_twice = chopped.substr(equal_pos);
103 
104  // chopped_twice: ={2,3,4,5},pig=3,cow=yes
105  // end_pos ^
106  // chopped_twice: =pig=3,cow=yes
107  // end_pos ^
108  std::string::size_type end_pos =
109  (is_array) ? chopped_twice.find("}") : chopped_twice.find(",");
110 
111  // out: 2,3,4,5
112  // out: 3
113  out = (is_array) ? chopped_twice.substr(2, end_pos - 2)
114  : chopped_twice.substr(1, end_pos - 1);
115 
116  return true;
117  }
118  }
119 
120  return false;
121 }
122 
125 template <typename T>
126 inline bool val_from_string(T& out, const std::string& str, const std::string& key)
127 {
128  std::string s;
129  if (!val_from_string(s, str, key))
130  return false;
131 
132  try
133  {
134  out = boost::lexical_cast<T>(s);
135  }
136  catch (boost::bad_lexical_cast&)
137  {
138  return false;
139  }
140 
141  return true;
142 }
143 
145 inline bool val_from_string(bool& out, const std::string& str, const std::string& key)
146 {
147  std::string s;
148  if (!val_from_string(s, str, key))
149  return false;
150 
151  out = goby::util::as<bool>(s);
152  return true;
153 }
155 
157 inline void stripblanks(std::string& s)
158 {
159  for (std::string::iterator it = s.end() - 1; it != s.begin() - 1; --it)
160  {
161  if (isspace(*it))
162  s.erase(it);
163  }
164 }
165 } // namespace moos
166 } // namespace goby
167 
168 #endif
The global namespace for the Goby project.