29 #include "ParserEventGeneratorKit.h"    39 extern SGMLApplication::OpenEntityPtr 
entity_ptr;
    40 extern SGMLApplication::Position 
position;
    59     curr_container_element = NULL;
    60     is_data_element = 
false;
    61     libofx_context = p_libofx_context;
    76     message_out(
PARSER, 
"startElement event received from OpenSP for element " + identifier);
    80     switch (event.contentType)
    82     case StartElementEvent::empty:
    85     case StartElementEvent::cdata:
    88     case StartElementEvent::rcdata:
    91     case StartElementEvent::mixed:
    93       is_data_element = 
true;
    95     case StartElementEvent::element:
    97       is_data_element = 
false;
   100       message_out(
ERROR, 
"Unknown SGML content type?!?!?!? OpenSP interface changed?");
   103     if (is_data_element == 
false)
   107       if (identifier == 
"OFX")
   110         MainContainer = 
new OfxMainContainer (libofx_context, curr_container_element, identifier);
   111         curr_container_element = MainContainer;
   113       else if (identifier == 
"STATUS")
   116         curr_container_element = 
new OfxStatusContainer (libofx_context, curr_container_element, identifier);
   118       else if (identifier == 
"STMTRS" ||
   119                identifier == 
"CCSTMTRS" ||
   120                identifier == 
"INVSTMTRS")
   123         curr_container_element = 
new OfxStatementContainer (libofx_context, curr_container_element, identifier);
   125       else if (identifier == 
"BANKTRANLIST" || identifier == 
"INVTRANLIST")
   129         if (curr_container_element && curr_container_element->
type != 
"STATEMENT")
   131           message_out(
ERROR, 
"Element " + identifier + 
" found while not inside a STATEMENT container");
   135           curr_container_element = 
new OfxPushUpContainer (libofx_context, curr_container_element, identifier);
   138       else if (identifier == 
"STMTTRN")
   141         if (curr_container_element->
type == 
"INVESTMENT")
   144           curr_container_element = 
new OfxPushUpContainer (libofx_context, curr_container_element, identifier);
   151       else if (identifier == 
"BUYDEBT" ||
   152                identifier == 
"BUYMF" ||
   153                identifier == 
"BUYOPT" ||
   154                identifier == 
"BUYOTHER" ||
   155                identifier == 
"BUYSTOCK" ||
   156                identifier == 
"CLOSUREOPT" ||
   157                identifier == 
"INCOME" ||
   158                identifier == 
"INVEXPENSE" ||
   159                identifier == 
"JRNLFUND" ||
   160                identifier == 
"JRNLSEC" ||
   161                identifier == 
"MARGININTEREST" ||
   162                identifier == 
"REINVEST" ||
   163                identifier == 
"RETOFCAP" ||
   164                identifier == 
"SELLDEBT" ||
   165                identifier == 
"SELLMF" ||
   166                identifier == 
"SELLOPT" ||
   167                identifier == 
"SELLOTHER" ||
   168                identifier == 
"SELLSTOCK" ||
   169                identifier == 
"SPLIT" ||
   170                identifier == 
"TRANSFER" ||
   171                identifier == 
"INVBANKTRAN" )
   177       else if (identifier == 
"INVBUY" ||
   178                identifier == 
"INVSELL" ||
   179                identifier == 
"INVTRAN" ||
   180                identifier == 
"SECINFO" ||
   181                identifier == 
"SECID" ||
   182                identifier == 
"CURRENCY" ||
   183                identifier == 
"ORIGCURRENCY")
   186         curr_container_element = 
new OfxPushUpContainer (libofx_context, curr_container_element, identifier);
   190       else if (identifier == 
"BANKACCTINFO" || identifier == 
"CCACCTINFO" || identifier == 
"INVACCTINFO")
   193         curr_container_element = 
