1 #ifndef OSMIUM_IO_READER_HPP 2 #define OSMIUM_IO_READER_HPP 37 #include <osmium/io/detail/input_format.hpp> 38 #include <osmium/io/detail/queue_util.hpp> 39 #include <osmium/io/detail/read_thread.hpp> 40 #include <osmium/io/detail/read_write.hpp> 56 #include <system_error> 61 # include <sys/wait.h> 74 inline std::size_t get_input_queue_size() noexcept {
78 inline std::size_t get_osmdata_queue_size() noexcept {
108 } m_status = status::okay;
121 std::future<osmium::io::Header> m_header_future{};
126 std::size_t m_file_size = 0;
136 m_read_which_entities = value;
140 m_read_metadata = value;
145 const detail::ParserFactory::create_parser_type& creator,
146 detail::future_string_queue_type& input_queue,
147 detail::future_buffer_queue_type& osmdata_queue,
148 std::promise<osmium::io::Header>&& header_promise,
151 std::promise<osmium::io::Header> promise{std::move(header_promise)};
152 osmium::io::detail::parser_arguments args = {
160 creator(args)->parse();
175 static int execute(
const std::string& command,
const std::string& filename,
int* childpid) {
177 if (pipe(pipefd) < 0) {
178 throw std::system_error{errno, std::system_category(),
"opening pipe failed"};
180 const pid_t pid = fork();
182 throw std::system_error{errno, std::system_category(),
"fork failed"};
186 for (
int i = 0; i < 32; ++i) {
187 if (i != pipefd[1]) {
191 if (dup2(pipefd[1], 1) < 0) {
195 ::open(
"/dev/null", O_RDONLY);
196 ::open(
"/dev/null", O_WRONLY);
201 if (::execlp(command.c_str(), command.c_str(),
"-g", filename.c_str(),
nullptr) < 0) {
221 const std::string protocol{filename.substr(0, filename.find_first_of(
':'))};
222 if (protocol ==
"http" || protocol ==
"https" || protocol ==
"ftp" || protocol ==
"file") {
224 return execute(
"curl", filename, childpid);
226 throw io_error{
"Reading OSM files from the network currently not supported on Windows."};
229 return osmium::io::detail::open_for_reading(filename);
256 template <
typename... TArgs>
258 m_file(file.check()),
259 m_creator(
detail::ParserFactory::instance().get_creator_function(m_file)),
260 m_input_queue(
detail::get_input_queue_size(),
"raw_input"),
261 m_decompressor(m_file.buffer() ?
262 osmium::io::
CompressionFactory::instance().create_decompressor(file.compression(), m_file.buffer(), m_file.buffer_size()) :
263 osmium::io::
CompressionFactory::instance().create_decompressor(file.compression(), open_input_file_or_url(m_file.filename(), &m_childpid))),
264 m_read_thread_manager(*m_decompressor, m_input_queue),
265 m_osmdata_queue(
detail::get_osmdata_queue_size(),
"parser_results"),
266 m_osmdata_queue_wrapper(m_osmdata_queue),
267 m_file_size(m_decompressor->
file_size()) {
269 (void)std::initializer_list<int>{
270 (set_option(args), 0)...
277 std::promise<osmium::io::Header> header_promise;
278 m_header_future = header_promise.get_future();
279 m_thread =
osmium::thread::thread_handler{parser_thread, std::ref(*m_pool), std::ref(m_creator), std::ref(m_input_queue), std::ref(m_osmdata_queue), std::move(header_promise), m_read_which_entities, m_read_metadata};
282 template <
typename... TArgs>
283 explicit Reader(
const std::string& filename, TArgs&&... args) :
287 template <
typename... TArgs>
288 explicit Reader(
const char* filename, TArgs&&... args) :
315 m_status = status::closed;
317 m_read_thread_manager.stop();
319 m_osmdata_queue_wrapper.drain();
322 m_read_thread_manager.close();
330 const pid_t pid = ::waitpid(m_childpid, &status, 0);
331 #pragma GCC diagnostic push 332 #pragma GCC diagnostic ignored "-Wold-style-cast" 333 if (pid < 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
334 throw std::system_error{errno, std::system_category(),
"subprocess returned error"};
336 #pragma GCC diagnostic pop 349 if (m_status == status::error) {
350 throw io_error{
"Can not get header from reader when in status 'error'"};
354 if (m_header_future.valid()) {
355 m_header = m_header_future.get();
359 m_status = status::error;
378 if (m_back_buffers) {
379 if (m_back_buffers.has_nested_buffers()) {
380 buffer = std::move(*m_back_buffers.get_last_nested());
382 buffer = std::move(m_back_buffers);
388 if (m_status != status::okay) {
389 throw io_error{
"Can not read from reader when in status 'closed', 'eof', or 'error'"};
393 m_status = status::eof;
403 buffer = m_osmdata_queue_wrapper.pop();
404 if (detail::at_end_of_data(buffer)) {
405 m_status = status::eof;
406 m_read_thread_manager.close();
410 m_back_buffers = std::move(buffer);
411 buffer = std::move(*m_back_buffers.get_last_nested());
419 m_status = status::error;
429 return m_status == status::eof || m_status == status::closed;
455 return m_decompressor->offset();
468 template <
typename... TArgs>
472 Reader reader{std::forward<TArgs>(args)...};
473 while (
auto read_buffer = reader.read()) {
474 buffer.add_buffer(read_buffer);
485 #endif // OSMIUM_IO_READER_HPP detail::queue_wrapper< osmium::memory::Buffer > m_osmdata_queue_wrapper
Definition: reader.hpp:119
status
Definition: reader.hpp:103
osmium::memory::Buffer read()
Definition: reader.hpp:374
Reader(const osmium::io::File &file, TArgs &&... args)
Definition: reader.hpp:257
type
Definition: entity_bits.hpp:63
std::size_t file_size(int fd)
Definition: file.hpp:109
std::size_t file_size() const noexcept
Definition: reader.hpp:436
bool eof() const
Definition: reader.hpp:428
static Pool & default_instance()
Definition: pool.hpp:180
Reader(const char *filename, TArgs &&... args)
Definition: reader.hpp:288
Definition: location.hpp:554
std::unique_ptr< osmium::io::Decompressor > m_decompressor
Definition: reader.hpp:114
std::size_t committed() const noexcept
Definition: buffer.hpp:356
object or changeset
Definition: entity_bits.hpp:76
detail::future_string_queue_type m_input_queue
Definition: reader.hpp:112
osmium::memory::Buffer read_file(TArgs &&... args)
Definition: reader.hpp:469
osmium::io::File m_file
Definition: reader.hpp:97
Namespace for everything in the Osmium library.
Definition: assembler.hpp:53
void set_option(osmium::osm_entity_bits::type value) noexcept
Definition: reader.hpp:135
osmium::io::detail::ReadThreadManager m_read_thread_manager
Definition: reader.hpp:116
static int execute(const std::string &command, const std::string &filename, int *childpid)
Definition: reader.hpp:175
static void parser_thread(osmium::thread::Pool &pool, const detail::ParserFactory::create_parser_type &creator, detail::future_string_queue_type &input_queue, detail::future_buffer_queue_type &osmdata_queue, std::promise< osmium::io::Header > &&header_promise, osmium::osm_entity_bits::type read_which_entities, osmium::io::read_meta read_metadata)
Definition: reader.hpp:144
Reader(const std::string &filename, TArgs &&... args)
Definition: reader.hpp:283
Definition: reader.hpp:90
~Reader() noexcept
Definition: reader.hpp:298
std::size_t offset() const noexcept
Definition: reader.hpp:454
osmium::io::Header header()
Definition: reader.hpp:348
void set_option(osmium::io::read_meta value) noexcept
Definition: reader.hpp:139
std::size_t get_max_queue_size(const char *queue_name, const std::size_t default_value) noexcept
Definition: config.hpp:83
bool has_nested_buffers() const noexcept
Definition: buffer.hpp:437
void set_option(osmium::thread::Pool &pool) noexcept
Definition: reader.hpp:131
Definition: buffer.hpp:97
static int open_input_file_or_url(const std::string &filename, int *childpid)
Definition: reader.hpp:220
detail::future_buffer_queue_type m_osmdata_queue
Definition: reader.hpp:118
read_meta
Definition: file_format.hpp:54
Definition: entity_bits.hpp:67
Definition: compression.hpp:137
detail::ParserFactory::create_parser_type m_creator
Definition: reader.hpp:101
void close()
Definition: reader.hpp:314