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     return 0; // MUST RETURN ZERO here because otherwise the uninitialized &time will be returned!
00197   }
00198   return mktime(&time);
00199 }
00200 
00205 double ofxamount_to_double(const string ofxamount)
00206 {
00207   //Replace commas and decimal points for atof()
00208   string::size_type idx;
00209   string tmp = ofxamount;
00210 
00211   idx = tmp.find(',');
00212   if (idx == string::npos)
00213   {
00214     idx = tmp.find('.');
00215   }
00216 
00217   if (idx != string::npos)
00218   {
00219     tmp.replace(idx, 1, 1, ((localeconv())->decimal_point)[0]);
00220   }
00221 
00222   return atof(tmp.c_str());
00223 }
00224 
00228 string strip_whitespace(const string para_string)
00229 {
00230   size_t index;
00231   size_t i;
00232   string temp_string = para_string;
00233   if (temp_string.empty())
00234     return temp_string; // so that size()-1 is allowed below
00235 
00236   const char *whitespace = " \b\f\n\r\t\v";
00237   const char *abnormal_whitespace = "\b\f\n\r\t\v";//backspace,formfeed,newline,cariage return, horizontal and vertical tabs
00238   message_out(DEBUG4, "strip_whitespace() Before: |" + temp_string + "|");
00239 
00240   for (i = 0;
00241        i <= temp_string.size()
00242        && temp_string.find_first_of(whitespace, i) == i
00243        && temp_string.find_first_of(whitespace, i) != string::npos;
00244        i++);
00245   temp_string.erase(0, i); //Strip leading whitespace
00246 
00247   for (i = temp_string.size() - 1;
00248        (i > 0)
00249        && (temp_string.find_last_of(whitespace, i) == i)
00250        && (temp_string.find_last_of(whitespace, i) != string::npos);
00251        i--);
00252   temp_string.erase(i + 1, temp_string.size() - (i + 1)); //Strip trailing whitespace
00253 
00254   while ((index = temp_string.find_first_of(abnormal_whitespace)) != string::npos)
00255   {
00256     temp_string.erase(index, 1); //Strip leading whitespace
00257   };
00258 
00259   message_out(DEBUG4, "strip_whitespace() After:  |" + temp_string + "|");
00260 
00261   return temp_string;
00262 }
00263 
00264 
00265 std::string get_tmp_dir()
00266 {
00267   // Tries to mimic the behaviour of
00268   // http://developer.gnome.org/doc/API/2.0/glib/glib-Miscellaneous-Utility-Functions.html#g-get-tmp-dir
00269   char *var;
00270   var = getenv("TMPDIR");
00271   if (var) return var;
00272   var = getenv("TMP");
00273   if (var) return var;
00274   var = getenv("TEMP");
00275   if (var) return var;
00276 #ifdef OS_WIN32
00277   return "C:\\";
00278 #else
00279   return "/tmp";
00280 #endif
00281 }
00282 
00283 int mkTempFileName(const char *tmpl, char *buffer, unsigned int size)
00284 {
00285 
00286   std::string tmp_dir = get_tmp_dir();
00287 
00288   strncpy(buffer, tmp_dir.c_str(), size);
00289   assert((strlen(buffer) + strlen(tmpl) + 2) < size);
00290   strcat(buffer, DIRSEP);
00291   strcat(buffer, tmpl);
00292   return 0;
00293 }
00294 
00295 
00296