The Pedigree Project 0.1
StaticCord.h
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#ifndef KERNEL_UTILITIES_STATICCORD_H
21#define KERNEL_UTILITIES_STATICCORD_H
22
26#include "pedigree/kernel/compiler.h"
27#include "pedigree/kernel/processor/types.h"
28#include "pedigree/kernel/utilities/String.h"
29#include "pedigree/kernel/utilities/assert.h"
30#include "pedigree/kernel/utilities/template.h" // IWYU pragma: keep
31#include "pedigree/kernel/utilities/utility.h"
32
37template <unsigned int N>
38class EXPORTED_PUBLIC StaticCord {
39 friend class CordIterator;
40
41 public:
43 friend class StaticCord;
44
45 public:
46 CordIterator(const StaticCord& owner) : cord(owner), segment(0), index(0) {}
47 virtual ~CordIterator() = default;
48
50 if (segment >= cord.m_NumSegments) {
51 return *this;
52 }
53
54 ++index;
55 if (index >= cord.m_Segments[segment].length) {
56 index = 0;
57 ++segment;
58 }
59
60 if (segment >= cord.m_NumSegments) {
61 segment = cord.m_NumSegments;
62 index = 0;
63 }
64
65 return *this;
66 }
67
69 if (index) {
70 --index;
71 } else if (segment) {
72 --segment;
73 index = cord.m_Segments[segment].length - 1;
74 }
75
76 return *this;
77 }
78
79 char operator*() const {
80 return cord.m_Segments[segment].ptr[index];
81 }
82
83 bool operator==(const CordIterator& other) const {
84 return segment == other.segment && index == other.index;
85 }
86
87 bool operator!=(const CordIterator& other) const {
88 return !(*this == other);
89 }
90
91 protected:
92 CordIterator(const StaticCord& owner, bool end) : cord(owner), segment(0), index(0) {
93 if (end) {
94 segment = owner.m_NumSegments;
95 }
96 }
97
98 private:
99 const StaticCord& cord;
100 size_t segment;
101 size_t index;
102 };
103
105 friend class StaticCord;
106
107 public:
108 CordSegmentIterator(const StaticCord& owner) : cord(owner), segment(0) {}
109 virtual ~CordSegmentIterator() = default;
110
112 ++segment;
113
114 if (segment > cord.m_NumSegments) {
115 segment = cord.m_NumSegments;
116 }
117
118 return *this;
119 }
120
122 if (segment) {
123 --segment;
124 }
125
126 return *this;
127 }
128
129 const char* ptr() const {
130 return cord.m_Segments[segment].ptr;
131 }
132
133 size_t length() const {
134 return cord.m_Segments[segment].length;
135 }
136
137 bool operator==(const CordSegmentIterator& other) const {
138 return segment == other.segment;
139 }
140
141 bool operator!=(const CordSegmentIterator& other) const {
142 return !(*this == other);
143 }
144
145 protected:
146 CordSegmentIterator(const StaticCord& owner, bool end) : cord(owner), segment(0) {
147 if (end) {
148 segment = owner.m_NumSegments;
149 }
150 }
151
152 private:
153 const StaticCord& cord;
154 size_t segment;
155 };
156
157 StaticCord() = default;
158 StaticCord(const StaticCord& other) : StaticCord() {
159 assign(other);
160 }
161 virtual ~StaticCord() = default;
162
163 StaticCord& operator=(const StaticCord& s) {
164 assign(s);
165 return *this;
166 }
167
168 void assign(const StaticCord& other) {
169 m_Length = other.m_Length;
170 m_NumSegments = other.m_NumSegments;
171 pedigree_std::copy(m_Segments, other.m_Segments, N);
172 }
173
174 void clear() {
175 m_NumSegments = 0;
176 m_Length = 0;
177 }
178
179 size_t length() const {
180 return m_Length;
181 }
182
183 char operator[](size_t index) const {
184 size_t offset = 0;
185 for (size_t i = 0; i < m_NumSegments; ++i) {
186 if ((index >= offset) && (index < (offset + m_Segments[i].length))) {
187 return m_Segments[i].ptr[index - offset];
188 }
189
190 offset += m_Segments[i].length;
191 }
192
193 return 0;
194 }
195
196 String toString() const {
197 char* buf = new char[m_Length + 1];
198 size_t offset = 0;
199 for (size_t i = 0; i < m_NumSegments; ++i) {
200 MemoryCopy(buf + offset, m_Segments[i].ptr, m_Segments[i].length);
201 offset += m_Segments[i].length;
202 }
203
204 buf[m_Length] = 0;
205
206 String result(buf, m_Length);
207 delete[] buf;
208 return result;
209 }
210
211 void append(const char* s, size_t len = 0) {
212 assert(m_NumSegments < N);
213
214 if (!len) {
215 len = StringLength(s);
216 }
217
218 if (!len)
219 return;
220
221 m_Segments[m_NumSegments++] = CordSegment(s, len);
222 m_Length += len;
223 }
224
225 CordIterator begin() const {
226 return CordIterator(*this);
227 }
228
229 CordIterator end() const {
230 return CordIterator(*this, true);
231 }
232
233 CordSegmentIterator segbegin() const {
234 return CordSegmentIterator(*this);
235 }
236
237 CordSegmentIterator segend() const {
238 return CordSegmentIterator(*this, true);
239 }
240
241 private:
242 struct CordSegment {
243 CordSegment() = default;
244 CordSegment(const char* s, size_t len) : ptr(s), length(len) {}
245
246 const char* ptr = nullptr;
247 size_t length = 0;
248 };
249
250 CordSegment m_Segments[N];
251 size_t m_Length = 0;
252 size_t m_NumSegments = 0;
253};
254
255// Specializations
256extern template class EXPORTED_PUBLIC StaticCord<8>; // IWYU pragma: keep
257
260#endif // KERNEL_UTILITIES_STATICCORD_H
T operator--(T &x, int)
Global postdecrement operator for types with overloaded predecrement operator.
Definition template.h:53
T operator++(T &x, int)
Global postincrement operator for types with overloaded preincrement operator.
Definition template.h:43
bool operator==(const Iterator< originalT, Struct, FunctionPrev, FunctionNext, T1 > &x1, const Iterator< originalT, Struct, FunctionPrev, FunctionNext, T2 > &x2)
Definition Iterator.h:256