(truncated): Simplified this method, and added schemes for truncating

at the beginning and middle of a string (neither of which seems better
than truncating at the front).  (output_xml_string): Change xml_string
to output_xml_string, for simplicity's sake.  Also, < and > are now
output as &lt; and &gt;.  (format_last_entry): Use output_xml_string
for the account name as well as the code, payee and note.
This commit is contained in:
John Wiegley 2005-02-14 07:44:40 +00:00
parent 65b2181860
commit 38b126edbd

View file

@ -12,12 +12,35 @@ namespace ledger {
std::string truncated(const std::string& str, unsigned int width) std::string truncated(const std::string& str, unsigned int width)
{ {
const int len = str.length();
if (len <= width)
return str;
assert(width < 254);
char buf[256]; char buf[256];
std::memset(buf, '\0', 255); #if 1
assert(width < 256); // This method truncates at the end.
std::strncpy(buf, str.c_str(), str.length()); std::strncpy(buf, str.c_str(), width - 2);
if (buf[width]) buf[width - 2] = '.';
std::strcpy(&buf[width - 2], ".."); buf[width - 1] = '.';
#else
#if 0
// This method truncates at the beginning.
std::strncpy(buf, str.c_str() + (len - width), width);
buf[0] = '.';
buf[1] = '.';
#else
// This method truncates in the middle.
std::strncpy(buf, str.c_str(), width / 2);
std::strncpy(buf + width / 2,
str.c_str() + (len - (width / 2 + width % 2)),
width / 2 + width % 2);
buf[width / 2 - 1] = '.';
buf[width / 2] = '.';
#endif
#endif
buf[width] = '\0';
return buf; return buf;
} }
@ -608,21 +631,24 @@ void xml_write_value(std::ostream& out, const value_t& value,
out << "</value>\n"; out << "</value>\n";
} }
std::string xml_string(const std::string& str) void output_xml_string(std::ostream& out, const std::string& str)
{ {
std::string::size_type pos = 0; for (const char * s = str.c_str(); *s; s++) {
std::string::size_type index = str.find('&', pos); switch (*s) {
if (index == std::string::npos) case '<':
return str; out << "&lt;";
break;
std::string temp; case '>':
while (index != std::string::npos) { out << "&rt;";
temp += std::string(str, pos, index) + "&amp;"; break;
pos = index + 1; case '&':
index = str.find('&', pos); out << "&amp;";
break;
default:
out << *s;
break;
}
} }
return temp;
} }
void format_xml_entries::format_last_entry() void format_xml_entries::format_last_entry()
@ -639,13 +665,17 @@ void format_xml_entries::format_last_entry()
else if (last_entry->state == entry_t::PENDING) else if (last_entry->state == entry_t::PENDING)
output_stream << " <en:pending/>\n"; output_stream << " <en:pending/>\n";
if (! last_entry->code.empty()) if (! last_entry->code.empty()) {
output_stream << " <en:code>" << xml_string(last_entry->code) output_stream << " <en:code>";
<< "</en:code>\n"; output_xml_string(output_stream, last_entry->code);
output_stream << "</en:code>\n";
}
if (! last_entry->payee.empty()) if (! last_entry->payee.empty()) {
output_stream << " <en:payee>" << xml_string(last_entry->payee) output_stream << " <en:payee>";
<< "</en:payee>\n"; output_xml_string(output_stream, last_entry->payee);
output_stream << "</en:payee>\n";
}
bool first = true; bool first = true;
for (transactions_list::const_iterator i = last_entry->transactions.begin(); for (transactions_list::const_iterator i = last_entry->transactions.begin();
@ -671,7 +701,10 @@ void format_xml_entries::format_last_entry()
name = "[TOTAL]"; name = "[TOTAL]";
else if (name == "<Unknown>") else if (name == "<Unknown>")
name = "[UNKNOWN]"; name = "[UNKNOWN]";
output_stream << " <tr:account>" << name << "</tr:account>\n";
output_stream << " <tr:account>";
output_xml_string(output_stream, name);
output_stream << "</tr:account>\n";
} }
output_stream << " <tr:amount>\n"; output_stream << " <tr:amount>\n";
@ -688,9 +721,11 @@ void format_xml_entries::format_last_entry()
output_stream << " </tr:cost>\n"; output_stream << " </tr:cost>\n";
} }
if (! (*i)->note.empty()) if (! (*i)->note.empty()) {
output_stream << " <tr:note>" << xml_string((*i)->note) output_stream << " <tr:note>";
<< "</tr:note>\n"; output_xml_string(output_stream, (*i)->note);
output_stream << "</tr:note>\n";
}
if (show_totals) { if (show_totals) {
output_stream << " <total>\n"; output_stream << " <total>\n";