Values can now be streamed to XML, and all the types they refer to.

This commit is contained in:
John Wiegley 2009-02-01 01:48:07 -04:00
parent cac7d02dd8
commit 9f8997f1b5
8 changed files with 124 additions and 24 deletions

View file

@ -1228,14 +1228,16 @@ void amount_t::read_xml(std::istream& in)
void amount_t::write_xml(std::ostream& out, const int depth) const
{
xml_print(out, "<amount>\n", depth);
out << xml_str("<amount>\n", depth);
commodity().write_xml(out, depth + 1);
if (has_commodity())
commodity().write_xml(out, depth + 1);
xml_print(out, "<quantity>", depth + 1);
out << quantity_string() << "</quantity>\n";
out << xml_str("<quantity>", depth + 1)
<< quantity_string()
<< "</quantity>\n";
xml_print(out, "</amount>\n", depth);
out << xml_str("</amount>\n", depth);
}
bool amount_t::valid() const

View file

@ -252,4 +252,14 @@ void balance_t::print(std::ostream& out,
}
}
void balance_t::write_xml(std::ostream& out, const int depth) const
{
out << xml_str("<balance>\n", depth);
foreach (const amounts_map::value_type& pair, amounts)
pair.second.write_xml(out, depth + 1);
out << xml_str("</balance>\n", depth);
}
} // namespace ledger

View file

@ -475,6 +475,15 @@ public:
void print(std::ostream& out, const int first_width,
const int latter_width = -1) const;
/** @name XML Serialization
*/
/*@{*/
void read_xml(std::istream& in);
void write_xml(std::ostream& out, const int depth = 0) const;
/*@}*/
/**
* Debugging methods. There are two methods defined to help with
* debugging:

View file

@ -53,4 +53,15 @@ balance_pair_t::value(const optional<datetime_t>& moment,
return none;
}
void balance_pair_t::write_xml(std::ostream& out, const int depth) const
{
out << xml_str("<balance-pair>\n", depth);
quantity().write_xml(out, depth + 1);
if (cost)
cost->write_xml(out, depth + 1);
out << xml_str("</balance-pair>\n", depth);
}
} // namespace ledger

View file

@ -343,6 +343,15 @@ public:
return balance_t::operator==(val);
}
/** @name XML Serialization
*/
/*@{*/
void read_xml(std::istream& in);
void write_xml(std::ostream& out, const int depth = 0) const;
/*@}*/
/**
* Debugging methods. There is only one method specifically for
* balance pairs to help with debugging:

View file

@ -769,32 +769,25 @@ void commodity_t::read_xml(std::istream& in)
void commodity_t::write_xml(std::ostream& out, const int depth) const
{
xml_print(out, "<commodity flags=\"", depth);
out << xml_str("<commodity flags=\"", depth);
if (! (flags() & COMMODITY_STYLE_SUFFIXED)) out << 'P';
if (flags() & COMMODITY_STYLE_SEPARATED) out << 'S';
if (flags() & COMMODITY_STYLE_THOUSANDS) out << 'T';
if (flags() & COMMODITY_STYLE_EUROPEAN) out << 'E';
out << "\">\n";
#if 0
// jww (2006-03-02): !!!
if (price) {
for (int i = 0; i < depth + 2; i++) out << ' ';
out << "<symbol>" << base->symbol << "</symbol>\n";
for (int i = 0; i < depth + 2; i++) out << ' ';
out << "<price>\n";
xml_write_amount(out, *price, depth + 4);
for (int i = 0; i < depth + 2; i++) out << ' ';
out << "</price>\n";
} else
#endif
{
xml_print(out, "<symbol>", depth + 1);
out << symbol() << "</symbol>\n";
}
out << xml_str("<symbol>", depth + 1) << symbol() << "</symbol>\n";
xml_print(out, "</commodity>\n", depth);
#if 0
// jww (2009-02-01): If this is an annotated commodity, more has to happen
if (price) {
out << xml_str("<price>", depth + 1);
price->write_xml(out, depth + 2);
out << xml_str("</price>\n", depth + 1);
}
#endif
out << xml_str("</commodity>\n", depth);
}
bool compare_amount_commodities::operator()(const amount_t * left,

View file

@ -1804,6 +1804,63 @@ void value_t::write(std::ostream& out) const
throw_(value_error, "Cannot read " << label() << " to a stream");
}
void value_t::write_xml(std::ostream& out, const int depth) const
{
out << xml_str("<value>\n", depth);
switch (type()) {
case VOID:
out << xml_str("<void />\n", depth + 1);
break;
case BOOLEAN:
out << xml_str("<bool>", depth + 1)
<< (as_boolean() ? "true" : "false")
<< "</bool>\n";
break;
case DATETIME:
out << xml_str("<datetime>", depth + 1)
<< format_datetime(as_datetime())
<< "</datetime>\n";
break;
case DATE:
out << xml_str("<date>", depth + 1)
<< format_date(as_date())
<< "</date>\n";
break;
case INTEGER:
out << xml_str("<integer>", depth + 1)
<< as_long()
<< "</integer>\n";
break;
case AMOUNT:
as_amount().write_xml(out, depth + 1);
break;
case BALANCE:
as_balance().write_xml(out, depth + 1);
break;
case BALANCE_PAIR:
as_balance_pair().write_xml(out, depth + 1);
break;
case STRING:
out << xml_str("<string>", depth + 1)
<< as_string()
<< "</string>\n";
break;
case SEQUENCE:
out << xml_str("<sequence>\n", depth + 1);
foreach (const value_t& v, as_sequence())
v.write_xml(out, depth + 2);
out << xml_str("</sequence>\n", depth + 1);
break;
case POINTER:
default:
throw_(value_error, "Cannot output " << label() << " as XML");
break;
}
out << xml_str("</value>\n", depth);
}
bool value_t::valid() const
{
switch (type()) {

View file

@ -897,6 +897,15 @@ public:
void read(const char *& data);
void write(std::ostream& out) const;
/** @name XML Serialization
*/
/*@{*/
void read_xml(std::istream& in);
void write_xml(std::ostream& out, const int depth = 0) const;
/*@}*/
/**
* Debugging methods.
*/