From 718ef563cdcc42e491b0f09dd0134fd310d9edc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tommi=20M=C3=A4klin?= Date: Wed, 29 Jan 2020 11:28:08 +0200 Subject: [PATCH] update zstr -> bxzstr & use git submodules to fetch bxzstr --- .gitmodules | 5 +- CMakeLists.txt | 5 + external/bxzstr | 1 + external/zstr/.travis.Dockerfile.in | 26 -- external/zstr/.travis.yml | 17 - external/zstr/LICENSE | 21 - external/zstr/README.org | 54 --- external/zstr/examples/.gitignore | 4 - external/zstr/examples/Makefile | 45 -- .../zstr/examples/test-strict_fstream.cpp | 84 ---- external/zstr/examples/zc.cpp | 137 ------ external/zstr/examples/zpipe.cpp | 34 -- external/zstr/examples/ztxtpipe.cpp | 19 - external/zstr/src/strict_fstream.hpp | 199 --------- external/zstr/src/zstr.hpp | 415 ------------------ include/file.hpp | 9 +- 16 files changed, 15 insertions(+), 1060 deletions(-) create mode 160000 external/bxzstr delete mode 100644 external/zstr/.travis.Dockerfile.in delete mode 100644 external/zstr/.travis.yml delete mode 100644 external/zstr/LICENSE delete mode 100644 external/zstr/README.org delete mode 100644 external/zstr/examples/.gitignore delete mode 100644 external/zstr/examples/Makefile delete mode 100644 external/zstr/examples/test-strict_fstream.cpp delete mode 100644 external/zstr/examples/zc.cpp delete mode 100644 external/zstr/examples/zpipe.cpp delete mode 100644 external/zstr/examples/ztxtpipe.cpp delete mode 100644 external/zstr/src/strict_fstream.hpp delete mode 100644 external/zstr/src/zstr.hpp diff --git a/.gitmodules b/.gitmodules index 6eb7940..34c2b7f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "external/cxxargs"] path = external/cxxargs - url = git@github.com:tmaklin/cxxargs.git + url = https://github.com/tmaklin/cxxargs.git +[submodule "external/bxzstr"] + path = external/bxzstr + url = https://github.com/tmaklin/bxzstr.git diff --git a/CMakeLists.txt b/CMakeLists.txt index cc65b7b..1c7b87d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,11 @@ else() add_compile_options(-std=c++11) endif() +## Configure bxzstr +set(LIBLZMA_FOUND 0) +set(BZIP2_FOUND 0) +add_subdirectory(${CMAKE_SOURCE_DIR}/external/bxzstr) + ## Get version number from git tags find_package(Git) if(GIT_FOUND) diff --git a/external/bxzstr b/external/bxzstr new file mode 160000 index 0000000..4e05f3d --- /dev/null +++ b/external/bxzstr @@ -0,0 +1 @@ +Subproject commit 4e05f3dd5eb968d10f91e294573987358ef76f8e diff --git a/external/zstr/.travis.Dockerfile.in b/external/zstr/.travis.Dockerfile.in deleted file mode 100644 index 048539e..0000000 --- a/external/zstr/.travis.Dockerfile.in +++ /dev/null @@ -1,26 +0,0 @@ -FROM debian:stable -MAINTAINER Matei David -ARG DEBIAN_FRONTEND=noninteractive - -# install prerequisites -RUN apt-get update && \ - apt-get install -y \ - build-essential \ - zlib1g-dev - -# if necessary, specify compiler -#RUN apt-get install -y g++-4.9 g++-5 g++-6 -#ENV CC=gcc-4.9 -#ENV CXX=g++-4.9 - -# use host timezone -ENV TZ=${TZ} -RUN ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime && echo ${TZ} >/etc/timezone - -# use host id -RUN groupadd --gid ${GROUP_ID} ${GROUP_NAME} -RUN useradd --create-home --uid ${USER_ID} --gid ${GROUP_ID} ${USER_NAME} -USER ${USER_NAME} - -VOLUME /data -WORKDIR /data diff --git a/external/zstr/.travis.yml b/external/zstr/.travis.yml deleted file mode 100644 index 59c347b..0000000 --- a/external/zstr/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -# travis.yml for github.com/mateidavid/zstr - -sudo: required - -services: - - docker - -before_install: - - sudo apt-get update -y - - sudo apt-get install -y -o Dpkg::Options::="--force-confnew" docker-engine - - TZ=$(cat /etc/timezone) USER_ID=$(id -u) USER_NAME=$(id -un) GROUP_ID=$(id -g) GROUP_NAME=$(id -gn) envsubst <.travis.Dockerfile.in | docker build -t zstr - - -install: - - docker run --rm -v $PWD:/data zstr make -C examples - -script: - - docker run --rm -v $PWD:/data zstr make -C examples test diff --git a/external/zstr/LICENSE b/external/zstr/LICENSE deleted file mode 100644 index 841c721..0000000 --- a/external/zstr/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Matei David, Ontario Institute for Cancer Research - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/external/zstr/README.org b/external/zstr/README.org deleted file mode 100644 index bc0dd3e..0000000 --- a/external/zstr/README.org +++ /dev/null @@ -1,54 +0,0 @@ -# -*- mode:org; mode:visual-line; coding:utf-8; -*- - -** A C++ ZLib wrapper - -[[http://travis-ci.org/mateidavid/zstr][http://travis-ci.org/mateidavid/zstr.svg?branch=master]] [[https://tldrlegal.com/license/mit-license][http://img.shields.io/:license-mit-blue.svg]] - -This C++ header-only library enables the use of C++ standard iostreams to access ZLib-compressed streams. - -For input access (decompression), the compression format is auto-detected, and multiple concatenated compressed streams are decompressed seamlessly. - -For output access (compression), the only parameter exposed by this API is the compression level. - -Alternatives to this library include: - -- The original [[http://www.zlib.net/][ZLib]], through its [[http://www.zlib.net/manual.html][C API]]. This does not interact nicely with C++ iostreams. - -- The [[http://www.cs.unc.edu/Research/compgeom/gzstream/][GZStream]] library. This library does not auto-detect input compression, and it cannot wrap streams (only files). - -- The [[http://www.boost.org/doc/libs/release/libs/iostreams/][Boost IOStreams]] library. The library does not auto-detect input compression (by default, though that can be easily implemented with filters), and more importantly, it is not a header-only Boost library. - -For an example usage, see [[examples/ztxtpipe.cpp]] and [[examples/zc.cpp]]. - -**** Input Auto-detection - -For input access, the library seamlessly auto-detects whether the source stream is compressed or not. The following compressed streams are detected: - -- GZip header, when stream starts with =1F 8B=. See [[http://en.wikipedia.org/wiki/Gzip][GZip format]]. - -- ZLib header, when stream starts with =78 01=, =78 9C=, and =78 DA=. See [[http://stackoverflow.com/a/17176881][answer here]]. - -If none of these formats are detected, the library assumes the input is not compressed, and it produces a plain copy of the source stream. - -**** Classes - -The package provides 6 classes for accessing ZLib streams: - -- =zstr::istreambuf= is the core decompression class. This is constructed from an existing =std::streambuf= that contains source data. The =zstr::istreambuf= constructor accepts explicit settings for the internal buffer size (default: 1 MB) and the auto-detection option (default: on). ZLib errors cause exceptions to be thrown. - -- =zstr::ostreambuf= is the core compression class. This is constructed from an existing =std::streambuf= that contains sink data. The =zstr::ostreambuf= constructor accepts explicit settings for the internal buffer size (default: 1 MB) and the compression option (default: ZLib default). ZLib errors cause exceptions to be thrown. - -- =zstr::istream= is a wrapper for a =zstr::istreambuf= that accesses an /external/ =std::streambuf=. It can be constructed from an existing =std::istream= (such as =std::cin=) or =std::streambuf=. - -- =zstr::ostream= is a wrapper for a =zstr::ostreambuf= that accesses an /external/ =std::streambuf=. It can be constructed from an existing =std::ostream= (such as =std::cout=) or =std::streambuf=. - -- =zstr::ifstream= is a wrapper for a =zstr::istreambuf= that accesses an /internal/ =std::ifstream=. This can be used to open a file and read decompressed data from it. - -- =zstr::ofstream= is a wrapper for a =zstr::ostreambuf= that accesses an /internal/ =std::ofstream=. This can be used to open a file and write compressed data to it. - -For all stream objects, the =badbit= of their expection mask is turned on in order to propagate exceptions. - -**** License - -Released under the [[file:LICENSE][MIT license]]. - diff --git a/external/zstr/examples/.gitignore b/external/zstr/examples/.gitignore deleted file mode 100644 index 84f8aae..0000000 --- a/external/zstr/examples/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/test-strict_fstream -/ztxtpipe -/zpipe -/zc diff --git a/external/zstr/examples/Makefile b/external/zstr/examples/Makefile deleted file mode 100644 index e9a4de8..0000000 --- a/external/zstr/examples/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -.SUFFIXES: -MAKEFLAGS += -r -SHELL := /bin/bash -.DELETE_ON_ERROR: -.PHONY: all test clean - -all: test-strict_fstream ztxtpipe zpipe zc - -%: %.cpp - g++ -std=c++11 -O0 -g3 -ggdb -fno-eliminate-unused-debug-types -Wall -Wextra -pedantic -I../src -o $@ $^ -lz - -test: ztxtpipe zpipe zc - diff -q ztxtpipe.cpp <(./ztxtpipe -#include -#include -#include "strict_fstream.hpp" - -template < typename Stream_Type > -void test_open(const std::string& stream_class, const std::string& stream_type, - const std::string& filename, int mode, bool set_fail_bit) -{ - Stream_Type * s_p = new Stream_Type(); - if (set_fail_bit) - { - s_p->exceptions(std::ios_base::failbit); - } - bool exception_thrown = true; - try - { - s_p->open(filename, static_cast< std::ios_base::openmode >(mode)); - exception_thrown = false; - } - catch (std::exception) {} - std::cout << stream_class << " " << stream_type << " " << (set_fail_bit? "failbit" : "nofailbit") << " " - << strict_fstream::detail::static_method_holder::mode_to_string( - static_cast< std::ios_base::openmode >(mode)) - << " " << (exception_thrown? "1" : "0") << std::endl; - delete s_p; -} - -int main(int argc, char * argv[]) -{ - if (argc != 2) - { - std::cerr - << "Use: " << argv[0] << " file" << std::endl - << "Synopsis: Open `file` as a file stream object" << std::endl - << "Stream Classes:" << std::endl - << " std" << std::endl - << " std_mask" << std::endl - << " strict_fstream" << std::endl - << "Stream Types:" << std::endl - << " ifstream" << std::endl - << " ofstream" << std::endl - << " fstream" << std::endl - << "Modes:" << std::endl - << " in=" << std::ios_base::in << std::endl - << " out=" << std::ios_base::out << std::endl - << " app=" << std::ios_base::app << std::endl - << " ate=" << std::ios_base::ate << std::endl - << " trunc=" << std::ios_base::trunc << std::endl - << " binary=" << std::ios_base::binary << std::endl; - std::exit(EXIT_FAILURE); - } - std::vector< int > in_mode_v = { - 0, - std::ios_base::in - }; - std::vector< int > out_mode_v = { - 0, - std::ios_base::out, - std::ios_base::out | std::ios_base::app, - std::ios_base::out | std::ios_base::trunc - }; - std::vector< int > alt_mode_v = { - 0, - std::ios_base::binary, - std::ios_base::ate, - std::ios_base::binary | std::ios_base::ate - }; - for (const auto& in_mode : in_mode_v) - for (const auto& out_mode : out_mode_v) - //for (const auto& alt_mode : alt_mode_v) - { - int mode = in_mode | out_mode; // | alt_mode; - //test_open< std::ifstream >("std", "ifstream", argv[1], mode, false); - //test_open< std::ofstream >("std", "ofstream", argv[1], mode, false); - //test_open< std::fstream >("std", "fstream", argv[1], mode, false); - test_open< std::ifstream >("std", "ifstream", argv[1], mode, true); - test_open< std::ofstream >("std", "ofstream", argv[1], mode, true); - test_open< std::fstream >("std", "fstream", argv[1], mode, true); - test_open< strict_fstream::ifstream >("strict_fstream", "ifstream", argv[1], mode, false); - test_open< strict_fstream::ofstream >("strict_fstream", "ofstream", argv[1], mode, false); - test_open< strict_fstream::fstream >("strict_fstream", "fstream", argv[1], mode, false); - } -} diff --git a/external/zstr/examples/zc.cpp b/external/zstr/examples/zc.cpp deleted file mode 100644 index 50140e0..0000000 --- a/external/zstr/examples/zc.cpp +++ /dev/null @@ -1,137 +0,0 @@ -#include -#include -#include -#include -#include "zstr.hpp" - -void usage(std::ostream& os, const std::string& prog_name) -{ - os << "Use: " << prog_name << " [-c] [-o output_file] files..." << std::endl - << "Synposis:" << std::endl - << " Decompress (with `-c`, compress) files to stdout (with `-o`, to output_file)." << std::endl; -} - -void cat_stream(std::istream& is, std::ostream& os) -{ - const std::streamsize buff_size = 1 << 16; - char * buff = new char [buff_size]; - while (true) - { - is.read(buff, buff_size); - std::streamsize cnt = is.gcount(); - if (cnt == 0) break; - os.write(buff, cnt); - } - delete [] buff; -} // cat_stream - -void decompress_files(const std::vector< std::string >& file_v, const std::string& output_file) -{ - // - // Set up sink ostream - // - std::unique_ptr< std::ofstream > ofs_p; - std::ostream * os_p = &std::cout; - if (not output_file.empty()) - { - ofs_p = std::unique_ptr< std::ofstream >(new strict_fstream::ofstream(output_file)); - os_p = ofs_p.get(); - } - // - // Process files - // - for (const auto& f : file_v) - { - // - // If `f` is a file, create a zstr::ifstream, else (it is stdin) create a zstr::istream wrapper - // - std::unique_ptr< std::istream > is_p = - (f != "-" - ? std::unique_ptr< std::istream >(new zstr::ifstream(f)) - : std::unique_ptr< std::istream >(new zstr::istream(std::cin))); - // - // Cat stream - // - cat_stream(*is_p, *os_p); - } -} // decompress_files - -void compress_files(const std::vector< std::string >& file_v, const std::string& output_file) -{ - // - // Set up compression sink ostream - // - std::unique_ptr< std::ostream > os_p = - (not output_file.empty() - ? std::unique_ptr< std::ostream >(new zstr::ofstream(output_file)) - : std::unique_ptr< std::ostream >(new zstr::ostream(std::cout))); - // - // Process files - // - for (const auto& f : file_v) - { - // - // If `f` is a file, create an ifstream, else read stdin - // - std::unique_ptr< std::ifstream > ifs_p; - std::istream * is_p = &std::cin; - if (f != "-") - { - ifs_p = std::unique_ptr< std::ifstream >(new strict_fstream::ifstream(f)); - is_p = ifs_p.get(); - } - // - // Cat stream - // - cat_stream(*is_p, *os_p); - } -} // compress_files - -int main(int argc, char * argv[]) -{ - bool compress = false; - std::string output_file; - int c; - while ((c = getopt(argc, argv, "co:h?")) != -1) - { - switch (c) - { - case 'c': - compress = true; - break; - case 'o': - if (std::string("-") != optarg) - { - output_file = optarg; - } - break; - case '?': - case 'h': - usage(std::cout, argv[0]); - std::exit(EXIT_SUCCESS); - break; - default: - usage(std::cerr, argv[0]); - std::exit(EXIT_FAILURE); - } - } - // - // Gather files to process - // - std::vector< std::string > file_v(&argv[optind], &argv[argc]); - // - // With no other arguments, process stdin - // - if (file_v.empty()) file_v.push_back("-"); - // - // Perform compression/decompression - // - if (compress) - { - compress_files(file_v, output_file); - } - else - { - decompress_files(file_v, output_file); - } -} diff --git a/external/zstr/examples/zpipe.cpp b/external/zstr/examples/zpipe.cpp deleted file mode 100644 index 0ecb491..0000000 --- a/external/zstr/examples/zpipe.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include -#include "zstr.hpp" - -int main() -{ - // - // Create explicit zstr::streambuf feeding off the streambuf of std::cin. - // This syntax allows for setting the buffer size and the auto-detect option. - // - zstr::istreambuf zsbuf(std::cin.rdbuf(), 1<<16, true); - // - // Create an std::istream wrapper for the zstr::streambuf. - // NOTE: A zstr::istream constructed with a zstr::streambuf parameter would decompress twice. - // - std::istream is(&zsbuf); - // - // Turn on error reporting (otherwise, zstream exceptions are hidden). - // - is.exceptions(std::ios_base::badbit); - // - // Main loop - // - const std::streamsize buff_size = 1 << 16; - char * buff = new char [buff_size]; - while (true) - { - is.read(buff, buff_size); - std::streamsize cnt = is.gcount(); - if (cnt == 0) break; - std::cout.write(buff, cnt); - } - delete [] buff; -} diff --git a/external/zstr/examples/ztxtpipe.cpp b/external/zstr/examples/ztxtpipe.cpp deleted file mode 100644 index 96f2fa1..0000000 --- a/external/zstr/examples/ztxtpipe.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include -#include "zstr.hpp" - -int main() -{ - // - // Create zstr::istream feeding off std::cin. - // - zstr::istream is(std::cin); - // - // Main loop - // - std::string s; - while (getline(is, s)) - { - std::cout << s << std::endl; - } -} diff --git a/external/zstr/src/strict_fstream.hpp b/external/zstr/src/strict_fstream.hpp deleted file mode 100644 index f61320c..0000000 --- a/external/zstr/src/strict_fstream.hpp +++ /dev/null @@ -1,199 +0,0 @@ -#ifndef __STRICT_FSTREAM_HPP -#define __STRICT_FSTREAM_HPP - -#include -#include -#include -#include - -/** - * This namespace defines wrappers for std::ifstream, std::ofstream, and - * std::fstream objects. The wrappers perform the following steps: - * - check the open modes make sense - * - check that the call to open() is successful - * - (for input streams) check that the opened file is peek-able - * - turn on the badbit in the exception mask - */ -namespace strict_fstream -{ - -/// Overload of error-reporting function, to enable use with VS. -/// Ref: http://stackoverflow.com/a/901316/717706 -static std::string strerror() -{ - std::string buff(80, '\0'); -#ifdef _WIN32 - if (strerror_s(&buff[0], buff.size(), errno) != 0) - { - buff = "Unknown error"; - } -#elif (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE -// XSI-compliant strerror_r() - if (strerror_r(errno, &buff[0], buff.size()) != 0) - { - buff = "Unknown error"; - } -#else -// GNU-specific strerror_r() - auto p = strerror_r(errno, &buff[0], buff.size()); - std::string tmp(p, p); - std::swap(buff, tmp); -#endif - buff.resize(buff.find('\0')); - return buff; -} - -/// Exception class thrown by failed operations. -class Exception - : public std::exception -{ -public: - Exception(const std::string& msg) : _msg(msg) {} - const char * what() const noexcept { return _msg.c_str(); } -private: - std::string _msg; -}; // class Exception - -namespace detail -{ - -struct static_method_holder -{ - static std::string mode_to_string(std::ios_base::openmode mode) - { - static const int n_modes = 6; - static const std::ios_base::openmode mode_val_v[n_modes] = - { - std::ios_base::in, - std::ios_base::out, - std::ios_base::app, - std::ios_base::ate, - std::ios_base::trunc, - std::ios_base::binary - }; - - static const char * mode_name_v[n_modes] = - { - "in", - "out", - "app", - "ate", - "trunc", - "binary" - }; - std::string res; - for (int i = 0; i < n_modes; ++i) - { - if (mode & mode_val_v[i]) - { - res += (! res.empty()? "|" : ""); - res += mode_name_v[i]; - } - } - if (res.empty()) res = "none"; - return res; - } - static void check_mode(const std::string& filename, std::ios_base::openmode mode) - { - if ((mode & std::ios_base::trunc) && ! (mode & std::ios_base::out)) - { - throw Exception(std::string("strict_fstream: open('") + filename + "'): mode error: trunc and not out"); - } - else if ((mode & std::ios_base::app) && ! (mode & std::ios_base::out)) - { - throw Exception(std::string("strict_fstream: open('") + filename + "'): mode error: app and not out"); - } - else if ((mode & std::ios_base::trunc) && (mode & std::ios_base::app)) - { - throw Exception(std::string("strict_fstream: open('") + filename + "'): mode error: trunc and app"); - } - } - static void check_open(std::ios * s_p, const std::string& filename, std::ios_base::openmode mode) - { - if (s_p->fail()) - { - s_p->setstate(std::ios::failbit); - } - } - static void check_peek(std::istream * is_p, const std::string& filename, std::ios_base::openmode mode) - { - bool peek_failed = true; - try - { - is_p->peek(); - peek_failed = is_p->fail(); - } - catch (std::ios_base::failure e) {} - if (peek_failed) - { - is_p->setstate(std::ios::failbit); - } else { - is_p->clear(); - } - } -}; // struct static_method_holder - -} // namespace detail - -class ifstream - : public std::ifstream -{ -public: - ifstream() = default; - ifstream(const std::string& filename, std::ios_base::openmode mode = std::ios_base::in) - { - open(filename, mode); - } - void open(const std::string& filename, std::ios_base::openmode mode = std::ios_base::in) - { - mode |= std::ios_base::in; - exceptions(std::ios_base::badbit); - detail::static_method_holder::check_mode(filename, mode); - std::ifstream::open(filename, mode); - detail::static_method_holder::check_open(this, filename, mode); - detail::static_method_holder::check_peek(this, filename, mode); - } -}; // class ifstream - -class ofstream - : public std::ofstream -{ -public: - ofstream() = default; - ofstream(const std::string& filename, std::ios_base::openmode mode = std::ios_base::out) - { - open(filename, mode); - } - void open(const std::string& filename, std::ios_base::openmode mode = std::ios_base::out) - { - mode |= std::ios_base::out; - exceptions(std::ios_base::badbit); - detail::static_method_holder::check_mode(filename, mode); - std::ofstream::open(filename, mode); - detail::static_method_holder::check_open(this, filename, mode); - } -}; // class ofstream - -class fstream - : public std::fstream -{ -public: - fstream() = default; - fstream(const std::string& filename, std::ios_base::openmode mode = std::ios_base::in) - { - open(filename, mode); - } - void open(const std::string& filename, std::ios_base::openmode mode = std::ios_base::in) - { - if (! (mode & std::ios_base::out)) mode |= std::ios_base::in; - exceptions(std::ios_base::badbit); - detail::static_method_holder::check_mode(filename, mode); - std::fstream::open(filename, mode); - detail::static_method_holder::check_open(this, filename, mode); - detail::static_method_holder::check_peek(this, filename, mode); - } -}; // class fstream - -} // namespace strict_fstream - -#endif diff --git a/external/zstr/src/zstr.hpp b/external/zstr/src/zstr.hpp deleted file mode 100644 index 0d9566a..0000000 --- a/external/zstr/src/zstr.hpp +++ /dev/null @@ -1,415 +0,0 @@ -//--------------------------------------------------------- -// Copyright 2015 Ontario Institute for Cancer Research -// Written by Matei David (matei@cs.toronto.edu) -//--------------------------------------------------------- - -// Reference: -// http://stackoverflow.com/questions/14086417/how-to-write-custom-input-stream-in-c - -#ifndef __ZSTR_HPP -#define __ZSTR_HPP - -#include -#include -#include -#include -#include -#include "strict_fstream.hpp" - -namespace zstr -{ - -/// Exception class thrown by failed zlib operations. -class Exception - : public std::exception -{ -public: - Exception(z_stream * zstrm_p, int ret) - : _msg("zlib: ") - { - switch (ret) - { - case Z_STREAM_ERROR: - _msg += "Z_STREAM_ERROR: "; - break; - case Z_DATA_ERROR: - _msg += "Z_DATA_ERROR: "; - break; - case Z_MEM_ERROR: - _msg += "Z_MEM_ERROR: "; - break; - case Z_VERSION_ERROR: - _msg += "Z_VERSION_ERROR: "; - break; - case Z_BUF_ERROR: - _msg += "Z_BUF_ERROR: "; - break; - default: - std::ostringstream oss; - oss << ret; - _msg += "[" + oss.str() + "]: "; - break; - } - _msg += zstrm_p->msg; - } - Exception(const std::string msg) : _msg(msg) {} - const char * what() const noexcept { return _msg.c_str(); } -private: - std::string _msg; -}; // class Exception - -namespace detail -{ - -class z_stream_wrapper - : public z_stream -{ -public: - z_stream_wrapper(bool _is_input = true, int _level = Z_DEFAULT_COMPRESSION) - : is_input(_is_input) - { - this->zalloc = Z_NULL; - this->zfree = Z_NULL; - this->opaque = Z_NULL; - int ret; - if (is_input) - { - this->avail_in = 0; - this->next_in = Z_NULL; - ret = inflateInit2(this, 15+32); - } - else - { - ret = deflateInit2(this, _level, Z_DEFLATED, 15+16, 8, Z_DEFAULT_STRATEGY); - } - if (ret != Z_OK) throw Exception(this, ret); - } - ~z_stream_wrapper() - { - if (is_input) - { - inflateEnd(this); - } - else - { - deflateEnd(this); - } - } -private: - bool is_input; -}; // class z_stream_wrapper - -} // namespace detail - -class istreambuf - : public std::streambuf -{ -public: - istreambuf(std::streambuf * _sbuf_p, - std::size_t _buff_size = default_buff_size, bool _auto_detect = true) - : sbuf_p(_sbuf_p), - zstrm_p(nullptr), - buff_size(_buff_size), - auto_detect(_auto_detect), - auto_detect_run(false), - is_text(false) - { - assert(sbuf_p); - in_buff = new char [buff_size]; - in_buff_start = in_buff; - in_buff_end = in_buff; - out_buff = new char [buff_size]; - setg(out_buff, out_buff, out_buff); - } - - istreambuf(const istreambuf &) = delete; - istreambuf(istreambuf &&) = default; - istreambuf & operator = (const istreambuf &) = delete; - istreambuf & operator = (istreambuf &&) = default; - - virtual ~istreambuf() - { - delete [] in_buff; - delete [] out_buff; - if (zstrm_p) delete zstrm_p; - } - - virtual std::streambuf::int_type underflow() - { - if (this->gptr() == this->egptr()) - { - // pointers for free region in output buffer - char * out_buff_free_start = out_buff; - do - { - // read more input if none available - if (in_buff_start == in_buff_end) - { - // empty input buffer: refill from the start - in_buff_start = in_buff; - std::streamsize sz = sbuf_p->sgetn(in_buff, buff_size); - in_buff_end = in_buff + sz; - if (in_buff_end == in_buff_start) break; // end of input - } - // auto detect if the stream contains text or deflate data - if (auto_detect && ! auto_detect_run) - { - auto_detect_run = true; - unsigned char b0 = *reinterpret_cast< unsigned char * >(in_buff_start); - unsigned char b1 = *reinterpret_cast< unsigned char * >(in_buff_start + 1); - // Ref: - // http://en.wikipedia.org/wiki/Gzip - // http://stackoverflow.com/questions/9050260/what-does-a-zlib-header-look-like - is_text = ! (in_buff_start + 2 <= in_buff_end - && ((b0 == 0x1F && b1 == 0x8B) // gzip header - || (b0 == 0x78 && (b1 == 0x01 // zlib header - || b1 == 0x9C - || b1 == 0xDA)))); - } - if (is_text) - { - // simply swap in_buff and out_buff, and adjust pointers - assert(in_buff_start == in_buff); - std::swap(in_buff, out_buff); - out_buff_free_start = in_buff_end; - in_buff_start = in_buff; - in_buff_end = in_buff; - } - else - { - // run inflate() on input - if (! zstrm_p) zstrm_p = new detail::z_stream_wrapper(true); - zstrm_p->next_in = reinterpret_cast< decltype(zstrm_p->next_in) >(in_buff_start); - zstrm_p->avail_in = in_buff_end - in_buff_start; - zstrm_p->next_out = reinterpret_cast< decltype(zstrm_p->next_out) >(out_buff_free_start); - zstrm_p->avail_out = (out_buff + buff_size) - out_buff_free_start; - int ret = inflate(zstrm_p, Z_NO_FLUSH); - // process return code - if (ret != Z_OK && ret != Z_STREAM_END) throw Exception(zstrm_p, ret); - // update in&out pointers following inflate() - in_buff_start = reinterpret_cast< decltype(in_buff_start) >(zstrm_p->next_in); - in_buff_end = in_buff_start + zstrm_p->avail_in; - out_buff_free_start = reinterpret_cast< decltype(out_buff_free_start) >(zstrm_p->next_out); - assert(out_buff_free_start + zstrm_p->avail_out == out_buff + buff_size); - // if stream ended, deallocate inflator - if (ret == Z_STREAM_END) - { - delete zstrm_p; - zstrm_p = nullptr; - } - } - } while (out_buff_free_start == out_buff); - // 2 exit conditions: - // - end of input: there might or might not be output available - // - out_buff_free_start != out_buff: output available - this->setg(out_buff, out_buff, out_buff_free_start); - } - return this->gptr() == this->egptr() - ? traits_type::eof() - : traits_type::to_int_type(*this->gptr()); - } -private: - std::streambuf * sbuf_p; - char * in_buff; - char * in_buff_start; - char * in_buff_end; - char * out_buff; - detail::z_stream_wrapper * zstrm_p; - std::size_t buff_size; - bool auto_detect; - bool auto_detect_run; - bool is_text; - - static const std::size_t default_buff_size = (std::size_t)1 << 20; -}; // class istreambuf - -class ostreambuf - : public std::streambuf -{ -public: - ostreambuf(std::streambuf * _sbuf_p, - std::size_t _buff_size = default_buff_size, int _level = Z_DEFAULT_COMPRESSION) - : sbuf_p(_sbuf_p), - zstrm_p(new detail::z_stream_wrapper(false, _level)), - buff_size(_buff_size) - { - assert(sbuf_p); - in_buff = new char [buff_size]; - out_buff = new char [buff_size]; - setp(in_buff, in_buff + buff_size); - } - - ostreambuf(const ostreambuf &) = delete; - ostreambuf(ostreambuf &&) = default; - ostreambuf & operator = (const ostreambuf &) = delete; - ostreambuf & operator = (ostreambuf &&) = default; - - int deflate_loop(int flush) - { - while (true) - { - zstrm_p->next_out = reinterpret_cast< decltype(zstrm_p->next_out) >(out_buff); - zstrm_p->avail_out = buff_size; - int ret = deflate(zstrm_p, flush); - if (ret != Z_OK && ret != Z_STREAM_END && ret != Z_BUF_ERROR) throw Exception(zstrm_p, ret); - std::streamsize sz = sbuf_p->sputn(out_buff, reinterpret_cast< decltype(out_buff) >(zstrm_p->next_out) - out_buff); - if (sz != reinterpret_cast< decltype(out_buff) >(zstrm_p->next_out) - out_buff) - { - // there was an error in the sink stream - return -1; - } - if (ret == Z_STREAM_END || ret == Z_BUF_ERROR || sz == 0) - { - break; - } - } - return 0; - } - - virtual ~ostreambuf() - { - // flush the zlib stream - // - // NOTE: Errors here (sync() return value not 0) are ignored, because we - // cannot throw in a destructor. This mirrors the behaviour of - // std::basic_filebuf::~basic_filebuf(). To see an exception on error, - // close the ofstream with an explicit call to close(), and do not rely - // on the implicit call in the destructor. - // - sync(); - delete [] in_buff; - delete [] out_buff; - delete zstrm_p; - } - virtual std::streambuf::int_type overflow(std::streambuf::int_type c = traits_type::eof()) - { - zstrm_p->next_in = reinterpret_cast< decltype(zstrm_p->next_in) >(pbase()); - zstrm_p->avail_in = pptr() - pbase(); - while (zstrm_p->avail_in > 0) - { - int r = deflate_loop(Z_NO_FLUSH); - if (r != 0) - { - setp(nullptr, nullptr); - return traits_type::eof(); - } - } - setp(in_buff, in_buff + buff_size); - return traits_type::eq_int_type(c, traits_type::eof()) ? traits_type::eof() : sputc(c); - } - virtual int sync() - { - // first, call overflow to clear in_buff - overflow(); - if (! pptr()) return -1; - // then, call deflate asking to finish the zlib stream - zstrm_p->next_in = nullptr; - zstrm_p->avail_in = 0; - if (deflate_loop(Z_FINISH) != 0) return -1; - deflateReset(zstrm_p); - return 0; - } -private: - std::streambuf * sbuf_p; - char * in_buff; - char * out_buff; - detail::z_stream_wrapper * zstrm_p; - std::size_t buff_size; - - static const std::size_t default_buff_size = (std::size_t)1 << 20; -}; // class ostreambuf - -class istream - : public std::istream -{ -public: - istream(std::istream & is) - : std::istream(new istreambuf(is.rdbuf())) - { - exceptions(std::ios_base::badbit); - } - explicit istream(std::streambuf * sbuf_p) - : std::istream(new istreambuf(sbuf_p)) - { - exceptions(std::ios_base::badbit); - } - virtual ~istream() - { - delete rdbuf(); - } -}; // class istream - -class ostream - : public std::ostream -{ -public: - ostream(std::ostream & os) - : std::ostream(new ostreambuf(os.rdbuf())) - { - exceptions(std::ios_base::badbit); - } - explicit ostream(std::streambuf * sbuf_p) - : std::ostream(new ostreambuf(sbuf_p)) - { - exceptions(std::ios_base::badbit); - } - virtual ~ostream() - { - delete rdbuf(); - } -}; // class ostream - -namespace detail -{ - -template < typename FStream_Type > -struct strict_fstream_holder -{ - strict_fstream_holder() {}; - strict_fstream_holder(const std::string& filename, std::ios_base::openmode mode = std::ios_base::in) - : _fs(filename, mode) - {} - FStream_Type _fs; -}; // class strict_fstream_holder - -} // namespace detail - -class ifstream - : private detail::strict_fstream_holder< strict_fstream::ifstream >, - public std::istream -{ -public: - ifstream() : std::istream(new istreambuf(_fs.rdbuf())) {} - explicit ifstream(const std::string& filename, std::ios_base::openmode mode = std::ios_base::in) - : detail::strict_fstream_holder< strict_fstream::ifstream >(filename, mode), - std::istream(new istreambuf(_fs.rdbuf())) - { - this->setstate(_fs.rdstate()); - exceptions(std::ios_base::badbit); - } - virtual ~ifstream() - { - if (rdbuf()) delete rdbuf(); - } -}; // class ifstream - -class ofstream - : private detail::strict_fstream_holder< strict_fstream::ofstream >, - public std::ostream -{ -public: - explicit ofstream(const std::string& filename, std::ios_base::openmode mode = std::ios_base::out) - : detail::strict_fstream_holder< strict_fstream::ofstream >(filename, mode | std::ios_base::binary), - std::ostream(new ostreambuf(_fs.rdbuf())) - { - exceptions(std::ios_base::badbit); - } - virtual ~ofstream() - { - if (rdbuf()) delete rdbuf(); - } -}; // class ofstream - -} // namespace zstr - -#endif diff --git a/include/file.hpp b/include/file.hpp index 6a5d90b..f88f9ed 100644 --- a/include/file.hpp +++ b/include/file.hpp @@ -5,8 +5,9 @@ #include #include #include +#include -#include "zstr/src/zstr.hpp" +#include "bxzstr/include/bxzstr.hpp" namespace File { namespace exceptions { @@ -44,7 +45,7 @@ namespace File { } void open_compressed(const std::string &filename) { os.flush(); - byname.reset(new zstr::ofstream(filename)); + byname.reset(new bxz::ofstream(filename)); os.rdbuf(byname->rdbuf()); os.setstate(byname->rdstate()); if (!os) @@ -61,12 +62,12 @@ namespace File { }; class In { - std::unique_ptr byname; + std::unique_ptr byname; std::istream is; std::string myfile; void reset_state(const std::string &filename) { - byname.reset(new zstr::ifstream(filename)); + byname.reset(new bxz::ifstream(filename)); is.rdbuf(byname->rdbuf()); is.setstate(byname->rdstate()); }