| // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <stdlib.h> |
| |
| #include "remoting/base/compressor_zlib.h" |
| #include "remoting/base/decompressor_zlib.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace remoting { |
| |
| static void GenerateTestData(uint8* data, int size, int seed) { |
| srand(seed); |
| for (int i = 0; i < size; ++i) |
| data[i] = rand() % 256; |
| } |
| |
| // Keep compressing |input_data| into |output_data| until the last |
| // bytes is consumed. |
| // |
| // The compressed size is written to |compressed_size|. |
| static void Compress(remoting::Compressor* compressor, |
| const uint8* input_data, int input_size, |
| uint8* output_data, int output_size, |
| int* compressed_size) { |
| *compressed_size = 0; |
| while (true) { |
| int consumed, written; |
| bool ret = compressor->Process( |
| input_data, input_size, output_data, output_size, |
| input_size == 0 ? |
| Compressor::CompressorFinish : Compressor::CompressorNoFlush, |
| &consumed, &written); |
| input_data += consumed; |
| input_size -= consumed; |
| output_data += written; |
| output_size -= written; |
| *compressed_size += written; |
| |
| if (!ret) |
| break; |
| } |
| } |
| |
| // The decompressed size is written to |decompressed_size|. |
| static void Decompress(remoting::Decompressor* decompressor, |
| const uint8* input_data, int input_size, |
| uint8* output_data, int output_size, |
| int* decompressed_size) { |
| *decompressed_size = 0; |
| while (true) { |
| int consumed, written; |
| bool ret = decompressor->Process(input_data, input_size, |
| output_data, output_size, |
| &consumed, &written); |
| input_data += consumed; |
| input_size -= consumed; |
| output_data += written; |
| output_size -= written; |
| *decompressed_size += written; |
| |
| if (!ret) |
| break; |
| } |
| } |
| |
| TEST(DecompressorZlibTest, CompressAndDecompress) { |
| static const int kRawDataSize = 1024 * 128; |
| static const int kCompressedDataSize = 2 * kRawDataSize; |
| static const int kDecompressedDataSize = kRawDataSize; |
| |
| uint8 raw_data[kRawDataSize]; |
| uint8 compressed_data[kCompressedDataSize]; |
| uint8 decompressed_data[kDecompressedDataSize]; |
| |
| // Generate the test data.g |
| GenerateTestData(raw_data, kRawDataSize, 99); |
| |
| // Then use the compressor. |
| remoting::CompressorZlib compressor; |
| int compressed_size = 0; |
| Compress(&compressor, raw_data, kRawDataSize, |
| compressed_data, kCompressedDataSize, |
| &compressed_size); |
| |
| // Then use the decompressor. |
| remoting::DecompressorZlib decompressor; |
| int decompressed_size = 0; |
| Decompress(&decompressor, compressed_data, compressed_size, |
| decompressed_data, kDecompressedDataSize, |
| &decompressed_size); |
| |
| EXPECT_EQ(kRawDataSize, decompressed_size); |
| EXPECT_EQ(0, memcmp(raw_data, decompressed_data, decompressed_size)); |
| } |
| |
| // Checks that zlib can work with a small output buffer by limiting |
| // number of bytes it gets from the input. |
| TEST(DecompressorZlibTest, SmallOutputBuffer) { |
| static const int kRawDataSize = 1024 * 128; |
| static const int kCompressedDataSize = 2 * kRawDataSize; |
| |
| uint8 raw_data[kRawDataSize]; |
| uint8 compressed_data[kCompressedDataSize]; |
| |
| // Generate the test data. |
| GenerateTestData(raw_data, kRawDataSize, 99); |
| |
| // Then use the compressor to compress. |
| remoting::CompressorZlib compressor; |
| int compressed_size = 0; |
| Compress(&compressor, raw_data, kRawDataSize, |
| compressed_data, kCompressedDataSize, |
| &compressed_size); |
| |
| // Then use the decompressor. We decompress into a 1 byte buffer |
| // every time. |
| remoting::DecompressorZlib decompressor; |
| uint8* input_data = compressed_data; |
| int input_size = compressed_size; |
| int decompressed_size = 0; |
| while (true) { |
| int consumed, written; |
| uint8 output_data; |
| bool ret = decompressor.Process(input_data, input_size, |
| &output_data, 1, |
| &consumed, &written); |
| input_data += consumed; |
| input_size -= consumed; |
| |
| // Expect that there's only one byte written. |
| EXPECT_EQ(1, written); |
| decompressed_size += written; |
| |
| if (!ret) |
| break; |
| } |
| EXPECT_EQ(kRawDataSize, decompressed_size); |
| } |
| |
| } // namespace remoting |