1 /*************************************************************************
3 * Copyright 2016 Realm Inc.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * 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, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 **************************************************************************/
19 #ifndef REALM_UTIL_STRING_BUFFER_HPP
20 #define REALM_UTIL_STRING_BUFFER_HPP
26 #include <realm/util/features.h>
27 #include <realm/util/buffer.hpp>
33 // FIXME: Check whether this class provides anything that a C++03
34 // std::string does not already provide. In particular, can a C++03
35 // std::string be used as a contiguous mutable buffer?
38 StringBuffer() noexcept;
40 std::string str() const;
42 /// Returns the current size of the string in this buffer. This
43 /// size does not include the terminating zero.
44 size_t size() const noexcept;
46 /// Gives read and write access to the bytes of this buffer. The
47 /// caller may read and write from *c_str() up to, but not
48 /// including, *(c_str()+size()).
49 char* data() noexcept;
51 /// Gives read access to the bytes of this buffer. The caller may
52 /// read from *c_str() up to, but not including,
53 /// *(c_str()+size()).
54 const char* data() const noexcept;
56 /// Guarantees that the returned string is zero terminated, that
57 /// is, *(c_str()+size()) is zero. The caller may read from
58 /// *c_str() up to and including *(c_str()+size()).
59 const char* c_str() const noexcept;
61 void append(const std::string&);
63 void append(const char* append_data, size_t append_size);
65 /// Append a zero-terminated string to this buffer.
66 void append_c_str(const char* c_string);
68 /// The specified size is understood as not including the
69 /// terminating zero. If the specified size is less than the
70 /// current size, then the string is truncated accordingly. If the
71 /// specified size is greater than the current size, then the
72 /// extra characters will have undefined values, however, there
73 /// will be a terminating zero at *(c_str()+size()), and the
74 /// original terminating zero will also be left in place such that
75 /// from the point of view of c_str(), the size of the string is
77 void resize(size_t new_size);
79 /// The specified minimum capacity is understood as not including
80 /// the terminating zero. This operation does not change the size
81 /// of the string in the buffer as returned by size(). If the
82 /// specified capacity is less than the current capacity, this
83 /// operation has no effect.
84 void reserve(size_t min_capacity);
86 /// Set size to zero. The capacity remains unchanged.
87 void clear() noexcept;
90 util::Buffer<char> m_buffer;
91 size_t m_size; // Excluding the terminating zero
92 void reallocate(size_t min_capacity);
98 inline StringBuffer::StringBuffer() noexcept
103 inline std::string StringBuffer::str() const
105 return std::string(m_buffer.data(), m_size);
108 inline size_t StringBuffer::size() const noexcept
113 inline char* StringBuffer::data() noexcept
115 return m_buffer.data();
118 inline const char* StringBuffer::data() const noexcept
120 return m_buffer.data();
123 inline const char* StringBuffer::c_str() const noexcept
125 static const char zero = 0;
126 const char* d = data();
127 return d ? d : &zero;
130 inline void StringBuffer::append(const std::string& s)
132 return append(s.data(), s.size());
135 inline void StringBuffer::append_c_str(const char* c_string)
137 append(c_string, std::strlen(c_string));
140 inline void StringBuffer::reserve(size_t min_capacity)
142 size_t capacity = m_buffer.size();
143 if (capacity == 0 || capacity - 1 < min_capacity)
144 reallocate(min_capacity);
147 inline void StringBuffer::resize(size_t new_size)
150 // Note that even reserve(0) will attempt to allocate a
151 // buffer, so we can safely write the truncating zero at this
154 m_buffer[new_size] = 0;
157 inline void StringBuffer::clear() noexcept
159 if (m_buffer.size() == 0)
169 #endif // REALM_UTIL_STRING_BUFFER_HPP