source: box/trunk/test/compress/testcompress.cpp @ 2127

Revision 2127, 5.9 KB checked in by chris, 4 years ago (diff)

Undo mangling by tailor

  • Property svn:eol-style set to native
Line 
1// --------------------------------------------------------------------------
2//
3// File
4//              Name:    testcompress.cpp
5//              Purpose: Test lib/compress
6//              Created: 5/12/03
7//
8// --------------------------------------------------------------------------
9
10#include "Box.h"
11
12#include <stdio.h>
13#include <string.h>
14
15#include "Test.h"
16#include "Compress.h"
17#include "CompressStream.h"
18#include "CollectInBufferStream.h"
19
20#include "MemLeakFindOn.h"
21
22#define DATA_SIZE                       (1024*128+103)
23#define CHUNK_SIZE                      2561
24#define DECOMP_CHUNK_SIZE       3
25
26// Stream for testing
27class CopyInToOutStream : public IOStream
28{
29public:
30        CopyInToOutStream() : currentBuffer(0) {buffers[currentBuffer].SetForReading();}
31        ~CopyInToOutStream() {}
32        int Read(void *pBuffer, int NBytes, int Timeout = IOStream::TimeOutInfinite)
33        {
34                if(buffers[currentBuffer].StreamDataLeft())
35                {
36                        return buffers[currentBuffer].Read(pBuffer, NBytes, Timeout);
37                }
38               
39                // Swap buffers?
40                if(buffers[(currentBuffer + 1) & 1].GetSize() > 0)
41                {
42                        buffers[currentBuffer].Reset();
43                        currentBuffer = (currentBuffer + 1) & 1;
44                        buffers[currentBuffer].SetForReading();
45                        return buffers[currentBuffer].Read(pBuffer, NBytes, Timeout);           
46                }
47
48                return 0;
49        }
50        void Write(const void *pBuffer, int NBytes)
51        {
52                buffers[(currentBuffer + 1) & 1].Write(pBuffer, NBytes);
53        }
54        bool StreamDataLeft()
55        {
56                return buffers[currentBuffer].StreamDataLeft() || buffers[(currentBuffer + 1) % 1].GetSize() > 0;
57        }
58        bool StreamClosed()
59        {
60                return false;
61        }
62        int currentBuffer;
63        CollectInBufferStream buffers[2];
64};
65
66// Test stream based interface
67int test_stream()
68{
69        // Make a load of compressible data to compress
70        CollectInBufferStream source;
71        uint16_t data[1024];
72        for(int x = 0; x < 1024; ++x)
73        {
74                data[x] = x;
75        }
76        for(int x = 0; x < (32*1024); ++x)
77        {
78                source.Write(data, (x % 1024) * 2);
79        }
80        source.SetForReading();
81
82        // Straight compress from one stream to another
83        {
84                CollectInBufferStream *poutput = new CollectInBufferStream;
85                CompressStream compress(poutput, true /* take ownership */, false /* read */, true /* write */);
86               
87                source.CopyStreamTo(compress);
88                compress.Close();
89                poutput->SetForReading();
90               
91                // Check sizes
92                TEST_THAT(poutput->GetSize() < source.GetSize());
93                BOX_TRACE("compressed size = " << poutput->GetSize() <<
94                        ", source size = " << source.GetSize());
95               
96                // Decompress the data
97                {
98                        CollectInBufferStream decompressed;
99                        CompressStream decompress(poutput, false /* don't take ownership */, true /* read */, false /* write */);
100                        decompress.CopyStreamTo(decompressed);
101                        decompress.Close();
102                       
103                        TEST_THAT(decompressed.GetSize() == source.GetSize());
104                        TEST_THAT(::memcmp(decompressed.GetBuffer(), source.GetBuffer(), decompressed.GetSize()) == 0);
105                }
106               
107                // Don't delete poutput, let mem leak testing ensure it's deleted.
108        }
109
110        // Set source to the beginning
111        source.Seek(0, IOStream::SeekType_Absolute);
112
113        // Test where the same stream compresses and decompresses, should be fun!
114        {
115                CollectInBufferStream output;
116                CopyInToOutStream copyer;
117                CompressStream compress(&copyer, false /* no ownership */, true, true);
118
119                bool done = false;
120                int count = 0;
121                int written = 0;
122                while(!done)
123                {
124                        ++count;
125                        bool do_sync = (count % 256) == 0;
126                        uint8_t buffer[4096];
127                        int r = source.Read(buffer, sizeof(buffer), IOStream::TimeOutInfinite);
128                        if(r == 0)
129                        {
130                                done = true;
131                                compress.Close();
132                        }
133                        else
134                        {
135                                compress.Write(buffer, r);
136                                written += r;
137                                if(do_sync)
138                                {
139                                        compress.WriteAllBuffered();
140                                }
141                        }
142
143                        int r2 = 0;
144                        do
145                        {
146                                r2 = compress.Read(buffer, sizeof(buffer), IOStream::TimeOutInfinite);
147                                if(r2 > 0)
148                                {
149                                        output.Write(buffer, r2);
150                                }
151                        } while(r2 > 0);
152                        if(do_sync && r != 0)
153                        {
154                                // Check that everything is synced
155                                TEST_THAT(output.GetSize() == written);
156                                TEST_THAT(::memcmp(output.GetBuffer(), source.GetBuffer(), output.GetSize()) == 0);
157                        }
158                }
159                output.SetForReading();
160               
161                // Test that it's the same
162                TEST_THAT(output.GetSize() == source.GetSize());
163                TEST_THAT(::memcmp(output.GetBuffer(), source.GetBuffer(), output.GetSize()) == 0);
164        }
165
166        return 0;
167}
168
169// Test basic interface
170int test(int argc, const char *argv[])
171{
172        // Bad data to compress!
173        char *data = (char *)malloc(DATA_SIZE);
174        for(int l = 0; l < DATA_SIZE; ++l)
175        {
176                data[l] = l*23;
177        }
178       
179        // parameters about compression
180        int maxOutput = Compress_MaxSizeForCompressedData(DATA_SIZE);
181        TEST_THAT(maxOutput >= DATA_SIZE);
182
183        char *compressed = (char *)malloc(maxOutput);
184        int compressedSize = 0;
185       
186        // Do compression, in small chunks
187        {
188                Compress<true> compress;
189               
190                int in_loc = 0;
191                while(!compress.OutputHasFinished())
192                {
193                        int ins = DATA_SIZE - in_loc;
194                        if(ins > CHUNK_SIZE) ins = CHUNK_SIZE;
195                       
196                        if(ins == 0)
197                        {
198                                compress.FinishInput();
199                        }
200                        else
201                        {
202                                compress.Input(data + in_loc, ins);
203                        }
204                        in_loc += ins;
205                       
206                        // Get output data
207                        int s = 0;
208                        do
209                        {
210                                TEST_THAT(compressedSize < maxOutput);
211                                s = compress.Output(compressed + compressedSize, maxOutput - compressedSize);
212                                compressedSize += s;
213                        } while(s > 0);
214                }
215        }
216       
217        // a reasonable test, especially given the compressability of the input data.
218        TEST_THAT(compressedSize < DATA_SIZE);
219
220        // decompression
221        char *decompressed = (char*)malloc(DATA_SIZE * 2);
222        int decomp_size = 0;
223        {       
224                Compress<false> decompress;
225               
226                int in_loc = 0;
227                while(!decompress.OutputHasFinished())
228                {
229                        int ins = compressedSize - in_loc;
230                        if(ins > DECOMP_CHUNK_SIZE) ins = DECOMP_CHUNK_SIZE;
231                       
232                        if(ins == 0)
233                        {
234                                decompress.FinishInput();
235                        }
236                        else
237                        {
238                                decompress.Input(compressed + in_loc, ins);
239                        }
240                        in_loc += ins;
241                       
242                        // Get output data
243                        int s = 0;
244                        do
245                        {
246                                TEST_THAT(decomp_size <= DATA_SIZE);
247                                s = decompress.Output(decompressed + decomp_size, (DATA_SIZE*2) - decomp_size);
248                                decomp_size += s;
249                        } while(s > 0);
250                }
251        }
252       
253        TEST_THAT(decomp_size == DATA_SIZE);
254        TEST_THAT(::memcmp(data, decompressed, DATA_SIZE) == 0);
255
256        ::free(data);
257        ::free(compressed);
258        ::free(decompressed);
259       
260        return test_stream();
261}
Note: See TracBrowser for help on using the repository browser.