29 #include "ParserEventGeneratorKit.h"
38 extern SGMLApplication::OpenEntityPtr
entity_ptr;
39 extern SGMLApplication::Position
position;
50 std::string incoming_data;
58 curr_container_element = NULL;
59 is_data_element =
false;
60 libofx_context = p_libofx_context;
73 std::string identifier;
75 message_out(
PARSER,
"startElement event received from OpenSP for element " + identifier);
79 switch (event.contentType)
81 case StartElementEvent::empty:
84 case StartElementEvent::cdata:
87 case StartElementEvent::rcdata:
90 case StartElementEvent::mixed:
92 is_data_element =
true;
94 case StartElementEvent::element:
96 is_data_element =
false;
99 message_out(
ERROR,
"Unknown SGML content type?!?!?!? OpenSP interface changed?");
102 if (is_data_element ==
false)
106 if (identifier ==
"OFX")
109 MainContainer =
new OfxMainContainer (libofx_context, curr_container_element, identifier);
110 curr_container_element = MainContainer;
112 else if (identifier ==
"STATUS")
115 curr_container_element =
new OfxStatusContainer (libofx_context, curr_container_element, identifier);
117 else if (identifier ==
"STMTRS" ||
118 identifier ==
"CCSTMTRS" ||
119 identifier ==
"INVSTMTRS")
122 curr_container_element =
new OfxStatementContainer (libofx_context, curr_container_element, identifier);
124 else if (identifier ==
"BANKTRANLIST" || identifier ==
"INVTRANLIST")
128 if (curr_container_element && curr_container_element->
type !=
"STATEMENT")
130 message_out(
ERROR,
"Element " + identifier +
" found while not inside a STATEMENT container");
134 curr_container_element =
new OfxPushUpContainer (libofx_context, curr_container_element, identifier);
137 else if (identifier ==
"STMTTRN")
140 if (curr_container_element->
type ==
"INVESTMENT")
143 curr_container_element =
new OfxPushUpContainer (libofx_context, curr_container_element, identifier);
150 else if (identifier ==
"BUYDEBT" ||
151 identifier ==
"BUYMF" ||
152 identifier ==
"BUYOPT" ||
153 identifier ==
"BUYOTHER" ||
154 identifier ==
"BUYSTOCK" ||
155 identifier ==
"CLOSUREOPT" ||
156 identifier ==
"INCOME" ||
157 identifier ==
"INVEXPENSE" ||
158 identifier ==
"JRNLFUND" ||
159 identifier ==
"JRNLSEC" ||
160 identifier ==
"MARGININTEREST" ||
161 identifier ==
"REINVEST" ||
162 identifier ==
"RETOFCAP" ||
163 identifier ==
"SELLDEBT" ||
164 identifier ==
"SELLMF" ||
165 identifier ==
"SELLOPT" ||
166 identifier ==
"SELLOTHER" ||
167 identifier ==
"SELLSTOCK" ||
168 identifier ==
"SPLIT" ||
169 identifier ==
"TRANSFER" ||
170 identifier ==
"INVBANKTRAN" )
176 else if (identifier ==
"INVBUY" ||
177 identifier ==
"INVSELL" ||
178 identifier ==
"INVTRAN" ||
179 identifier ==
"SECINFO" ||
180 identifier ==
"SECID" ||
181 identifier ==
"CURRENCY" ||
182 identifier ==
"ORIGCURRENCY")
185 curr_container_element =
new OfxPushUpContainer (libofx_context, curr_container_element, identifier);
189 else if (identifier ==
"BANKACCTINFO" || identifier ==
"CCACCTINFO" || identifier ==
"INVACCTINFO")
192 curr_container_element =
new OfxPushUpContainer (libofx_context, curr_container_element, identifier);
196 else if (identifier ==
"BANKACCTFROM" || identifier ==
"CCACCTFROM" || identifier ==
"INVACCTFROM")
200 if (curr_container_element->
type ==
"STATEMENT"
204 curr_container_element =
new OfxAccountContainer (libofx_context, curr_container_element, identifier);
207 curr_container_element =
new OfxDummyContainer (libofx_context, curr_container_element, identifier);
209 else if (identifier ==
"STOCKINFO" || identifier ==
"OPTINFO" ||
210 identifier ==
"DEBTINFO" || identifier ==
"MFINFO" || identifier ==
"OTHERINFO")
213 curr_container_element =
new OfxSecurityContainer (libofx_context, curr_container_element, identifier);
216 else if (identifier ==
"LEDGERBAL" ||
217 identifier ==
"AVAILBAL" ||
218 identifier ==
"INVBAL")
221 curr_container_element =
new OfxBalanceContainer (libofx_context, curr_container_element, identifier);
223 else if (identifier ==
"INVPOS")
226 curr_container_element =
new OfxPositionContainer (libofx_context, curr_container_element, identifier);
231 curr_container_element =
new OfxDummyContainer(libofx_context, curr_container_element, identifier);
238 if (identifier ==
"INV401K")
242 curr_container_element =
new OfxInv401kContainer (libofx_context, curr_container_element, identifier);
244 if (identifier ==
"INV401KBAL")
247 curr_container_element =
new OfxBalanceContainer (libofx_context, curr_container_element, identifier);
254 if (incoming_data !=
"")
256 message_out (
ERROR,
"startElement: incoming_data should be empty! You are probably using OpenSP <= 1.3.4. The following data was lost: " + incoming_data );
257 incoming_data.assign (
"");
269 std::string identifier;
270 bool end_element_for_data_element;
273 end_element_for_data_element = is_data_element;
274 message_out(
PARSER,
"endElement event received from OpenSP for element " + identifier);
277 if (curr_container_element == NULL)
279 message_out (
ERROR,
"Tried to close a " + identifier +
" without a open element (NULL pointer)");
280 incoming_data.assign (
"");
284 if (end_element_for_data_element ==
true)
288 curr_container_element->
add_attribute (identifier, incoming_data);
289 message_out (
PARSER,
"endElement: Added data '" + incoming_data +
"' from " + identifier +
" to " + curr_container_element->
type +
" container_element");
290 incoming_data.assign (
"");
291 is_data_element =
false;
297 if (incoming_data !=
"")
299 message_out(
ERROR,
"End tag for non data element " + identifier +
", incoming data should be empty but contains: " + incoming_data +
" DATA HAS BEEN LOST SOMEWHERE!");
302 if (identifier ==
"OFX")
305 tmp_container_element = curr_container_element;
306 curr_container_element = curr_container_element->
getparent ();
307 if (curr_container_element == NULL)
310 curr_container_element = tmp_container_element;
312 if (MainContainer != NULL)
315 delete MainContainer;
316 MainContainer = NULL;
317 curr_container_element = NULL;
318 message_out (
DEBUG,
"Element " + identifier +
" closed, MainContainer destroyed");
322 message_out (
DEBUG,
"Element " + identifier +
" closed, but there was no MainContainer to destroy (probably a malformed file)!");
327 tmp_container_element = curr_container_element;
328 curr_container_element = curr_container_element->
getparent ();
329 if (MainContainer != NULL)
334 if (identifier ==
"CURRENCY" || identifier ==
"ORIGCURRENCY")
336 tmp_container_element->
add_attribute (identifier, incoming_data);
337 message_out (
DEBUG,
"Element " + identifier +
" closed, container " + tmp_container_element->
type +
" updated");
342 message_out (
PARSER,
"Element " + identifier +
" closed, object added to MainContainer");
347 message_out (
ERROR,
"MainContainer is NULL trying to add element " + identifier);
353 message_out (
ERROR,
"Tried to close a " + identifier +
" but a " + curr_container_element->
type +
" is currently open.");
363 void data (
const DataEvent & event)
368 message_out(
PARSER,
"data event received from OpenSP, incoming_data is now: " + incoming_data);
375 void error (
const ErrorEvent & event)
378 std::string string_buf;
382 message = message +
"OpenSP parser: ";
385 case SGMLApplication::ErrorEvent::quantity:
386 message = message +
"quantity (Exceeding a quantity limit):";
389 case SGMLApplication::ErrorEvent::idref:
390 message = message +
"idref (An IDREF to a non-existent ID):";
393 case SGMLApplication::ErrorEvent::capacity:
394 message = message +
"capacity (Exceeding a capacity limit):";
397 case SGMLApplication::ErrorEvent::otherError:
398 message = message +
"otherError (misc parse error):";
401 case SGMLApplication::ErrorEvent::warning:
402 message = message +
"warning (Not actually an error.):";
405 case SGMLApplication::ErrorEvent::info:
406 message = message +
"info (An informationnal message. Not actually an error):";
410 message = message +
"OpenSP sent an unknown error to LibOFX (You probably have a newer version of OpenSP):";
441 ParserEventGeneratorKit parserKit;
442 parserKit.setOption (ParserEventGeneratorKit::showOpenEntities);
443 EventGenerator *egp = parserKit.makeEventGenerator (argc, argv);
444 egp->inhibitMessages (
true);
446 unsigned nErrors = egp->run (app);
This object is driven by OpenSP as it parses the SGML from the ofx file(s)
void data(const DataEvent &event)
Callback: Data from an OFX element.
void error(const ErrorEvent &event)
Callback: SGML parse error.
void openEntityChange(const OpenEntityPtr ¶_entity_ptr)
Callback: Receive internal OpenSP state.
void startElement(const StartElementEvent &event)
Callback: Start of an OFX element.
void endElement(const EndElementEvent &event)
Callback: End of an OFX element.
Represents a bank account or a credit card account.
Represents the <BALANCE>, <INVBAL> or <INV401KBAL> OFX SGML entity.
Represents a bank or credid card transaction.
A container to hold OFX SGML elements that LibOFX knows nothing about.
A generic container for an OFX SGML element. Every container inherits from OfxGenericContainer.
std::string tag_identifier
OfxGenericContainer * getparent()
Returns the parent container object (the one representing the containing OFX SGML element)
virtual void add_attribute(const std::string identifier, const std::string value)
Add data to a container object.
virtual int add_to_main_tree()
Add this container to the main tree.
A container to hold OFX SGML elements for <INV401K>
Represents a bank or credid card transaction.
The root container. Created by the <OFX> OFX element or by the export functions.
int gen_event()
Generate libofx.h events.
Represents an investment position, such as a stock or bond.
A container to hold a OFX SGML element for which you want the parent to process it's data elements.
Represents a security, such as a stock or bond.
Represents a statement for either a bank account or a credit card account.
Represents the <STATUS> OFX SGML entity.
Main header file containing the LibOfx API.
int message_out(OfxMsgType error_type, const std::string message)
Message output function.
Message IO functionality.
LibOFX internal object code.
int ofx_proc_sgml(LibofxContext *libofx_context, int argc, char *const *argv)
Parses a DTD and OFX file(s)
SGMLApplication::Position position
SGMLApplication::OpenEntityPtr entity_ptr
OFX/SGML parsing functionality.
std::string CharStringtostring(const SGMLApplication::CharString source, std::string &dest)
Convert OpenSP CharString to a C++ STL string.
std::string AppendCharStringtostring(const SGMLApplication::CharString source, std::string &dest)
Append an OpenSP CharString to an existing C++ STL string.
std::string strip_whitespace(const std::string para_string)
Sanitize a string coming from OpenSP.
Various simple functions for type conversion & al.