1 /*
2  * Copyright (C) 2001-2012 Jacek Sieka, arnetheduck on gmail point com
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #include "stdinc.h"
20 
21 #include "BZUtils.h"
22 #include "Exception.h"
23 #include "format.h"
24 
25 namespace dcpp {
26 
27 using std::max;
28 
BZFilter()29 BZFilter::BZFilter() {
30     memset(&zs, 0, sizeof(zs));
31 
32     if(BZ2_bzCompressInit(&zs, 9, 0, 30) != BZ_OK) {
33         throw Exception(_("Error during compression"));
34     }
35 }
36 
~BZFilter()37 BZFilter::~BZFilter() {
38     dcdebug("BZFilter end, %u/%u = %.04f\n", zs.total_out_lo32, zs.total_in_lo32, (float)zs.total_out_lo32 / max((float)zs.total_in_lo32, (float)1));
39     BZ2_bzCompressEnd(&zs);
40 }
41 
operator ()(const void * in,size_t & insize,void * out,size_t & outsize)42 bool BZFilter::operator()(const void* in, size_t& insize, void* out, size_t& outsize) {
43     if(outsize == 0)
44         return 0;
45 
46     zs.avail_in = insize;
47     zs.next_in = (char*)in;
48     zs.avail_out = outsize;
49     zs.next_out = (char*)out;
50 
51     if(insize == 0) {
52         int err = ::BZ2_bzCompress(&zs, BZ_FINISH);
53         if(err != BZ_FINISH_OK && err != BZ_STREAM_END)
54             throw Exception(_("Error during compression"));
55 
56         outsize = outsize - zs.avail_out;
57         insize = insize - zs.avail_in;
58         return err == BZ_FINISH_OK;
59     } else {
60         int err = ::BZ2_bzCompress(&zs, BZ_RUN);
61         if(err != BZ_RUN_OK)
62             throw Exception(_("Error during compression"));
63 
64         outsize = outsize - zs.avail_out;
65         insize = insize - zs.avail_in;
66         return true;
67     }
68 }
69 
UnBZFilter()70 UnBZFilter::UnBZFilter() {
71     memset(&zs, 0, sizeof(zs));
72 
73     if(BZ2_bzDecompressInit(&zs, 0, 0) != BZ_OK)
74         throw Exception(_("Error during decompression"));
75 
76 }
77 
~UnBZFilter()78 UnBZFilter::~UnBZFilter() {
79     dcdebug("UnBZFilter end, %u/%u = %.04f\n", zs.total_out_lo32, zs.total_in_lo32, (float)zs.total_out_lo32 / max((float)zs.total_in_lo32, (float)1));
80     BZ2_bzDecompressEnd(&zs);
81 }
82 
operator ()(const void * in,size_t & insize,void * out,size_t & outsize)83 bool UnBZFilter::operator()(const void* in, size_t& insize, void* out, size_t& outsize) {
84     if(outsize == 0)
85         return 0;
86 
87     zs.avail_in = insize;
88     zs.next_in = (char*)in;
89     zs.avail_out = outsize;
90     zs.next_out = (char*)out;
91 
92     int err = ::BZ2_bzDecompress(&zs);
93 
94     // No more input data, and inflate didn't think it has reached the end...
95     if(insize == 0 && zs.avail_out != 0 && err != BZ_STREAM_END)
96         throw Exception(_("Error during decompression"));
97 
98     if(err != BZ_OK && err != BZ_STREAM_END)
99         throw Exception(_("Error during decompression"));
100 
101     outsize = outsize - zs.avail_out;
102     insize = insize - zs.avail_in;
103     return err == BZ_OK;
104 }
105 
106 } // namespace dcpp
107