| Index: content/browser/webui/i18n_source_stream.cc
|
| diff --git a/content/browser/webui/i18n_source_stream.cc b/content/browser/webui/i18n_source_stream.cc
|
| index 1ff237e26b82946452dbea00cc74eaadafbd42ab..c2120a8ed9a71ce365d6396325478acdbcb6514a 100644
|
| --- a/content/browser/webui/i18n_source_stream.cc
|
| +++ b/content/browser/webui/i18n_source_stream.cc
|
| @@ -29,7 +29,6 @@ I18nSourceStream::I18nSourceStream(std::unique_ptr<SourceStream> upstream,
|
| SourceStream::SourceType type,
|
| const ui::TemplateReplacements* replacements)
|
| : FilterSourceStream(type, std::move(upstream)),
|
| - drain_offset_(0),
|
| replacements_(replacements) {}
|
|
|
| std::string I18nSourceStream::GetTypeAsString() const {
|
| @@ -42,24 +41,30 @@ int I18nSourceStream::FilterData(net::IOBuffer* output_buffer,
|
| int input_buffer_size,
|
| int* consumed_bytes,
|
| bool upstream_end_reached) {
|
| - DCHECK(output_.empty() || (upstream_end_reached && input_buffer_size == 0));
|
| - *consumed_bytes = input_buffer_size;
|
| - // TODO(dschuyler): Perform replacements without accumulation.
|
| - // Accumulate.
|
| + // |input_| is often empty (or it may have something from the prior call).
|
| input_.append(input_buffer->data(), input_buffer_size);
|
| - if (upstream_end_reached && !drain_offset_ && output_.empty()) {
|
| - // Process.
|
| - output_ = ui::ReplaceTemplateExpressions(input_, *replacements_);
|
| - }
|
| + *consumed_bytes = input_buffer_size;
|
|
|
| - if (drain_offset_ == output_.size())
|
| - return 0;
|
| + // The replacement tag starts with '$' and ends with '}'. The white-space
|
| + // characters are an optimization that looks for characters that are invalid
|
| + // within $i18n{} tags.
|
| + size_t pos = input_.find_last_of("$} \t\r\n");
|
| + std::string to_process;
|
| + if (!upstream_end_reached && pos != std::string::npos && input_[pos] == '$') {
|
| + // If there is a trailing '$' then split the |input_| at that point. Process
|
| + // the first part; save the second part for the next call to FilterData().
|
| + to_process.assign(input_, 0, pos);
|
| + input_.erase(0, pos);
|
| + } else {
|
| + // There is no risk of a split key, process the whole input.
|
| + to_process.swap(input_);
|
| + }
|
|
|
| - // Drain.
|
| - int bytes_out = std::min(output_.size() - drain_offset_,
|
| - static_cast<size_t>(output_buffer_size));
|
| - output_.copy(output_buffer->data(), bytes_out, drain_offset_);
|
| - drain_offset_ += bytes_out;
|
| + output_.append(ui::ReplaceTemplateExpressions(to_process, *replacements_));
|
| + int bytes_out =
|
| + std::min(output_.size(), static_cast<size_t>(output_buffer_size));
|
| + output_.copy(output_buffer->data(), bytes_out);
|
| + output_.erase(0, bytes_out);
|
| return bytes_out;
|
| }
|
|
|
|
|