OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/base/bzip2_filter.h" | |
6 | |
7 BZip2Filter::BZip2Filter(const FilterContext& filter_context) | |
8 : Filter(filter_context), | |
9 decoding_status_(DECODING_UNINITIALIZED), | |
10 bzip2_data_stream_(NULL) { | |
11 } | |
12 | |
13 BZip2Filter::~BZip2Filter() { | |
14 if (bzip2_data_stream_.get() && | |
15 decoding_status_ != DECODING_UNINITIALIZED) { | |
16 BZ2_bzDecompressEnd(bzip2_data_stream_.get()); | |
17 } | |
18 } | |
19 | |
20 bool BZip2Filter::InitDecoding(bool use_small_memory) { | |
21 if (decoding_status_ != DECODING_UNINITIALIZED) | |
22 return false; | |
23 | |
24 // Initialize zlib control block | |
25 bzip2_data_stream_.reset(new bz_stream); | |
26 if (!bzip2_data_stream_.get()) | |
27 return false; | |
28 memset(bzip2_data_stream_.get(), 0, sizeof(bz_stream)); | |
29 | |
30 int result = BZ2_bzDecompressInit(bzip2_data_stream_.get(), | |
31 0, | |
32 use_small_memory ? 1 : 0); | |
33 | |
34 if (result != BZ_OK) | |
35 return false; | |
36 | |
37 decoding_status_ = DECODING_IN_PROGRESS; | |
38 return true; | |
39 } | |
40 | |
41 Filter::FilterStatus BZip2Filter::ReadFilteredData(char* dest_buffer, | |
42 int* dest_len) { | |
43 Filter::FilterStatus status = Filter::FILTER_ERROR; | |
44 | |
45 // check output | |
46 if (!dest_buffer || !dest_len || *dest_len <= 0) | |
47 return status; | |
48 | |
49 if (DECODING_DONE == decoding_status_) { | |
50 // this logic just follow gzip_filter, which be used to deal wth some | |
51 // server might send extra data after finish sending compress data | |
52 return CopyOut(dest_buffer, dest_len); | |
53 } | |
54 | |
55 if (decoding_status_ != DECODING_IN_PROGRESS) | |
56 return status; | |
57 | |
58 // Make sure we have valid input data | |
59 if (!next_stream_data_ || stream_data_len_ <= 0) { | |
60 *dest_len = 0; | |
61 return Filter::FILTER_NEED_MORE_DATA; | |
62 } | |
63 | |
64 // Fill in bzip2 control block | |
65 int ret, output_len = *dest_len; | |
66 *dest_len = 0; | |
67 | |
68 bzip2_data_stream_->next_in = next_stream_data_; | |
69 bzip2_data_stream_->avail_in = stream_data_len_; | |
70 bzip2_data_stream_->next_out = dest_buffer; | |
71 bzip2_data_stream_->avail_out = output_len; | |
72 | |
73 ret = BZ2_bzDecompress(bzip2_data_stream_.get()); | |
74 | |
75 // get real output length, rest data and rest data length | |
76 *dest_len = output_len - bzip2_data_stream_->avail_out; | |
77 | |
78 if (0 == bzip2_data_stream_->avail_in) { | |
79 next_stream_data_ = NULL; | |
80 stream_data_len_ = 0; | |
81 } else { | |
82 next_stream_data_ = bzip2_data_stream_->next_in; | |
83 stream_data_len_ = bzip2_data_stream_->avail_in; | |
84 } | |
85 | |
86 if (BZ_OK == ret) { | |
87 if (stream_data_len_) | |
88 status = Filter::FILTER_OK; | |
89 else | |
90 status = Filter::FILTER_NEED_MORE_DATA; | |
91 } else if (BZ_STREAM_END == ret) { | |
92 status = Filter::FILTER_DONE; | |
93 decoding_status_ = DECODING_DONE; | |
94 } else { | |
95 decoding_status_ = DECODING_ERROR; | |
96 } | |
97 | |
98 return status; | |
99 } | |
OLD | NEW |