20 #include "../config.h" 
   26 #include "ParserEventGeneratorKit.h" 
   50 #define LIBOFX_DEFAULT_INPUT_ENCODING "CP1252" 
   51 #define LIBOFX_DEFAULT_OUTPUT_ENCODING "UTF-8" 
   57 #ifdef MAKEFILE_DTD_PATH 
   68 #ifdef MAKEFILE_DTD_PATH 
   71   "/usr/local/share/libofx/dtd",
 
   72   "/usr/share/libofx/dtd",
 
   75 const unsigned int READ_BUFFER_SIZE = 1024;
 
   84   bool ofx_start = 
false;
 
   86   bool file_is_xml = 
false;
 
   90   char buffer[READ_BUFFER_SIZE];
 
   94   char tmp_filename[256];
 
   97   iconv_t conversion_descriptor;
 
  101   if (p_filename != NULL && strcmp(p_filename, 
"") != 0)
 
  105     input_file.open(p_filename);
 
  108       message_out(
ERROR, 
"ofx_proc_file():Unable to open the input file " + 
string(p_filename));
 
  111     mkTempFileName(
"libofxtmpXXXXXX", tmp_filename, 
sizeof(tmp_filename));
 
  113     message_out(
DEBUG, 
"ofx_proc_file(): Creating temp file: " + 
string(tmp_filename));
 
  114     tmp_file_fd = mkstemp(tmp_filename);
 
  117       tmp_file.open(tmp_filename);
 
  120         message_out(
ERROR, 
"ofx_proc_file():Unable to open the created temp file " + 
string(tmp_filename));
 
  126       message_out(
ERROR, 
"ofx_proc_file():Unable to create a temp file at " + 
string(tmp_filename));
 
  130     if (input_file && tmp_file)
 
  132       int header_separator_idx;
 
  140         bool end_of_line = 
