| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| #ifndef BRPC_JSON2PB_ZERO_COPY_STREAM_WRITER_H |
| #define BRPC_JSON2PB_ZERO_COPY_STREAM_WRITER_H |
| |
| #include <google/protobuf/io/zero_copy_stream.h> // ZeroCopyOutputStream |
| #include <iostream> |
| |
| //class IOBufAsZeroCopyOutputStream |
| // : public google::protobuf::io::ZeroCopyOutputStream { |
| //public: |
| // explicit IOBufAsZeroCopyOutputStream(IOBuf*); |
| // |
| // // Interfaces of ZeroCopyOutputStream |
| // bool Next(void** data, int* size); |
| // void BackUp(int count); |
| // google::protobuf::int64 ByteCount() const; |
| // |
| //private: |
| // IOBuf* _buf; |
| // size_t _initial_length; |
| //}; |
| |
| namespace json2pb { |
| |
| class ZeroCopyStreamWriter { |
| public: |
| typedef char Ch; |
| ZeroCopyStreamWriter(google::protobuf::io::ZeroCopyOutputStream *stream) |
| : _stream(stream), _data(NULL), |
| _cursor(NULL), _data_size(0) { |
| } |
| ~ZeroCopyStreamWriter() { |
| if (_stream && _data) { |
| _stream->BackUp(RemainSize()); |
| } |
| _stream = NULL; |
| } |
| |
| void Put(char c) { |
| if (__builtin_expect(AcquireNextBuf(), 1)) { |
| *_cursor = c; |
| ++_cursor; |
| } |
| } |
| void PutN(char c, size_t n) { |
| while (AcquireNextBuf() && n > 0) { |
| size_t remain_size = RemainSize(); |
| size_t to_write = n > remain_size ? remain_size : n; |
| memset(_cursor, c, to_write); |
| _cursor += to_write; |
| n -= to_write; |
| } |
| } |
| void Puts(const char* str, size_t length) { |
| while (AcquireNextBuf() && length > 0) { |
| size_t remain_size = RemainSize(); |
| size_t to_write = length > remain_size ? remain_size : length; |
| memcpy(_cursor, str, to_write); |
| _cursor += to_write; |
| str += to_write; |
| length -= to_write; |
| } |
| } |
| |
| void Flush() {} |
| |
| // TODO: Add BIADU_CHECK |
| char Peek() { return 0; } |
| char Take() { return 0; } |
| size_t Tell() { return 0; } |
| char *PutBegin() { return NULL; } |
| size_t PutEnd(char *) { return 0; } |
| private: |
| bool AcquireNextBuf() { |
| if (__builtin_expect(!_stream, 0)) { |
| return false; |
| } |
| if (_data == NULL || _cursor == _data + _data_size) { |
| if (!_stream->Next((void **)&_data, &_data_size)) { |
| return false; |
| } |
| _cursor = _data; |
| } |
| return true; |
| } |
| size_t RemainSize() { |
| return _data_size - (_cursor - _data); |
| } |
| |
| google::protobuf::io::ZeroCopyOutputStream *_stream; |
| char *_data; |
| char *_cursor; |
| int _data_size; |
| }; |
| |
| } // namespace json2pb |
| |
| #endif //BRPC_JSON2PB_ZERO_COPY_STREAM_WRITER_H |