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