Atlas  0.7.0
Networking protocol for the Worldforge system.
Bzip2.cpp
1 // This file may be redistributed and modified only under the terms of
2 // the GNU Lesser General Public License (See COPYING for details).
3 // Copyright (C) 2000 Stefanus Du Toit, Dmitry Derevyanko
4 
5 // $Id$
6 
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10 
11 #if defined(HAVE_BZLIB_H) && defined(HAVE_LIBBZ2)
12 
13 #include <Atlas/Filters/Bzip2.h>
14 
15 #ifndef ASSERT
16 #include <cassert>
17 #define ASSERT(exp) assert(exp)
18 #endif
19 
21 
22 const int BS100K = 6;
23 const int WORKFACTOR = 30;
24 
25 void Bzip2::begin()
26 {
27  incoming.next_in = nullptr;
28  incoming.avail_in = 0;
29  incoming.bzalloc = nullptr;
30  incoming.bzfree = nullptr;
31  incoming.opaque = nullptr;
32 
33  outgoing.bzalloc = nullptr;
34  outgoing.bzfree = nullptr;
35  outgoing.opaque = nullptr;
36 
37  BZ2_bzCompressInit(&outgoing, BS100K, 0, WORKFACTOR);
38  BZ2_bzDecompressInit(&incoming, 0, 0);
39 }
40 
41 void Bzip2::end()
42 {
43  BZ2_bzCompressEnd(&outgoing);
44  BZ2_bzDecompressEnd(&incoming);
45 }
46 
47 std::string Bzip2::encode(const std::string& data)
48 {
49  std::string out_string;
50  int status;
51 
52  buf[0] = 0;
53 
54  outgoing.next_in = const_cast<char*>(data.data());
55  outgoing.avail_in = data.size();
56 
57  do
58  {
59  outgoing.next_out = buf;
60  outgoing.avail_out = sizeof(buf);
61 
62  status = BZ2_bzCompress(&outgoing, BZ_FLUSH);
63 
64  ASSERT(status != BZ_SEQUENCE_ERROR);
65 
66  if (status != BZ_SEQUENCE_ERROR) {
67  out_string.append((char*)buf, sizeof(buf) - outgoing.avail_out);
68  }
69  // FIXME do something else in case of error?
70  } while (outgoing.avail_out == 0);
71 
72  return out_string;
73 }
74 
75 std::string Bzip2::decode(const std::string& data)
76 {
77  std::string out_string;
78 
79  buf[0] = 0;
80 
81  incoming.next_in = const_cast<char*>(data.data());
82  incoming.avail_in = data.size();
83 
84  do
85  {
86  incoming.next_out = buf;
87  incoming.avail_out = sizeof(buf);
88 
89  int status = BZ2_bzDecompress(&incoming);
90 
91  ASSERT(status == BZ_OK);
92 
93  if (status != BZ_SEQUENCE_ERROR) {
94  out_string.append((char*)buf, sizeof(buf) - incoming.avail_out);
95  }
96 
97  } while(incoming.avail_out == 0);
98 
99  return out_string;
100 }
101 
102 #endif // HAVE_BZLIB_H && HAVE_LIBBZ2