summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorljfa-ag <ljfa-ag@web.de>2015-09-20 19:15:27 +0200
committerljfa-ag <ljfa-ag@web.de>2015-09-20 19:15:27 +0200
commit84d2896da1c3f3ef0be80476585422d8b1230289 (patch)
treed400b490a6a8f556a0fe61d557ccc2dee9b275d6
parent264ec99e7bae08710449262e609c20ad76383615 (diff)
downloadProject-Tick-84d2896da1c3f3ef0be80476585422d8b1230289.tar.gz
Project-Tick-84d2896da1c3f3ef0be80476585422d8b1230289.zip
Implement ozlibstream
-rw-r--r--CMakeLists.txt1
-rw-r--r--include/io/ozlibstream.h2
-rw-r--r--src/io/ozlibstream.cpp87
-rw-r--r--test/zlibstream_test.h20
4 files changed, 109 insertions, 1 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bed0ca668a..39a3a5759c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -15,6 +15,7 @@ add_library(nbt++ STATIC
src/value_initializer.cpp
src/io/izlibstream.cpp
+ src/io/ozlibstream.cpp
src/io/stream_reader.cpp
src/io/stream_writer.cpp
diff --git a/include/io/ozlibstream.h b/include/io/ozlibstream.h
index 0be792d482..d4ea8c2840 100644
--- a/include/io/ozlibstream.h
+++ b/include/io/ozlibstream.h
@@ -78,7 +78,7 @@ public:
* @param bufsize the size of the internal buffers
*/
explicit ozlibstream(std::ostream& output, int level = Z_DEFAULT_COMPRESSION, bool gzip = false, size_t bufsize = 32768):
- std::ostream(&buf), buf(output, level, bufsize, 15 + (gzip ? 16 : 0))
+ std::ostream(&buf), buf(output, bufsize, level, 15 + (gzip ? 16 : 0))
{}
///@return the wrapped ostream
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;
+}
+
+}
diff --git a/test/zlibstream_test.h b/test/zlibstream_test.h
index 2a94ab7ccb..e0b22c1356 100644
--- a/test/zlibstream_test.h
+++ b/test/zlibstream_test.h
@@ -133,4 +133,24 @@ public:
TS_ASSERT(igzs.bad());
}
}
+
+ void test_deflate_zlib()
+ {
+ //Here we assume that inflating works and has already been tested
+ std::stringstream str;
+ std::stringbuf output;
+ //Small buffer
+ {
+ ozlibstream ozls(str, -1, false, 256);
+ ozls.exceptions(std::ios::failbit | std::ios::badbit);
+ ozls << bigtest;
+ TS_ASSERT(ozls.good());
+ }
+ {
+ izlibstream izls(str);
+ izls >> &output;
+ TS_ASSERT(izls);
+ }
+ TS_ASSERT_EQUALS(output.str(), bigtest);
+ }
};