new OfxPushUpContainer (libofx_context, curr_container_element, identifier);
   197       else if (identifier == 
"BANKACCTFROM" || identifier == 
"CCACCTFROM" || identifier == 
"INVACCTFROM")
   201         if (curr_container_element->
type == 
"STATEMENT"   205           curr_container_element = 
new OfxAccountContainer (libofx_context, curr_container_element, identifier);
   208           curr_container_element = 
new OfxDummyContainer (libofx_context, curr_container_element, identifier);
   210       else if (identifier == 
"STOCKINFO" || identifier == 
"OPTINFO" ||
   211                identifier == 
"DEBTINFO" || identifier == 
"MFINFO" || identifier == 
"OTHERINFO")
   214         curr_container_element = 
new OfxSecurityContainer (libofx_context, curr_container_element, identifier);
   217       else if (identifier == 
"LEDGERBAL" ||
   218                identifier == 
"AVAILBAL" ||
   219                identifier == 
"INVBAL")
   222         curr_container_element = 
new OfxBalanceContainer (libofx_context, curr_container_element, identifier);
   224       else if (identifier == 
"INVPOS")
   227         curr_container_element = 
new OfxPositionContainer (libofx_context, curr_container_element, identifier);
   232         curr_container_element = 
new OfxDummyContainer(libofx_context, curr_container_element, identifier);
   239       if (identifier == 
"INV401K")
   243         curr_container_element = 
new OfxInv401kContainer (libofx_context, curr_container_element, identifier);
   245       if (identifier == 
"INV401KBAL")
   248         curr_container_element = 
new OfxBalanceContainer (libofx_context, curr_container_element, identifier);
   255         if (incoming_data != 
"")
   257           message_out (
ERROR, 
"startElement: incoming_data should be empty! You are probably using OpenSP <= 1.3.4.  The following data was lost: " + incoming_data );
   258           incoming_data.assign (
"");
   271     bool end_element_for_data_element;
   274     end_element_for_data_element = is_data_element;
   275     message_out(
PARSER, 
"endElement event received from OpenSP for element " + identifier);
   278     if (curr_container_element == NULL)
   280       message_out (
ERROR, 
"Tried to close a " + identifier + 
" without a open element (NULL pointer)");
   281       incoming_data.assign (
"");
   285       if (end_element_for_data_element == 
true)
   289         curr_container_element->
add_attribute (identifier, incoming_data);
   290         message_out (
PARSER, 
"endElement: Added data '" + incoming_data + 
"' from " + identifier + 
" to " + curr_container_element->
type + 
" container_element");
   291         incoming_data.assign (
"");
   292         is_data_element = 
false;
   298           if (incoming_data != 
"")
   300             message_out(
ERROR, 
"End tag for non data element " + identifier + 
", incoming data should be empty but contains: " + incoming_data + 
" DATA HAS BEEN LOST SOMEWHERE!");
   303           if (identifier == 
"OFX")
   306             tmp_container_element = curr_container_element;
   307             curr_container_element = curr_container_element->
getparent ();
   308             if (curr_container_element == NULL)
   311               curr_container_element = tmp_container_element;
   313             if (MainContainer != NULL)
   316               delete MainContainer;
   317               MainContainer = NULL;
   318               curr_container_element = NULL;
   319               message_out (
DEBUG, 
"Element " + identifier + 
" closed, MainContainer destroyed");
   323               message_out (
DEBUG, 
"Element " + identifier + 
" closed, but there was no MainContainer to destroy (probably a malformed file)!");
   328             tmp_container_element = curr_container_element;
   329             curr_container_element = curr_container_element->
getparent ();
   330             if (MainContainer != NULL)
   335               if (identifier == 
"CURRENCY" || identifier == 
"ORIGCURRENCY")
   337                 tmp_container_element->
add_attribute (identifier, incoming_data);
   338                 message_out (
DEBUG, 
"Element " + identifier + 
" closed, container " + tmp_container_element->
type + 
" updated");
   343                 message_out (
PARSER, 
"Element " + identifier + 
" closed, object added to MainContainer");
   348               message_out (
ERROR, 
"MainContainer is NULL trying to add element " + identifier);
   354           message_out (
ERROR, 
"Tried to close a " + identifier + 
" but a " + curr_container_element->
type + 
" is currently open.");
   364   void data (
const DataEvent & event)
   369     message_out(
PARSER, 
"data event received from OpenSP, incoming_data is now: " + incoming_data);
   376   void error (
const ErrorEvent & event)
   383     message = message + 
"OpenSP parser: ";
   386     case SGMLApplication::ErrorEvent::quantity:
   387       message = message + 
"quantity (Exceeding a quantity limit):";
   390     case SGMLApplication::ErrorEvent::idref:
   391       message = message + 
"idref (An IDREF to a non-existent ID):";
   394     case SGMLApplication::ErrorEvent::capacity:
   395       message = message + 
"capacity (Exceeding a capacity limit):";
   398     case SGMLApplication::ErrorEvent::otherError:
   399       message = message + 
"otherError (misc parse error):";
   402     case SGMLApplication::ErrorEvent::warning:
   403       message = message + 
"warning (Not actually an error.):";
   406     case SGMLApplication::ErrorEvent::info:
   407       message =  message + 
"info (An informationnal message.  Not actually an error):";
   411       message = message + 
"OpenSP sent an unknown error to LibOFX (You probably have a newer version of OpenSP):";
   442   ParserEventGeneratorKit parserKit;
   443   parserKit.setOption (ParserEventGeneratorKit::showOpenEntities);
   444   EventGenerator *egp = parserKit.makeEventGenerator (argc, argv);
   445   egp->inhibitMessages (
true);  
   447   unsigned nErrors = egp->run (*app); 
 SGMLApplication::Position position
int ofx_proc_sgml(LibofxContext *libofx_context, int argc, char *const *argv)
Parses a DTD and OFX file(s) 
Represents a security, such as a stock or bond. 
OfxGenericContainer * getparent()
Returns the parent container object (the one representing the containing OFX SGML element) ...
A generic container for an OFX SGML element. Every container inherits from OfxGenericContainer. 
string CharStringtostring(const SGMLApplication::CharString source, string &dest)
Convert OpenSP CharString to a C++ STL string. 
Various simple functions for type conversion & al. 
void openEntityChange(const OpenEntityPtr ¶_entity_ptr)
Callback: Receive internal OpenSP state. 
virtual void add_attribute(const string identifier, const string value)
Add data to a container object. 
string strip_whitespace(const string para_string)
Sanitize a string coming from OpenSP. 
SGMLApplication::OpenEntityPtr entity_ptr
void error(const ErrorEvent &event)
Callback: SGML parse error. 
int message_out(OfxMsgType error_type, const string message)
Message output function. 
void data(const DataEvent &event)
Callback: Data from an OFX element. 
string AppendCharStringtostring(const SGMLApplication::CharString source, string &dest)
Append an OpenSP CharString to an existing C++ STL string. 
LibOFX internal object code. 
Represents a statement for either a bank account or a credit card account. 
Message IO functionality. 
virtual int add_to_main_tree()
Add this container to the main tree. 
Represents a bank or credid card transaction. 
OFX/SGML parsing functionnality. 
A container to hold a OFX SGML element for which you want the parent to process it's data elements...
void startElement(const StartElementEvent &event)
Callback: Start of an OFX element. 
Represents an investment position, such as a stock or bond. 
Represents a bank or credid card transaction. 
Represents a bank account or a credit card account. 
The root container. Created by the <OFX> OFX element or by the export functions. 
int gen_event()
Generate libofx.h events. 
This object is driven by OpenSP as it parses the SGML from the ofx file(s) 
void endElement(const EndElementEvent &event)
Callback: End of an OFX element. 
A container to hold OFX SGML elements that LibOFX knows nothing about. 
Represents the <BALANCE>, <INVBAL> or <INV401KBAL> OFX SGML entity. 
A container to hold OFX SGML elements for <INV401K> 
Represents the <STATUS> OFX SGML entity.