Bryce Harrington wrote:
Can you show us an example of the before/after code? I'm curious what the existing code looks like, and how it'll get streamlined with the new stuff.
I'll paste below what repr-io.cpp's output section would look like with streams (omitting some stuff). It is just an example. I would expect that we would have something like Inkscape::IO::ostream or ozstream. But I have actually tested it, and it works, and does .svgz without a pipe. It looks very readable to me, at least (at least as well as the previous printfs). Note how save_file() and save_file_gzip() can now use the same code.
FYI: we have been using Mental's Inkscape::SVGOStringStream for inserting text data into Repr nodes for months now, and it works very, very well.
Also, take a look at my ftos code - this was written as a part of a iostream subclassing thing I did, and worked pretty good. I'd love to see this incorporated since it provides a better approach to formatting numbers (so you can say x="4.21" instead of x="4.209999999").
I think it would fit in easily as the code that implements the operator overload for <<(double) and <<(float)
Bob
===== SNIP SNIP ========
//######################################################################### //### W R I T E //#########################################################################
static void sp_repr_quote_write (std::ostream &outs, const gchar * val) { if (!val) return;
for (; *val != '\0'; val++) { switch (*val) { case '"': outs << """; break; case '&': outs << "&"; break; case '<': outs << "<"; break; case '>': outs << ">"; break; default : outs << *val; break; } } }
static void sp_repr_write_stream_element (SPRepr *repr, std::ostream &outs, gint indent_level, gboolean add_whitespace) { gint i;
g_return_if_fail (repr != NULL);
if ( indent_level > 16 ) indent_level = 16;
if (add_whitespace) { for ( i = 0 ; i < indent_level ; i++ ) { outs << " "; } }
outs << "<" << sp_repr_name (repr);
// if this is a <text> element, suppress formatting whitespace // for its content and children:
if (!strcmp(sp_repr_name(repr), "text")) { add_whitespace = false; }
SPReprAttr *attr; for ( attr = repr->attributes ; attr != NULL ; attr = attr->next ) { gchar const * const key = SP_REPR_ATTRIBUTE_KEY(attr); gchar const * const val = SP_REPR_ATTRIBUTE_VALUE(attr); outs << "\n"; for ( i = 0 ; i < indent_level + 1 ; i++ ) { outs << " "; } outs << " " << key << '"'; sp_repr_quote_write (outs, val); outs << '"'; }
gboolean loose = TRUE; SPRepr *child; for (child = repr->children; child != NULL; child = child->next) { if (child->type == SP_XML_TEXT_NODE) { loose = FALSE; break; } } if (repr->children) { outs << ">"; if (loose && add_whitespace) { outs << "\n"; } for (child = repr->children; child != NULL; child = child->next) { sp_repr_write_stream (child, outs, ( loose) ? (indent_level + 1) : 0, add_whitespace); }
if (loose && add_whitespace) { for (i = 0; i < indent_level; i++) { outs << " "; } } outs << "</" << sp_repr_name (repr) << ">"; } else { outs << " />"; }
// text elements cannot nest, so we can output newline // after closing text
if (add_whitespace || !strcmp (sp_repr_name (repr), "text")) { outs << "\n"; } }
static void sp_repr_write_stream (SPRepr *repr, std::ostream &outs, gint indent_level, gboolean add_whitespace) { if (repr->type == SP_XML_TEXT_NODE) { sp_repr_quote_write (outs, sp_repr_content (repr)); } else if (repr->type == SP_XML_COMMENT_NODE) { outs << "<!--" << sp_repr_content (repr) << "-->"; } else if (repr->type == SP_XML_ELEMENT_NODE) { sp_repr_write_stream_element(repr, outs, indent_level, add_whitespace); } else { g_assert_not_reached(); } }
void sp_repr_save_stream (SPReprDoc *doc, std::ostream &outs) {
outs << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n";
const gchar *str = sp_repr_attr ((SPRepr *) doc, "doctype"); if (str) outs << str;
SPRepr *repr = sp_repr_document_first_child(doc); for ( repr = sp_repr_document_first_child(doc) ; repr ; repr = sp_repr_next(repr) ) { sp_repr_write_stream(repr, outs, 0, TRUE); if ( repr->type == SP_XML_COMMENT_NODE ) { outs << '\n'; } } }
/* Returns TRUE if file successfully saved; FALSE if not */ gboolean sp_repr_save_file (SPReprDoc *doc, const gchar *filename) { if (filename == NULL) { return false; }
std::ofstream outs(filename);
sp_repr_save_stream (doc, outs);
outs.close();
return true; }
/* Returns TRUE if file successfully saved; FALSE if not */ gboolean sp_repr_save_file_gzip (SPReprDoc *doc, const gchar *filename) { if (filename == NULL) { return false; }
ogzstream outs(filename);
sp_repr_save_stream (doc, outs);
outs.close();
return true; }
void sp_repr_print(SPRepr *repr) { sp_repr_write_stream (repr, std::cout, 0, true); }