From 5fa2c3b3cb8fb04adb5dace900ce03e8b5a1c9b4 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 16 Mar 2020 08:41:17 +0100 Subject: record: Add zlib filter class Update #3904. --- trace/record/client.h | 24 ++++++++++++ trace/record/record-filter-zlib.cc | 77 ++++++++++++++++++++++++++++++++++++++ trace/wscript | 5 +++ 3 files changed, 106 insertions(+) create mode 100644 trace/record/record-filter-zlib.cc diff --git a/trace/record/client.h b/trace/record/client.h index b4a0c26..62ffdb5 100644 --- a/trace/record/client.h +++ b/trace/record/client.h @@ -42,6 +42,11 @@ #include #include #include +#include + +#ifdef HAVE_ZLIB_H +#include +#endif class ErrnoException : public std::runtime_error { public: @@ -132,6 +137,25 @@ class Base64Filter : public Filter { bool DecodeChar(int c, char **target); }; +#ifdef HAVE_ZLIB_H +class ZlibFilter : public Filter { + public: + ZlibFilter(); + + ZlibFilter(const ZlibFilter&) = default; + + ZlibFilter& operator=(const ZlibFilter&) = default; + + virtual ~ZlibFilter(); + + virtual bool Run(void** buf, size_t* n); + + private: + z_stream stream_; + std::vector buffer_; +}; +#endif + class Client { public: Client() = default; diff --git a/trace/record/record-filter-zlib.cc b/trace/record/record-filter-zlib.cc new file mode 100644 index 0000000..87b2cfe --- /dev/null +++ b/trace/record/record-filter-zlib.cc @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_ZLIB_H + +#include "client.h" + +ZlibFilter::ZlibFilter() : buffer_(65536) +{ + inflateInit(&stream_); +} + +ZlibFilter::~ZlibFilter() +{ + inflateEnd(&stream_); +} + +bool ZlibFilter::Run(void** buf, size_t* n) { + stream_.next_in = static_cast(*buf); + stream_.avail_in = *n; + stream_.next_out = &buffer_[0]; + size_t avail_out = 0; + size_t buffer_size = buffer_.size(); + size_t chunk_size = buffer_size; + stream_.avail_out = buffer_size; + + while (true) { + int err = inflate(&stream_, Z_NO_FLUSH); + if (err != Z_OK && err != Z_STREAM_END) { + return false; + } + + if (stream_.avail_in > 0) { + chunk_size = buffer_size; + buffer_size *= 2; + buffer_.resize(buffer_size); + stream_.next_out = reinterpret_cast(&buffer_[chunk_size]); + stream_.avail_out = chunk_size; + avail_out += chunk_size; + continue; + } + + *buf = &buffer_[0]; + *n = avail_out + chunk_size - stream_.avail_out; + return true; + } +} + +#endif // HAVE_ZLIB_H diff --git a/trace/wscript b/trace/wscript index 7e35f74..656f92b 100644 --- a/trace/wscript +++ b/trace/wscript @@ -42,6 +42,8 @@ def configure(conf): pass if conf.check_cxx(lib = 'LLVM', mandatory=False): conf.check(header_name='llvm/DebugInfo/Symbolize/Symbolize.h', features='cxx', mandatory=False) + if conf.check(header_name='zlib.h', features='cxx', mandatory=False): + conf.check_cxx(lib = 'z') conf.check_cxx(lib = 'ws2_32', mandatory=False) conf.write_config_header('config.h') @@ -65,6 +67,8 @@ def build(bld): conf['lib'].extend(bld.env.LIB_WS2_32) if bld.env.LIB_LLVM: conf['lib'].extend(bld.env.LIB_LLVM) + if bld.env.LIB_Z: + conf['lib'].extend(bld.env.LIB_Z) # # The list of defines @@ -81,6 +85,7 @@ def build(bld): 'record/record-text.c', 'record/record-client-base.cc', 'record/record-filter-base64.cc', + 'record/record-filter-zlib.cc', 'record/record-main-lttng.cc', 'record/inih/ini.c'], includes = conf['includes'], -- cgit v1.2.3