LibOFX

- Main Page
- Related Pages
- Namespaces
- Data Structures
- Files

- File List
- Globals

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
AppendCharStringtostring
string AppendCharStringtostring(const SGMLApplication::CharString source, string &dest)
Append an OpenSP CharString to an existing C++ STL string.
Definition: ofx_utilities.cpp:83
WARNING
Definition: messages.hh:33
DEBUG4
Definition: messages.hh:29
message_out
int message_out(OfxMsgType error_type, const string message)
Message output function.
Definition: messages.cpp:60
ofxdate_to_time_t
time_t ofxdate_to_time_t(const string ofxdate)
Convert a C++ string containing a time in OFX format to a C time_t.
Definition: ofx_utilities.cpp:108
ofxamount_to_double
double ofxamount_to_double(const string ofxamount)
Convert OFX amount of money to double float.
Definition: ofx_utilities.cpp:205
CharStringtostring
string CharStringtostring(const SGMLApplication::CharString source, string &dest)
Convert OpenSP CharString to a C++ STL string.
Definition: ofx_utilities.cpp:70
ofx_utilities.hh
Various simple functions for type conversion & al.
ERROR
Definition: messages.hh:34
strip_whitespace
string strip_whitespace(const string para_string)
Sanitize a string coming from OpenSP.
Definition: ofx_utilities.cpp:228
messages.hh
Message IO functionality.