LibOFX

ofx_utilities.cpp

Go to the documentation of this file.
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