The Pedigree Project  0.1
Cord.cc
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 #include "pedigree/kernel/compiler.h"
21 #include "pedigree/kernel/processor/types.h"
22 #include "pedigree/kernel/utilities/Cord.h"
23 #include "pedigree/kernel/utilities/String.h"
24 #include "pedigree/kernel/utilities/List.h"
25 
26 Cord::Cord() = default;
27 
28 Cord::Cord(const Cord &other) : Cord()
29 {
30  assign(other);
31 }
32 
33 Cord::~Cord()
34 {
35  clear();
36 }
37 
38 Cord &Cord::operator=(const Cord &s)
39 {
40  assign(s);
41  return *this;
42 }
43 
44 void Cord::reserve(size_t segments)
45 {
46  m_Segments.reserve(segments, true);
47 }
48 
49 void Cord::assign(const Cord &other)
50 {
51  clear();
52 
53  m_Segments.reserve(other.m_Segments.count(), false);
54 
55  for (auto &it : other.m_Segments)
56  {
57  m_Segments.pushBack(it);
58  m_Length += it.length;
59  }
60 }
61 
62 void Cord::clear()
63 {
64  m_Segments.clear(false);
65 }
66 
67 size_t Cord::length() const
68 {
69  return m_Length;
70 }
71 
72 String Cord::toString() const
73 {
74  char *buf = new char[m_Length + 1];
75  size_t offset = 0;
76  for (auto &it : m_Segments)
77  {
78  MemoryCopy(buf + offset, it.ptr, it.length);
79  offset += it.length;
80  }
81 
82  buf[m_Length] = 0;
83 
84  String result(buf, m_Length);
85  delete [] buf;
86  return result;
87 }
88 
89 char Cord::operator[](size_t index) const
90 {
91  size_t i = 0;
92  for (auto &it : m_Segments)
93  {
94  if ((index >= i) && (index < (i + it.length)))
95  {
96  return it.ptr[index - i];
97  }
98 
99  i += it.length;
100  }
101 
103  return 0;
104 }
105 
106 void Cord::append(const char *s, size_t len)
107 {
108  if (!len)
109  {
110  len = StringLength(s);
111  }
112 
113  m_Segments.pushBack(CordSegment(s, len));
114  m_Length += len;
115 }
116 
117 void Cord::prepend(const char *s, size_t len)
118 {
119  if (!len)
120  {
121  len = StringLength(s);
122  }
123 
124  m_Segments.pushFront(CordSegment(s, len));
125  m_Length += len;
126 }
127 
128 Cord::CordIterator Cord::begin() const
129 {
130  return Cord::CordIterator(*this);
131 }
132 
133 Cord::CordIterator Cord::end() const
134 {
135  return Cord::CordIterator(*this, true);
136 }
137 
138 Cord::CordIterator::CordIterator(const Cord &owner) : cord(owner), segment(0), index(0)
139 {
140 }
141 
142 Cord::CordIterator::CordIterator(const Cord &owner, bool end) : cord(owner), segment(0), index(0)
143 {
144  segment = owner.m_Segments.count();
145 }
146 
147 Cord::CordIterator::~CordIterator() = default;
148 
149 Cord::CordIterator &Cord::CordIterator::operator++()
150 {
151  ++index;
152  if (index >= cord.m_Segments[segment].length)
153  {
154  index = 0;
155  ++segment;
156  }
157 
158  if (segment > cord.m_Segments.count())
159  {
160  segment = cord.m_Segments.count();
161  index = 0;
162  }
163 
164  return *this;
165 }
166 
167 Cord::CordIterator &Cord::CordIterator::operator--()
168 {
169  if (index)
170  {
171  --index;
172  }
173  else if (segment)
174  {
175  --segment;
176  index = cord.m_Segments[segment].length;
177  }
178 
179  return *this;
180 }
181 
182 char Cord::CordIterator::operator*() const
183 {
184  return cord.m_Segments[segment].ptr[index];
185 }
186 
187 bool Cord::CordIterator::operator==(const CordIterator &other) const
188 {
189  return segment == other.segment && index == other.index;
190 }
191 
192 bool Cord::CordIterator::operator!=(const CordIterator &other) const
193 {
194  return !(*this == other);
195 }
char operator[](size_t index) const
Definition: Cord.cc:89
void reserve(size_t segments)
Definition: Cord.cc:44
Definition: String.h:49
Definition: Cord.h:33