1 #ifndef OSMIUM_IO_READER_HPP 2 #define OSMIUM_IO_READER_HPP 42 #include <system_error> 47 # include <sys/wait.h> 55 #include <osmium/io/detail/input_format.hpp> 56 #include <osmium/io/detail/read_thread.hpp> 57 #include <osmium/io/detail/read_write.hpp> 58 #include <osmium/io/detail/queue_util.hpp> 73 inline size_t get_input_queue_size() noexcept {
78 inline size_t get_osmdata_queue_size() noexcept {
123 m_options.read_which_entities = value;
127 m_options.read_metadata = value;
132 detail::future_string_queue_type& input_queue,
133 detail::future_buffer_queue_type& osmdata_queue,
134 std::promise<osmium::io::Header>&& header_promise,
135 osmium::io::detail::reader_options options) {
136 std::promise<osmium::io::Header> promise = std::move(header_promise);
137 const auto creator = detail::ParserFactory::instance().get_creator_function(file);
138 const auto parser = creator(input_queue, osmdata_queue, promise, options);
154 static int execute(
const std::string& command,
const std::string& filename,
int* childpid) {
156 if (pipe(pipefd) < 0) {
157 throw std::system_error(errno, std::system_category(),
"opening pipe failed");
159 const pid_t pid = fork();
161 throw std::system_error(errno, std::system_category(),
"fork failed");
165 for (
int i = 0; i < 32; ++i) {
166 if (i != pipefd[1]) {
170 if (dup2(pipefd[1], 1) < 0) {
174 ::open(
"/dev/null", O_RDONLY);
175 ::open(
"/dev/null", O_WRONLY);
180 if (::execlp(command.c_str(), command.c_str(),
"-g", filename.c_str(),
nullptr) < 0) {
200 std::string protocol = filename.substr(0, filename.find_first_of(
':'));
201 if (protocol ==
"http" || protocol ==
"https" || protocol ==
"ftp" || protocol ==
"file") {
203 return execute(
"curl", filename, childpid);
205 throw io_error(
"Reading OSM files from the network currently not supported on Windows.");
208 return osmium::io::detail::open_for_reading(filename);
236 template <
typename... TArgs>
238 m_file(file.check()),
241 m_input_queue(
detail::get_input_queue_size(),
"raw_input"),
242 m_decompressor(m_file.buffer() ?
243 osmium::io::
CompressionFactory::instance().create_decompressor(file.compression(), m_file.buffer(), m_file.buffer_size()) :
244 osmium::io::
CompressionFactory::instance().create_decompressor(file.compression(), open_input_file_or_url(m_file.filename(), &m_childpid))),
245 m_read_thread_manager(*m_decompressor, m_input_queue),
246 m_osmdata_queue(
detail::get_osmdata_queue_size(),
"parser_results"),
247 m_osmdata_queue_wrapper(m_osmdata_queue),
251 m_file_size(m_decompressor->
file_size()) {
253 (void)std::initializer_list<int>{
254 (set_option(args), 0)...
257 std::promise<osmium::io::Header> header_promise;
258 m_header_future = header_promise.get_future();
259 m_thread =
osmium::thread::thread_handler{parser_thread, std::ref(m_file), std::ref(m_input_queue), std::ref(m_osmdata_queue), std::move(header_promise), m_options};
262 template <
typename... TArgs>
263 explicit Reader(
const std::string& filename, TArgs&&... args) :
267 template <
typename... TArgs>
268 explicit Reader(
const char* filename, TArgs&&... args) :
295 m_status = status::closed;
297 m_read_thread_manager.stop();
299 m_osmdata_queue_wrapper.drain();
302 m_read_thread_manager.close();
310 const pid_t pid = ::waitpid(m_childpid, &status, 0);
311 #pragma GCC diagnostic push 312 #pragma GCC diagnostic ignored "-Wold-style-cast" 313 if (pid < 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
314 throw std::system_error(errno, std::system_category(),
"subprocess returned error");
316 #pragma GCC diagnostic pop 329 if (m_status == status::error) {
330 throw io_error(
"Can not get header from reader when in status 'error'");
334 if (m_header_future.valid()) {
335 m_header = m_header_future.
get();
337 m_status = status::eof;
342 m_status = status::error;
361 if (m_status != status::okay ||
363 throw io_error(
"Can not read from reader when in status 'closed', 'eof', or 'error'");
372 buffer = m_osmdata_queue_wrapper.pop();
373 if (detail::at_end_of_data(buffer)) {
374 m_status = status::eof;
375 m_read_thread_manager.close();
384 m_status = status::error;
394 return m_status == status::eof || m_status == status::closed;
420 return m_decompressor->offset();
433 template <
typename... TArgs>
437 Reader reader(std::forward<TArgs>(args)...);
450 #endif // OSMIUM_IO_READER_HPP detail::queue_wrapper< osmium::memory::Buffer > m_osmdata_queue_wrapper
Definition: reader.hpp:111
status
Definition: reader.hpp:95
osmium::memory::Buffer read()
Definition: reader.hpp:358
Reader(const osmium::io::File &file, TArgs &&... args)
Definition: reader.hpp:237
type
Definition: entity_bits.hpp:63
size_t file_size(int fd)
Definition: file.hpp:67
bool eof() const
Definition: reader.hpp:393
int m_childpid
Definition: reader.hpp:102
Reader(const char *filename, TArgs &&... args)
Definition: reader.hpp:268
std::future< osmium::io::Header > m_header_future
Definition: reader.hpp:113
Definition: reader_iterator.hpp:39
std::unique_ptr< osmium::io::Decompressor > m_decompressor
Definition: reader.hpp:106
detail::future_string_queue_type m_input_queue
Definition: reader.hpp:104
osmium::memory::Buffer read_file(TArgs &&... args)
Definition: reader.hpp:434
osmium::io::File m_file
Definition: reader.hpp:93
Namespace for everything in the Osmium library.
Definition: assembler.hpp:73
void set_option(osmium::osm_entity_bits::type value) noexcept
Definition: reader.hpp:122
void add_buffer(const Buffer &buffer)
Definition: buffer.hpp:500
osmium::io::detail::ReadThreadManager m_read_thread_manager
Definition: reader.hpp:108
size_t file_size() const noexcept
Definition: reader.hpp:401
static int execute(const std::string &command, const std::string &filename, int *childpid)
Definition: reader.hpp:154
Reader(const std::string &filename, TArgs &&... args)
Definition: reader.hpp:263
Definition: reader.hpp:91
~Reader() noexcept
Definition: reader.hpp:278
osmium::io::Header header()
Definition: reader.hpp:328
void set_option(osmium::io::read_meta value) noexcept
Definition: reader.hpp:126
size_t committed() const noexcept
Definition: buffer.hpp:259
size_t get_max_queue_size(const char *queue_name, size_t default_value) noexcept
Definition: config.hpp:69
Definition: buffer.hpp:97
size_t m_file_size
Definition: reader.hpp:118
osmium::thread::thread_handler m_thread
Definition: reader.hpp:116
static int open_input_file_or_url(const std::string &filename, int *childpid)
Definition: reader.hpp:199
detail::future_buffer_queue_type m_osmdata_queue
Definition: reader.hpp:110
osmium::io::detail::reader_options m_options
Definition: reader.hpp:120
osmium::io::Header m_header
Definition: reader.hpp:114
read_meta
Definition: file_format.hpp:52
Definition: entity_bits.hpp:67
Definition: compression.hpp:138
size_t offset() const noexcept
Definition: reader.hpp:419
static void parser_thread(const osmium::io::File &file, detail::future_string_queue_type &input_queue, detail::future_buffer_queue_type &osmdata_queue, std::promise< osmium::io::Header > &&header_promise, osmium::io::detail::reader_options options)
Definition: reader.hpp:131
std::string get(const std::string &key, const std::string &default_value="") const noexcept
Definition: options.hpp:125
void close()
Definition: reader.hpp:294
size_t commit()
Definition: buffer.hpp:354