modified: makefile
[GalaxyCodeBases.git] / tools / bwt / dcs-bwt / src / stream_compressor.cc
bloba779075d65fd044c4f9eb280a3d2d7ba81fd7cd3
1 // Copyright 2007 Google Inc.
2 //
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License
5 // as published by the Free Software Foundation; either version 2
6 // of the License, or (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 #include "bbb_compress.h"
18 #include "rl_compress.h"
19 #include "stream_compressor.h"
21 #include <string>
23 namespace dcsbwt {
25 // Trivial implementations of StreamCompressor and StreamDecompressor
26 // They serve as an example, and can be useful as a replacement of a real
27 // (de)compressor in testing, debugging and development.
28 class TrivialCompressor : public StreamCompressor {
29 public:
30 class Options : public StreamCompressor::OptionsBase {
31 public:
32 bool Set(const std::string& options) { return 0 == options.length(); }
33 std::string Get() const { return std::string(); }
34 int64 SizeInBytes() const { return 1; }
35 StreamCompressor* GetCompressor() { return new TrivialCompressor; }
38 TrivialCompressor() {}
39 virtual ~TrivialCompressor() {}
41 virtual void WriteBegin() {}
42 virtual void WriteEndPrivate() {}
43 virtual void Write(const char* bytes, size_t n) { Emit(bytes, n); }
44 private:
45 TrivialCompressor(const TrivialCompressor&);
46 TrivialCompressor& operator=(const TrivialCompressor&);
49 class TrivialDecompressor : public StreamDecompressor {
50 public:
51 static StreamDecompressor* Create(const std::string&) {
52 return new TrivialDecompressor;
54 TrivialDecompressor() {}
55 virtual ~TrivialDecompressor() {}
56 virtual void ReadBegin() {}
57 virtual void ReadEnd() {}
58 virtual void Read(char* bytes, size_t n) { GetCompressed(bytes, n); }
59 virtual int64 SizeInBytes() const { return 1; }
60 private:
61 TrivialDecompressor(const TrivialDecompressor&);
62 TrivialDecompressor& operator=(const TrivialDecompressor&);
66 /////////////////////// StreamCompressor ///////////////////////
68 const int StreamCompressor::kBufferSize = 1 << 16;
70 // Select the compression algorithm based on the first character
71 // of the options_string and let the algorithm specific options
72 // processor handle the rest of options_string.
73 bool StreamCompressor::Options::Set(const std::string& options_string) {
74 if (options_string.length() < 1) return false;
75 char compression_algorithm = options_string[0];
76 OptionsBase* options;
77 switch (compression_algorithm) {
78 case 't': // TrivialCompressor (see above)
79 options = new TrivialCompressor::Options;
80 break;
81 case 'b': // BbbCompressor (see bbb_compressor.h)
82 options = new BbbCompressor::Options;
83 break;
84 case 'c':
85 options = new ByteCompressor::Options;
86 break;
87 case 'r':
88 options = new RunLengthCompressor::Options;
89 break;
90 default:
91 return false;
93 std::string algorithm_specific_options_string(options_string, 1);
94 bool success = options->Set(algorithm_specific_options_string);
95 if (success) {
96 compression_algorithm_ = compression_algorithm;
97 if (algorithm_specific_options_) delete algorithm_specific_options_;
98 algorithm_specific_options_ = options;
99 } else {
100 delete options;
102 return success;
105 StreamCompressor* StreamCompressor::Options::GetCompressor() {
106 return algorithm_specific_options_->GetCompressor();
109 StreamCompressor* StreamCompressor::Connect(OutStream* output,
110 Options options) {
111 StreamCompressor* compressor = options.GetCompressor();
112 if (compressor) {
113 // '\n' is used as the terminator of the compression format string.
114 std::string compression_format = options.Get() + '\n';
115 output->Write(compression_format.data(), compression_format.length());
116 compressor->output_.Connect(output);
117 compressor->ConnectPrivate(&compressor->output_);
119 return compressor;
122 OutStream* StreamCompressor::Disconnect() {
123 DisconnectPrivate();
124 OutStream* oldoutput = output_.Disconnect();
125 delete this;
126 return oldoutput;
129 /////////////////////// StreamDecompressor ///////////////////////
131 StreamDecompressor* StreamDecompressor::Connect(InStreamBuffer* input) {
132 // The compression format is identified by the input prefix ending
133 // with the first '\n'.
134 std::string format;
135 char ch = input->ReadByte();
136 while (ch != '\n') {
137 if (format.length() > 1000) return NULL; // guard against infinite loop
138 format += ch;
139 ch = input->ReadByte();
141 if (0 == format.length()) return NULL;
142 char compression_type = format[0];
143 std::string options(format, 1);
144 StreamDecompressor* decompressor;
145 switch (compression_type) {
146 case 't':
147 decompressor = TrivialDecompressor::Create(options);
148 break;
149 case 'b':
150 decompressor = BbbDecompressor::Create(options);
151 break;
152 case 'c':
153 decompressor = ByteDecompressor::Create(options);
154 break;
155 case 'r':
156 decompressor = RunLengthDecompressor::Create(options);
157 break;
158 default:
159 decompressor = NULL;
161 if (decompressor) {
162 decompressor->format_ = format;
163 decompressor->input_.Connect(input);
164 decompressor->ConnectPrivate(decompressor->input_.GetServant());
166 return decompressor;
169 InStreamBuffer* StreamDecompressor::Disconnect() {
170 DisconnectPrivate();
171 InStreamBuffer* oldinput = input_.Disconnect();
172 delete this;
173 return oldinput;
176 } // namespace dcsbwt