diff options
| author | ljfa-ag <ljfa-ag@web.de> | 2015-09-20 19:15:27 +0200 |
|---|---|---|
| committer | ljfa-ag <ljfa-ag@web.de> | 2015-09-20 19:15:27 +0200 |
| commit | 84d2896da1c3f3ef0be80476585422d8b1230289 (patch) | |
| tree | d400b490a6a8f556a0fe61d557ccc2dee9b275d6 | |
| parent | 264ec99e7bae08710449262e609c20ad76383615 (diff) | |
| download | Project-Tick-84d2896da1c3f3ef0be80476585422d8b1230289.tar.gz Project-Tick-84d2896da1c3f3ef0be80476585422d8b1230289.zip | |
Implement ozlibstream
| -rw-r--r-- | CMakeLists.txt | 1 | ||||
| -rw-r--r-- | include/io/ozlibstream.h | 2 | ||||
| -rw-r--r-- | src/io/ozlibstream.cpp | 87 | ||||
| -rw-r--r-- | test/zlibstream_test.h | 20 |
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); + } }; |
