fix8  version 1.4.0
Open Source C++ FIX Framework
f8utils.cpp
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------------------
2 /*
3 
4 Fix8 is released under the GNU LESSER GENERAL PUBLIC LICENSE Version 3.
5 
6 Fix8 Open Source FIX Engine.
7 Copyright (C) 2010-16 David L. Dight <fix@fix8.org>
8 
9 Fix8 is free software: you can redistribute it and / or modify it under the terms of the
10 GNU Lesser General Public License as published by the Free Software Foundation, either
11 version 3 of the License, or (at your option) any later version.
12 
13 Fix8 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
14 even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 
16 You should have received a copy of the GNU Lesser General Public License along with Fix8.
17 If not, see <http://www.gnu.org/licenses/>.
18 
19 BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO
20 THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE
21 COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY
22 KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO
24 THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE,
25 YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
26 
27 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT
28 HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED
29 ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
30 CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
31 NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR
32 THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH
33 HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
34 
35 */
36 //-----------------------------------------------------------------------------------------
37 #include "precomp.hpp"
38 #include <fix8/f8includes.hpp>
39 
40 //----------------------------------------------------------------------------------------
41 #ifndef FIX8_HAVE_GMTOFF
42 extern long timezone;
43 #endif
44 
45 //-----------------------------------------------------------------------------------------
46 using namespace std;
47 
48 namespace FIX8 {
49 
50 //-------------------------------------------------------------------------------------------------
51 const string& GetTimeAsStringMS(string& result, const Tickval *tv, const unsigned dplaces, bool use_gm)
52 {
53  const Tickval *startTime;
54  Tickval gotTime;
55  if (tv)
56  startTime = tv;
57  else
58  {
59  gotTime.now();
60  startTime = &gotTime;
61  }
62 
63 #ifdef _MSC_VER
64  time_t tval(startTime->secs());
65  struct tm *ptim(use_gm ? gmtime(&tval) : localtime (&tval));
66 #else
67  struct tm tim, *ptim;
68  time_t tval(startTime->secs());
69  use_gm ? gmtime_r(&tval, &tim) : localtime_r(&tval, &tim);
70  ptim = &tim;
71 #endif
72 
73  // 2014-07-02 23:15:51.514776595
74  ostringstream oss;
75  oss << setfill('0') << setw(4) << (ptim->tm_year + 1900) << '-';
76  oss << setw(2) << (ptim->tm_mon + 1) << '-' << setw(2) << ptim->tm_mday << ' ' << setw(2) << ptim->tm_hour;
77  oss << ':' << setw(2) << ptim->tm_min << ':';
78  if (dplaces)
79  {
80  const double secs((startTime->secs() % 60) + static_cast<double>(startTime->nsecs()) / Tickval::billion);
81  oss.setf(ios::showpoint);
82  oss.setf(ios::fixed);
83  oss << setw(3 + dplaces) << setfill('0') << setprecision(dplaces) << secs;
84  }
85  else
86  oss << setfill('0') << setw(2) << ptim->tm_sec;
87  return result = oss.str();
88 }
89 
90 //-------------------------------------------------------------------------------------------------
91 const string& GetTimeAsStringMini(string& result, const Tickval *tv)
92 {
93  const Tickval *startTime;
94  Tickval gotTime;
95  if (tv)
96  startTime = tv;
97  else
98  {
99  gotTime.now();
100  startTime = &gotTime;
101  }
102 
103 #ifdef _MSC_VER
104  time_t tval(startTime->secs());
105  struct tm *ptim(localtime (&tval));
106 #else
107  struct tm tim, *ptim;
108  time_t tval(startTime->secs());
109  localtime_r(&tval, &tim);
110  ptim = &tim;
111 #endif
112 
113 // 14-07-02 23:15:51
114  ostringstream oss;
115  oss << setfill('0') << setw(2) << ((ptim->tm_year + 1900) % 100) << '-';
116  oss << setw(2) << (ptim->tm_mon + 1) << '-' << setw(2) << ptim->tm_mday << ' ' << setw(2) << ptim->tm_hour;
117  oss << ':' << setw(2) << ptim->tm_min << ':' << setfill('0') << setw(2) << ptim->tm_sec;
118  return result = oss.str();
119 }
120 
121 //-------------------------------------------------------------------------------------------------
122 string& CheckAddTrailingSlash(string& src)
123 {
124  if (!src.empty() && *src.rbegin() != '/')
125  src += '/';
126  return src;
127 }
128 
129 //-----------------------------------------------------------------------------------------
130 string& InPlaceStrToUpper(string& src)
131 {
132  //for (string::iterator itr(src.begin()); itr != src.end(); ++itr)
133  for (auto& itr : src)
134  if (islower(itr))
135  itr = toupper(itr);
136  return src;
137 }
138 
139 //-----------------------------------------------------------------------------------------
140 string& InPlaceReplaceInSet(const string& iset, string& src, const char repl)
141 {
142  for (string::iterator itr(src.begin()); itr != src.end(); ++itr)
143  if (iset.find(*itr) == string::npos)
144  *itr = repl;
145  return src;
146 }
147 
148 //-----------------------------------------------------------------------------------------
149 string& InPlaceStrToLower(string& src)
150 {
151  for (auto& itr : src)
152  if (isupper(itr))
153  itr = tolower(itr);
154  return src;
155 }
156 
157 //-----------------------------------------------------------------------------------------
158 string StrToLower(const string& src)
159 {
160  string result(src);
161  return InPlaceStrToLower(result);
162 }
163 
164 //----------------------------------------------------------------------------------------
165 string Str_error(const int err, const char *str)
166 {
167  const size_t max_str(256);
168  char buf[max_str] {};
169 #ifdef _MSC_VER
170  ignore_value(strerror_s(buf, max_str - 1, err));
171 #else
172  ignore_value(strerror_r(err, buf, max_str - 1));
173 #endif
174  if (str && *str)
175  {
176  ostringstream ostr;
177  ostr << str << ": " << buf;
178  return ostr.str();
179  }
180  return string(buf);
181 }
182 
183 //----------------------------------------------------------------------------------------
185 {
186 #ifdef _MSC_VER
187  const int mask(_umask(0));
188  _umask(mask);
189 #else
190  const int mask(umask(0));
191  umask(mask);
192 #endif
193  return mask;
194 }
195 
196 //----------------------------------------------------------------------------------------
197 void create_path(const string& path)
198 {
199  string new_path;
200  for(string::const_iterator pos(path.begin()); pos != path.end(); ++pos)
201  {
202  new_path += *pos;
203  if(*pos == '/' || *pos == '\\' || pos + 1 == path.end())
204  {
205 #ifdef _MSC_VER
206  _mkdir(new_path.c_str());
207 #else
208  mkdir(new_path.c_str(), 0777); // umask applied after
209 #endif
210  }
211  }
212 }
213 
214 //----------------------------------------------------------------------------------------
215 namespace
216 {
217  using Day = pair<char, int>;
218  using Daymap = multimap<char, int>;
219  static const string day_names[] { "su", "mo", "tu", "we", "th", "fr", "sa" };
220  static const Day days[] { {'s',0}, {'m',1}, {'t',2}, {'w',3}, {'t',4}, {'f',5}, {'s', 6} };
221  static const Daymap daymap(days, days + sizeof(days)/sizeof(Day));
222 };
223 
224 int decode_dow (const string& from)
225 {
226  if (from.empty())
227  return -1;
228  const string source(StrToLower(from));
229  if (isdigit(source[0]) && source.size() == 1 && source[0] >= '0' && source[0] <= '6') // accept numeric dow
230  return source[0] - '0';
231  pair<Daymap::const_iterator, Daymap::const_iterator> result(daymap.equal_range(source[0]));
232  switch(distance(result.first, result.second))
233  {
234  case 1:
235  return result.first->second;
236  default:
237  if (source.size() == 1) // drop through
238  case 0:
239  return -1;
240  break;
241  }
242  return day_names[result.first->second][1] == source[1]
243  || day_names[(++result.first)->second][1] == source[1] ? result.first->second : -1;
244 }
245 
246 //----------------------------------------------------------------------------------------
248 {
249  //ostr << "Package info for " PACKAGE " version " VERSION;
250  static const Package_info pinfo
251  {
252  { "FIX8_VERSION", FIX8_VERSION },
253  { "FIX8_PACKAGE", FIX8_PACKAGE },
254 #if defined FIX8_PACKAGE_BUGREPORT
255  { "FIX8_PACKAGE_BUGREPORT", FIX8_PACKAGE_BUGREPORT },
256 #endif
257 #if defined FIX8_PACKAGE_URL
258  { "FIX8_PACKAGE_URL", FIX8_PACKAGE_URL },
259 #endif
260  { "FIX8_MAGIC_NUM", STRINGIFY(FIX8_MAGIC_NUM) },
261  { "FIX8_CONFIGURE_OPTIONS", FIX8_CONFIGURE_OPTIONS },
262  { "FIX8_CPPFLAGS", FIX8_CPPFLAGS },
263  { "FIX8_LIBS", FIX8_LIBS },
264  { "FIX8_LDFLAGS", FIX8_LDFLAGS },
265  { "FIX8_CONFIGURE_SDATE", FIX8_CONFIGURE_SDATE },
266  { "FIX8_CONFIGURE_TIME", FIX8_CONFIGURE_TIME },
267  { "FIX8_MAJOR_VERSION_NUM", STRINGIFY(FIX8_MAJOR_VERSION_NUM) },
268  { "FIX8_MINOR_VERSION_NUM", STRINGIFY(FIX8_MINOR_VERSION_NUM) },
269  { "FIX8_PATCH_VERSION_NUM", STRINGIFY(FIX8_PATCH_VERSION_NUM) },
270  { "FIX8_CONFIGURE_TIME_NUM", STRINGIFY(FIX8_CONFIGURE_TIME_NUM) },
271  { "FIX8_HOST_SYSTEM", FIX8_HOST_SYSTEM },
272  { "FIX8_MAX_FLD_LENGTH", STRINGIFY(FIX8_MAX_FLD_LENGTH) },
273  { "FIX8_MAX_MSG_LENGTH", STRINGIFY(FIX8_MAX_MSG_LENGTH) },
274  { "FIX8_MPMC_FF", STRINGIFY(FIX8_MPMC_FF) },
275  { "FIX8_MPMC_TBB", STRINGIFY(FIX8_MPMC_TBB) },
276  { "FIX8_MPMC_SYSTEM", STRINGIFY(FIX8_MPMC_SYSTEM) },
277  { "FIX8_DEFAULT_PRECISION", STRINGIFY(FIX8_DEFAULT_PRECISION) },
278  { "FIX8_THREAD_PTHREAD", STRINGIFY(FIX8_THREAD_PTHREAD) },
279  { "FIX8_THREAD_STDTHREAD", STRINGIFY(FIX8_THREAD_STDTHREAD) },
280  { "FIX8_THREAD_SYSTEM", STRINGIFY(FIX8_THREAD_SYSTEM) },
281 #if defined FIX8_SLEEP_NO_YIELD
282  { "FIX8_SLEEP_NO_YIELD", STRINGIFY(FIX8_SLEEP_NO_YIELD) },
283 #endif
284 #if defined FIX8_CODECTIMING
285  { "FIX8_CODECTIMING", STRINGIFY(FIX8_CODECTIMING) },
286 #endif
287 #if defined FIX8_HAVE_OPENSSL
288  { "FIX8_HAVE_OPENSSL", STRINGIFY(FIX8_HAVE_OPENSSL) },
289 #endif
290 #if defined FIX8_HAVE_EXTENDED_METADATA
291  { "FIX8_HAVE_EXTENDED_METADATA", STRINGIFY(FIX8_HAVE_EXTENDED_METADATA) },
292 #endif
293 #if defined FIX8_DEBUG
294  { "FIX8_DEBUG", STRINGIFY(FIX8_DEBUG) },
295 #endif
296  };
297 
298  return pinfo;
299 }
300 
302 {
303  auto itr(package_info().find(what));
304  return itr != package_info().cend() ? itr->second : f8String{};
305 }
306 
307 //----------------------------------------------------------------------------------------
308 
309 } // namespace FIX8
310 
#define FIX8_HOST_SYSTEM
Definition: f8config.h:510
const string & GetTimeAsStringMS(string &result, const Tickval *tv, const unsigned dplaces, bool use_gm)
Definition: f8utils.cpp:51
#define STRINGIFY(x)
Definition: f8utils.hpp:67
unsigned nsecs() const
Definition: tickval.hpp:159
#define FIX8_DEFAULT_PRECISION
Definition: f8config.h:99
F8API std::string Str_error(const int err, const char *str=0)
Definition: f8utils.cpp:165
#define FIX8_MAX_FLD_LENGTH
Definition: f8config.h:571
string & InPlaceReplaceInSet(const string &iset, string &src, const char repl)
Definition: f8utils.cpp:140
F8API int get_umask()
Definition: f8utils.cpp:184
int decode_dow(const string &from)
Definition: f8utils.cpp:224
#define FIX8_MINOR_VERSION_NUM
Definition: f8config.h:581
#define FIX8_PACKAGE
Definition: f8config.h:601
#define FIX8_LIBS
Definition: f8config.h:520
string & CheckAddTrailingSlash(string &src)
Definition: f8utils.cpp:122
#define FIX8_PACKAGE_URL
Definition: f8config.h:626
#define FIX8_PATCH_VERSION_NUM
Definition: f8config.h:636
long timezone
#define FIX8_CPPFLAGS
Definition: f8config.h:81
#define FIX8_CONFIGURE_TIME
Definition: f8config.h:71
#define FIX8_PACKAGE_BUGREPORT
Definition: f8config.h:606
#define FIX8_DEBUG
Definition: f8config.h:94
#define FIX8_CONFIGURE_TIME_NUM
Definition: f8config.h:76
#define FIX8_THREAD_SYSTEM
Definition: f8config.h:723
F8API f8String find_package_info_string(const f8String &what)
Definition: f8utils.cpp:301
string & InPlaceStrToLower(string &src)
Definition: f8utils.cpp:149
#define FIX8_THREAD_STDTHREAD
Definition: f8config.h:718
#define FIX8_MPMC_TBB
Definition: f8config.h:596
#define FIX8_MAX_MSG_LENGTH
Definition: f8config.h:576
F8API const Package_info & package_info()
Definition: f8utils.cpp:247
string & InPlaceStrToUpper(string &src)
Definition: f8utils.cpp:130
#define FIX8_CONFIGURE_SDATE
Definition: f8config.h:66
Tickval & now()
Definition: tickval.hpp:133
time_t secs() const
Definition: tickval.hpp:141
#define FIX8_LDFLAGS
Definition: f8config.h:515
#define FIX8_MAJOR_VERSION_NUM
Definition: f8config.h:546
string StrToLower(const string &src)
Definition: f8utils.cpp:158
#define FIX8_VERSION
Definition: f8config.h:742
#define FIX8_MPMC_FF
Definition: f8config.h:586
#define FIX8_MPMC_SYSTEM
Definition: f8config.h:591
const string & GetTimeAsStringMini(string &result, const Tickval *tv)
Definition: f8utils.cpp:91
void ignore_value(T val)
Definition: f8utils.hpp:188
void create_path(const string &path)
Definition: f8utils.cpp:197
#define FIX8_CODECTIMING
Definition: f8config.h:56
std::string f8String
Definition: f8types.hpp:47
#define FIX8_CONFIGURE_OPTIONS
Definition: f8config.h:61
#define FIX8_THREAD_PTHREAD
Definition: f8config.h:713
std::map< f8String, f8String > Package_info
Definition: f8utils.hpp:172
#define FIX8_MAGIC_NUM
Definition: f8config.h:536