diff options
Diffstat (limited to 'src/http_protocol.cc')
| -rw-r--r-- | src/http_protocol.cc | 45 |
1 files changed, 21 insertions, 24 deletions
diff --git a/src/http_protocol.cc b/src/http_protocol.cc index ad81050..f0e3cb3 100644 --- a/src/http_protocol.cc +++ b/src/http_protocol.cc @@ -326,7 +326,7 @@ private: class TextOutput : public OutputFilter { public: TextOutput(AttributedText* text) - : text_(text) { + : text_(text), checked_(0) { } void write(void const* data, size_t size, bool last) override { @@ -334,49 +334,46 @@ public: hex_->write(data, size, last); return; } - auto d = reinterpret_cast<char const*>(data); - if (!buf_.empty()) { - buf_.append(d, size); - for (size_t i = 0; i < 4; ++i) { - if (i >= buf_.size()) break; - if (valid_utf8(buf_.data(), buf_.size() - i)) { - if (last && i > 0) break; - text_->append(buf_.data(), buf_.size() - i); - buf_.erase(0, buf_.size() - i); - return; - } - } - } else { - for (size_t i = 0; i < 4; ++i) { - if (i >= size) break; - if (valid_utf8(d, size - i)) { - if (last && i > 0) break; - text_->append(d, size - i); - if (i > 0) buf_.append(d + size - i, i); - return; + + if (size == 0 && (!last || buf_.empty())) return; + + buf_.append(reinterpret_cast<char const*>(data), size); + for (size_t i = 0; i < 4; ++i) { + if (checked_ + i >= buf_.size()) break; + if (valid_utf8(buf_.data() + checked_, buf_.size() - checked_ - i)) { + if (last) { + if (i > 0) break; + text_->append(buf_); + buf_.clear(); + checked_ = 0; + } else { + checked_ = buf_.size() - i; } + return; } } - buf_.assign(text_->text()); - buf_.append(d, size); - text_->clear(); hex_.reset(new HexOutput(text_)); hex_->write(buf_.data(), buf_.size(), last); buf_.clear(); } void error() override { + text_->append(buf_.data(), checked_); + buf_.clear(); text_->append("\nDecoding failed, invalid data\n"); } void incomplete() override { + text_->append(buf_.data(), checked_); + buf_.clear(); text_->append("\nNeed more data...\n"); } private: AttributedText* const text_; std::string buf_; + size_t checked_; std::unique_ptr<HexOutput> hex_; }; |
