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 OS_WIN32
32 # define DIRSEP "\\"
33 #else
34 # define DIRSEP "/"
35 #endif
36 
37 
38 using namespace std;
42 /*ostream &operator<<(ostream &os, SGMLApplication::CharString s)
43  {
44  for (size_t i = 0; i < s.len; i++)
45  {
46  os << ((char *)(s.ptr))[i*sizeof(SGMLApplication::Char)];
47  }
48  return os;
49  }*/
50 
51 /*wostream &operator<<(wostream &os, SGMLApplication::CharString s)
52  {
53  for (size_t i = 0; i < s.len; i++)
54  {//cout<<i;
55  os << wchar_t(s.ptr[i*MULTIPLY4]);
56  }
57  return os;
58  } */
59 
60 /*wchar_t* CharStringtowchar_t(SGMLApplication::CharString source, wchar_t *dest)
61  {
62  size_t i;
63  for (i = 0; i < source.len; i++)
64  {
65  dest[i]+=wchar_t(source.ptr[i*sizeof(SGMLApplication::Char)*(sizeof(char)/sizeof(wchar_t))]);
66  }
67  return dest;
68  }*/
69 
70 string CharStringtostring(const SGMLApplication::CharString source, string &dest)
71 {
72  size_t i;
73  dest.assign("");//Empty the provided string
74  // cout<<"Length: "<<source.len<<"sizeof(Char)"<<sizeof(SGMLApplication::Char)<<endl;
75  for (i = 0; i < source.len; i++)
76  {
77  dest += (char)(((source.ptr)[i]));
78  // cout<<i<<" "<<(char)(((source.ptr)[i]))<<endl;
79  }
80  return dest;
81 }
82 
83 string AppendCharStringtostring(const SGMLApplication::CharString source, string &dest)
84 {
85  size_t i;
86  for (i = 0; i < source.len; i++)
87  {
88  dest += (char)(((source.ptr)[i]));
89  }
90  return dest;
91 }
92 
108 time_t ofxdate_to_time_t(const string ofxdate)
109 {
110  struct tm time;
111  double local_offset; /* in seconds */
112  float ofx_gmt_offset; /* in fractional hours */
113  char timezone[4]; /* Original timezone: the library does not expose this value*/
114  char exact_time_specified = false;
115  char time_zone_specified = false;
116  string ofxdate_whole;
117  time_t temptime;
118 
119  time.tm_isdst = daylight; // initialize dst setting
120  std::time(&temptime);
121  local_offset = difftime(mktime(localtime(&temptime)), mktime(gmtime(&temptime))) + (3600 * daylight);
122 
123  if (ofxdate.size() != 0)
124  {
125  ofxdate_whole = ofxdate.substr(0, ofxdate.find_first_not_of("0123456789"));
126  if (ofxdate_whole.size() >= 8)
127  {
128  time.tm_year = atoi(ofxdate_whole.substr(0, 4).c_str()) - 1900;
129  time.tm_mon = atoi(ofxdate_whole.substr(4, 2).c_str()) - 1;
130  time.tm_mday = atoi(ofxdate_whole.substr(6, 2).c_str());
131 
132  if (ofxdate_whole.size() > 8)
133  {
134  if (ofxdate_whole.size() == 14)
135  {
136  /* if exact time is specified */
137  exact_time_specified = true;
138  time.tm_hour = atoi(ofxdate_whole.substr(8, 2).c_str());
139  time.tm_min = atoi(ofxdate_whole.substr(10, 2).c_str());
140  time.tm_sec = atoi(ofxdate_whole.substr(12, 2).c_str());
141  }
142  else
143  {
144  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!");
145  }
146  }
147 
148  }
149  else
150  {
151  /* Catch invalid string format */
152  message_out(ERROR, "ofxdate_to_time_t(): Unable to convert time, string " + ofxdate + " is not in proper YYYYMMDDHHMMSS.XXX[gmt offset:tz name] format!");
153  return mktime(&time);
154  }
155 
156 
157  /* Check if the timezone has been specified */
158  string::size_type startidx = ofxdate.find("[");
159  string::size_type endidx;
160  if (startidx != string::npos)
161  {
162  /* Time zone was specified */
163  time_zone_specified = true;
164  startidx++;
165  endidx = ofxdate.find(":", startidx) - 1;
166  ofx_gmt_offset = atof(ofxdate.substr(startidx, (endidx - startidx) + 1).c_str());
167  startidx = endidx + 2;
168  strncpy(timezone, ofxdate.substr(startidx, 3).c_str(), 4);
169  }
170  else
171  {
172  /* Time zone was not specified, assume GMT (provisionnaly) in case exact time is specified */
173  ofx_gmt_offset = 0;
174  strcpy(timezone, "GMT");
175  }
176 
177  if (time_zone_specified == true)
178  {
179  /* If the timezone is specified always correct the timezone */
180  /* If the timezone is not specified, but the exact time is, correct the timezone, assuming GMT following the spec */
181  /* Correct the time for the timezone */
182  time.tm_sec = time.tm_sec + (int)(local_offset - (ofx_gmt_offset * 60 * 60)); //Convert from fractionnal hours to seconds
183  }
184  else if (exact_time_specified == false)
185  {
186  /*Time zone data missing and exact time not specified, diverge from the OFX spec ans assume 11h59 local time */
187  time.tm_hour = 11;
188  time.tm_min = 59;
189  time.tm_sec = 0;
190  }
191  return mktime(&time);
192  }
193  else
194  {
195  message_out(ERROR, "ofxdate_to_time_t(): Unable to convert time, string is 0 length!");
196  return 0; // MUST RETURN ZERO here because otherwise the uninitialized &time will be returned!
197  }
198  return mktime(&time);
199 }
200 
205 double ofxamount_to_double(const string ofxamount)
206 {
207  //Replace commas and decimal points for atof()
208  string::size_type idx;
209  string tmp = ofxamount;
210 
211  idx = tmp.find(',');
212  if (idx == string::npos)
213  {
214  idx = tmp.find('.');
215  }
216 
217  if (idx != string::npos)
218  {
219  tmp.replace(idx, 1, 1, ((localeconv())->decimal_point)[0]);
220  }
221 
222  return atof(tmp.c_str());
223 }
224 
228 string strip_whitespace(const string para_string)
229 {
230  size_t index;
231  size_t i;
232  string temp_string = para_string;
233  if (temp_string.empty())
234  return temp_string; // so that size()-1 is allowed below
235 
236  const char *whitespace = " \b\f\n\r\t\v";
237  const char *abnormal_whitespace = "\b\f\n\r\t\v";//backspace,formfeed,newline,cariage return, horizontal and vertical tabs
238  message_out(DEBUG4, "strip_whitespace() Before: |" + temp_string + "|");
239 
240  for (i = 0;
241  i <= temp_string.size()
242  && temp_string.find_first_of(whitespace, i) == i
243  && temp_string.find_first_of(whitespace, i) != string::npos;
244  i++);
245  temp_string.erase(0, i); //Strip leading whitespace
246 
247  for (i = temp_string.size() - 1;
248  (i > 0)
249  && (temp_string.find_last_of(whitespace, i) == i)
250  && (temp_string.find_last_of(whitespace, i) != string::npos);
251  i--);
252  temp_string.erase(i + 1, temp_string.size() - (i + 1)); //Strip trailing whitespace
253 
254  while ((index = temp_string.find_first_of(abnormal_whitespace)) != string::npos)
255  {
256  temp_string.erase(index, 1); //Strip leading whitespace
257  };
258 
259  message_out(DEBUG4, "strip_whitespace() After: |" + temp_string + "|");
260 
261  return temp_string;
262 }
263 
264 
265 std::string get_tmp_dir()
266 {
267  // Tries to mimic the behaviour of
268  // http://developer.gnome.org/doc/API/2.0/glib/glib-Miscellaneous-Utility-Functions.html#g-get-tmp-dir
269  char *var;
270  var = getenv("TMPDIR");
271  if (var) return var;
272  var = getenv("TMP");
273  if (var) return var;
274  var = getenv("TEMP");
275  if (var) return var;
276 #ifdef OS_WIN32
277  return "C:\\";
278 #else
279  return "/tmp";
280 #endif
281 }
282 
283 int mkTempFileName(const char *tmpl, char *buffer, unsigned int size)
284 {
285 
286  std::string tmp_dir = get_tmp_dir();
287 
288  strncpy(buffer, tmp_dir.c_str(), size);
289  assert((strlen(buffer) + strlen(tmpl) + 2) < size);
290  strcat(buffer, DIRSEP);
291  strcat(buffer, tmpl);
292  return 0;
293 }
294 
295 
296 
string AppendCharStringtostring(const SGMLApplication::CharString source, string &dest)
Append an OpenSP CharString to an existing C++ STL string.
int message_out(OfxMsgType error_type, const string message)
Message output function.
Definition: messages.cpp:60
time_t ofxdate_to_time_t(const string ofxdate)
Convert a C++ string containing a time in OFX format to a C time_t.
double ofxamount_to_double(const string ofxamount)
Convert OFX amount of money to double float.
string CharStringtostring(const SGMLApplication::CharString source, string &dest)
Convert OpenSP CharString to a C++ STL string.
Various simple functions for type conversion & al.
string strip_whitespace(const string para_string)
Sanitize a string coming from OpenSP.
Message IO functionality.