Sourcemeta Core 0.0.0
Loading...
Searching...
No Matches
html_buffer.h
1#ifndef SOURCEMETA_CORE_HTML_BUFFER_H_
2#define SOURCEMETA_CORE_HTML_BUFFER_H_
3
4#ifndef SOURCEMETA_CORE_HTML_EXPORT
5#include <sourcemeta/core/html_export.h>
6#endif
7
8#include <sourcemeta/core/preprocessor.h>
9
10#include <cstring> // std::memcpy
11#include <iostream> // std::ostream
12#include <string> // std::string
13#include <string_view> // std::string_view
14
15namespace sourcemeta::core {
16
19class SOURCEMETA_CORE_HTML_EXPORT HTMLBuffer {
20public:
21 HTMLBuffer() = default;
22 HTMLBuffer(const HTMLBuffer &) = delete;
23 auto operator=(const HTMLBuffer &) -> HTMLBuffer & = delete;
24 HTMLBuffer(HTMLBuffer &&) = delete;
25 auto operator=(HTMLBuffer &&) -> HTMLBuffer & = delete;
26
28 SOURCEMETA_FORCEINLINE inline auto reserve(const std::size_t bytes) -> void {
29 this->buffer_.resize(bytes);
30 this->cursor_ = this->buffer_.data();
31 this->end_ = this->cursor_ + bytes;
32 }
33
35 SOURCEMETA_FORCEINLINE inline auto append(const char character) -> void {
36 if (!this->cursor_ || this->cursor_ >= this->end_) [[unlikely]] {
37 this->grow(1);
38 }
39
40 *this->cursor_ = character;
41 ++this->cursor_;
42 }
43
45 SOURCEMETA_FORCEINLINE inline auto append(const std::string_view data)
46 -> void {
47 const auto length{data.size()};
48 if (length == 0) {
49 return;
50 }
51
52 const auto remaining{
53 this->cursor_ ? static_cast<std::size_t>(this->end_ - this->cursor_)
54 : 0uz};
55 if (remaining < length) [[unlikely]] {
56 this->grow(length);
57 }
58
59 std::memcpy(this->cursor_, data.data(), length);
60 this->cursor_ += length;
61 }
62
64 [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto str()
65 -> const std::string & {
66 if (this->cursor_) {
67 this->buffer_.resize(
68 static_cast<std::size_t>(this->cursor_ - this->buffer_.data()));
69 this->cursor_ = nullptr;
70 this->end_ = nullptr;
71 }
72
73 return this->buffer_;
74 }
75
77 auto write(std::ostream &stream) -> void;
78
79private:
80 auto grow(std::size_t needed) -> void;
81
82// Exporting symbols that depends on the standard C++ library is considered
83// safe.
84// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN
85#if defined(_MSC_VER)
86#pragma warning(disable : 4251)
87#endif
88 std::string buffer_;
89#if defined(_MSC_VER)
90#pragma warning(default : 4251)
91#endif
92 char *cursor_{nullptr};
93 char *end_{nullptr};
94};
95
96} // namespace sourcemeta::core
97
98#endif
SOURCEMETA_FORCEINLINE auto append(const std::string_view data) -> void
Append a sequence of characters to the buffer.
Definition html_buffer.h:45
auto write(std::ostream &stream) -> void
Write the accumulated contents to an output stream.
SOURCEMETA_FORCEINLINE auto append(const char character) -> void
Append a single character to the buffer.
Definition html_buffer.h:35
SOURCEMETA_FORCEINLINE auto str() -> const std::string &
Get the accumulated contents of the buffer.
Definition html_buffer.h:64
SOURCEMETA_FORCEINLINE auto reserve(const std::size_t bytes) -> void
Reserve a number of bytes of capacity up front.
Definition html_buffer.h:28