/* * Copyright (c) 2016, Luca Fulchir, All rights reserved. * * This file is part of "libRaptorQ". * * libRaptorQ 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. * * libRaptorQ 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 * and a copy of the GNU Lesser General Public License * along with libRaptorQ. If not, see . */ #ifndef RAPTORQ_LZ4_HPP #define RAPTORQ_LZ4_HPP #include "../common.hpp" #include #include namespace RaptorQ { namespace Impl { enum class LZ4_t : uint8_t { ENCODER=0, DECODER=1 }; template class RAPTORQ_API LZ4 { public: LZ4(); ~LZ4(); std::vector encode (const std::vector &in); std::vector decode (const std::vector &in); private: void *stream; }; template LZ4::LZ4() { if (type == LZ4_t::ENCODER) { stream = static_cast (LZ4_createStream()); } else { stream = static_cast (LZ4_createStreamDecode()); } } template LZ4::~LZ4() { if (type == LZ4_t::ENCODER) { LZ4_freeStream (static_cast (stream)); } else { LZ4_freeStreamDecode (static_cast (stream)); } } template std::vector LZ4::encode (const std::vector &in) { std::vector ret; if (type == LZ4_t::DECODER || in.size() == 0 || in.size() >= LZ4_MAX_INPUT_SIZE) { return ret; } auto max_size = LZ4_compressBound (static_cast (in.size())); if (stream == nullptr || max_size == 0) return ret; ret.resize (static_cast (max_size) + sizeof(uint32_t), 0); // put original size in the first 4 bytes, for decoding. // int32 is fine, LZ4 has a limit of 2^31 bytes. int32_t *size = reinterpret_cast (ret.data()); *size = static_cast (in.size()); // now the compressed data. auto written = LZ4_compress_fast_continue ( static_cast (stream), reinterpret_cast (in.data()), reinterpret_cast (ret.data()) + sizeof(int32_t), static_cast (in.size()), max_size, 1); ret.resize (static_cast (written) + sizeof(int32_t)); return ret; } template std::vector LZ4::decode (const std::vector &in) { std::vector ret; if (type == LZ4_t::ENCODER || in.size() < sizeof(uint32_t)) return ret; if (stream == nullptr) return ret; // get the original uncompresseed size: int32_t *orig_size = reinterpret_cast ( const_cast (in.data())); // now the compressed data. ret.reserve (static_cast (*orig_size)); ret.resize (static_cast (*orig_size), 0); auto written = LZ4_decompress_safe_continue ( static_cast (stream), reinterpret_cast (in.data()) + sizeof(uint32_t), reinterpret_cast (ret.data()), static_cast (in.size() - sizeof(uint32_t)), *orig_size); if (written <= 0) { return std::vector(); } ret.resize (static_cast (written)); return ret; } } // namepace Impl } // namespace RaptorQ #endif