| Index: net/base/filter.cc
|
| diff --git a/net/base/filter.cc b/net/base/filter.cc
|
| index 5e47ecbe5b4a9eff01936e2769c3400b00dc81df..309eab303aa3472240af30a991d4df8e1b664b19 100644
|
| --- a/net/base/filter.cc
|
| +++ b/net/base/filter.cc
|
| @@ -39,6 +39,8 @@ const char kTextHtml[] = "text/html";
|
| FilterContext::~FilterContext() {
|
| }
|
|
|
| +Filter::~Filter() {}
|
| +
|
| Filter* Filter::Factory(const std::vector<FilterType>& filter_types,
|
| const FilterContext& filter_context) {
|
| DCHECK_GT(filter_context.GetInputStreamBufferSize(), 0);
|
| @@ -56,6 +58,59 @@ Filter* Filter::Factory(const std::vector<FilterType>& filter_types,
|
| return filter_list;
|
| }
|
|
|
| +Filter::FilterStatus Filter::ReadData(char* dest_buffer, int* dest_len) {
|
| + const int dest_buffer_capacity = *dest_len;
|
| + if (last_status_ == FILTER_ERROR)
|
| + return last_status_;
|
| + if (!next_filter_.get())
|
| + return last_status_ = ReadFilteredData(dest_buffer, dest_len);
|
| + if (last_status_ == FILTER_NEED_MORE_DATA && !stream_data_len())
|
| + return next_filter_->ReadData(dest_buffer, dest_len);
|
| +
|
| + do {
|
| + if (next_filter_->last_status() == FILTER_NEED_MORE_DATA) {
|
| + PushDataIntoNextFilter();
|
| + if (FILTER_ERROR == last_status_)
|
| + return FILTER_ERROR;
|
| + }
|
| + *dest_len = dest_buffer_capacity; // Reset the input/output parameter.
|
| + next_filter_->ReadData(dest_buffer, dest_len);
|
| + if (FILTER_NEED_MORE_DATA == last_status_)
|
| + return next_filter_->last_status();
|
| +
|
| + // In the case where this filter has data internally, and is indicating such
|
| + // with a last_status_ of FILTER_OK, but at the same time the next filter in
|
| + // the chain indicated it FILTER_NEED_MORE_DATA, we have to be cautious
|
| + // about confusing the caller. The API confusion can appear if we return
|
| + // FILTER_OK (suggesting we have more data in aggregate), but yet we don't
|
| + // populate our output buffer. When that is the case, we need to
|
| + // alternately call our filter element, and the next_filter element until we
|
| + // get out of this state (by pumping data into the next filter until it
|
| + // outputs data, or it runs out of data and reports that it NEED_MORE_DATA.)
|
| + } while (FILTER_OK == last_status_ &&
|
| + FILTER_NEED_MORE_DATA == next_filter_->last_status() &&
|
| + 0 == *dest_len);
|
| +
|
| + if (next_filter_->last_status() == FILTER_ERROR)
|
| + return FILTER_ERROR;
|
| + return FILTER_OK;
|
| +}
|
| +
|
| +bool Filter::FlushStreamBuffer(int stream_data_len) {
|
| + DCHECK(stream_data_len <= stream_buffer_size_);
|
| + if (stream_data_len <= 0 || stream_data_len > stream_buffer_size_)
|
| + return false;
|
| +
|
| + DCHECK(stream_buffer());
|
| + // Bail out if there is more data in the stream buffer to be filtered.
|
| + if (!stream_buffer() || stream_data_len_)
|
| + return false;
|
| +
|
| + next_stream_data_ = stream_buffer()->data();
|
| + stream_data_len_ = stream_data_len;
|
| + return true;
|
| +}
|
| +
|
| // static
|
| Filter::FilterType Filter::ConvertEncodingToType(
|
| const std::string& filter_type) {
|
| @@ -232,6 +287,42 @@ void Filter::FixupEncodingTypes(
|
| return;
|
| }
|
|
|
| +Filter::Filter(const FilterContext& filter_context)
|
| + : stream_buffer_(NULL),
|
| + stream_buffer_size_(0),
|
| + next_stream_data_(NULL),
|
| + stream_data_len_(0),
|
| + next_filter_(NULL),
|
| + last_status_(FILTER_NEED_MORE_DATA),
|
| + filter_context_(filter_context) {
|
| +}
|
| +
|
| +Filter::FilterStatus Filter::ReadFilteredData(char* dest_buffer,
|
| + int* dest_len) {
|
| + return Filter::FILTER_ERROR;
|
| +}
|
| +
|
| +Filter::FilterStatus Filter::CopyOut(char* dest_buffer, int* dest_len) {
|
| + int out_len;
|
| + int input_len = *dest_len;
|
| + *dest_len = 0;
|
| +
|
| + if (0 == stream_data_len_)
|
| + return Filter::FILTER_NEED_MORE_DATA;
|
| +
|
| + out_len = std::min(input_len, stream_data_len_);
|
| + memcpy(dest_buffer, next_stream_data_, out_len);
|
| + *dest_len += out_len;
|
| + stream_data_len_ -= out_len;
|
| + if (0 == stream_data_len_) {
|
| + next_stream_data_ = NULL;
|
| + return Filter::FILTER_NEED_MORE_DATA;
|
| + } else {
|
| + next_stream_data_ += out_len;
|
| + return Filter::FILTER_OK;
|
| + }
|
| +}
|
| +
|
| // static
|
| Filter* Filter::PrependNewFilter(FilterType type_id,
|
| const FilterContext& filter_context,
|
| @@ -274,18 +365,6 @@ Filter* Filter::PrependNewFilter(FilterType type_id,
|
| return first_filter;
|
| }
|
|
|
| -Filter::Filter(const FilterContext& filter_context)
|
| - : stream_buffer_(NULL),
|
| - stream_buffer_size_(0),
|
| - next_stream_data_(NULL),
|
| - stream_data_len_(0),
|
| - next_filter_(NULL),
|
| - last_status_(FILTER_NEED_MORE_DATA),
|
| - filter_context_(filter_context) {
|
| -}
|
| -
|
| -Filter::~Filter() {}
|
| -
|
| bool Filter::InitBuffer() {
|
| int buffer_size = filter_context_.GetInputStreamBufferSize();
|
| DCHECK_GT(buffer_size, 0);
|
| @@ -302,72 +381,6 @@ bool Filter::InitBuffer() {
|
| return false;
|
| }
|
|
|
| -
|
| -Filter::FilterStatus Filter::CopyOut(char* dest_buffer, int* dest_len) {
|
| - int out_len;
|
| - int input_len = *dest_len;
|
| - *dest_len = 0;
|
| -
|
| - if (0 == stream_data_len_)
|
| - return Filter::FILTER_NEED_MORE_DATA;
|
| -
|
| - out_len = std::min(input_len, stream_data_len_);
|
| - memcpy(dest_buffer, next_stream_data_, out_len);
|
| - *dest_len += out_len;
|
| - stream_data_len_ -= out_len;
|
| - if (0 == stream_data_len_) {
|
| - next_stream_data_ = NULL;
|
| - return Filter::FILTER_NEED_MORE_DATA;
|
| - } else {
|
| - next_stream_data_ += out_len;
|
| - return Filter::FILTER_OK;
|
| - }
|
| -}
|
| -
|
| -
|
| -Filter::FilterStatus Filter::ReadFilteredData(char* dest_buffer,
|
| - int* dest_len) {
|
| - return Filter::FILTER_ERROR;
|
| -}
|
| -
|
| -Filter::FilterStatus Filter::ReadData(char* dest_buffer, int* dest_len) {
|
| - const int dest_buffer_capacity = *dest_len;
|
| - if (last_status_ == FILTER_ERROR)
|
| - return last_status_;
|
| - if (!next_filter_.get())
|
| - return last_status_ = ReadFilteredData(dest_buffer, dest_len);
|
| - if (last_status_ == FILTER_NEED_MORE_DATA && !stream_data_len())
|
| - return next_filter_->ReadData(dest_buffer, dest_len);
|
| -
|
| - do {
|
| - if (next_filter_->last_status() == FILTER_NEED_MORE_DATA) {
|
| - PushDataIntoNextFilter();
|
| - if (FILTER_ERROR == last_status_)
|
| - return FILTER_ERROR;
|
| - }
|
| - *dest_len = dest_buffer_capacity; // Reset the input/output parameter.
|
| - next_filter_->ReadData(dest_buffer, dest_len);
|
| - if (FILTER_NEED_MORE_DATA == last_status_)
|
| - return next_filter_->last_status();
|
| -
|
| - // In the case where this filter has data internally, and is indicating such
|
| - // with a last_status_ of FILTER_OK, but at the same time the next filter in
|
| - // the chain indicated it FILTER_NEED_MORE_DATA, we have to be cautious
|
| - // about confusing the caller. The API confusion can appear if we return
|
| - // FILTER_OK (suggesting we have more data in aggregate), but yet we don't
|
| - // populate our output buffer. When that is the case, we need to
|
| - // alternately call our filter element, and the next_filter element until we
|
| - // get out of this state (by pumping data into the next filter until it
|
| - // outputs data, or it runs out of data and reports that it NEED_MORE_DATA.)
|
| - } while (FILTER_OK == last_status_ &&
|
| - FILTER_NEED_MORE_DATA == next_filter_->last_status() &&
|
| - 0 == *dest_len);
|
| -
|
| - if (next_filter_->last_status() == FILTER_ERROR)
|
| - return FILTER_ERROR;
|
| - return FILTER_OK;
|
| -}
|
| -
|
| void Filter::PushDataIntoNextFilter() {
|
| net::IOBuffer* next_buffer = next_filter_->stream_buffer();
|
| int next_size = next_filter_->stream_buffer_size();
|
| @@ -375,19 +388,3 @@ void Filter::PushDataIntoNextFilter() {
|
| if (FILTER_ERROR != last_status_)
|
| next_filter_->FlushStreamBuffer(next_size);
|
| }
|
| -
|
| -
|
| -bool Filter::FlushStreamBuffer(int stream_data_len) {
|
| - DCHECK(stream_data_len <= stream_buffer_size_);
|
| - if (stream_data_len <= 0 || stream_data_len > stream_buffer_size_)
|
| - return false;
|
| -
|
| - DCHECK(stream_buffer());
|
| - // Bail out if there is more data in the stream buffer to be filtered.
|
| - if (!stream_buffer() || stream_data_len_)
|
| - return false;
|
| -
|
| - next_stream_data_ = stream_buffer()->data();
|
| - stream_data_len_ = stream_data_len;
|
| - return true;
|
| -}
|
|
|