LibOFX
|
00001 /*************************************************************************** 00002 ofx_util.cpp 00003 ------------------- 00004 copyright : (C) 2002 by Benoit Gr�goire 00005 email : benoitg@coeus.ca 00006 ***************************************************************************/ 00010 /*************************************************************************** 00011 * * 00012 * This program is free software; you can redistribute it and/or modify * 00013 * it under the terms of the GNU General Public License as published by * 00014 * the Free Software Foundation; either version 2 of the License, or * 00015 * (at your option) any later version. * 00016 * * 00017 ***************************************************************************/ 00018 #include <config.h> 00019 #include <iostream> 00020 #include <assert.h> 00021 00022 #include "ParserEventGeneratorKit.h" 00023 #include "SGMLApplication.h" 00024 #include <ctime> 00025 #include <cstdlib> 00026 #include <string> 00027 #include <locale.h> 00028 #include "messages.hh" 00029 #include "ofx_utilities.hh" 00030 00031 #ifdef OS_WIN32 00032 # define DIRSEP "\\" 00033 #else 00034 # define DIRSEP "/" 00035 #endif 00036 00037 00038 using namespace std; 00042 /*ostream &operator<<(ostream &os, SGMLApplication::CharString s) 00043 { 00044 for (size_t i = 0; i < s.len; i++) 00045 { 00046 os << ((char *)(s.ptr))[i*sizeof(SGMLApplication::Char)]; 00047 } 00048 return os; 00049 }*/ 00050 00051 /*wostream &operator<<(wostream &os, SGMLApplication::CharString s) 00052 { 00053 for (size_t i = 0; i < s.len; i++) 00054 {//cout<<i; 00055 os << wchar_t(s.ptr[i*MULTIPLY4]); 00056 } 00057 return os; 00058 } */ 00059 00060 /*wchar_t* CharStringtowchar_t(SGMLApplication::CharString source, wchar_t *dest) 00061 { 00062 size_t i; 00063 for (i = 0; i < source.len; i++) 00064 { 00065 dest[i]+=wchar_t(source.ptr[i*sizeof(SGMLApplication::Char)*(sizeof(char)/sizeof(wchar_t))]); 00066 } 00067 return dest; 00068 }*/ 00069 00070 string CharStringtostring(const SGMLApplication::CharString source, string &dest) 00071 { 00072 size_t i; 00073 dest.assign("");//Empty the provided string 00074 // cout<<"Length: "<<source.len<<"sizeof(Char)"<<sizeof(SGMLApplication::Char)<<endl; 00075 for (i = 0; i < source.len; i++) 00076 { 00077 dest += (char)(((source.ptr)[i])); 00078 // cout<<i<<" "<<(char)(((source.ptr)[i]))<<endl; 00079 } 00080 return dest; 00081 } 00082 00083 string AppendCharStringtostring(const SGMLApplication::CharString source, string &dest) 00084 { 00085 size_t i; 00086 for (i = 0; i < source.len; i++) 00087 { 00088 dest += (char)(((source.ptr)[i])); 00089 } 00090 return dest; 00091 } 00092 00108 time_t ofxdate_to_time_t(const string ofxdate) 00109 { 00110 struct tm time; 00111 double local_offset; /* in seconds */ 00112 float ofx_gmt_offset; /* in fractional hours */ 00113 char timezone[4]; /* Original timezone: the library does not expose this value*/ 00114 char exact_time_specified = false; 00115 char time_zone_specified = false; 00116 string ofxdate_whole; 00117 time_t temptime; 00118 00119 time.tm_isdst = daylight; // initialize dst setting 00120 std::time(&temptime); 00121 local_offset = difftime(mktime(localtime(&temptime)), mktime(gmtime(&temptime))) + (3600 * daylight); 00122 00123 if (ofxdate.size() != 0) 00124 { 00125 ofxdate_whole = ofxdate.substr(0,ofxdate.find_first_not_of("0123456789")); 00126 if (ofxdate_whole.size()>=8) 00127 { 00128 time.tm_year = atoi(ofxdate_whole.substr(0, 4).c_str()) - 1900; 00129 time.tm_mon = atoi(ofxdate_whole.substr(4, 2).c_str()) - 1; 00130 time.tm_mday = atoi(ofxdate_whole.substr(6, 2).c_str()); 00131 00132 if (ofxdate_whole.size() > 8) 00133 { 00134 if (ofxdate_whole.size() == 14) 00135 { 00136 /* if exact time is specified */ 00137 exact_time_specified = true; 00138 time.tm_hour = atoi(ofxdate_whole.substr(8, 2).c_str()); 00139 time.tm_min = atoi(ofxdate_whole.substr(10, 2).c_str()); 00140 time.tm_sec = atoi(ofxdate_whole.substr(12, 2).c_str()); 00141 } 00142 else 00143 { 00144 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!"); 00145 } 00146 } 00147 00148 } 00149 else 00150 { 00151 /* Catch invalid string format */ 00152 message_out(ERROR, "ofxdate_to_time_t(): Unable to convert time, string " + ofxdate + " is not in proper YYYYMMDDHHMMSS.XXX[gmt offset:tz name] format!"); 00153 return mktime(&time); 00154 } 00155 00156 00157 /* Check if the timezone has been specified */ 00158 string::size_type startidx = ofxdate.find("["); 00159 string::size_type endidx; 00160 if (startidx != string::npos) 00161 { 00162 /* Time zone was specified */ 00163 time_zone_specified = true; 00164 startidx++; 00165 endidx = ofxdate.find(":", startidx) - 1; 00166 ofx_gmt_offset = atof(ofxdate.substr(startidx, (endidx - startidx) + 1).c_str()); 00167 startidx = endidx + 2; 00168 strncpy(timezone, ofxdate.substr(startidx, 3).c_str(), 4); 00169 } 00170 else 00171 { 00172 /* Time zone was not specified, assume GMT (provisionnaly) in case exact time is specified */ 00173 ofx_gmt_offset = 0; 00174 strcpy(timezone, "GMT"); 00175 } 00176 00177 if (time_zone_specified == true) 00178 { 00179 /* If the timezone is specified always correct the timezone */ 00180 /* If the timezone is not specified, but the exact time is, correct the timezone, assuming GMT following the spec */ 00181 /* Correct the time for the timezone */ 00182 time.tm_sec = time.tm_sec + (int)(local_offset - (ofx_gmt_offset * 60 * 60)); //Convert from fractionnal hours to seconds 00183 } 00184 else if (exact_time_specified == false) 00185 { 00186 /*Time zone data missing and exact time not specified, diverge from the OFX spec ans assume 11h59 local time */ 00187 time.tm_hour = 11; 00188 time.tm_min = 59; 00189 time.tm_sec = 0; 00190 } 00191 return mktime(&time); 00192 } 00193 else 00194 { 00195 message_out(ERROR, "ofxdate_to_time_t(): Unable to convert time, string is 0 length!"); 00196 } 00197 return mktime(&time); 00198 } 00199 00204 double ofxamount_to_double(const string ofxamount) 00205 { 00206 //Replace commas and decimal points for atof() 00207 string::size_type idx; 00208 string tmp = ofxamount; 00209 00210 idx = tmp.find(','); 00211 if (idx == string::npos) 00212 { 00213 idx = tmp.find('.'); 00214 } 00215 00216 if (idx != string::npos) 00217 { 00218 tmp.replace(idx, 1, 1, ((localeconv())->decimal_point)[0]); 00219 } 00220 00221 return atof(tmp.c_str()); 00222 } 00223 00227 string strip_whitespace(const string para_string) 00228 { 00229 size_t index; 00230 size_t i; 00231 string temp_string = para_string; 00232 const char *whitespace = " \b\f\n\r\t\v"; 00233 const char *abnormal_whitespace = "\b\f\n\r\t\v";//backspace,formfeed,newline,cariage return, horizontal and vertical tabs 00234 message_out(DEBUG4, "strip_whitespace() Before: |" + temp_string + "|"); 00235 for (i = 0; i <= temp_string.size() && temp_string.find_first_of(whitespace, i) == i && temp_string.find_first_of(whitespace, i) != string::npos; i++); 00236 temp_string.erase(0, i); //Strip leading whitespace 00237 for (i = temp_string.size() - 1; (i >= 0) && (temp_string.find_last_of(whitespace, i) == i) && (temp_string.find_last_of(whitespace, i) != string::npos); i--); 00238 temp_string.erase(i + 1, temp_string.size() - (i + 1)); //Strip trailing whitespace 00239 00240 while ((index = temp_string.find_first_of(abnormal_whitespace)) != string::npos) 00241 { 00242 temp_string.erase(index, 1); //Strip leading whitespace 00243 }; 00244 00245 message_out(DEBUG4, "strip_whitespace() After: |" + temp_string + "|"); 00246 00247 return temp_string; 00248 } 00249 00250 00251 std::string get_tmp_dir() 00252 { 00253 // Tries to mimic the behaviour of 00254 // http://developer.gnome.org/doc/API/2.0/glib/glib-Miscellaneous-Utility-Functions.html#g-get-tmp-dir 00255 char *var; 00256 var = getenv("TMPDIR"); 00257 if (var) return var; 00258 var = getenv("TMP"); 00259 if (var) return var; 00260 var = getenv("TEMP"); 00261 if (var) return var; 00262 #ifdef OS_WIN32 00263 return "C:\\"; 00264 #else 00265 return "/tmp"; 00266 #endif 00267 } 00268 00269 int mkTempFileName(const char *tmpl, char *buffer, unsigned int size) 00270 { 00271 00272 std::string tmp_dir = get_tmp_dir(); 00273 00274 strncpy(buffer, tmp_dir.c_str(), size); 00275 assert((strlen(buffer) + strlen(tmpl) + 2) < size); 00276 strcat(buffer, DIRSEP); 00277 strcat(buffer, tmpl); 00278 return 0; 00279 } 00280 00281 00282