Skip to content

Commit e970573

Browse files
committed
Add Writer::set_header() function to set header after constructing
This function has to be called before any data is written. Setting the header later is sometimes useful, when we want to open a file (for instance to immediately throw an error if this fails) and only later know the header (for instance after reading an input file).
1 parent 9d5b890 commit e970573

1 file changed

Lines changed: 33 additions & 8 deletions

File tree

include/osmium/io/writer.hpp

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ namespace osmium {
111111

112112
osmium::memory::Buffer m_buffer{};
113113

114+
osmium::io::Header m_header;
115+
114116
size_t m_buffer_size = default_buffer_size;
115117

116118
std::future<std::size_t> m_write_future{};
@@ -128,6 +130,9 @@ namespace osmium {
128130
closed = 2 // close() called successfully
129131
} m_status = status::okay;
130132

133+
// Has the header already bin written to the file?
134+
bool m_header_written = false;
135+
131136
// This function will run in a separate thread.
132137
static void write_thread(detail::future_string_queue_type& output_queue,
133138
std::unique_ptr<osmium::io::Compressor>&& compressor,
@@ -140,13 +145,29 @@ namespace osmium {
140145
write_thread();
141146
}
142147

148+
void write_header() {
149+
if (m_header.get("generator").empty()) {
150+
m_header.set("generator", "libosmium/" LIBOSMIUM_VERSION_STRING);
151+
}
152+
153+
m_output->write_header(m_header);
154+
155+
m_header_written = true;
156+
}
157+
143158
void do_write(osmium::memory::Buffer&& buffer) {
159+
if (!m_header_written) {
160+
write_header();
161+
}
144162
if (buffer && buffer.committed() > 0) {
145163
m_output->write_buffer(std::move(buffer));
146164
}
147165
}
148166

149167
void do_flush() {
168+
if (!m_header_written) {
169+
write_header();
170+
}
150171
if (m_notification) {
151172
osmium::thread::check_for_exception(m_write_future);
152173
}
@@ -256,11 +277,9 @@ namespace osmium {
256277
options.pool = &thread::Pool::default_instance();
257278
}
258279

259-
m_output = osmium::io::detail::OutputFormatFactory::instance().create_output(*options.pool, m_file, m_output_queue);
280+
m_header = options.header;
260281

261-
if (options.header.get("generator").empty()) {
262-
options.header.set("generator", "libosmium/" LIBOSMIUM_VERSION_STRING);
263-
}
282+
m_output = osmium::io::detail::OutputFormatFactory::instance().create_output(*options.pool, m_file, m_output_queue);
264283

265284
std::unique_ptr<osmium::io::Compressor> compressor =
266285
CompressionFactory::instance().create_compressor(file.compression(),
@@ -270,10 +289,6 @@ namespace osmium {
270289
std::promise<std::size_t> write_promise;
271290
m_write_future = write_promise.get_future();
272291
m_thread = osmium::thread::thread_handler{write_thread, std::ref(m_output_queue), std::move(compressor), std::move(write_promise), &m_notification};
273-
274-
ensure_cleanup([&](){
275-
m_output->write_header(options.header);
276-
});
277292
}
278293

279294
template <typename... TArgs>
@@ -315,6 +330,16 @@ namespace osmium {
315330
m_buffer_size = size;
316331
}
317332

333+
/**
334+
* Set header. This will overwrite a header set in the constructor.
335+
*
336+
* Has to be called before writing anything to the file, otherwise
337+
* this will not do anything.
338+
*/
339+
void set_header(const osmium::io::Header& header) {
340+
m_header = header;
341+
}
342+
318343
/**
319344
* Flush the internal buffer if it contains any data. This is
320345
* usually not needed as the buffer gets flushed on close()

0 commit comments

Comments
 (0)