Chromium Code Reviews| 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..31550c6b258f94791c4f82b31725c5344b21946e 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\f\v\r\n"); |
|
mmenke
2017/01/03 20:47:32
Are spaces and tabs not allowed in string identifi
dschuyler
2017/01/03 21:51:40
Ah, I wondered if omitting them would beg the ques
|
| + 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; |
| } |