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 
43 /*ostream &operator<<(ostream &os, SGMLApplication::CharString s)
44  {
45  for (size_t i = 0; i < s.len; i++)
46  {
47  os << ((char *)(s.ptr))[i*sizeof(SGMLApplication::Char)];
48  }
49  return os;
50  }*/
51 
52 /*wostream &operator<<(wostream &os, SGMLApplication::CharString s)
53  {
54  for (size_t i = 0; i < s.len; i++)
55  {//cout<<i;
56  os << wchar_t(s.ptr[i*MULTIPLY4]);
57  }
58  return os;
59  } */
60 
61 /*wchar_t* CharStringtowchar_t(SGMLApplication::CharString source, wchar_t *dest)
62  {
63  size_t i;
64  for (i = 0; i < source.len; i++)
65  {
66  dest[i]+=wchar_t(source.ptr[i*sizeof(SGMLApplication::Char)*(sizeof(char)/sizeof(wchar_t))]);
67  }
68  return dest;
69  }*/
70 
71 std::string CharStringtostring(const SGMLApplication::CharString source, std::string &dest)
72 {
73  size_t i;
74  dest.assign("");//Empty the provided string
75  // cout<<"Length: "<<source.len<<"sizeof(Char)"<<sizeof(SGMLApplication::Char)<<endl;
76  for (i = 0; i < source.len; i++)
77  {
78  dest += (char)(((source.ptr)[i]));
79  // cout<<i<<" "<<(char)(((source.ptr)[i]))<<endl;
80  }
81  return dest;
82 }
83 
84 std::string AppendCharStringtostring(const SGMLApplication::CharString source, std::string &dest)
85 {
86  size_t i;
87  for (i = 0; i < source.len; i++)
88  {
89  dest += (char)(((source.ptr)[i]));
90  }
91  return dest;
92 }
93 
104  time_t ofxdate_to_time_t(const std::string& ofxdate)
105 {
106  if (ofxdate.empty())
107  {
108  message_out(ERROR, "ofxdate_to_time_t(): Unable to convert time, string is 0 length!");
109  return 0;
110  }
111  std::string ofxdate_whole =
112  ofxdate.substr(0, ofxdate.find_first_not_of("0123456789"));
113 
114  if (ofxdate_whole.size() < 8)
115  {
116  message_out(ERROR, "ofxdate_to_time_t(): Unable to convert time, string " + ofxdate + " is not in proper YYYYMMDDHHMMSS.XXX[gmt offset:tz name] format!");
117  return std::time(NULL);
118  }
119 
120  struct tm time;
121  memset(&time, 0, sizeof(tm));
122  time.tm_year = atoi(ofxdate_whole.substr(0, 4).c_str()) - 1900;
123  time.tm_mon = atoi(ofxdate_whole.substr(4, 2).c_str()) - 1;
124  time.tm_mday = atoi(ofxdate_whole.substr(6, 2).c_str());
125 
126  if (ofxdate_whole.size() < 14)
127  {
128  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!");
129  }
130  else
131  {
132  time.tm_hour = atoi(ofxdate_whole.substr(8, 2).c_str());
133  time.tm_min = atoi(ofxdate_whole.substr(10, 2).c_str());
134  time.tm_sec = atoi(ofxdate_whole.substr(12, 2).c_str());
135  }
136 
137  if (time.tm_hour + time.tm_min + time.tm_sec == 0)
138  {
139  time.tm_hour = 10;
140  time.tm_min = 59;
141  time.tm_sec = 0;
142  return timegm(&time);
143  }
144 
145  std::string::size_type startidx = ofxdate.find("[");
146  if (startidx != std::string::npos)
147  {
148  startidx++;
149  std::string::size_type endidx = ofxdate.find(":", startidx) - 1;
150  std::string offset_str = ofxdate.substr(startidx, (endidx - startidx) + 1);
151  float ofx_gmt_offset = atof(offset_str.c_str());
152  std::time_t temptime = std::time(nullptr);
153  static const double secs_per_hour = 3600.0;
154  time.tm_sec -= static_cast<int>(ofx_gmt_offset * secs_per_hour);
155  return timegm(&time);
156  }
157 
158  /* No timezone, assume GMT */
159  return timegm(&time);
160 }
161 
166 double ofxamount_to_double(const std::string ofxamount)
167 {
168  //Replace commas and decimal points for atof()
169  std::string::size_type idx;
170  std::string tmp = ofxamount;
171 
172  idx = tmp.find(',');
173  if (idx == std::string::npos)
174  {
175  idx = tmp.find('.');
176  }
177 
178  if (idx != std::string::npos)
179  {
180  tmp.replace(idx, 1, 1, ((localeconv())->decimal_point)[0]);
181  }
182 
183  return atof(tmp.c_str());
184 }
185 
189 std::string strip_whitespace(const std::string para_string)
190 {
191  size_t index;
192  size_t i;
193  std::string temp_string = para_string;
194  if (temp_string.empty())
195  return temp_string; // so that size()-1 is allowed below
196 
197  const char *whitespace = " \b\f\n\r\t\v";
198  const char *abnormal_whitespace = "\b\f\n\r\t\v";//backspace,formfeed,newline,carriage return, horizontal and vertical tabs
199  message_out(DEBUG4, "strip_whitespace() Before: |" + temp_string + "|");
200 
201  for (i = 0;
202  i <= temp_string.size()
203  && temp_string.find_first_of(whitespace, i) == i
204  && temp_string.find_first_of(whitespace, i) != std::string::npos;
205  i++);
206  temp_string.erase(0, i); //Strip leading whitespace
207 
208  for (i = temp_string.size() - 1;
209  (i > 0)
210  && (temp_string.find_last_of(whitespace, i) == i)
211  && (temp_string.find_last_of(whitespace, i) != std::string::npos);
212  i--);
213  temp_string.erase(i + 1, temp_string.size() - (i + 1)); //Strip trailing whitespace
214 
215  while ((index = temp_string.find_first_of(abnormal_whitespace)) != std::string::npos)
216  {
217  temp_string.erase(index, 1); //Strip leading whitespace
218  };
219 
220  message_out(DEBUG4, "strip_whitespace() After: |" + temp_string + "|");
221 
222  return temp_string;
223 }
224 
225 
226 std::string get_tmp_dir()
227 {
228  // Tries to mimic the behaviour of
229  // http://developer.gnome.org/doc/API/2.0/glib/glib-Miscellaneous-Utility-Functions.html#g-get-tmp-dir
230  char *var;
231  var = getenv("TMPDIR");
232  if (var) return var;
233  var = getenv("TMP");
234  if (var) return var;
235  var = getenv("TEMP");
236  if (var) return var;
237 #ifdef __WIN32__
238  return "C:\\";
239 #else
240  return "/tmp";
241 #endif
242 }
243 
244 int mkTempFileName(const char *tmpl, char *buffer, unsigned int size)
245 {
246 
247  std::string tmp_dir = get_tmp_dir();
248 
249  strncpy(buffer, tmp_dir.c_str(), size);
250  assert((strlen(buffer) + strlen(tmpl) + 2) < size);
251  strcat(buffer, DIRSEP);
252  strcat(buffer, tmpl);
253  return 0;
254 }
255 
256 
257 
int message_out(OfxMsgType error_type, const std::string message)
Message output function.
Definition: messages.cpp:61
Message IO functionality.
@ ERROR
Definition: messages.hh:34
@ WARNING
Definition: messages.hh:33
@ DEBUG4
Definition: messages.hh:29
std::string CharStringtostring(const SGMLApplication::CharString source, std::string &dest)
Convert OpenSP CharString to a C++ STL string.
std::string AppendCharStringtostring(const SGMLApplication::CharString source, std::string &dest)
Append an OpenSP CharString to an existing C++ STL string.
std::string strip_whitespace(const std::string para_string)
Sanitize a string coming from OpenSP.
double ofxamount_to_double(const std::string ofxamount)
Convert OFX amount of money to double float.
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.
Various simple functions for type conversion & al.