summaryrefslogtreecommitdiff
path: root/src/io/ozlibstream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/io/ozlibstream.cpp')
-rw-r--r--src/io/ozlibstream.cpp87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/io/ozlibstream.cpp b/src/io/ozlibstream.cpp
new file mode 100644
index 0000000000..97702a37e1
--- /dev/null
+++ b/src/io/ozlibstream.cpp
@@ -0,0 +1,87 @@
+/*
+ * libnbt++ - A library for the Minecraft Named Binary Tag format.
+ * Copyright (C) 2013, 2015 ljfa-ag
+ *
+ * This file is part of libnbt++.
+ *
+ * libnbt++ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * libnbt++ is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libnbt++. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "io/ozlibstream.h"
+#include "io/zlib_error.h"
+
+namespace zlib
+{
+
+deflate_streambuf::deflate_streambuf(std::ostream& output, size_t bufsize, int level, int window_bits, int mem_level, int strategy):
+ os(output), in(bufsize), out(bufsize)
+{
+ zstr.zalloc = Z_NULL;
+ zstr.zfree = Z_NULL;
+ zstr.opaque = Z_NULL;
+ int ret = deflateInit2(&zstr, level, Z_DEFLATED, window_bits, mem_level, strategy);
+ if(ret != Z_OK)
+ throw zlib_error(zstr.msg, ret);
+
+ setp(in.data(), in.data() + in.size());
+}
+
+deflate_streambuf::~deflate_streambuf() noexcept
+{
+ try
+ {
+ deflate_chunk(Z_FINISH);
+ }
+ catch(...)
+ {
+ //ignore as we can't do anything about it
+ }
+ deflateEnd(&zstr);
+}
+
+void deflate_streambuf::deflate_chunk(int flush)
+{
+ zstr.next_in = reinterpret_cast<Bytef*>(pbase());
+ zstr.avail_in = pptr() - pbase();
+ do
+ {
+ zstr.next_out = reinterpret_cast<Bytef*>(out.data());
+ zstr.avail_out = out.size();
+ int ret = deflate(&zstr, flush);
+ if(ret != Z_OK && ret != Z_STREAM_END)
+ throw zlib_error(zstr.msg, ret);
+ int have = out.size() - zstr.avail_out;
+ if(!os.write(out.data(), have))
+ throw std::ios_base::failure("Could not write to the output stream");
+ } while(zstr.avail_out == 0);
+ setp(in.data(), in.data() + in.size());
+}
+
+deflate_streambuf::int_type deflate_streambuf::overflow(int_type ch)
+{
+ deflate_chunk();
+ if(ch != traits_type::eof())
+ {
+ *pptr() = ch;
+ pbump(1);
+ }
+ return ch;
+}
+
+int deflate_streambuf::sync()
+{
+ deflate_chunk();
+ return 0;
+}
+
+}