| /** | |
| @section license License | |
| 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. | |
| */ | |
| #pragma once | |
| #include <sstream> | |
| #include <swoc/BufferWriter.h> | |
| /// @brief Simple storage to keep the jsonrpc server's response. | |
| /// | |
| /// With small content it will just use the LocalBufferWriter, if the | |
| /// content gets bigger, then it will just save the buffer into a string | |
| /// and reuse the already created LocalBufferWriter. If stored data fits in the | |
| /// original bw, then no need to create the extra string. If message fist in the | |
| /// first chunk, no extra space will be allocated into the storage string. | |
| /// This is not meant to be performant as is mainly used for single request | |
| /// data storage, which will be at some point stored into a string anyways. | |
| /// @note User should deal with the buffer limit. | |
| /// | |
| template <size_t N> class MessageStorage | |
| { | |
| std::string _content; | |
| swoc::LocalBufferWriter<N> _bw; | |
| size_t _written{0}; | |
| public: | |
| char * | |
| writable_data() | |
| { | |
| return _bw.aux_data(); | |
| } | |
| void | |
| save(size_t n) | |
| { | |
| _bw.commit(n); | |
| if (_bw.remaining() == 0) { // no more space available, flush what's on the bw | |
| // and reset it. | |
| flush(); | |
| } | |
| } | |
| size_t | |
| available() const | |
| { | |
| return _bw.remaining(); | |
| } | |
| void | |
| flush() | |
| { | |
| if (_bw.size() == 0) { | |
| return; | |
| } | |
| if (_written == 0) { | |
| _content.reserve(_bw.size()); | |
| } else { | |
| // need more space. | |
| _content.reserve(_written + _bw.size()); | |
| } | |
| _content.append(_bw.data(), _bw.size()); | |
| _written += _bw.size(); | |
| _bw.clear(); | |
| } | |
| std::string | |
| str() | |
| { | |
| if (stored() <= _bw.size()) { | |
| // just get it directly from the BW. | |
| return {_bw.data(), _bw.size()}; | |
| } | |
| // There is content in the bw that needs to be saved into the internal string. | |
| flush(); | |
| return _content; | |
| } | |
| size_t | |
| stored() const | |
| { | |
| return _written ? _written : _bw.size(); | |
| } | |
| }; |