LibOFX
ofx_utilities.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  ofx_util.cpp
3  -------------------
4  copyright : (C) 2002 by Benoit Gr�goire
5  email : benoitg@coeus.ca
6  ***************************************************************************/
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 #include <config.h>
19 #include <iostream>
20 #include <assert.h>
21 
22 #include "ParserEventGeneratorKit.h"
23 #include "SGMLApplication.h"
24 #include <ctime>
25 #include <cstdlib>
26 #include <string>
27 #include <locale.h>
28 #include "messages.hh"
29 #include "ofx_utilities.hh"
30 
31 #ifdef _WIN32
32 # define DIRSEP "\\"
33 /* MSWin calls it _mkgmtime instead of timegm */
34 # define timegm(tm) _mkgmtime(tm)
35 #else
36 # define DIRSEP "/"
37 #endif
38 
39 
40 std::string CharStringtostring(const SGMLApplication::CharString source)
41 {
42  // The CharString type might have multi-byte characters if SP_MULTI_BYTE was defined
43  std::string result;
44  result.resize(source.len);
45  for (size_t i = 0; i < source.len; i++)
46  {
47  result[i] = static_cast<char>(source.ptr[i]);
48  }
49  return result;
50 }
51 
52 void AppendCharStringtostring(const SGMLApplication::CharString source, std::string &dest)
53 {
54  const std::string toBeAppended = CharStringtostring(source);
55  dest.append(toBeAppended);
56 }
57 
68  time_t ofxdate_to_time_t(const std::string& ofxdate)
69 {
70  if (ofxdate.empty())
71  {
72  message_out(ERROR, "ofxdate_to_time_t(): Unable to convert time, string is 0 length!");
73  return 0;
74  }
75  std::string ofxdate_whole =
76  ofxdate.substr(0, ofxdate.find_first_not_of("0123456789"));
77 
78  if (ofxdate_whole.size() < 8)
79  {
80  message_out(ERROR, "ofxdate_to_time_t(): Unable to convert time, string " + ofxdate + " is not in proper YYYYMMDDHHMMSS.XXX[gmt offset:tz name] format!");
81  return std::time(NULL);
82  }
83 
84  struct tm time;
85  memset(&time, 0, sizeof(tm));
86  time.tm_year = atoi(ofxdate_whole.substr(0, 4).c_str()) - 1900;
87  time.tm_mon = atoi(ofxdate_whole.substr(4, 2).c_str()) - 1;
88  time.tm_mday = atoi(ofxdate_whole.substr(6, 2).c_str());
89 
90  if (ofxdate_whole.size() < 14)
91  {
92  message_out(WARNING, "ofxdate_to_time_t(): Successfully parsed date part, but unable to parse time part of string " + ofxdate_whole + ". It is not in proper YYYYMMDDHHMMSS.XXX[gmt offset:tz name] format!");
93  }
94  else
95  {
96  time.tm_hour = atoi(ofxdate_whole.substr(8, 2).c_str());
97  time.tm_min = atoi(ofxdate_whole.substr(10, 2).c_str());
98  time.tm_sec = atoi(ofxdate_whole.substr(12, 2).c_str());
99  }
100 
101  if (time.tm_hour + time.tm_min + time.tm_sec == 0)
102  {
103  time.tm_hour = 10;
104  time.tm_min = 59;
105  time.tm_sec = 0;
106  return timegm(&time);
107  }
108 
109  std::string::size_type startidx = ofxdate.find("[");
110  if (startidx != std::string::npos)
111  {
112  startidx++;
113  std::string::size_type endidx = ofxdate.find(":", startidx) - 1;
114  std::string offset_str = ofxdate.substr(startidx, (endidx - startidx) + 1);
115  float ofx_gmt_offset = atof(offset_str.c_str());
116  std::time_t temptime = std::time(nullptr);
117  static const double secs_per_hour = 3600.0;
118  time.tm_sec -= static_cast<int>(ofx_gmt_offset * secs_per_hour);
119  return timegm(&time);
120  }
121 
122  /* No timezone, assume GMT */
123  return timegm(&time);
124 }
125 
130 double ofxamount_to_double(const std::string ofxamount)
131 {
132  //Replace commas and decimal points for atof()
133  std::string::size_type idx;
134  std::string tmp = ofxamount;
135 
136  idx = tmp.find(',');
137  if (idx == std::string::npos)
138  {
139  idx = tmp.find('.');
140  }
141 
142  if (idx != std::string::npos)
143  {
144  tmp.replace(idx, 1, 1, ((localeconv())->decimal_point)[0]);
145  }
146 
147  return atof(tmp.c_str());
148 }
149 
153 std::string strip_whitespace(const std::string para_string)
154 {
155  size_t index;
156  size_t i;
157  std::string temp_string = para_string;
158  if (temp_string.empty())
159  return temp_string; // so that size()-1 is allowed below
160 
161  const char *whitespace = " \b\f\n\r\t\v";
162  const char *abnormal_whitespace = "\b\f\n\r\t\v";//backspace,formfeed,newline,carriage return, horizontal and vertical tabs
163  message_out(DEBUG4, "strip_whitespace() Before: |" + temp_string + "|");
164 
165  for (i = 0;
166  i <= temp_string.size()
167  && temp_string.find_first_of(whitespace, i) == i
168  && temp_string.find_first_of(whitespace, i) != std::string::npos;
169  i++);
170  temp_string.erase(0, i); //Strip leading whitespace
171 
172  for (i = temp_string.size() - 1;
173  (i > 0)
174  && (temp_string.find_last_of(whitespace, i) == i)
175  && (temp_string.find_last_of(whitespace, i) != std::string::npos);
176  i--);
177  temp_string.erase(i + 1, temp_string.size() - (i + 1)); //Strip trailing whitespace
178 
179  while ((index = temp_string.find_first_of(abnormal_whitespace)) != std::string::npos)
180  {
181  temp_string.erase(index, 1); //Strip leading whitespace
182  };
183 
184  message_out(DEBUG4, "strip_whitespace() After: |" + temp_string + "|");
185 
186  return temp_string;
187 }
188 
189 
190 std::string get_tmp_dir()
191 {
192  // Tries to mimic the behaviour of
193  // http://developer.gnome.org/doc/API/2.0/glib/glib-Miscellaneous-Utility-Functions.html#g-get-tmp-dir
194  char *var;
195  var = getenv("TMPDIR");
196  if (var) return var;
197  var = getenv("TMP");
198  if (var) return var;
199  var = getenv("TEMP");
200  if (var) return var;
201 #ifdef _WIN32
202  return "C:\\";
203 #else
204  return "/tmp";
205 #endif
206 }
207 
208 int mkTempFileName(const char *tmpl, char *buffer, unsigned int size)
209 {
210 
211  std::string tmp_dir = get_tmp_dir();
212 
213  strncpy(buffer, tmp_dir.c_str(), size);
214  assert((strlen(buffer) + strlen(tmpl) + 2) < size);
215  strcat(buffer, DIRSEP);
216  strcat(buffer, tmpl);
217  return 0;
218 }
219 
220 
221 
strip_whitespace
std::string strip_whitespace(const std::string para_string)
Sanitize a string coming from OpenSP.
Definition: ofx_utilities.cpp:153
ERROR
@ ERROR
Definition: messages.hh:41
ofx_utilities.hh
Various simple functions for type conversion & al.
ofxamount_to_double
double ofxamount_to_double(const std::string ofxamount)
Convert OFX amount of money to double float.
Definition: ofx_utilities.cpp:130
message_out
int message_out(OfxMsgType error_type, const std::string message)
Message output function.
Definition: messages.cpp:67
ofxdate_to_time_t
time_t ofxdate_to_time_t(const std::string &ofxdate)
Convert a C++ string containing a time in OFX format to a C time_t.
Definition: ofx_utilities.cpp:68
AppendCharStringtostring
void AppendCharStringtostring(const SGMLApplication::CharString source, std::string &dest)
Append an OpenSP CharString to an existing C++ STL string.
Definition: ofx_utilities.cpp:52
WARNING
@ WARNING
Definition: messages.hh:40
messages.hh
Message IO functionality.
CharStringtostring
std::string CharStringtostring(const SGMLApplication::CharString source)
Convert OpenSP CharString to a C++ STL string.
Definition: ofx_utilities.cpp:40
DEBUG4
@ DEBUG4
Definition: messages.hh:36