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];
93 char tmp_filename[256];
96 iconv_t conversion_descriptor;
100 if (p_filename != NULL && strcmp(p_filename,
"") != 0)
104 input_file.open(p_filename);
107 message_out(
ERROR,
"ofx_proc_file():Unable to open the input file " +
string(p_filename));
110 mkTempFileName(
"libofxtmpXXXXXX", tmp_filename,
sizeof(tmp_filename));
112 message_out(
DEBUG,
"ofx_proc_file(): Creating temp file: " +
string(tmp_filename));
113 tmp_file_fd = mkstemp(tmp_filename);
116 tmp_file.open(tmp_filename);
119 message_out(
ERROR,
"ofx_proc_file():Unable to open the created temp file " +
string(tmp_filename));
125 message_out(
ERROR,
"ofx_proc_file():Unable to create a temp file at " +
string(tmp_filename));
129 if (input_file && tmp_file)
131 int header_separator_idx;
139 bool end_of_line =
false;
142 input_file.get(buffer,
sizeof(buffer),
'\n');
144 s_buffer.append(buffer);
148 if (input_file.eof())
152 if (input_file.fail())
162 if (input_file.peek() ==
'\n')
167 s_buffer.append(
"\n");
173 while (!input_file.eof() && !end_of_line);
175 if (ofx_start ==
false && (s_buffer.find(
"<?xml") != string::npos))
177 message_out(
DEBUG,
"ofx_proc_file(): File is an actual XML file, iconv conversion will be skipped.");
182 if (ofx_start ==
false &&
184 (libofx_context->currentFileType() ==
OFX &&
185 ((ofx_start_idx = s_buffer.find(
"<OFX>")) !=
186 string::npos || (ofx_start_idx = s_buffer.find(
"<ofx>")) != string::npos))
187 || (libofx_context->currentFileType() ==
OFC &&
188 ((ofx_start_idx = s_buffer.find(
"<OFC>")) != string::npos ||
189 (ofx_start_idx = s_buffer.find(
"<ofc>")) != string::npos))
194 if (file_is_xml ==
false)
196 s_buffer.erase(0, ofx_start_idx);
200 if (file_is_xml ==
true)
202 static char sp_charset_fixed[] =
"SP_CHARSET_FIXED=1";
203 if (putenv(sp_charset_fixed) != 0)
214 static char sp_encoding[] =
"SP_ENCODING=ms-dos";
215 if (putenv(sp_encoding) != 0)
222 static char sp_charset_fixed[] =
"SP_CHARSET_FIXED=1";
223 if (putenv(sp_charset_fixed) != 0)
227 static char sp_encoding[] =
"SP_ENCODING=ms-dos";
228 if (putenv(sp_encoding) != 0)
235 if (ofx_encoding.compare(
"USASCII") == 0)
237 if (ofx_charset.compare(
"ISO-8859-1") == 0 || ofx_charset.compare(
"8859-1") == 0)
240 fromcode =
"ISO-8859-1";
242 else if (ofx_charset.compare(
"1252") == 0 || ofx_charset.compare(
"CP1252") == 0)
247 else if (ofx_charset.compare(
"NONE") == 0)
249 fromcode = LIBOFX_DEFAULT_INPUT_ENCODING;
253 fromcode = LIBOFX_DEFAULT_INPUT_ENCODING;
256 else if (ofx_encoding.compare(
"UTF-8") == 0 || ofx_encoding.compare(
"UNICODE") == 0)
263 fromcode = LIBOFX_DEFAULT_INPUT_ENCODING;
265 tocode = LIBOFX_DEFAULT_OUTPUT_ENCODING;
266 message_out(
DEBUG,
"ofx_proc_file(): Setting up iconv for fromcode: " + fromcode +
", tocode: " + tocode);
267 conversion_descriptor = iconv_open (tocode.c_str(), fromcode.c_str());
274 if ((header_separator_idx = s_buffer.find(
':')) != string::npos)
277 header_name.assign(s_buffer.substr(0, header_separator_idx));
278 header_value.assign(s_buffer.substr(header_separator_idx + 1));
279 while ( header_value[header_value.length() -1 ] ==
'\n' ||
280 header_value[header_value.length() -1 ] ==
'\r' )
281 header_value.erase(header_value.length() - 1);
282 message_out(
DEBUG,
"ofx_proc_file():Header: " + header_name +
" with value: " + header_value +
" has been found");
283 if (header_name.compare(
"ENCODING") == 0)
285 ofx_encoding.assign(header_value);
287 if (header_name.compare(
"CHARSET") == 0)
289 ofx_charset.assign(header_value);
294 if (file_is_xml ==
true || (ofx_start ==
true && ofx_end ==
false))
296 if (ofx_start ==
true)
305 if (file_is_xml ==
false)
308 size_t inbytesleft = s_buffer.size();
309 size_t outbytesleft = inbytesleft * 2 - 1;
310 char * iconv_buffer = (
char*) malloc (inbytesleft * 2);
311 memset(iconv_buffer, 0, inbytesleft * 2);
312 #if defined(OS_WIN32) || defined(__sun) || defined(__NetBSD__) 313 const char * inchar = (
const char *)s_buffer.c_str();
315 char * inchar = (
char *)s_buffer.c_str();
317 char * outchar = iconv_buffer;
318 int iconv_retval = iconv (conversion_descriptor,
319 &inchar, &inbytesleft,
320 &outchar, &outbytesleft);
321 if (iconv_retval == -1)
327 s_buffer = std::string(iconv_buffer, outchar - iconv_buffer);
332 tmp_file.write(s_buffer.c_str(), s_buffer.length());
335 if (ofx_start ==
true &&
337 (libofx_context->currentFileType() ==
OFX &&
338 ((ofx_start_idx = s_buffer.find(
"</OFX>")) != string::npos ||
339 (ofx_start_idx = s_buffer.find(
"</ofx>")) != string::npos))
340 || (libofx_context->currentFileType() ==
OFC &&
341 ((ofx_start_idx = s_buffer.find(
"</OFC>")) != string::npos ||
342 (ofx_start_idx = s_buffer.find(
"</ofc>")) != string::npos))
351 while (!input_file.eof() && !input_file.bad());
356 if (file_is_xml ==
false)
358 iconv_close(conversion_descriptor);
361 char filename_openspdtd[255];
362 char filename_dtd[255];
363 char filename_ofx[255];
364 strncpy(filename_openspdtd,
find_dtd(ctx, OPENSPDCL_FILENAME).c_str(), 255);
365 if (libofx_context->currentFileType() ==
OFX)
367 strncpy(filename_dtd,
find_dtd(ctx, OFX160DTD_FILENAME).c_str(), 255);
369 else if (libofx_context->currentFileType() ==
OFC)
371 strncpy(filename_dtd,
find_dtd(ctx, OFCDTD_FILENAME).c_str(), 255);
375 message_out(
ERROR,
string(
"ofx_proc_file(): Error unknown file format for the OFX parser"));
378 if ((
string)filename_dtd !=
"" && (
string)filename_openspdtd !=
"")
380 strncpy(filename_ofx, tmp_filename, 255);
381 filenames[0] = filename_openspdtd;
382 filenames[1] = filename_dtd;
383 filenames[2] = filename_ofx;
384 if (libofx_context->currentFileType() ==
OFX)
388 else if (libofx_context->currentFileType() ==
OFC)
394 message_out(
ERROR,
string(
"ofx_proc_file(): Error unknown file format for the OFX parser"));
396 if (
remove(tmp_filename) != 0)
398 message_out(
ERROR,
"ofx_proc_file(): Error deleting temporary file " +
string(tmp_filename));
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 size_t input_string_size = input_string.size();
451 for (i = 0; i < std::min(input_string_size,
size_t(READ_BUFFER_SIZE)); i++)
453 if (input_string.c_str()[i] ==
'<')
457 if (proprietary_tag ==
true && input_string.c_str()[i+1] ==
'/')
460 closing_tag_open =
true;
462 if (strncmp(tagname, &(input_string.c_str()[i+2]), strlen(tagname)) != 0)
466 crop_end_idx = i - 1;
472 proprietary_closing_tag =
true;
475 else if (proprietary_tag ==
true)
478 crop_end_idx = i - 1;
482 else if (input_string.c_str()[i] ==
'>')
485 closing_tag_open =
false;
486 tagname[tagname_idx] = 0;
488 if (proprietary_closing_tag ==
true)
494 else if (tag_open ==
true && closing_tag_open ==
false)
496 if (input_string.c_str()[i] ==
'.')
498 if (proprietary_tag !=
true)
500 orig_tag_open_idx = tag_open_idx;
501 proprietary_tag =
true;
504 tagname[tagname_idx] = input_string.c_str()[i];
508 if (strip ==
true && orig_tag_open_idx < input_string.size())
510 input_string.copy(buffer, (crop_end_idx - orig_tag_open_idx) + 1, orig_tag_open_idx);
511 message_out(
INFO,
"sanitize_proprietary_tags() (end tag or new tag) removed: " +
string(buffer));
512 input_string.erase(orig_tag_open_idx, (crop_end_idx - orig_tag_open_idx) + 1);
513 i = orig_tag_open_idx - 1;
514 proprietary_tag =
false;
515 proprietary_closing_tag =
false;
516 closing_tag_open =
false;
520 input_string_size = input_string.size();
524 if (proprietary_tag ==
true && orig_tag_open_idx < input_string.size())
526 if (crop_end_idx == 0)
528 crop_end_idx = input_string.size() - 1;
530 input_string.copy(buffer, (crop_end_idx - orig_tag_open_idx) + 1, orig_tag_open_idx);
531 message_out(
INFO,
"sanitize_proprietary_tags() (end of line) removed: " +
string(buffer));
532 input_string.erase(orig_tag_open_idx, (crop_end_idx - orig_tag_open_idx) + 1);
533 input_string_size = input_string.size();
540 static std::string get_dtd_installation_directory()
544 char ch_fn[MAX_PATH], *p;
547 if (!GetModuleFileName(NULL, ch_fn, MAX_PATH))
return "";
549 if ((p = strrchr(ch_fn,
'\\')) != NULL)
552 p = strrchr(ch_fn,
'\\');
553 if (p && (_stricmp(p + 1,
"bin") == 0 ||
554 _stricmp(p + 1,
"lib") == 0))
558 str_fn +=
"\\share\\libofx\\dtd";
577 std::string
find_dtd(LibofxContextPtr ctx,
const std::string& dtd_filename)
579 string dtd_path_filename;
582 dtd_path_filename =
reinterpret_cast<const LibofxContext*
>(ctx)->dtdDir();
583 if (!dtd_path_filename.empty())
585 dtd_path_filename.append(dtd_filename);
586 ifstream dtd_file(dtd_path_filename.c_str());
590 return dtd_path_filename;
595 dtd_path_filename = get_dtd_installation_directory();
596 if (!dtd_path_filename.empty())
598 dtd_path_filename.append(DIRSEP);
599 dtd_path_filename.append(dtd_filename);
600 ifstream dtd_file(dtd_path_filename.c_str());
604 return dtd_path_filename;
609 env_dtd_path = getenv(
"OFX_DTD_PATH");
612 dtd_path_filename.append(env_dtd_path);
613 dtd_path_filename.append(DIRSEP);
614 dtd_path_filename.append(dtd_filename);
615 ifstream dtd_file(dtd_path_filename.c_str());
618 message_out(
STATUS,
"find_dtd():OFX_DTD_PATH env variable was was present, but unable to open the file " + dtd_path_filename);
623 return dtd_path_filename;
630 dtd_path_filename.append(DIRSEP);
631 dtd_path_filename.append(dtd_filename);
632 ifstream dtd_file(dtd_path_filename.c_str());
635 message_out(
DEBUG,
"find_dtd():Unable to open the file " + dtd_path_filename);
640 return dtd_path_filename;
645 dtd_path_filename =
"";
646 dtd_path_filename.append(
"..");
647 dtd_path_filename.append(DIRSEP);
648 dtd_path_filename.append(
"dtd");
649 dtd_path_filename.append(DIRSEP);
650 dtd_path_filename.append(dtd_filename);
651 ifstream dtd_file(dtd_path_filename.c_str());
654 message_out(
DEBUG,
"find_dtd(): Unable to open the file " + dtd_path_filename +
", most likely we are not in the source tree.");
659 return dtd_path_filename;
663 message_out(
ERROR,
"find_dtd():Unable to find the DTD named " + dtd_filename);
int ofx_proc_file(LibofxContextPtr ctx, const char *p_filename)
File pre-processing of OFX AND for OFC files.
Main header file containing the LibOfx API.
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.
OFX/SGML parsing functionnality.
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)
Various simple functions for type conversion & al.
int ofx_proc_sgml(LibofxContext *libofx_context, int argc, char *const *argv)
Parses a DTD and OFX file(s)
string sanitize_proprietary_tags(string input_string)
Removes proprietary tags and comments.
OFX/SGML parsing functionnality.
Message IO functionality.
Preprocessing of the OFX files before parsing.
std::string find_dtd(LibofxContextPtr ctx, const std::string &dtd_filename)
Find the appropriate DTD for the file version.