diff --git a/src/util/delayed_index_maps.hpp b/src/util/delayed_index_maps.hpp index 4f1cd2c8..66088e78 100644 --- a/src/util/delayed_index_maps.hpp +++ b/src/util/delayed_index_maps.hpp @@ -59,7 +59,12 @@ void Reader::handle(DelayedIndexMapsData& d) { template void Writer::handle(const DelayedIndexMapsData& d) { if (!d.unread_data.empty()) { - handle(d.unread_data); // TODO: how to handle filenames + if (d.unread_data == _("\n")) { + // this is not interesting, it is only used to make unread_data nonempty (see above) + // we don't need to write it + } else { + handle(d.unread_data); // TODO: how to handle filenames + } } else { handle(d.read_data); } diff --git a/src/util/io/writer.cpp b/src/util/io/writer.cpp index c0732ed9..182db49b 100644 --- a/src/util/io/writer.cpp +++ b/src/util/io/writer.cpp @@ -17,7 +17,7 @@ // ----------------------------------------------------------------------------- : Writer Writer::Writer(const OutputStreamP& output, Version file_app_version) - : indentation(0), just_opened(false) + : indentation(0) , output(output), stream(*output) { stream.WriteString(BYTE_ORDER_MARK); @@ -27,27 +27,35 @@ Writer::Writer(const OutputStreamP& output, Version file_app_version) void Writer::enterBlock(const Char* name) { - // indenting into a sub-block? - if (just_opened) { - writeKey(); - stream.WriteString(_(":\n")); - } // don't write the key yet - indentation += 1; - opened_key = cannocial_name_form(name); - just_opened = true; + pending_opened.push_back(name); } void Writer::exitBlock() { - assert(indentation > 0); - indentation -= 1; - just_opened = false; + if (pending_opened.empty()) { + assert(indentation > 0); + indentation -= 1; + } else { + // this block was apparently empty, ignore it + pending_opened.pop_back(); + } } -void Writer::writeKey() { - writeIndentation(); - writeUTF8(stream, opened_key); +void Writer::writePending() { + // In enterBlock we have delayed the actual writing of the keys until this point + // here we write all the pending keys, and increase indentation along the way. + for (size_t i = 0 ; i < pending_opened.size() ; ++i) { + if (i > 0) { + // before entering a sub-block, write a colon after the parent's name + stream.WriteString(_(":\n")); + } + indentation += 1; + writeIndentation(); + writeUTF8(stream, cannocial_name_form(pending_opened[i])); + } + pending_opened.clear(); } + void Writer::writeIndentation() { for(int i = 1 ; i < indentation ; ++i) { stream.PutChar(_('\t')); @@ -57,15 +65,14 @@ void Writer::writeIndentation() { // ----------------------------------------------------------------------------- : Handling basic types void Writer::handle(const String& value) { - if (!just_opened) { + if (pending_opened.empty()) { throw InternalError(_("Can only write a value in a key that was just opened")); } + writePending(); // write indentation and key - writeKey(); - writeUTF8(stream, _(": ")); if (value.find_first_of(_('\n')) != String::npos || (!value.empty() && isSpace(value.GetChar(0)))) { // multiline string, or contains leading whitespace - stream.PutChar(_('\n')); + stream.WriteString(_(":\n")); indentation += 1; // split lines, and write each line size_t start = 0, end, size = value.size(); @@ -87,10 +94,10 @@ void Writer::handle(const String& value) { } indentation -= 1; } else { + stream.WriteString(_(": ")); writeUTF8(stream, value); } stream.PutChar(_('\n')); - just_opened = false; } template <> void Writer::handle(const int& value) { diff --git a/src/util/io/writer.hpp b/src/util/io/writer.hpp index a572b08c..49ba2947 100644 --- a/src/util/io/writer.hpp +++ b/src/util/io/writer.hpp @@ -77,10 +77,8 @@ class Writer { // --------------------------------------------------- : Data /// Indentation of the current block int indentation; - /// Did we just open a block (i.e. not written any lines of it)? - bool just_opened; - /// Last key opened - String opened_key; + /// Blocks opened to which nothing has been written + vector pending_opened; /// Output stream we are writing to OutputStreamP output; @@ -94,8 +92,8 @@ class Writer { /// Leave the block we are in void exitBlock(); - /// Write the opened_key and the required indentation - void writeKey(); + /// Write the pending_opened with the required indentation + void writePending(); /// Output some taps to represent the indentation level void writeIndentation(); };