Skip to content

Commit d2e2bcc

Browse files
authored
Merge pull request #388 from yarray/master
Fix handling of global discussions files from planet.osm.org
2 parents 5ad2bab + c33de34 commit d2e2bcc

File tree

2 files changed

+55
-16
lines changed

2 files changed

+55
-16
lines changed

include/osmium/builder/osm_object_builder.hpp

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ namespace osmium {
324324

325325
class ChangesetDiscussionBuilder : public Builder {
326326

327-
osmium::ChangesetComment* m_comment = nullptr;
327+
std::size_t m_comment_offset = std::numeric_limits<std::size_t>::max();
328328

329329
void add_user(osmium::ChangesetComment& comment, const char* user, const std::size_t length) {
330330
if (length > osmium::max_osm_string_length) {
@@ -343,6 +343,20 @@ namespace osmium {
343343
add_padding(true);
344344
}
345345

346+
bool has_open_comment() const noexcept {
347+
return m_comment_offset != std::numeric_limits<std::size_t>::max();
348+
}
349+
350+
// Get current comment pointer (recalculated each time to handle buffer reallocation)
351+
osmium::ChangesetComment* get_comment_ptr() {
352+
if (!has_open_comment()) {
353+
return nullptr;
354+
}
355+
return reinterpret_cast<osmium::ChangesetComment*>(
356+
buffer().data() + buffer().committed() + m_comment_offset
357+
);
358+
}
359+
346360
public:
347361

348362
explicit ChangesetDiscussionBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
@@ -362,32 +376,46 @@ namespace osmium {
362376
ChangesetDiscussionBuilder& operator=(ChangesetDiscussionBuilder&&) = delete;
363377

364378
~ChangesetDiscussionBuilder() {
365-
assert(!m_comment && "You have to always call both add_comment() and then add_comment_text() in that order for each comment!");
379+
assert(!has_open_comment() && "You have to always call both add_comment() and then add_comment_text() in that order for each comment!");
366380
add_padding();
367381
}
368382

369383
void add_comment(osmium::Timestamp date, osmium::user_id_type uid, const char* user) {
370-
assert(!m_comment && "You have to always call both add_comment() and then add_comment_text() in that order for each comment!");
371-
m_comment = reserve_space_for<osmium::ChangesetComment>();
372-
new (m_comment) osmium::ChangesetComment{date, uid};
384+
assert(!has_open_comment() && "You have to always call both add_comment() and then add_comment_text() in that order for each comment!");
385+
386+
// Store offset instead of pointer to handle buffer reallocation
387+
m_comment_offset = buffer().written() - buffer().committed();
388+
389+
auto* comment = reserve_space_for<osmium::ChangesetComment>();
390+
new (comment) osmium::ChangesetComment{date, uid};
373391
add_size(sizeof(ChangesetComment));
374-
add_user(*m_comment, user, std::strlen(user));
392+
393+
add_user(*comment, user, std::strlen(user));
375394
}
376395

377396
void add_comment_text(const char* text) {
378-
assert(m_comment && "You have to always call both add_comment() and then add_comment_text() in that order for each comment!");
379-
osmium::ChangesetComment& comment = *m_comment;
380-
m_comment = nullptr;
381-
add_text(comment, text, std::strlen(text));
397+
assert(has_open_comment() && "You have to always call both add_comment() and then add_comment_text() in that order for each comment!");
398+
399+
// Get fresh pointer each time to handle buffer reallocation
400+
auto* comment = get_comment_ptr();
401+
402+
// Invalidate offset to ensure right adding order
403+
m_comment_offset = std::numeric_limits<std::size_t>::max();
404+
405+
add_text(*comment, text, std::strlen(text));
382406
}
383407

384408
void add_comment_text(const std::string& text) {
385-
assert(m_comment && "You have to always call both add_comment() and then add_comment_text() in that order for each comment!");
386-
osmium::ChangesetComment& comment = *m_comment;
387-
m_comment = nullptr;
388-
add_text(comment, text.c_str(), text.size());
409+
assert(has_open_comment() && "You have to always call both add_comment() and then add_comment_text() in that order for each comment!");
410+
411+
// Get fresh pointer each time to handle buffer reallocation
412+
auto* comment = get_comment_ptr();
413+
414+
// Invalidate offset to ensure right adding order
415+
m_comment_offset = std::numeric_limits<std::size_t>::max();
416+
417+
add_text(*comment, text.c_str(), text.size());
389418
}
390-
391419
}; // class ChangesetDiscussionBuilder
392420

393421
#define OSMIUM_FORWARD(setter) \

include/osmium/io/bzip2_compression.hpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,18 @@ namespace osmium {
313313
throw bzip2_error{"bzip2 error: read open failed", bzerror};
314314
}
315315
} else {
316-
m_stream_end = true;
316+
// Close current stream and try to open a new one for multi-stream files
317+
::BZ2_bzReadClose(&bzerror, m_bzfile);
318+
if (bzerror != BZ_OK) {
319+
throw bzip2_error{"bzip2 error: read close failed", bzerror};
320+
}
321+
// Try to open a new stream - there might be more bzip2 streams concatenated
322+
m_bzfile = ::BZ2_bzReadOpen(&bzerror, m_file.file(), 0, 0, nullptr, 0);
323+
if (!m_bzfile || bzerror != BZ_OK) {
324+
// If we can't open a new stream, we've truly reached the end
325+
m_stream_end = true;
326+
m_bzfile = nullptr;
327+
}
317328
}
318329
} else {
319330
m_stream_end = true;

0 commit comments

Comments
 (0)