mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
move vector_streambuf definitions to a separate file, fix zip buffer bug
This commit is contained in:
parent
f5b5d67594
commit
f42d3eee74
@ -32,9 +32,6 @@
|
|||||||
namespace xlnt {
|
namespace xlnt {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
#pragma clang diagnostic push
|
|
||||||
#pragma clang diagnostic ignored "-Wweak-vtables"
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Allows a std::vector to be read through a std::istream.
|
/// Allows a std::vector to be read through a std::istream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -43,102 +40,21 @@ class vector_istreambuf : public std::streambuf
|
|||||||
using int_type = std::streambuf::int_type;
|
using int_type = std::streambuf::int_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
vector_istreambuf(const std::vector<std::uint8_t> &data)
|
vector_istreambuf(const std::vector<std::uint8_t> &data);
|
||||||
: data_(data),
|
|
||||||
position_(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
vector_istreambuf(const vector_istreambuf &) = delete;
|
vector_istreambuf(const vector_istreambuf &) = delete;
|
||||||
vector_istreambuf &operator=(const vector_istreambuf &) = delete;
|
vector_istreambuf &operator=(const vector_istreambuf &) = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int_type underflow()
|
int_type underflow();
|
||||||
{
|
|
||||||
if (position_ == data_.size())
|
|
||||||
{
|
|
||||||
return traits_type::eof();
|
|
||||||
}
|
|
||||||
|
|
||||||
return traits_type::to_int_type(static_cast<char>(data_[position_]));
|
int_type uflow();
|
||||||
}
|
|
||||||
|
|
||||||
int_type uflow()
|
std::streamsize showmanyc();
|
||||||
{
|
|
||||||
if (position_ == data_.size())
|
|
||||||
{
|
|
||||||
return traits_type::eof();
|
|
||||||
}
|
|
||||||
|
|
||||||
return traits_type::to_int_type(static_cast<char>(data_[position_++]));
|
std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode);
|
||||||
}
|
|
||||||
|
|
||||||
std::streamsize showmanyc()
|
std::streampos seekpos(std::streampos sp, std::ios_base::openmode);
|
||||||
{
|
|
||||||
if (position_ == data_.size())
|
|
||||||
{
|
|
||||||
return static_cast<std::streamsize>(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return static_cast<std::streamsize>(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<std::size_t>(-off) > position_)
|
|
||||||
{
|
|
||||||
position_ = 0;
|
|
||||||
return static_cast<std::ptrdiff_t>(-1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
position_ -= static_cast<std::size_t>(-off);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (off > 0)
|
|
||||||
{
|
|
||||||
if (static_cast<std::size_t>(off) + position_ > data_.size())
|
|
||||||
{
|
|
||||||
position_ = data_.size();
|
|
||||||
return static_cast<std::ptrdiff_t>(-1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
position_ += static_cast<std::size_t>(off);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return static_cast<std::ptrdiff_t>(position_);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::streampos seekpos(std::streampos sp, std::ios_base::openmode)
|
|
||||||
{
|
|
||||||
if (sp < 0)
|
|
||||||
{
|
|
||||||
position_ = 0;
|
|
||||||
}
|
|
||||||
else if (static_cast<std::size_t>(sp) > data_.size())
|
|
||||||
{
|
|
||||||
position_ = data_.size();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
position_ = static_cast<std::size_t>(sp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return static_cast<std::ptrdiff_t>(position_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::vector<std::uint8_t> &data_;
|
const std::vector<std::uint8_t> &data_;
|
||||||
@ -153,102 +69,19 @@ class vector_ostreambuf : public std::streambuf
|
|||||||
using int_type = std::streambuf::int_type;
|
using int_type = std::streambuf::int_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
vector_ostreambuf(std::vector<std::uint8_t> &data)
|
vector_ostreambuf(std::vector<std::uint8_t> &data);
|
||||||
: data_(data),
|
|
||||||
position_(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
vector_ostreambuf(const vector_ostreambuf &) = delete;
|
vector_ostreambuf(const vector_ostreambuf &) = delete;
|
||||||
vector_ostreambuf &operator=(const vector_ostreambuf &) = delete;
|
vector_ostreambuf &operator=(const vector_ostreambuf &) = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int_type overflow(int_type c = traits_type::eof())
|
int_type overflow(int_type c = traits_type::eof());
|
||||||
{
|
|
||||||
if (c != traits_type::eof())
|
|
||||||
{
|
|
||||||
data_.push_back(static_cast<std::uint8_t>(c));
|
|
||||||
position_ = data_.size() - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return traits_type::to_int_type(static_cast<char>(data_[position_]));
|
std::streamsize xsputn(const char *s, std::streamsize n);
|
||||||
}
|
|
||||||
|
|
||||||
std::streamsize xsputn(const char *s, std::streamsize n)
|
std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode);
|
||||||
{
|
|
||||||
if (data_.empty())
|
|
||||||
{
|
|
||||||
data_.resize(static_cast<std::size_t>(n));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto position_size = data_.size();
|
|
||||||
auto required_size = static_cast<std::size_t>(position_ + static_cast<std::size_t>(n));
|
|
||||||
data_.resize(std::max(position_size, required_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::copy(s, s + n, data_.begin() + static_cast<std::ptrdiff_t>(position_));
|
std::streampos seekpos(std::streampos sp, std::ios_base::openmode);
|
||||||
position_ += static_cast<std::size_t>(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<std::size_t>(-off) > position_)
|
|
||||||
{
|
|
||||||
position_ = 0;
|
|
||||||
return static_cast<std::ptrdiff_t>(-1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
position_ -= static_cast<std::size_t>(-off);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (off > 0)
|
|
||||||
{
|
|
||||||
if (static_cast<std::size_t>(off) + position_ > data_.size())
|
|
||||||
{
|
|
||||||
position_ = data_.size();
|
|
||||||
return static_cast<std::ptrdiff_t>(-1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
position_ += static_cast<std::size_t>(off);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return static_cast<std::ptrdiff_t>(position_);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::streampos seekpos(std::streampos sp, std::ios_base::openmode)
|
|
||||||
{
|
|
||||||
if (sp < 0)
|
|
||||||
{
|
|
||||||
position_ = 0;
|
|
||||||
}
|
|
||||||
else if (static_cast<std::size_t>(sp) > data_.size())
|
|
||||||
{
|
|
||||||
position_ = data_.size();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
position_ = static_cast<std::size_t>(sp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return static_cast<std::ptrdiff_t>(position_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::uint8_t> &data_;
|
std::vector<std::uint8_t> &data_;
|
||||||
@ -260,34 +93,17 @@ private:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper function to read all data from in_stream and store them in a vector.
|
/// Helper function to read all data from in_stream and store them in a vector.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
XLNT_API inline std::vector<std::uint8_t> to_vector(std::istream &in_stream)
|
XLNT_API std::vector<std::uint8_t> to_vector(std::istream &in_stream);
|
||||||
{
|
|
||||||
in_stream.seekg(0, std::ios::end);
|
|
||||||
std::vector<std::uint8_t> bytes(in_stream.tellg(), 0);
|
|
||||||
in_stream.seekg(0, std::ios::beg);
|
|
||||||
in_stream.read(reinterpret_cast<char *>(bytes.data()), bytes.size());
|
|
||||||
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper function to write all data from bytes into out_stream.
|
/// Helper function to write all data from bytes into out_stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
XLNT_API inline void to_stream(const std::vector<std::uint8_t> &bytes, std::ostream &out_stream)
|
XLNT_API void to_stream(const std::vector<std::uint8_t> &bytes, std::ostream &out_stream);
|
||||||
{
|
|
||||||
out_stream.write(reinterpret_cast<const char *>(bytes.data()), bytes.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shortcut function to stream a vector of bytes into a std::ostream.
|
/// Shortcut function to stream a vector of bytes into a std::ostream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
XLNT_API inline std::ostream &operator<<(std::ostream &out_stream, const std::vector<std::uint8_t> &bytes)
|
XLNT_API std::ostream &operator<<(std::ostream &out_stream, const std::vector<std::uint8_t> &bytes);
|
||||||
{
|
|
||||||
to_stream(bytes, out_stream);
|
|
||||||
return out_stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma clang diagnostic pop
|
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace xlnt
|
} // namespace xlnt
|
||||||
|
@ -191,13 +191,16 @@ public:
|
|||||||
zip_streambuf_decompress(std::istream &stream, zheader central_header)
|
zip_streambuf_decompress(std::istream &stream, zheader central_header)
|
||||||
: istream(stream), header(central_header), total_read(0), total_uncompressed(0), valid(true)
|
: istream(stream), header(central_header), total_read(0), total_uncompressed(0), valid(true)
|
||||||
{
|
{
|
||||||
|
in.fill(0);
|
||||||
|
out.fill(0);
|
||||||
|
|
||||||
strm.zalloc = Z_NULL;
|
strm.zalloc = Z_NULL;
|
||||||
strm.zfree = Z_NULL;
|
strm.zfree = Z_NULL;
|
||||||
strm.opaque = Z_NULL;
|
strm.opaque = Z_NULL;
|
||||||
strm.avail_in = 0;
|
strm.avail_in = 0;
|
||||||
strm.next_in = Z_NULL;
|
strm.next_in = Z_NULL;
|
||||||
|
|
||||||
setg(in.data(), in.data(), in.data() + buffer_size);
|
setg(in.data(), in.data(), in.data());
|
||||||
setp(0, 0);
|
setp(0, 0);
|
||||||
|
|
||||||
// skip the header
|
// skip the header
|
||||||
|
@ -64,13 +64,7 @@ public:
|
|||||||
wb.save(wb_data);
|
wb.save(wb_data);
|
||||||
|
|
||||||
std::ifstream file_stream(file.string(), std::ios::binary);
|
std::ifstream file_stream(file.string(), std::ios::binary);
|
||||||
std::vector<std::uint8_t> file_data;
|
auto file_data = xlnt::detail::to_vector(file_stream);
|
||||||
|
|
||||||
{
|
|
||||||
xlnt::detail::vector_ostreambuf file_data_buffer(file_data);
|
|
||||||
std::ostream file_data_stream(&file_data_buffer);
|
|
||||||
file_data_stream << file_stream.rdbuf();
|
|
||||||
}
|
|
||||||
|
|
||||||
return xml_helper::xlsx_archives_match(wb_data, file_data);
|
return xml_helper::xlsx_archives_match(wb_data, file_data);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user