aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/google/protobuf/util/json_util.cc29
-rw-r--r--src/google/protobuf/util/json_util.h5
2 files changed, 20 insertions, 14 deletions
diff --git a/src/google/protobuf/util/json_util.cc b/src/google/protobuf/util/json_util.cc
index d7ac2dba..5974cc4a 100644
--- a/src/google/protobuf/util/json_util.cc
+++ b/src/google/protobuf/util/json_util.cc
@@ -49,22 +49,25 @@ namespace protobuf {
namespace util {
namespace internal {
+ZeroCopyStreamByteSink::~ZeroCopyStreamByteSink() {
+ stream_->BackUp(buffer_size_);
+}
+
void ZeroCopyStreamByteSink::Append(const char* bytes, size_t len) {
- while (len > 0) {
- void* buffer;
- int length;
- if (!stream_->Next(&buffer, &length)) {
- // There isn't a way for ByteSink to report errors.
+ while (true) {
+ if (len <= buffer_size_) {
+ memcpy(buffer_, bytes, len);
+ buffer_ = static_cast<char*>(buffer_) + len;
+ buffer_size_ -= len;
return;
}
- if (len < length) {
- memcpy(buffer, bytes, len);
- stream_->BackUp(length - len);
- break;
- } else {
- memcpy(buffer, bytes, length);
- bytes += length;
- len -= length;
+ memcpy(buffer_, bytes, buffer_size_);
+ bytes += buffer_size_;
+ len -= buffer_size_;
+ if (!stream_->Next(&buffer_, &buffer_size_)) {
+ // There isn't a way for ByteSink to report errors.
+ buffer_size_ = 0;
+ return;
}
}
}
diff --git a/src/google/protobuf/util/json_util.h b/src/google/protobuf/util/json_util.h
index 6d3cee52..0e45ef81 100644
--- a/src/google/protobuf/util/json_util.h
+++ b/src/google/protobuf/util/json_util.h
@@ -172,12 +172,15 @@ namespace internal {
class LIBPROTOBUF_EXPORT ZeroCopyStreamByteSink : public strings::ByteSink {
public:
explicit ZeroCopyStreamByteSink(io::ZeroCopyOutputStream* stream)
- : stream_(stream) {}
+ : stream_(stream), buffer_size_(0) {}
+ ~ZeroCopyStreamByteSink();
virtual void Append(const char* bytes, size_t len);
private:
io::ZeroCopyOutputStream* stream_;
+ void* buffer_;
+ int buffer_size_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyStreamByteSink);
};