false;
 
  143           input_file.get(buffer, 
sizeof(buffer), 
'\n');
 
  145           s_buffer.append(buffer);
 
  149           if (input_file.eof())
 
  153           if (input_file.fail()) 
 
  163           if (input_file.peek() == 
'\n')
 
  168             s_buffer.append(
"\n");
 
  174         while (!input_file.eof() && !end_of_line);
 
  176         if (ofx_start == 
false && (s_buffer.find(
"<?xml") != string::npos))
 
  178           message_out(
DEBUG, 
"ofx_proc_file(): File is an actual XML file, iconv conversion will be skipped.");
 
  183         if (ofx_start == 
false &&
 
  185               (libofx_context->currentFileType() == 
OFX &&
 
  186                ((ofx_start_idx = s_buffer.find(
"<OFX>")) !=
 
  187                 string::npos || (ofx_start_idx = s_buffer.find(
"<ofx>")) != string::npos))
 
  188               || (libofx_context->currentFileType() == 
OFC &&
 
  189                   ((ofx_start_idx = s_buffer.find(
"<OFC>")) != string::npos ||
 
  190                    (ofx_start_idx = s_buffer.find(
"<ofc>")) != string::npos))
 
  195           if (file_is_xml == 
false)
 
  197             s_buffer.erase(0, ofx_start_idx); 
 
  201           if (file_is_xml == 
true)
 
  203             static char sp_charset_fixed[] = 
"SP_CHARSET_FIXED=1";
 
  204             if (putenv(sp_charset_fixed) != 0)
 
  215             static char sp_encoding[] = 
"SP_ENCODING=ms-dos";
 
  216             if (putenv(sp_encoding) != 0)
 
  223             static char sp_charset_fixed[] = 
"SP_CHARSET_FIXED=1";
 
  224             if (putenv(sp_charset_fixed) != 0)
 
  228             static char sp_encoding[] = 
"SP_ENCODING=ms-dos"; 
 
  229             if (putenv(sp_encoding) != 0)
 
  236             if (ofx_encoding.compare(
"USASCII") == 0)
 
  238               if (ofx_charset.compare(
"ISO-8859-1") == 0 || ofx_charset.compare(
"8859-1") == 0)
 
  241                 fromcode = 
"ISO-8859-1";
 
  243               else if (ofx_charset.compare(
"1252") == 0 || ofx_charset.compare(
"CP1252") == 0)
 
  248               else if (ofx_charset.compare(
"NONE") == 0)
 
  250                 fromcode = LIBOFX_DEFAULT_INPUT_ENCODING;
 
  254                 fromcode = LIBOFX_DEFAULT_INPUT_ENCODING;
 
  257             else if (ofx_encoding.compare(
"UTF-8") == 0 || ofx_encoding.compare(
"UNICODE") == 0)
 
  264               fromcode = LIBOFX_DEFAULT_INPUT_ENCODING;
 
  266             tocode = LIBOFX_DEFAULT_OUTPUT_ENCODING;
 
  267             message_out(
DEBUG, 
"ofx_proc_file(): Setting up iconv for fromcode: " + fromcode + 
", tocode: " + tocode);
 
  268             conversion_descriptor = iconv_open (tocode.c_str(), fromcode.c_str());
 
  275           if ((header_separator_idx = s_buffer.find(
':')) != string::npos)
 
  278             header_name.assign(s_buffer.substr(0, header_separator_idx));
 
  279             header_value.assign(s_buffer.substr(header_separator_idx + 1));
 
  280             while ( header_value[header_value.length() -1 ] == 
'\n' ||
 
  281                     header_value[header_value.length() -1 ] == 
'\r' )
 
  282               header_value.erase(header_value.length() - 1);
 
  283             message_out(
DEBUG, 
"ofx_proc_file():Header: " + header_name + 
" with value: " + header_value + 
" has been found");
 
  284             if (header_name.compare(
"ENCODING") == 0)
 
  286               ofx_encoding.assign(header_value);
 
  288             if (header_name.compare(
"CHARSET") == 0)
 
  290               ofx_charset.assign(header_value);
 
  295         if (file_is_xml == 
true || (ofx_start == 
true && ofx_end == 
false))
 
  297           if (ofx_start == 
true)
 
  306           if (file_is_xml == 
false)
 
  309             size_t inbytesleft = strlen(s_buffer.c_str());
 
  310             size_t outbytesleft = inbytesleft * 2 - 1;
 
  311             iconv_buffer = (
char*) malloc (inbytesleft * 2);
 
  312             memset(iconv_buffer, 0, inbytesleft * 2);
 
  313 #if defined(OS_WIN32) || defined(__sun) 
  314             const char * inchar = (
const char *)s_buffer.c_str();
 
  316             char * inchar = (
char *)s_buffer.c_str();
 
  318             char * outchar = iconv_buffer;
 
  319             int iconv_retval = iconv (conversion_descriptor,
 
  320                                       &inchar, &inbytesleft,
 
  321                                       &outchar, &outbytesleft);
 
  322             if (iconv_retval == -1)
 
  326             s_buffer = iconv_buffer;
 
  331           tmp_file.write(s_buffer.c_str(), s_buffer.length());
 
  334         if (ofx_start == 
true &&
 
  336               (libofx_context->currentFileType() == 
OFX &&
 
  337                ((ofx_start_idx = s_buffer.find(
"</OFX>")) != string::npos ||
 
  338                 (ofx_start_idx = s_buffer.find(
"</ofx>")) != string::npos))
 
  339               || (libofx_context->currentFileType() == 
OFC &&
 
  340                   ((ofx_start_idx = s_buffer.find(
"</OFC>")) != string::npos ||
 
  341                    (ofx_start_idx = s_buffer.find(
"</ofc>")) != string::npos))
 
  350       while (!input_file.eof() && !input_file.bad());
 
  355     if (file_is_xml == 
false)
 
  357       iconv_close(conversion_descriptor);
 
  360     char filename_openspdtd[255];
 
  361     char filename_dtd[255];
 
  362     char filename_ofx[255];
 
  363     strncpy(filename_openspdtd, 
find_dtd(ctx, OPENSPDCL_FILENAME).c_str(), 255); 
 
  364     if (libofx_context->currentFileType() == 
OFX)
 
  366       strncpy(filename_dtd, 
find_dtd(ctx, OFX160DTD_FILENAME).c_str(), 255); 
 
  368     else if (libofx_context->currentFileType() == 
OFC)
 
  370       strncpy(filename_dtd, 
find_dtd(ctx, OFCDTD_FILENAME).c_str(), 255); 
 
  374       message_out(
ERROR, 
string(
"ofx_proc_file(): Error unknown file format for the OFX parser"));
 
  377     if ((
string)filename_dtd != 
"" && (
string)filename_openspdtd != 
"")
 
  379       strncpy(filename_ofx, tmp_filename, 255); 
 
  380       filenames[0] = filename_openspdtd;
 
  381       filenames[1] = filename_dtd;
 
  382       filenames[2] = filename_ofx;
 
  383       if (libofx_context->currentFileType() == 
OFX)
 
  387       else if (libofx_context->currentFileType() == 
OFC)
 
  393         message_out(
ERROR, 
string(
"ofx_proc_file(): Error unknown file format for the OFX parser"));
 
  395       if (
remove(tmp_filename) != 0)
 
  397         message_out(
ERROR, 
"ofx_proc_file(): Error deleting temporary file " + 
string(tmp_filename));
 
  420   size_t input_string_size;
 
  422   bool tag_open = 
false;
 
  423   int tag_open_idx = 0; 
 
  424   bool closing_tag_open = 
false; 
 
  425   int orig_tag_open_idx = 0;
 
  426   bool proprietary_tag = 
false; 
 
  427   bool proprietary_closing_tag = 
false;
 
  428   int crop_end_idx = 0;
 
  429   char buffer[READ_BUFFER_SIZE] = 
"";
 
  430   char tagname[READ_BUFFER_SIZE] = 
"";
 
  432   char close_tagname[READ_BUFFER_SIZE] = 
"";
 
  434   for (i = 0; i < READ_BUFFER_SIZE; i++)
 
  438     close_tagname[i] = 0;
 
  441   input_string_size = input_string.size();
 
  443   for (i = 0; i < input_string_size; i++)
 
  445     if (input_string.c_str()[i] == 
'<')
 
  449       if (proprietary_tag == 
true && input_string.c_str()[i+1] == 
'/')
 
  452         closing_tag_open = 
true;
 
  454         if (strncmp(tagname, &(input_string.c_str()[i+2]), strlen(tagname)) != 0)
 
  458           crop_end_idx = i - 1;
 
  464           proprietary_closing_tag = 
true;
 
  467       else if (proprietary_tag == 
true)
 
  470         crop_end_idx = i - 1;
 
  474     else if (input_string.c_str()[i] == 
'>')
 
  477       closing_tag_open = 
false;
 
  478       tagname[tagname_idx] = 0;
 
  480       if (proprietary_closing_tag == 
true)
 
  486     else if (tag_open == 
true && closing_tag_open == 
false)
 
  488       if (input_string.c_str()[i] == 
'.')
 
  490         if (proprietary_tag != 
true)
 
  492           orig_tag_open_idx = tag_open_idx;
 
  493           proprietary_tag = 
true;
 
  496       tagname[tagname_idx] = input_string.c_str()[i];
 
  500     if (strip == 
true && orig_tag_open_idx < input_string.size())
 
  502       input_string.copy(buffer, (crop_end_idx - orig_tag_open_idx) + 1, orig_tag_open_idx);
 
  503       message_out(
INFO, 
"sanitize_proprietary_tags() (end tag or new tag) removed: " + 
string(buffer));
 
  504       input_string.erase(orig_tag_open_idx, (crop_end_idx - orig_tag_open_idx) + 1);
 
  505       i = orig_tag_open_idx - 1;
 
  506       proprietary_tag = 
false;
 
  507       proprietary_closing_tag = 
false;
 
  508       closing_tag_open = 
false;
 
  512       input_string_size = input_string.size();
 
  516   if (proprietary_tag == 
true && orig_tag_open_idx < input_string.size())
 
  518     if (crop_end_idx == 0)   
 
  520       crop_end_idx = input_string.size() - 1;
 
  522     input_string.copy(buffer, (crop_end_idx - orig_tag_open_idx) + 1, orig_tag_open_idx);
 
  523     message_out(
INFO, 
"sanitize_proprietary_tags() (end of line) removed: " + 
string(buffer));
 
  524     input_string.erase(orig_tag_open_idx, (crop_end_idx - orig_tag_open_idx) + 1);
 
  525     input_string_size = input_string.size();
 
  532 static std::string get_dtd_installation_directory()
 
  536   char ch_fn[MAX_PATH], *p;
 
  539   if (!GetModuleFileName(NULL, ch_fn, MAX_PATH)) 
return "";
 
  541   if ((p = strrchr(ch_fn, 
'\\')) != NULL)
 
  544   p = strrchr(ch_fn, 
'\\');
 
  545   if (p && (_stricmp(p + 1, 
"bin") == 0 ||
 
  546             _stricmp(p + 1, 
"lib") == 0))
 
  550   str_fn += 
"\\share\\libofx\\dtd";
 
  569 std::string 
find_dtd(LibofxContextPtr ctx, 
const std::string& dtd_filename)
 
  571   string dtd_path_filename;
 
  574   dtd_path_filename = 
reinterpret_cast<const LibofxContext*
>(ctx)->dtdDir();
 
  575   if (!dtd_path_filename.empty())
 
  577     dtd_path_filename.append(dtd_filename);
 
  578     ifstream dtd_file(dtd_path_filename.c_str());
 
  582       return dtd_path_filename;
 
  587   dtd_path_filename = get_dtd_installation_directory();
 
  588   if (!dtd_path_filename.empty())
 
  590     dtd_path_filename.append(DIRSEP);
 
  591     dtd_path_filename.append(dtd_filename);
 
  592     ifstream dtd_file(dtd_path_filename.c_str());
 
  596       return dtd_path_filename;
 
  601   env_dtd_path = getenv(
"OFX_DTD_PATH");
 
  604     dtd_path_filename.append(env_dtd_path);
 
  605     dtd_path_filename.append(DIRSEP);
 
  606     dtd_path_filename.append(dtd_filename);
 
  607     ifstream dtd_file(dtd_path_filename.c_str());
 
  610       message_out(
STATUS, 
"find_dtd():OFX_DTD_PATH env variable was was present, but unable to open the file " + dtd_path_filename);
 
  615       return dtd_path_filename;
 
  622     dtd_path_filename.append(DIRSEP);
 
  623     dtd_path_filename.append(dtd_filename);
 
  624     ifstream dtd_file(dtd_path_filename.c_str());
 
  627       message_out(
DEBUG, 
"find_dtd():Unable to open the file " + dtd_path_filename);
 
  632       return dtd_path_filename;
 
  637   dtd_path_filename = 
"";
 
  638   dtd_path_filename.append(
"..");
 
  639   dtd_path_filename.append(DIRSEP);
 
  640   dtd_path_filename.append(
"dtd");
 
  641   dtd_path_filename.append(DIRSEP);
 
  642   dtd_path_filename.append(dtd_filename);
 
  643   ifstream dtd_file(dtd_path_filename.c_str());
 
  646     message_out(
DEBUG, 
"find_dtd(): Unable to open the file " + dtd_path_filename + 
", most likely we are not in the source tree.");
 
  651     return dtd_path_filename;
 
  655   message_out(
ERROR, 
"find_dtd():Unable to find the DTD named " + dtd_filename);
 
Message IO functionality. 
const int DTD_SEARCH_PATH_NUM
The number of different paths to search for DTDs. 
int message_out(OfxMsgType error_type, const string message)
Message output function. 
const char * DTD_SEARCH_PATH[DTD_SEARCH_PATH_NUM]
The list of paths to search for the DTDs. 
int ofc_proc_sgml(LibofxContext *libofx_context, int argc, char *const *argv)
Parses a DTD and OFX file(s) 
int ofx_proc_sgml(LibofxContext *libofx_context, int argc, char *const *argv)
Parses a DTD and OFX file(s) 
int ofx_proc_file(LibofxContextPtr ctx, const char *p_filename)
File pre-processing of OFX AND for OFC files. 
std::string find_dtd(LibofxContextPtr ctx, const std::string &dtd_filename)
Find the appropriate DTD for the file version. 
string sanitize_proprietary_tags(string input_string)
Removes proprietary tags and comments. 
OFX/SGML parsing functionnality. 
OFX/SGML parsing functionnality. 
Various simple functions for type conversion & al. 
Preprocessing of the OFX files before parsing.