From 36d6ead65cf507948744ee5d8615c8ef20e42f9d Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 16 Dec 2015 10:14:56 +0100 Subject: [PATCH] fs/io/GzipOutputStream: use C++ exceptions in constructor --- Makefile.am | 4 +- .../plugins/simple/SimpleDatabasePlugin.cxx | 5 +-- src/fs/io/GzipOutputStream.cxx | 13 +++---- src/fs/io/GzipOutputStream.hxx | 15 ++------ src/lib/zlib/Error.cxx | 29 ++++++++++++++ src/lib/zlib/Error.hxx | 38 +++++++++++++++++++ test/run_gzip.cxx | 21 ++++++---- 7 files changed, 92 insertions(+), 33 deletions(-) create mode 100644 src/lib/zlib/Error.cxx create mode 100644 src/lib/zlib/Error.hxx diff --git a/Makefile.am b/Makefile.am index 4ad1cea80..e836c7343 100644 --- a/Makefile.am +++ b/Makefile.am @@ -605,6 +605,7 @@ libfs_a_CPPFLAGS = $(AM_CPPFLAGS) $(ZLIB_CFLAGS) if ENABLE_ZLIB libfs_a_SOURCES += \ src/lib/zlib/Domain.cxx src/lib/zlib/Domain.hxx \ + src/lib/zlib/Error.cxx src/lib/zlib/Error.hxx \ src/fs/io/GunzipReader.cxx src/fs/io/GunzipReader.hxx \ src/fs/io/AutoGunzipReader.cxx src/fs/io/AutoGunzipReader.hxx \ src/fs/io/GzipOutputStream.cxx src/fs/io/GzipOutputStream.hxx @@ -1759,7 +1760,8 @@ noinst_PROGRAMS += test/run_gzip test/run_gunzip test_run_gzip_LDADD = \ libutil.a \ $(FS_LIBS) -test_run_gzip_SOURCES = test/run_gzip.cxx +test_run_gzip_SOURCES = test/run_gzip.cxx \ + src/Log.cxx src/LogBackend.cxx test_run_gunzip_SOURCES = test/run_gunzip.cxx \ src/Log.cxx src/LogBackend.cxx diff --git a/src/db/plugins/simple/SimpleDatabasePlugin.cxx b/src/db/plugins/simple/SimpleDatabasePlugin.cxx index 97e2e6c2b..aa62870c6 100644 --- a/src/db/plugins/simple/SimpleDatabasePlugin.cxx +++ b/src/db/plugins/simple/SimpleDatabasePlugin.cxx @@ -386,10 +386,7 @@ SimpleDatabase::Save(Error &error) #ifdef ENABLE_ZLIB std::unique_ptr gzip; if (compress) { - gzip.reset(new GzipOutputStream(*os, error)); - if (!gzip->IsDefined()) - return false; - + gzip.reset(new GzipOutputStream(*os)); os = gzip.get(); } #endif diff --git a/src/fs/io/GzipOutputStream.cxx b/src/fs/io/GzipOutputStream.cxx index d2a693b87..e903aaaa3 100644 --- a/src/fs/io/GzipOutputStream.cxx +++ b/src/fs/io/GzipOutputStream.cxx @@ -20,10 +20,10 @@ #include "config.h" #include "GzipOutputStream.hxx" #include "lib/zlib/Domain.hxx" +#include "lib/zlib/Error.hxx" #include "util/Error.hxx" -#include "util/Domain.hxx" -GzipOutputStream::GzipOutputStream(OutputStream &_next, Error &error) +GzipOutputStream::GzipOutputStream(OutputStream &_next) throw(ZlibError) :next(_next) { z.next_in = nullptr; @@ -38,16 +38,13 @@ GzipOutputStream::GzipOutputStream(OutputStream &_next, Error &error) int result = deflateInit2(&z, Z_DEFAULT_COMPRESSION, Z_DEFLATED, windowBits | gzip_encoding, 8, Z_DEFAULT_STRATEGY); - if (result != Z_OK) { - z.opaque = this; - error.Set(zlib_domain, result, zError(result)); - } + if (result != Z_OK) + throw ZlibError(result); } GzipOutputStream::~GzipOutputStream() { - if (IsDefined()) - deflateEnd(&z); + deflateEnd(&z); } bool diff --git a/src/fs/io/GzipOutputStream.hxx b/src/fs/io/GzipOutputStream.hxx index fdab7bca4..700a69354 100644 --- a/src/fs/io/GzipOutputStream.hxx +++ b/src/fs/io/GzipOutputStream.hxx @@ -22,13 +22,13 @@ #include "check.h" #include "OutputStream.hxx" +#include "lib/zlib/Error.hxx" #include "Compiler.h" #include #include class Error; -class Domain; /** * A filter that compresses data written to it using zlib, forwarding @@ -43,20 +43,11 @@ class GzipOutputStream final : public OutputStream { public: /** - * Construct the filter. Call IsDefined() to check whether - * the constructor has succeeded. If not, #error will hold - * information about the failure. + * Construct the filter. */ - GzipOutputStream(OutputStream &_next, Error &error); + GzipOutputStream(OutputStream &_next) throw(ZlibError); ~GzipOutputStream(); - /** - * Check whether the constructor has succeeded. - */ - bool IsDefined() const { - return z.opaque == nullptr; - } - /** * Finish the file and write all data remaining in zlib's * output buffer. diff --git a/src/lib/zlib/Error.cxx b/src/lib/zlib/Error.cxx new file mode 100644 index 000000000..dc9dd9b19 --- /dev/null +++ b/src/lib/zlib/Error.cxx @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2003-2015 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "Error.hxx" + +#include + +const char * +ZlibError::what() const noexcept +{ + return zError(code); +} diff --git a/src/lib/zlib/Error.hxx b/src/lib/zlib/Error.hxx new file mode 100644 index 000000000..a71f5edbd --- /dev/null +++ b/src/lib/zlib/Error.hxx @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2003-2015 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_ZLIB_ERROR_HXX +#define MPD_ZLIB_ERROR_HXX + +#include + +class ZlibError final : public std::exception { + int code; + +public: + explicit ZlibError(int _code):code(_code) {} + + int GetCode() const { + return code; + } + + const char *what() const noexcept override; +}; + +#endif diff --git a/test/run_gzip.cxx b/test/run_gzip.cxx index 15b769f0a..af63c0991 100644 --- a/test/run_gzip.cxx +++ b/test/run_gzip.cxx @@ -20,6 +20,7 @@ #include "config.h" #include "fs/io/GzipOutputStream.hxx" #include "fs/io/StdioOutputStream.hxx" +#include "Log.hxx" #include "util/Error.hxx" #include @@ -48,9 +49,8 @@ Copy(OutputStream &dest, int src, Error &error) static bool CopyGzip(OutputStream &_dest, int src, Error &error) { - GzipOutputStream dest(_dest, error); - return dest.IsDefined() && - Copy(dest, src, error) && + GzipOutputStream dest(_dest); + return Copy(dest, src, error) && dest.Flush(error); } @@ -69,11 +69,16 @@ main(int argc, gcc_unused char **argv) return EXIT_FAILURE; } - Error error; - if (!CopyGzip(stdout, STDIN_FILENO, error)) { - fprintf(stderr, "%s\n", error.GetMessage()); + try { + Error error; + if (!CopyGzip(stdout, STDIN_FILENO, error)) { + fprintf(stderr, "%s\n", error.GetMessage()); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; + } catch (const std::exception &e) { + LogError(e); return EXIT_FAILURE; } - - return EXIT_SUCCESS; }