1 /*
2  * Copyright (C) 2020 Veloman Yunkan
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
11  * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
12  * NON-INFRINGEMENT.  See the GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
17  *
18  */
19 
20 #include "decoderstreamreader.h"
21 #include "buffer_reader.h"
22 
23 #include "gtest/gtest.h"
24 
25 namespace
26 {
27 
28 template<class CompressionInfo>
29 std::string
compress(const std::string & data)30 compress(const std::string& data)
31 {
32   zim::Compressor<CompressionInfo> compressor(data.size());
33   compressor.init(const_cast<char*>(data.c_str()));
34   compressor.feed(data.c_str(), data.size());
35   zim::zsize_t comp_size;
36   const auto comp_data = compressor.get_data(&comp_size);
37   return std::string(comp_data.get(), comp_size.v);
38 }
39 
operator *(const std::string & s,unsigned N)40 std::string operator*(const std::string& s, unsigned N)
41 {
42   std::string result;
43   for (unsigned i=0; i<N; i++)
44     result += s;
45   return result;
46 }
47 
toString(const zim::Buffer & buffer)48 std::string toString(const zim::Buffer& buffer)
49 {
50   return std::string(buffer.data(), buffer.size().v);
51 }
52 
53 template<typename T>
54 class DecoderStreamReaderTest : public testing::Test {
55   protected:
56     typedef T CompressionInfo;
57 };
58 
59 using CompressionTypes = ::testing::Types<
60   LZMA_INFO,
61   ZSTD_INFO
62 >;
63 
64 TYPED_TEST_CASE(DecoderStreamReaderTest, CompressionTypes);
65 
TYPED_TEST(DecoderStreamReaderTest,justCompressedData)66 TYPED_TEST(DecoderStreamReaderTest, justCompressedData) {
67   typedef typename TestFixture::CompressionInfo CompressionInfo;
68 
69   const int N = 10;
70   const std::string s("DecoderStreamReader should work correctly");
71   const std::string compDataStr = compress<CompressionInfo>(s*N);
72   auto compData = zim::Buffer::makeBuffer(compDataStr.data(), zim::zsize_t(compDataStr.size()));
73 
74   auto compReader = std::make_shared<zim::BufferReader>(compData);
75   zim::DecoderStreamReader<CompressionInfo> dds(compReader);
76   for (int i=0; i<N; i++)
77   {
78     auto decompReader = dds.sub_reader(zim::zsize_t(s.size()));
79     ASSERT_EQ(s, toString(decompReader->get_buffer(zim::offset_t(0), zim::zsize_t(s.size())))) << "i: " << i;
80   }
81 }
82 
TYPED_TEST(DecoderStreamReaderTest,compressedDataFollowedByGarbage)83 TYPED_TEST(DecoderStreamReaderTest, compressedDataFollowedByGarbage) {
84   typedef typename TestFixture::CompressionInfo CompressionInfo;
85 
86   const int N = 10;
87   const std::string s("DecoderStreamReader should work correctly");
88   std::string compDataStr = compress<CompressionInfo>(s*N);
89   compDataStr += std::string(10, '\0');
90 
91   auto compData = zim::Buffer::makeBuffer(compDataStr.data(), zim::zsize_t(compDataStr.size()));
92   auto compReader = std::make_shared<zim::BufferReader>(compData);
93 
94   zim::DecoderStreamReader<CompressionInfo> dds(compReader);
95   for (int i=0; i<N; i++)
96   {
97     auto decompReader = dds.sub_reader(zim::zsize_t(s.size()));
98     ASSERT_EQ(s, toString(decompReader->get_buffer(zim::offset_t(0), zim::zsize_t(s.size())))) << "i: " << i;
99   }
100 }
101 
102 } // unnamed namespace
103