IODA Bundle
StringTool.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 1996-2012 ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation nor
8  * does it submit to any jurisdiction.
9  */
10 
11 /// \file StringTool.h
12 ///
13 /// @author Piotr Kuchta, ECMWF, Feb 2009
14 
15 #include "eckit/utils/StringTools.h"
16 
17 #include <cstring>
18 
19 #include "eckit/exception/Exceptions.h"
20 #include "eckit/filesystem/PathName.h"
21 #include "eckit/io/FileHandle.h"
22 #include "eckit/log/CodeLocation.h"
23 #include "eckit/log/Log.h"
24 #include "eckit/utils/Translator.h"
25 #include "eckit/utils/Regex.h"
26 
27 #include "odc/StringTool.h"
28 
29 using namespace std;
30 using namespace eckit;
31 
32 namespace odc {
33 
34 std::vector<std::string> StringTool::readLines(const PathName fileName, bool logging)
35 {
36  std::string s = readFile(fileName, logging);
37  return StringTools::split("\n", s);
38 }
39 
40 std::string StringTool::readFile(const PathName fileName, bool logging)
41 {
42  const size_t CHUNK_SIZE = 1024;
43  char buffer[CHUNK_SIZE];
44 
45  FileHandle f(fileName);
46  f.openForRead();
47 
48  std::string ret;
49  size_t read, totalRead = 0;
50 
51  while ( (read = f.read(buffer, sizeof(buffer) / sizeof(char))) > 0 )
52  {
53  totalRead += read;
54  ret.append(std::string(static_cast<char*>(buffer), read));
55  }
56 
57  if (logging)
58  Log::info() << "Read " << totalRead << " bytes from file " << fileName << "[" << ret << "]" << std::endl;
59 
60  f.close();
61  return ret;
62 }
63 
64 int StringTool::shell(std::string cmd, const CodeLocation& where, bool assertSuccess)
65 {
66  std::string c = "/bin/sh -c \"" + cmd + "\"";
67 
68  Log::info() << "Executing '" + c + "' ";
69  Log::info() << " " << where.file() << " +" << where.line();
70  Log::info() << std::endl;
71 
72  int rc = system(c.c_str());
73 
74  if (assertSuccess && rc != 0)
75  {
76  throw eckit::SeriousBug(std::string(" \"") + cmd + "\" failed. " + where.file() + " +" + Translator<int, std::string>()(where.line()));
77  ASSERT(rc == 0);
78  }
79  return rc;
80 }
81 
82 bool StringTool::check(const std::string& s, ctypeFun fun)
83 {
84  for (size_t i = 0; i < s.size(); ++i)
85  if (! fun(s[i]))
86  return false;
87  return true;
88 }
89 
90 bool StringTool::isInQuotes(const std::string& value)
91 {
92  return value.size() > 1
93  && ((value[0] == '"' && value[value.size() - 1] == '"')
94  || (value[0] == '\'' && value[value.size() - 1] == '\''));
95 }
96 
97 std::string StringTool::unQuote(const std::string& value)
98 {
99  if (! value.size())
100  return value;
101  if (isInQuotes(value))
102  return value.substr(1, value.size() - 2);
103  return value;
104 }
105 
106 std::string StringTool::double_as_string(double m)
107 {
108  char buf[sizeof(double) + 1];
109  memset(buf, 0, sizeof(buf));
110  memcpy(buf, reinterpret_cast<char *>(&m), sizeof(double));
111  return std::string(buf, sizeof(double));
112 }
113 
114 double StringTool::cast_as_double(const std::string& value)
115 {
116  char buf[sizeof(double)];
117  memset(buf, ' ', sizeof(double));
118 
119  ASSERT(value.size() <= sizeof(double));
120 
121  strncpy(buf + sizeof(double) - value.size(), value.c_str(), value.size());
122  return *reinterpret_cast<double *>(buf);
123 }
124 
125 std::string StringTool::int_as_double2string(double v)
126 {
127  std::stringstream s;
128  s.precision(0);
129  s << fixed << v;
130  return s.str();
131 }
132 
133 double StringTool::translate(const std::string& v)
134 {
135  return isInQuotes(v) ? cast_as_double(unQuote(v)) : Translator<std::string, double>()(v);
136 }
137 
138 void StringTool::trimInPlace(std::string &str) { str = StringTools::trim(str); }
139 
140 bool StringTool::match(const std::string& regex, const std::string& s)
141 {
142  return Regex(regex).match(s);
143 }
144 
145 bool StringTool::matchAny(const std::vector<std::string>& regs, const std::string& s)
146 {
147  for (size_t i = 0; i < regs.size(); ++i)
148  if (match(regs[i], s))
149  return true;
150  return false;
151 }
152 
153 ostream& operator<<(std::ostream& s, const std::vector<std::string>& st)
154 {
155  s << '[';
156  for (std::vector<std::string>::const_iterator it = st.begin(); it != st.end(); ++it)
157  s << *it << ",";
158  s << ']';
159  return s;
160 }
161 
162 
163 std::string StringTool::valueAsString(double d, api::ColumnType t)
164 {
165  using namespace api;
166  stringstream s;
167  switch (t) {
168  case INTEGER: return int_as_double2string(d);
169  case BITFIELD: return int_as_double2string(d); // TODO: have something to print bitfields in StringTool
170  case STRING: return double_as_string(d);
171  case DOUBLE:
172  case REAL:
173  s << d; return s.str();
174  case IGNORE:
175  default:
176  ASSERT(0 && "Type not known.");
177  }
178  s << d;
179  return s.str();
180 }
181 
182 std::string StringTool::patchTimeForMars(const std::string& ss)
183 {
184  std::string v = ss;
185  if (v.size() == 5) v = std::string("0") + v;
186  if (v.size() == 6)
187  {
188  std::string s = v;
189  v = v.substr(0, 4);
190  Log::debug() << "StringTool::patchTimeForMars: stripping seconds from TIME: '"
191  << s << "' => '" << v << "'" << std::endl;
192  }
193  return v;
194 }
195 
196 bool StringTool::isSelectStatement(const std::string& s) { return StringTool::match("select", eckit::StringTools::lower(eckit::StringTools::trim(s))); }
197 
198 } // namespace odc
199 
subroutine check(status)
std::string trim(const std::string &str)
@ BITFIELD
Definition: ColumnType.h:27
string int_as_double2string(double v)
Definition: ColumnInfo.h:23
ostream & operator<<(std::ostream &s, const std::vector< std::string > &st)
Definition: StringTool.cc:153
Definition: encode.cc:30