test_compress.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:20k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: test_compress.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:42:40  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: test_compress.cpp,v 1000.2 2004/06/01 19:42:40 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Author:  Vladimir Ivanov
  35.  *
  36.  * File Description:  Test program for the Compression API
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <corelib/ncbiapp.hpp>
  41. #include <corelib/ncbiargs.hpp>
  42. #include <corelib/ncbi_limits.hpp>
  43. #include <corelib/ncbifile.hpp>
  44. #include <util/compress/bzip2.hpp>
  45. #include <util/compress/zlib.hpp>
  46. #include <test/test_assert.h>  // This header must go last
  47. USING_NCBI_SCOPE;
  48. const size_t        kDataLen    = 100*1024;
  49. const size_t        kBufLen     = 102*1024;
  50. const int           kUnknownErr = kMax_Int;
  51. const unsigned int  kUnknown    = kMax_UInt;
  52. //////////////////////////////////////////////////////////////////////////////
  53. //
  54. // The template class for compressor test
  55. //
  56. template<class TCompression,
  57.          class TCompressionFile,
  58.          class TStreamCompressor,
  59.          class TStreamDecompressor>
  60. class CTestCompressor
  61. {
  62. public:
  63.     // Run test for the template compressor usind data from "src_buf"
  64.     static void Run(const char* src_buf);
  65.     // Print out compress/decompress status
  66.     enum EPrintType { 
  67.         eCompress,
  68.         eDecompress 
  69.     };
  70.     static void PrintResult(EPrintType type, int last_errcode,
  71.                             unsigned int src_len,
  72.                             unsigned int dst_len,
  73.                             unsigned int out_len);
  74. };
  75. // Print OK message
  76. #define OK cout << "OKnn"
  77. // Init destination buffers
  78. #define INIT_BUFFERS  memset(dst_buf, 0, kBufLen); memset(cmp_buf, 0, kBufLen)
  79. template<class TCompression,
  80.     class TCompressionFile,
  81.     class TStreamCompressor,
  82.     class TStreamDecompressor>
  83. void CTestCompressor<TCompression, TCompressionFile,
  84.     TStreamCompressor, TStreamDecompressor>
  85.     ::Run(const char* src_buf)
  86. {
  87.     char* dst_buf = new char[kBufLen];
  88.     char* cmp_buf = new char[kBufLen];
  89.     unsigned int dst_len, out_len;
  90.     bool result;
  91.     assert(dst_buf);
  92.     assert(cmp_buf);
  93.     //------------------------------------------------------------------------
  94.     // Compress/decomress buffer
  95.     //------------------------------------------------------------------------
  96.     {{
  97.         cout << "Testing default level compression...n";
  98.         INIT_BUFFERS;
  99.         // Compress data
  100.         TCompression c(CCompression::eLevel_Medium);
  101.         result = c.CompressBuffer(src_buf, kDataLen, dst_buf, kBufLen,
  102.                                   &out_len);
  103.         PrintResult(eCompress, c.GetErrorCode(), kDataLen, kBufLen, out_len);
  104.         assert(result);
  105.         // Decompress data
  106.         dst_len = out_len;
  107.         result = c.DecompressBuffer(dst_buf, dst_len, cmp_buf, kBufLen,
  108.                                     &out_len);
  109.         PrintResult(eDecompress, c.GetErrorCode(), dst_len, kBufLen,out_len);
  110.         assert(result);
  111.         assert(out_len == kDataLen);
  112.         // Compare original and decompressed data
  113.         assert(memcmp(src_buf, cmp_buf, out_len) == 0);
  114.         OK;
  115.     }}
  116.     //------------------------------------------------------------------------
  117.     // Overflow test
  118.     //------------------------------------------------------------------------
  119.     {{
  120.         cout << "Output buffer overflow test...n";
  121.         TCompression c;
  122.         dst_len = 100;
  123.         result = c.CompressBuffer(src_buf, kDataLen, dst_buf, dst_len,
  124.                                   &out_len);
  125.         PrintResult(eCompress, c.GetErrorCode(), kDataLen, dst_len, out_len);
  126.         assert(!result);
  127.         assert(out_len == dst_len);
  128.         OK;
  129.     }}
  130.     //------------------------------------------------------------------------
  131.     // File compress/decompress test
  132.     //------------------------------------------------------------------------
  133.     {{
  134.         cout << "File compress/decompress test...n";
  135.         INIT_BUFFERS;
  136.         int n;
  137.         TCompressionFile zfile;
  138.         const string kFileName = "compressed.file";
  139.         // Compress data to file
  140.         assert(zfile.Open(kFileName, TCompressionFile::eMode_Write)); 
  141.         for (unsigned int i=0; i < kDataLen/1024; i++) {
  142.             n = zfile.Write(src_buf + i*1024, 1024);
  143.             assert(n == 1024);
  144.         }
  145.         assert(zfile.Close()); 
  146.         assert(CFile(kFileName).GetLength() > 0);
  147.         
  148.         // Decompress data from file
  149.         assert(zfile.Open(kFileName, TCompressionFile::eMode_Read)); 
  150.         assert(zfile.Read(cmp_buf, kDataLen) == (int)kDataLen);
  151.         assert(zfile.Close()); 
  152.         // Compare original and decompressed data
  153.         assert(memcmp(src_buf, cmp_buf, kDataLen) == 0);
  154.         // Second test
  155.         INIT_BUFFERS;
  156.         {{
  157.             TCompressionFile zf(kFileName, TCompressionFile::eMode_Write,
  158.                                 CCompression::eLevel_Best);
  159.             n = zf.Write(src_buf, kDataLen);
  160.             assert(n == (int)kDataLen);
  161.         }}
  162.         {{
  163.             TCompressionFile zf(kFileName, TCompressionFile::eMode_Read);
  164.             int nread = 0;
  165.             do {
  166.                 n = zf.Read(cmp_buf + nread, 100);
  167.                 assert(n >= 0);
  168.                 nread += n;
  169.             } while ( n != 0 );
  170.             assert(nread == (int)kDataLen);
  171.         }}
  172.         // Compare original and decompressed data
  173.         assert(memcmp(src_buf, cmp_buf, kDataLen) == 0);
  174.         CFile(kFileName).Remove();
  175.         OK;
  176.     }}
  177.     //------------------------------------------------------------------------
  178.     // Compression input stream test
  179.     //------------------------------------------------------------------------
  180.     {{
  181.         cout << "Testing compression input stream...n";
  182.         INIT_BUFFERS;
  183.         // Compression input stream test 
  184.         CNcbiIstrstream is_str(src_buf, kDataLen);
  185.         CCompressionIStream ics_zip(is_str, new TStreamCompressor(),
  186.                                     CCompressionStream::fOwnProcessor);
  187.         // Read as much as possible
  188.         ics_zip.read(dst_buf, kBufLen);
  189.         dst_len = ics_zip.gcount();
  190.         assert(ics_zip.eof());
  191.         ics_zip.Finalize();
  192.         // Read the residue of the data after the compression finalization
  193.         if ( dst_len < kDataLen ) {
  194.             ics_zip.clear();
  195.             ics_zip.read(dst_buf + dst_len, kBufLen - dst_len);
  196.             dst_len += ics_zip.gcount();
  197.         }
  198.         PrintResult(eCompress, kUnknownErr, kDataLen, kUnknown, dst_len);
  199.         assert(ics_zip.GetProcessedSize() == kDataLen);
  200.         assert(ics_zip.GetOutputSize() == dst_len);
  201.         // Compress the data
  202.         TCompression c;
  203.         result = c.DecompressBuffer(dst_buf, dst_len, cmp_buf, kBufLen,
  204.                                     &out_len);
  205.         PrintResult(eDecompress, c.GetErrorCode(), dst_len, kBufLen, out_len);
  206.         assert(result);
  207.         // Compare original and uncompressed data
  208.         assert(out_len == kDataLen);
  209.         assert(memcmp(src_buf, cmp_buf, kDataLen) == 0);
  210.         OK;
  211.    }}
  212.     //------------------------------------------------------------------------
  213.     // Decompression input stream test
  214.     //------------------------------------------------------------------------
  215.     {{
  216.         cout << "Testing decompression input stream...n";
  217.         INIT_BUFFERS;
  218.         // Compress the data
  219.         TCompression c;
  220.         result = c.CompressBuffer(src_buf, kDataLen, dst_buf, kBufLen,
  221.                                   &out_len);
  222.         PrintResult(eCompress, c.GetErrorCode(), kDataLen, kBufLen, out_len);
  223.         assert(result);
  224.         // Read decompressed data from stream
  225.         CNcbiIstrstream is_str(dst_buf, out_len);
  226.         size_t ids_zip_len;
  227.         {{
  228.             CCompressionIStream ids_zip(is_str, new TStreamDecompressor(),
  229.                                     CCompressionStream::fOwnReader);
  230.             ids_zip.read(cmp_buf, kDataLen);
  231.             ids_zip_len = ids_zip.gcount();
  232.             // For majority of decompressors we should have all unpacked data
  233.             // here, before the finalization.
  234.             assert(ids_zip.GetProcessedSize() == out_len);
  235.             assert(ids_zip.GetOutputSize() == kDataLen);
  236.             // Finalize decompression stream in the destructor
  237.         }}
  238.         // Get decompressed size
  239.         PrintResult(eDecompress, kUnknownErr, out_len, kBufLen, ids_zip_len);
  240.         // Compare original and uncompressed data
  241.         assert(ids_zip_len == kDataLen);
  242.         assert(memcmp(src_buf, cmp_buf, kDataLen) == 0);
  243.         OK;
  244.     }}
  245.     //------------------------------------------------------------------------
  246.     // Compression output stream test
  247.     //------------------------------------------------------------------------
  248.     {{
  249.         cout << "Testing compression output stream...n";
  250.         INIT_BUFFERS;
  251.         // Write data to compressing stream
  252.         CNcbiOstrstream os_str;
  253.         {{
  254.             CCompressionOStream os_zip(os_str, new TStreamCompressor(),
  255.                                        CCompressionStream::fOwnWriter);
  256.             os_zip.write(src_buf, kDataLen);
  257.             // Finalize compression stream in the destructor
  258.         }}
  259.         // Get compressed size
  260.         const char* str = os_str.str();
  261.         size_t os_str_len = os_str.pcount();
  262.         PrintResult(eCompress, kUnknownErr, kDataLen, kBufLen, os_str_len);
  263.         // Try to decompress data
  264.         TCompression c;
  265.         result = c.DecompressBuffer(str, os_str_len, cmp_buf, kBufLen,
  266.                                     &out_len);
  267.         PrintResult(eDecompress, c.GetErrorCode(), os_str_len, kBufLen,
  268.                     out_len);
  269.         assert(result);
  270.         // Compare original and decompressed data
  271.         assert(out_len == kDataLen);
  272.         assert(memcmp(src_buf, cmp_buf, out_len) == 0);
  273.         os_str.rdbuf()->freeze(0);
  274.         OK;
  275.     }}
  276.     //------------------------------------------------------------------------
  277.     // Decompression output stream test
  278.     //------------------------------------------------------------------------
  279.     {{
  280.         cout << "Testing decompression output stream...n";
  281.         INIT_BUFFERS;
  282.         // Compress the data
  283.         TCompression c;
  284.         result = c.CompressBuffer(src_buf, kDataLen, dst_buf, kBufLen,
  285.                                   &out_len);
  286.         PrintResult(eCompress, c.GetErrorCode(), kDataLen, kBufLen, out_len);
  287.         assert(result);
  288.         // Write compressed data to decompressing stream
  289.         CNcbiOstrstream os_str;
  290.         CCompressionOStream os_zip(os_str, new TStreamDecompressor(),
  291.                                    CCompressionStream::fOwnProcessor);
  292.         os_zip.write(dst_buf, out_len);
  293.         // Finalize a compression stream via direct call Finalize()
  294.         os_zip.Finalize();
  295.         // Get decompressed size
  296.         const char*  str = os_str.str();
  297.         size_t os_str_len = os_str.pcount();
  298.         PrintResult(eDecompress, kUnknownErr, out_len, kBufLen, os_str_len);
  299.         assert(os_zip.GetProcessedSize() == out_len);
  300.         assert(os_zip.GetOutputSize() == kDataLen);
  301.         // Compare original and uncompressed data
  302.         assert(os_str_len == kDataLen);
  303.         assert(memcmp(src_buf, str, os_str_len) == 0);
  304.         os_str.rdbuf()->freeze(0);
  305.         OK;
  306.     }}
  307.     //------------------------------------------------------------------------
  308.     // IO stream tests
  309.     //------------------------------------------------------------------------
  310.     {{
  311.         cout << "Testing IO stream...n";
  312.         {{
  313.             INIT_BUFFERS;
  314.             CNcbiStrstream stm(dst_buf, kBufLen);
  315.             CCompressionIOStream zip(stm, new TStreamDecompressor(),
  316.                                           new TStreamCompressor(),
  317.                                           CCompressionStream::fOwnProcessor);
  318.             zip.write(src_buf, kDataLen);
  319.             assert(zip.good()  &&  stm.good());
  320.             zip.Finalize(CCompressionStream::eWrite);
  321.             assert(!stm.eof()  &&  stm.good());
  322.             assert(!zip.eof()  &&  zip.good());
  323.             assert(zip.GetProcessedSize(CCompressionStream::eWrite)
  324.                    == kDataLen);
  325.             assert(zip.GetProcessedSize(CCompressionStream::eRead) == 0);
  326.             assert(zip.GetOutputSize(CCompressionStream::eWrite) > 0);
  327.             assert(zip.GetOutputSize(CCompressionStream::eRead) == 0);
  328.             // Read as much as possible
  329.             zip.read(cmp_buf, kDataLen);
  330.             out_len = zip.gcount();
  331.             assert(!stm.eof()  &&  stm.good());
  332.             assert(!zip.eof()  &&  zip.good());
  333.             assert(out_len <= kDataLen);
  334.             zip.Finalize(CCompressionStream::eRead);
  335.             // Read the residue of the data after finalization
  336.             if ( out_len < kDataLen ) {
  337.                 zip.clear();
  338.                 zip.read(cmp_buf + out_len, kDataLen - out_len);
  339.                 out_len += zip.gcount();
  340.                 assert(out_len == kDataLen);
  341.             }
  342.             assert(!zip.eof());
  343.             assert(zip.GetProcessedSize(CCompressionStream::eWrite)
  344.                    == kDataLen);
  345.             assert(zip.GetProcessedSize(CCompressionStream::eRead) > 0);
  346.             assert(zip.GetOutputSize(CCompressionStream::eWrite) > 0);
  347.             assert(zip.GetOutputSize(CCompressionStream::eRead) == kDataLen);
  348.             // Check on EOF
  349.             char c;
  350.             zip >> c;
  351.             assert(zip.eof());
  352.             // Compare buffers
  353.             assert(memcmp(src_buf, cmp_buf, kDataLen) == 0);
  354.         }}
  355.         {{
  356.             INIT_BUFFERS;
  357.             CNcbiStrstream stm(dst_buf, kBufLen);
  358.             CCompressionIOStream zip(stm, new TStreamDecompressor(),
  359.                                           new TStreamCompressor(),
  360.                                           CCompressionStream::fOwnProcessor);
  361.             int v;
  362.             for (int i = 0; i < 1000; i++) {
  363.                  v = i * 2;
  364.                  zip << v << endl;
  365.             }
  366.             zip.Finalize(CCompressionStream::eWrite);
  367.             zip.clear();
  368.             for (int i = 0; i < 1000; i++) {
  369.                  zip >> v;
  370.                  assert(!zip.eof());
  371.                  assert(v == i * 2);
  372.             }
  373.             zip.Finalize();
  374.             zip >> v;
  375.             assert(zip.eof());
  376.         }}
  377.         OK;
  378.     }}
  379.     //------------------------------------------------------------------------
  380.     // Advanced I/O stream test
  381.     //------------------------------------------------------------------------
  382.     {{
  383.         cout << "Advanced I/O stream test...n";
  384.         INIT_BUFFERS;
  385.         int v;
  386.         // Compress output
  387.         CNcbiOstrstream os_str;
  388.         {{
  389.             CCompressionOStream ocs_zip(os_str, new TStreamCompressor(),
  390.                                         CCompressionStream::fOwnWriter);
  391.             for (int i = 0; i < 1000; i++) {
  392.                 v = i * 2;
  393.                 ocs_zip << v << endl;
  394.             }
  395.         }}
  396.         const char* str = os_str.str();
  397.         size_t os_str_len = os_str.pcount();
  398.         PrintResult(eCompress, kUnknownErr, kUnknown, kUnknown,os_str_len);
  399.         // Decompress input
  400.         CNcbiIstrstream is_str(str, os_str_len);
  401.         CCompressionIStream ids_zip(is_str, new TStreamDecompressor(),
  402.                                     CCompressionStream::fOwnReader);
  403.         for (int i = 0; i < 1000; i++) {
  404.             ids_zip >> v;
  405.             assert(!ids_zip.eof());
  406.             assert( i*2 == v);
  407.         }
  408.         // Check EOF
  409.         ids_zip >> v;
  410.         PrintResult(eDecompress, kUnknownErr, os_str_len, kUnknown,
  411.                     kUnknown);
  412.         assert(ids_zip.eof());
  413.         os_str.rdbuf()->freeze(0);
  414.         OK;
  415.     }}
  416.     //------------------------------------------------------------------------
  417. }
  418. template<class TCompression,
  419.          class TCompressionFile,
  420.          class TStreamCompressor,
  421.          class TStreamDecompressor>
  422. void CTestCompressor<TCompression, TCompressionFile,
  423.                      TStreamCompressor, TStreamDecompressor>
  424.     ::PrintResult(EPrintType type, int last_errcode, 
  425.                   unsigned int src_len,
  426.                   unsigned int dst_len,
  427.                   unsigned int out_len)
  428. {
  429.     cout << (type == eCompress) ? "Compress   ": 
  430.                                   "Decompress ";
  431.     cout << "errcode = ";
  432.     cout << ((last_errcode == kUnknownErr) ? '?' : last_errcode) << ", ";
  433.     cout << ((src_len == kUnknown) ? '?' : src_len) << " -> ";
  434.     cout << ((out_len == kUnknown) ? '?' : out_len) << ", limit ";
  435.     cout << ((dst_len == kUnknown) ? '?' : dst_len) << endl;
  436. }
  437. //////////////////////////////////////////////////////////////////////////////
  438. //
  439. // Test application
  440. //
  441. class CTest : public CNcbiApplication
  442. {
  443. public:
  444.     void Init(void);
  445.     int  Run(void);
  446. };
  447. void CTest::Init(void)
  448. {
  449.     SetDiagPostLevel(eDiag_Warning);
  450. }
  451. int CTest::Run(void)
  452. {
  453.     char* src_buf = new char[kBufLen];
  454.     assert(src_buf);
  455.     // Preparing a data for compression
  456.     unsigned int seed = time(0);
  457.     cout << "Random seed = " << seed << endl << endl;
  458.     srand(seed);
  459.     for (size_t i=0; i<kDataLen; i++) {
  460.         // Use a set from 25 chars [A-Z]
  461.         // src_buf[i] = (char)(65+(double)rand()/RAND_MAX*(90-65));
  462.         // Use a set from 10 chars [''-'9']
  463.         src_buf[i] = (char)((double)rand()/RAND_MAX*10);
  464.     }
  465.     // Test compressors
  466.     cout << "-------------- BZip2 ---------------nn";
  467.     CTestCompressor<CBZip2Compression, CBZip2CompressionFile,
  468.                     CBZip2StreamCompressor, CBZip2StreamDecompressor>
  469.         ::Run(src_buf);
  470.     cout << "--------------- Zlib ---------------nn";
  471.     
  472.     CTestCompressor<CZipCompression, CZipCompressionFile,
  473.                     CZipStreamCompressor, CZipStreamDecompressor>
  474.         ::Run(src_buf);
  475.     cout << "nTEST execution completed successfully!nn";
  476.  
  477.     return 0;
  478. }
  479. //////////////////////////////////////////////////////////////////////////////
  480. //
  481. // MAIN
  482. //
  483. int main(int argc, const char* argv[])
  484. {
  485.     // Execute main application function
  486.     return CTest().AppMain(argc, argv, 0, eDS_Default, 0);
  487. }
  488. /*
  489.  * ===========================================================================
  490.  * $Log: test_compress.cpp,v $
  491.  * Revision 1000.2  2004/06/01 19:42:40  gouriano
  492.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
  493.  *
  494.  * Revision 1.9  2004/05/17 21:09:26  gorelenk
  495.  * Added include of PCH ncbi_pch.hpp
  496.  *
  497.  * Revision 1.8  2004/05/13 13:56:05  ivanov
  498.  * Cosmetic changes
  499.  *
  500.  * Revision 1.7  2004/05/10 12:07:26  ivanov
  501.  * Added tests for GetProcessedSize() and GetOutputSize()
  502.  *
  503.  * Revision 1.6  2004/04/09 11:48:26  ivanov
  504.  * Added ownership parameter to CCompressionStream constructors.
  505.  *
  506.  * Revision 1.5  2003/07/15 15:54:43  ivanov
  507.  * GetLastError() -> GetErrorCode() renaming
  508.  *
  509.  * Revision 1.4  2003/06/17 15:53:31  ivanov
  510.  * Changed tests accordingly the last Compression API changes.
  511.  * Some tests rearrangemets.
  512.  *
  513.  * Revision 1.3  2003/06/04 21:12:17  ivanov
  514.  * Added a random seed print out. Minor cosmetic changes.
  515.  *
  516.  * Revision 1.2  2003/06/03 20:12:26  ivanov
  517.  * Added small changes after Compression API redesign.
  518.  * Added tests for CCompressionFile class.
  519.  *
  520.  * Revision 1.1  2003/04/08 15:02:47  ivanov
  521.  * Initial revision
  522.  *
  523.  * ===========================================================================
  524.  */