From f42d3eee745f53c18a599d15f2f11ba544105223 Mon Sep 17 00:00:00 2001 From: Thomas Fussell Date: Sat, 29 Apr 2017 12:29:41 -0400 Subject: [PATCH] move vector_streambuf definitions to a separate file, fix zip buffer bug --- .../detail/serialization/vector_streambuf.hpp | 212 ++---------------- source/detail/serialization/zstream.cpp | 5 +- tests/workbook/serialization_test_suite.hpp | 8 +- 3 files changed, 19 insertions(+), 206 deletions(-) diff --git a/source/detail/serialization/vector_streambuf.hpp b/source/detail/serialization/vector_streambuf.hpp index 9c5fe194..d625c269 100644 --- a/source/detail/serialization/vector_streambuf.hpp +++ b/source/detail/serialization/vector_streambuf.hpp @@ -32,9 +32,6 @@ namespace xlnt { namespace detail { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wweak-vtables" - /// /// Allows a std::vector to be read through a std::istream. /// @@ -43,102 +40,21 @@ class vector_istreambuf : public std::streambuf using int_type = std::streambuf::int_type; public: - vector_istreambuf(const std::vector &data) - : data_(data), - position_(0) - { - } + vector_istreambuf(const std::vector &data); vector_istreambuf(const vector_istreambuf &) = delete; vector_istreambuf &operator=(const vector_istreambuf &) = delete; private: - int_type underflow() - { - if (position_ == data_.size()) - { - return traits_type::eof(); - } + int_type underflow(); - return traits_type::to_int_type(static_cast(data_[position_])); - } + int_type uflow(); - int_type uflow() - { - if (position_ == data_.size()) - { - return traits_type::eof(); - } + std::streamsize showmanyc(); - return traits_type::to_int_type(static_cast(data_[position_++])); - } + std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode); - std::streamsize showmanyc() - { - if (position_ == data_.size()) - { - return static_cast(-1); - } - - return static_cast(data_.size() - position_); - } - - std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode) - { - if (way == std::ios_base::beg) - { - position_ = 0; - } - else if (way == std::ios_base::end) - { - position_ = data_.size(); - } - - if (off < 0) - { - if (static_cast(-off) > position_) - { - position_ = 0; - return static_cast(-1); - } - else - { - position_ -= static_cast(-off); - } - } - else if (off > 0) - { - if (static_cast(off) + position_ > data_.size()) - { - position_ = data_.size(); - return static_cast(-1); - } - else - { - position_ += static_cast(off); - } - } - - return static_cast(position_); - } - - std::streampos seekpos(std::streampos sp, std::ios_base::openmode) - { - if (sp < 0) - { - position_ = 0; - } - else if (static_cast(sp) > data_.size()) - { - position_ = data_.size(); - } - else - { - position_ = static_cast(sp); - } - - return static_cast(position_); - } + std::streampos seekpos(std::streampos sp, std::ios_base::openmode); private: const std::vector &data_; @@ -153,102 +69,19 @@ class vector_ostreambuf : public std::streambuf using int_type = std::streambuf::int_type; public: - vector_ostreambuf(std::vector &data) - : data_(data), - position_(0) - { - } + vector_ostreambuf(std::vector &data); vector_ostreambuf(const vector_ostreambuf &) = delete; vector_ostreambuf &operator=(const vector_ostreambuf &) = delete; private: - int_type overflow(int_type c = traits_type::eof()) - { - if (c != traits_type::eof()) - { - data_.push_back(static_cast(c)); - position_ = data_.size() - 1; - } + int_type overflow(int_type c = traits_type::eof()); - return traits_type::to_int_type(static_cast(data_[position_])); - } + std::streamsize xsputn(const char *s, std::streamsize n); - std::streamsize xsputn(const char *s, std::streamsize n) - { - if (data_.empty()) - { - data_.resize(static_cast(n)); - } - else - { - auto position_size = data_.size(); - auto required_size = static_cast(position_ + static_cast(n)); - data_.resize(std::max(position_size, required_size)); - } + std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode); - std::copy(s, s + n, data_.begin() + static_cast(position_)); - position_ += static_cast(n); - - return n; - } - - std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode) - { - if (way == std::ios_base::beg) - { - position_ = 0; - } - else if (way == std::ios_base::end) - { - position_ = data_.size(); - } - - if (off < 0) - { - if (static_cast(-off) > position_) - { - position_ = 0; - return static_cast(-1); - } - else - { - position_ -= static_cast(-off); - } - } - else if (off > 0) - { - if (static_cast(off) + position_ > data_.size()) - { - position_ = data_.size(); - return static_cast(-1); - } - else - { - position_ += static_cast(off); - } - } - - return static_cast(position_); - } - - std::streampos seekpos(std::streampos sp, std::ios_base::openmode) - { - if (sp < 0) - { - position_ = 0; - } - else if (static_cast(sp) > data_.size()) - { - position_ = data_.size(); - } - else - { - position_ = static_cast(sp); - } - - return static_cast(position_); - } + std::streampos seekpos(std::streampos sp, std::ios_base::openmode); private: std::vector &data_; @@ -260,34 +93,17 @@ private: /// /// Helper function to read all data from in_stream and store them in a vector. /// -XLNT_API inline std::vector to_vector(std::istream &in_stream) -{ - in_stream.seekg(0, std::ios::end); - std::vector bytes(in_stream.tellg(), 0); - in_stream.seekg(0, std::ios::beg); - in_stream.read(reinterpret_cast(bytes.data()), bytes.size()); - - return bytes; -} +XLNT_API std::vector to_vector(std::istream &in_stream); /// /// Helper function to write all data from bytes into out_stream. /// -XLNT_API inline void to_stream(const std::vector &bytes, std::ostream &out_stream) -{ - out_stream.write(reinterpret_cast(bytes.data()), bytes.size()); -} +XLNT_API void to_stream(const std::vector &bytes, std::ostream &out_stream); /// /// Shortcut function to stream a vector of bytes into a std::ostream. /// -XLNT_API inline std::ostream &operator<<(std::ostream &out_stream, const std::vector &bytes) -{ - to_stream(bytes, out_stream); - return out_stream; -} - -#pragma clang diagnostic pop +XLNT_API std::ostream &operator<<(std::ostream &out_stream, const std::vector &bytes); } // namespace detail } // namespace xlnt diff --git a/source/detail/serialization/zstream.cpp b/source/detail/serialization/zstream.cpp index 6fee8ff1..b9aab711 100644 --- a/source/detail/serialization/zstream.cpp +++ b/source/detail/serialization/zstream.cpp @@ -191,13 +191,16 @@ public: zip_streambuf_decompress(std::istream &stream, zheader central_header) : istream(stream), header(central_header), total_read(0), total_uncompressed(0), valid(true) { + in.fill(0); + out.fill(0); + strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = 0; strm.next_in = Z_NULL; - setg(in.data(), in.data(), in.data() + buffer_size); + setg(in.data(), in.data(), in.data()); setp(0, 0); // skip the header diff --git a/tests/workbook/serialization_test_suite.hpp b/tests/workbook/serialization_test_suite.hpp index f3c4e562..f20bdaaf 100644 --- a/tests/workbook/serialization_test_suite.hpp +++ b/tests/workbook/serialization_test_suite.hpp @@ -64,13 +64,7 @@ public: wb.save(wb_data); std::ifstream file_stream(file.string(), std::ios::binary); - std::vector file_data; - - { - xlnt::detail::vector_ostreambuf file_data_buffer(file_data); - std::ostream file_data_stream(&file_data_buffer); - file_data_stream << file_stream.rdbuf(); - } + auto file_data = xlnt::detail::to_vector(file_stream); return xml_helper::xlsx_archives_match(wb_data, file_data); }