2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
19 * Copyright (C) 2020 Cloudius Systems, Ltd.
26 /// \addtogroup logging
34 /// A buffer to format log messages into.
36 /// It was designed to allow formatting the entire message into it, without any
37 /// intermediary buffers. To minimize the amount of reallocations it supports
38 /// using an external buffer. When this is full it moves to using buffers
39 /// allocated by itself.
40 /// To accommodate the most widely used way of formatting messages -- fmt --,
41 /// it provides an output iterator interface for writing into it.
49 void free_buffer() noexcept;
50 void realloc_buffer();
53 class inserter_iterator {
55 using iterator_category = std::output_iterator_tag;
56 using difference_type = std::ptrdiff_t;
57 using value_type = char;
58 using pointer = char*;
59 using reference = char&;
66 explicit inserter_iterator(log_buf& buf) noexcept : _buf(&buf), _current(_buf->_current) { }
67 inserter_iterator(const inserter_iterator& o) noexcept : _buf(o._buf), _current(o._current) { }
69 reference operator*() {
70 if (__builtin_expect(_current == _buf->_end, false)) {
71 _buf->realloc_buffer();
72 _current = _buf->_current;
76 inserter_iterator& operator++() noexcept {
77 if (__builtin_expect(_current == _buf->_current, true)) {
83 inserter_iterator operator++(int) noexcept {
84 inserter_iterator o(*this);
92 /// Allocates an internal buffer of 512 bytes.
94 /// External buffer ctor.
96 /// Use the external buffer until its full, then switch to internally
97 /// allocated buffer. log_buf doesn't take ownership of the buffer.
98 log_buf(char* external_buf, size_t size) noexcept;
100 /// Create an output iterator which allows writing into the buffer.
101 inserter_iterator back_insert_begin() noexcept { return inserter_iterator(*this); }
102 /// The amount of data written so far.
103 const size_t size() const noexcept { return _current - _begin; }
104 /// The size of the buffer.
105 const size_t capacity() const noexcept { return _end - _begin; }
106 /// Read only pointer to the buffer.
107 /// Note that the buffer is not guaranteed to be null terminated. The writer
108 /// has to ensure that, should it wish to.
109 const char* data() const noexcept { return _begin; }
110 /// A view of the buffer content.
111 std::string_view view() const noexcept { return std::string_view(_begin, size()); }
114 } // namespace internal
117 } // namespace seastar