amath  1.8.5
Simple command line calculator
charbuf.cpp
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2014-2018 Carsten Sonne Larsen <cs@innolan.net>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  * Project homepage:
26  * https://amath.innolan.net
27  *
28  */
29 
30 #include "amath.h"
31 #include "amathc.h"
32 #include "charbuf.h"
33 
34 /**
35  * @brief Initialize without allocating memory.
36  *
37  */
39 {
40  buf = nullptr;
41  ptr = buf;
42  cursize = 0;
43 }
44 
45 /**
46  * @brief Initialize while allocating specified amount of memory.
47  *
48  */
49 CharBuffer::CharBuffer(unsigned int size)
50 {
51  cursize = (size < minimumSize ? minimumSize : size);
52  buf = new char[cursize];
53  ptr = buf;
54 }
55 
57 {
59 }
60 
61 /**
62  * @brief Release memory in buffer.
63  *
64  */
66 {
67  if (buf != nullptr)
68  {
69  delete [] buf;
70  }
71 
72  buf = nullptr;
73  ptr = buf;
74  cursize = 0;
75 }
76 
77 /**
78  * @brief Release memory, allocate and copy source.
79  *
80  */
81 void CharBuffer::ClearAndCopy(const char* source)
82 {
84  cursize = AllocAndCopy(&buf, source);
85  ptr = buf + cursize - sizeof(char);
86 }
87 
88 /**
89  * @brief Release memory and allocate new size.
90  *
91  */
92 void CharBuffer::ClearAndAlloc(unsigned int size)
93 {
95  cursize = (size < minimumSize ? minimumSize : size);
96  buf = new char[cursize];
97  ptr = buf;
98 }
99 
101 {
102  if (buf == nullptr)
103  {
104  unsigned int size = minimumSize;
105  buf = new char[size];
106  ptr = buf;
107  }
108 }
109 
110 /**
111  * @brief Ensure a memory block of specified size is allocated.
112  *
113  */
114 void CharBuffer::EnsureSize(unsigned int size)
115 {
116  if (cursize < size)
117  {
118  unsigned int tempsize = cursize;
119  cursize = (size < minimumSize ? minimumSize : size);
120 
121  if (buf == nullptr)
122  { // Nothing allocated yet. Just allocate requested size.
123  buf = new char[cursize];
124  ptr = buf;
125  }
126  else if (buf == ptr)
127  { // Already allocated but buffer is empty.
128  delete [] buf;
129  buf = new char[cursize];
130  ptr = buf;
131  }
132  else
133  { // Buffer already in use.
134  // Make at least double size
135  cursize = cursize < tempsize * 2 ? tempsize * 2 : cursize;
136  unsigned int offset = (unsigned int)(ptr - buf);
137  char* temp = new char[cursize];
138  MemCopy(temp, buf, tempsize);
139  delete [] buf;
140  buf = temp;
141  ptr = buf + offset;
142  }
143  }
144 }
145 
146 void CharBuffer::EnsureSize(unsigned int blocksize, unsigned int blocks)
147 {
148  if (cursize < blocksize * blocks)
149  {
150  if (buf == nullptr)
151  {
152  cursize = blocksize * blocks;
153  buf = new char[cursize];
154  ptr = buf;
155  }
156  else
157  {
158  unsigned int tptr = (unsigned int)(ptr - buf);
159  char* temp = new char[blocksize * blocks];
160  MemCopy(temp, buf, cursize);
161  delete [] buf;
162  cursize = blocksize * blocks;
163  buf = temp;
164  ptr = buf + tptr;
165  }
166  }
167 }
168 
169 void CharBuffer::EnsureGrowth(unsigned int size)
170 {
171  EnsureSize((unsigned int)((ptr - buf) + size));
172 }
173 
174 bool CharBuffer::IsEmpty() const
175 {
176  char* i = buf;
177 
178  if (i == nullptr || buf == ptr)
179  return true;
180 
181  do
182  {
183  // Blank space characters
184  if (*i != ' ' && *i != '\t' && *i != '\r' && *i != '\n')
185  return false;
186 
187  i++;
188  }
189  while (i != ptr);
190 
191  return true;
192 }
193 
194 bool CharBuffer::Is(const char* string) const
195 {
196  return StrIsEqual(GetString(), string);
197 }
198 
199 bool CharBuffer::Contains(const char c) const
200 {
201  char* i = buf;
202 
203  if (i == nullptr || buf == ptr)
204  return false;
205 
206  do
207  {
208  if (*i == c)
209  return true;
210 
211  i++;
212  }
213  while (i != ptr);
214 
215  return false;
216 }
217 
219 {
220  if (buf == nullptr)
221  {
223  }
224 
225  ptr = buf;
226 }
227 
229 {
230  ptr--;
231 }
232 
233 void CharBuffer::Copy(CharBuffer* source)
234 {
235  EnsureSize(source->cursize);
236  const char* s = source->GetString();
237 
238  ptr = buf;
239  // ReSharper disable once CppPossiblyErroneousEmptyStatements
240  while ((*ptr++ = *s++));
241 
242  ptr--;
243 }
244 
245 void CharBuffer::Append(const char c)
246 {
247  *ptr++ = c;
248 }
249 
250 void CharBuffer::Append(const char c, unsigned int count)
251 {
252  if (count == 0)
253  {
254  return;
255  }
256 
257  unsigned int n = count;
258  while (n--)
259  *ptr++ = c;
260 }
261 
262 void CharBuffer::Append(const char* source)
263 {
264  // ReSharper disable once CppPossiblyErroneousEmptyStatements
265  while ((*ptr++ = *source++));
266 
267  ptr--;
268 }
269 
270 bool CharBuffer::RemoveTrailing(const char c)
271 {
272  if (ptr == buf)
273  {
274  return false;
275  }
276 
277  if (*(--ptr) == c)
278  {
279  return true;
280  }
281 
282  ptr++;
283  return false;
284 }
285 
286 bool CharBuffer::RemoveTrailing(const char* string)
287 {
288  int len = StrLen(string) * sizeof(char);
289  char* s = ptr - len;
290  if (s < buf)
291  {
292  return false;
293  }
294 
295  *ptr = '\0';
296 
297  if (StrIsEqual(s, string))
298  {
299  ptr = s;
300  return true;
301  }
302 
303  return false;
304 }
305 
306 char* CharBuffer::GetString() const
307 {
308  *ptr = '\0';
309  return buf;
310 }
void Append(const char c)
Definition: charbuf.cpp:245
void Empty()
Definition: charbuf.cpp:218
char * GetString() const
Definition: charbuf.cpp:306
bool RemoveTrailing(const char c)
Definition: charbuf.cpp:270
CharBuffer(unsigned int size)
Initialize while allocating specified amount of memory.
Definition: charbuf.cpp:49
bool Is(const char *string) const
Compare content of CharBuffer with string)
Definition: charbuf.cpp:194
void ClearBuffer()
Release memory in buffer.
Definition: charbuf.cpp:65
bool RemoveTrailing(const char *string)
Definition: charbuf.cpp:286
void Append(const char *source)
Definition: charbuf.cpp:262
CharBuffer()
Initialize without allocating memory.
Definition: charbuf.cpp:38
bool StrIsEqual(const char *s1, const char *s2)
Compare two null terminated strings to each other.
Definition: strcmp.c:50
void EnsureMinimumSize()
Definition: charbuf.cpp:100
unsigned int cursize
Definition: charbuf.h:83
void EnsureGrowth(unsigned int size)
Definition: charbuf.cpp:169
void DeleteLastChar()
Definition: charbuf.cpp:228
int StrLen(const char *string)
Get the length of a null terminated string.
Definition: strlen.c:34
void Copy(CharBuffer *buf)
Definition: charbuf.cpp:233
bool Contains(const char c) const
Definition: charbuf.cpp:199
char * ptr
Definition: charbuf.h:82
char * buf
Definition: charbuf.h:81
bool IsEmpty() const
Definition: charbuf.cpp:174
void ClearAndCopy(const char *source)
Release memory, allocate and copy source.
Definition: charbuf.cpp:81
void EnsureSize(unsigned int blocksize, unsigned int blocks)
Definition: charbuf.cpp:146
unsigned int AllocAndCopy(char **destination, const char *source)
Allocate memory and copy a string into the array.
Definition: alloccpy.c:40
void Append(const char c, unsigned int count)
Definition: charbuf.cpp:250
static const unsigned int minimumSize
Definition: charbuf.h:84
Encapsulate an character array which can be used as a string.
Definition: charbuf.h:44
void EnsureSize(unsigned int size)
Ensure a memory block of specified size is allocated.
Definition: charbuf.cpp:114
void MemCopy(void *destination, const void *source, unsigned int length)
Copy a block of memory, handling overlap.
Definition: memcpy.c:75
void ClearAndAlloc(unsigned int size)
Release memory and allocate new size.
Definition: charbuf.cpp:92
~CharBuffer()
Definition: charbuf.cpp:56