1#ifndef OSMIUM_IO_BZIP2_COMPRESSION_HPP
2#define OSMIUM_IO_BZIP2_COMPRESSION_HPP
46#include <osmium/io/detail/read_write.hpp>
59#include <system_error>
79 if (error_code == BZ_IO_ERROR) {
90 [[noreturn]]
inline void throw_bzip2_error(BZFILE* bzfile,
const char* msg,
const int bzlib_error) {
91 std::string error{
"bzip2 error: "};
94 int errnum = bzlib_error;
96 error += std::to_string(bzlib_error);
98 error += ::BZ2_bzerror(bzfile, &errnum);
105 FILE* m_file =
nullptr;
109 file_wrapper()
noexcept =
default;
111 file_wrapper(
const int fd,
const char* mode) {
113 throw std::system_error{errno, std::system_category(),
"file descriptor must be >= 0"};
116 osmium::detail::disable_invalid_parameter_handler diph;
118 m_file = fdopen(fd, mode);
125 throw std::system_error{errno, std::system_category(),
"fdopen failed"};
129 file_wrapper(
const file_wrapper&) =
delete;
130 file_wrapper& operator=(
const file_wrapper&) =
delete;
132 file_wrapper(file_wrapper&&) =
delete;
133 file_wrapper& operator=(file_wrapper&&) =
delete;
135 ~file_wrapper()
noexcept {
137 osmium::detail::disable_invalid_parameter_handler diph;
140 (void)fclose(m_file);
144 FILE* file()
const noexcept {
150 osmium::detail::disable_invalid_parameter_handler diph;
153 FILE* wrapped_file = m_file;
157 if (fileno(wrapped_file) == 1) {
161 if (fclose(wrapped_file) != 0) {
162 throw std::system_error{errno, std::system_category(),
"fclose failed"};
183 osmium::detail::disable_invalid_parameter_handler diph;
188 throw bzip2_error{
"bzip2 error: write open failed", bzerror};
206 void write(
const std::string& data)
override {
207 assert(data.size() < std::numeric_limits<int>::max());
210 osmium::detail::disable_invalid_parameter_handler diph;
213 ::BZ2_bzWrite(&bzerror,
m_bzfile,
const_cast<char*
>(data.data()),
static_cast<int>(data.size()));
214 if (bzerror != BZ_OK && bzerror != BZ_STREAM_END) {
215 detail::throw_bzip2_error(
m_bzfile,
"write failed", bzerror);
222 osmium::detail::disable_invalid_parameter_handler diph;
225 unsigned int nbytes_out_lo32 = 0;
226 unsigned int nbytes_out_hi32 = 0;
227 ::BZ2_bzWriteClose64(&bzerror,
m_bzfile, 0,
nullptr,
nullptr, &nbytes_out_lo32, &nbytes_out_hi32);
230 osmium::io::detail::reliable_fsync(fileno(
m_file.file()));
233 if (bzerror != BZ_OK) {
234 throw bzip2_error{
"bzip2 error: write close failed", bzerror};
236 m_file_size =
static_cast<std::size_t
>(
static_cast<uint64_t
>(nbytes_out_hi32) << 32U | nbytes_out_lo32);
257 osmium::detail::disable_invalid_parameter_handler diph;
260 m_bzfile = ::BZ2_bzReadOpen(&bzerror,
m_file.file(), 0, 0,
nullptr, 0);
262 throw bzip2_error{
"bzip2 error: read open failed", bzerror};
281 const auto offset = ftell(
m_file.file());
283 osmium::io::detail::remove_buffered_pages(fileno(
m_file.file()),
static_cast<std::size_t
>(offset));
286 osmium::detail::disable_invalid_parameter_handler diph;
294 assert(buffer.size() < std::numeric_limits<int>::max());
295 const int nread = ::BZ2_bzRead(&bzerror,
m_bzfile, &*buffer.begin(),
static_cast<int>(buffer.size()));
296 if (bzerror != BZ_OK && bzerror != BZ_STREAM_END) {
297 detail::throw_bzip2_error(
m_bzfile,
"read failed", bzerror);
299 if (bzerror == BZ_STREAM_END) {
300 if (!feof(
m_file.file())) {
301 void* unused =
nullptr;
303 ::BZ2_bzReadGetUnused(&bzerror,
m_bzfile, &unused, &num_unused);
304 if (bzerror != BZ_OK) {
305 detail::throw_bzip2_error(
m_bzfile,
"get unused failed", bzerror);
307 if (num_unused != 0) {
308 std::string unused_data{
static_cast<const char*
>(unused),
static_cast<std::string::size_type
>(num_unused)};
309 ::BZ2_bzReadClose(&bzerror,
m_bzfile);
310 if (bzerror != BZ_OK) {
311 throw bzip2_error{
"bzip2 error: read close failed", bzerror};
313 assert(unused_data.size() < std::numeric_limits<int>::max());
314 m_bzfile = ::BZ2_bzReadOpen(&bzerror,
m_file.file(), 0, 0, &*unused_data.begin(),
static_cast<int>(unused_data.size()));
316 throw bzip2_error{
"bzip2 error: read open failed", bzerror};
320 ::BZ2_bzReadClose(&bzerror,
m_bzfile);
321 if (bzerror != BZ_OK) {
322 throw bzip2_error{
"bzip2 error: read close failed", bzerror};
325 m_bzfile = ::BZ2_bzReadOpen(&bzerror,
m_file.file(), 0, 0,
nullptr, 0);
326 if (!
m_bzfile || bzerror != BZ_OK) {
336 buffer.resize(
static_cast<std::string::size_type
>(nread));
347 osmium::io::detail::remove_buffered_pages(fileno(
m_file.file()));
350 osmium::detail::disable_invalid_parameter_handler diph;
353 ::BZ2_bzReadClose(&bzerror,
m_bzfile);
356 if (bzerror != BZ_OK) {
357 throw bzip2_error{
"bzip2 error: read close failed", bzerror};
376 m_bzstream.next_in =
const_cast<char*
>(buffer);
377 assert(size < std::numeric_limits<unsigned int>::max());
378 m_bzstream.avail_in =
static_cast<unsigned int>(size);
379 const int result = BZ2_bzDecompressInit(&
m_bzstream, 0, 0);
380 if (result != BZ_OK) {
381 throw bzip2_error{
"bzip2 error: decompression init failed: ", result};
403 const std::size_t buffer_size = 10240;
404 output.resize(buffer_size);
407 const int result = BZ2_bzDecompress(&
m_bzstream);
409 if (result != BZ_OK) {
414 if (result != BZ_OK && result != BZ_STREAM_END) {
415 throw bzip2_error{
"bzip2 error: decompress failed: ", result};
418 output.resize(
static_cast<std::size_t
>(
m_bzstream.next_out - output.data()));
441 inline bool get_registered_bzip2_compression() noexcept {
442 return registered_bzip2_compression;
Definition bzip2_compression.hpp:364
Bzip2BufferDecompressor(const Bzip2BufferDecompressor &)=delete
Bzip2BufferDecompressor(const char *buffer, const std::size_t size)
Definition bzip2_compression.hpp:372
Bzip2BufferDecompressor & operator=(Bzip2BufferDecompressor &&)=delete
Bzip2BufferDecompressor & operator=(const Bzip2BufferDecompressor &)=delete
Bzip2BufferDecompressor(Bzip2BufferDecompressor &&)=delete
std::string read() override
Definition bzip2_compression.hpp:399
~Bzip2BufferDecompressor() noexcept override
Definition bzip2_compression.hpp:391
void close() override
Definition bzip2_compression.hpp:424
bz_stream m_bzstream
Definition bzip2_compression.hpp:368
std::size_t m_buffer_size
Definition bzip2_compression.hpp:367
const char * m_buffer
Definition bzip2_compression.hpp:366
Definition bzip2_compression.hpp:171
BZFILE * m_bzfile
Definition bzip2_compression.hpp:175
Bzip2Compressor(const Bzip2Compressor &)=delete
Bzip2Compressor(Bzip2Compressor &&)=delete
Bzip2Compressor & operator=(const Bzip2Compressor &)=delete
~Bzip2Compressor() noexcept override
Definition bzip2_compression.hpp:198
std::size_t file_size() const override
Definition bzip2_compression.hpp:240
Bzip2Compressor(const int fd, const fsync sync)
Definition bzip2_compression.hpp:179
Bzip2Compressor & operator=(Bzip2Compressor &&)=delete
std::size_t m_file_size
Definition bzip2_compression.hpp:173
void close() override
Definition bzip2_compression.hpp:219
void write(const std::string &data) override
Definition bzip2_compression.hpp:206
detail::file_wrapper m_file
Definition bzip2_compression.hpp:174
Definition bzip2_compression.hpp:246
~Bzip2Decompressor() noexcept override
Definition bzip2_compression.hpp:272
BZFILE * m_bzfile
Definition bzip2_compression.hpp:249
Bzip2Decompressor & operator=(const Bzip2Decompressor &)=delete
detail::file_wrapper m_file
Definition bzip2_compression.hpp:248
Bzip2Decompressor & operator=(Bzip2Decompressor &&)=delete
bool m_stream_end
Definition bzip2_compression.hpp:250
Bzip2Decompressor(Bzip2Decompressor &&)=delete
void close() override
Definition bzip2_compression.hpp:344
Bzip2Decompressor(const int fd)
Definition bzip2_compression.hpp:254
Bzip2Decompressor(const Bzip2Decompressor &)=delete
std::string read() override
Definition bzip2_compression.hpp:280
bool register_compression(osmium::io::file_compression compression, const create_compressor_type &create_compressor, const create_decompressor_type_fd &create_decompressor_fd, const create_decompressor_type_buffer &create_decompressor_buffer)
Definition compression.hpp:196
static CompressionFactory & instance()
Definition compression.hpp:191
Definition compression.hpp:57
bool do_fsync() const noexcept
Definition compression.hpp:63
Definition compression.hpp:91
@ input_buffer_size
Definition compression.hpp:100
void set_offset(const std::size_t offset) noexcept
Definition compression.hpp:125
bool want_buffered_pages_removed() const noexcept
Definition compression.hpp:131
fsync
Definition writer_options.hpp:51
Namespace for everything in the Osmium library.
Definition assembler.hpp:53
Definition bzip2_compression.hpp:71
bzip2_error(const std::string &what, const int error_code)
Definition bzip2_compression.hpp:76
int bzip2_error_code
Definition bzip2_compression.hpp:73
int system_errno
Definition bzip2_compression.hpp:74