The SWORD Project  1.9.0.svnversion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
swbuf.h
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * swbuf.h - class SWBuf: a rich buffer / string class providing optimized
4  * implementations of many basic string operations
5  *
6  * $Id: swbuf.h 3786 2020-08-30 11:35:14Z scribe $
7  *
8  * Copyright 2003-2013 CrossWire Bible Society (http://www.crosswire.org)
9  * CrossWire Bible Society
10  * P. O. Box 2528
11  * Tempe, AZ 85280-2528
12  *
13  * This program is free software; you can redistribute it and/or modify it
14  * under the terms of the GNU General Public License as published by the
15  * Free Software Foundation version 2.
16  *
17  * This program is distributed in the hope that it will be useful, but
18  * WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20  * General Public License for more details.
21  *
22  */
23 
24 #ifndef SWBUF_H
25 #define SWBUF_H
26 
27 #include <defs.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdarg.h>
31 #ifdef __BORLANDC__
32 #include <mem.h>
33 #endif
34 
36 
37 
38 #define JUNKBUFSIZE 65534
39 
48 
49 private:
50  char *buf;
51  char *end;
52  char *endAlloc;
53  char fillByte;
54  unsigned long allocSize;
55 
56  inline void assureMore(size_t pastEnd) {
57  if (size_t(endAlloc-end) < pastEnd) {
58  assureSize(allocSize + pastEnd);
59  }
60  }
61 
62  inline void assureSize(size_t checkSize) {
63  if (checkSize > allocSize) {
64  long size = (end - buf);
65  checkSize += 128;
66  buf = (char *)((allocSize) ? realloc(buf, checkSize) : malloc(checkSize));
67  allocSize = checkSize;
68  end = (buf + size);
69  *end = 0;
70  endAlloc = buf + allocSize - 1;
71  }
72  }
73 
74  inline void init(size_t initSize) {
75  fillByte = ' ';
76  allocSize = 0;
77  buf = nullStr;
78  end = buf;
79  endAlloc = buf;
80  if (initSize)
81  assureSize(initSize);
82  }
83 
84 
85 public:
86 
87  static char *nullStr;
88 
89  /******************************************************************************
90  * SWBuf Constructor - Creates an empty SWBuf object
91  *
92  */
93  inline SWBuf() {
94  init(0);
95  }
96 
97  /******************************************************************************
98  * SWBuf Constructor - Creates an empty SWBuf object or an SWBuf initialized
99  * to a value from a const char *
100  *
101  */
102  inline SWBuf(const char *initVal, unsigned long initSize = 0) {
103  init(initSize);
104  if (initVal)
105  set(initVal, initSize);
106  }
107 
108  /******************************************************************************
109  * SWBuf Constructor - Creates an SWBuf initialized
110  * to a value from another SWBuf
111  *
112  */
113  inline SWBuf(const SWBuf &other, unsigned long initSize = 0) {
114  init(initSize);
115  set(other);
116  }
117 
118  /******************************************************************************
119  * SWBuf Constructor - Creates an SWBuf initialized
120  * to a value from a char
121  *
122  */
123  inline SWBuf(char initVal, unsigned long initSize = 0) {
124  init(initSize+1);
125  *buf = initVal;
126  end = buf+1;
127  *end = 0;
128  }
129 // SWBuf(unsigned long initSize);
130 
131 
132  /******************************************************************************
133  * SWBuf Destructor - Cleans up instance of SWBuf
134  */
135  inline ~SWBuf() {
136  if ((buf) && (buf != nullStr))
137  free(buf);
138  }
139 
146  inline void setFillByte(char ch) { fillByte = ch; }
147 
153  inline char getFillByte() { return fillByte; }
154 
158  inline const char *c_str() const{ return buf; }
159 
164  // fastest guarded impl. If we reference out of bounds, we return our
165  inline char &charAtGuarded(unsigned long pos) { return ((pos <= (unsigned long)(endAlloc - buf)) ? buf[pos] : (*endAlloc)); }
166  // unguarded impl. This is obviously much faster and is likely why std::string specifies references out of bounds have undefined
167  // behavior. This is the default impl for operator []
168  inline char &charAt(unsigned long pos) { return *(buf + pos); }
169  inline const char &charAt(unsigned long pos) const { return *(buf + pos); }
170 
171 // these have all proven to be slower implementations
172 // inline char &charAt(unsigned long pos) { return buf[pos]; }
173 // inline char &charAtGuarded(unsigned long pos) { return pos <= (unsigned long)end - (unsigned long)buf ? buf[pos] : *nullStr; }
174 // inline char &charAtGuarded(unsigned long pos) { return pos <= length() ? buf[pos] : *nullStr; }
175 // inline char &charAtGuarded(unsigned long pos) { assureSize(pos); return buf[pos]; }
176 // inline char &charAtGuarded(unsigned long pos) { return pos < allocSize ? buf[pos] : *nullStr; }
177 // inline char &charAtGuarded(unsigned long pos) { return buf + pos <= end ? buf[pos] : *nullStr; }
178 // inline char &charAtGuarded(unsigned long pos) { return buf[pos < allocSize ? pos : allocSize - 1]; }
179 
180 
185  inline unsigned long size() const { return length(); }
186 
192  inline void size(unsigned long newSize) { if (end - buf - newSize) setSize(newSize); }
193 
197  inline unsigned long length() const { return end - buf; }
198 
204  inline void set(const SWBuf &newVal) {
205  unsigned long len = newVal.allocSize;
206  assureSize(len);
207  memcpy(buf, newVal.c_str(), len);
208  end = buf + (newVal.length());
209  }
210 
216  inline void set(const char *newVal, unsigned long maxSize = 0) {
217  if (newVal) {
218  unsigned long len = strlen(newVal) + 1;
219  if (maxSize && maxSize < (len-1)) len = maxSize + 1;
220  assureSize(len);
221  memcpy(buf, newVal, len);
222  end = buf + (len - 1);
223  }
224  else {
225  assureSize(1);
226  end = buf;
227  }
228  *end = 0;
229  }
230 
248  SWBuf &setFormatted(const char *format, ...);
249  SWBuf &setFormattedVA(const char *format, va_list argptr);
250 
255  inline void setSize(unsigned long len) {
256  assureSize(len+1);
257  if ((unsigned)(end - buf) < len)
258  memset(end, fillByte, (size_t)len - (end-buf));
259  end = buf + len;
260  *end = 0;
261  }
266  inline void resize(unsigned long len) { setSize(len); }
267 
274  inline SWBuf &append(const char *str, long max = -1) {
275  // if (!str) //A null string was passed
276  // return;
277  if (max < 0)
278  max = strlen(str);
279  assureMore(max+1);
280  for (;((max)&&(*str));max--)
281  *end++ = *str++;
282  *end = 0;
283  return *this;
284  }
285 
292  inline SWBuf &append(const SWBuf &str, long max = -1) { return append(str.c_str(), max); }
293 
299  inline SWBuf &append(char ch) {
300  assureMore(1);
301  *end++ = ch;
302  *end = 0;
303  return *this;
304  }
305  inline SWBuf &append(const unsigned char ch) {
306  assureMore(1);
307  *end++ = ch;
308  *end = 0;
309  return *this;
310  }
311 
319  inline SWBuf &append(wchar_t wch) {
320  assureMore(sizeof(wchar_t)*2);
321  for (unsigned int i = 0; i < sizeof(wchar_t); i++) *end++ = ((char *)&wch)[i];
322  for (unsigned int i = 0; i < sizeof(wchar_t); i++) end[i] = 0;
323  return *this;
324  }
325 
342  SWBuf &appendFormatted(const char *format, ...);
343 
351  void insert(unsigned long pos, const char* str, unsigned long start = 0, signed long max = -1);
352 
360  inline void insert(unsigned long pos, const SWBuf &str, unsigned long start = 0, signed long max = -1) {
361  insert(pos, str.c_str(), start, max);
362  };
363 
369  inline void insert(unsigned long pos, char c) {
370  insert(pos, SWBuf(c));
371  }
372 
379  inline char *getRawData() { return buf; }
380 
381  inline operator const char *() const { return c_str(); }
382  inline char &operator[](unsigned long pos) { return charAt(pos); }
383  inline char &operator[](long pos) { return charAt((unsigned long)pos); }
384  inline char &operator[](unsigned int pos) { return charAt((unsigned long)pos); }
385  inline char &operator[](int pos) { return charAt((unsigned long)pos); }
386  inline const char &operator[](unsigned long pos) const { return charAt(pos); }
387  inline const char &operator[](long pos) const { return charAt((unsigned long)pos); }
388  inline const char &operator[](unsigned int pos) const { return charAt((unsigned long)pos); }
389  inline const char &operator[](int pos) const { return charAt((unsigned long)pos); }
390  inline SWBuf &operator =(const char *newVal) { set(newVal); return *this; }
391  inline SWBuf &operator =(const SWBuf &other) { set(other); return *this; }
392  inline SWBuf &operator +=(const char *str) { return append(str); }
393  inline SWBuf &operator +=(char ch) { return append(ch); }
394 
399  inline SWBuf &operator -=(unsigned long len) { setSize(length()-len); return *this; }
400 
404  inline SWBuf &operator --(int) { operator -=(1); return *this; }
405 
409  inline SWBuf &operator <<(unsigned long n) { if (n && length()) { n = (n<=length())?n:(length()-1); memmove(buf, buf+n, length()-n); (*this)-=n; } return *this; }
410 
414  inline SWBuf &operator >>(unsigned long n) { setSize(length()+n); memmove(buf+n, buf, length()-n); return *this; }
415 
419  inline SWBuf operator +(const SWBuf &other) const {
420  SWBuf retVal = buf;
421  retVal += other;
422  return retVal;
423  }
424 
428  inline SWBuf operator +(char ch) const { return (*this) + SWBuf(ch); }
429 
433  inline SWBuf &trimStart() { while (size() && (strchr("\t\r\n ", *(buf)))) *this << 1; return *this; }
434 
438  inline SWBuf &trimEnd() { while (size() && (strchr("\t\r\n ", *(end-1)))) setSize(size()-1); return *this; }
439 
443  inline SWBuf &trim() { trimStart(); return trimEnd(); }
444 
445 
457  inline const char *stripPrefix(char separator, bool endOfStringAsSeparator = false) { const char *m = strchr(buf, separator); if (!m && endOfStringAsSeparator) { if (*buf) { operator >>(1); *buf=0; end = buf; return buf + 1;} else return buf; } if (m) { int len = (int)(m-buf); char *hold = new char[len]; memcpy(hold, buf, len); *this << (len+1); memcpy(end+1, hold, len); delete [] hold; end[len+1] = 0; } return (m) ? end+1 : 0; } // safe. we know we don't actually realloc and shrink buffer when shifting, so we can place our return val at end.
458 
459  // this could be nicer, like replacing a contiguous series of target bytes with single replacement; offering replacement const char *
467  inline SWBuf &replaceBytes(const char *targets, char newByte) {
468  for (unsigned int i = 0; (i < size()); i++) {
469  if (strchr(targets, buf[i])) {
470  if (newByte) buf[i] = newByte;
471  // delete byte
472  else {
473  if (i < (size()-1)) {
474  memmove(buf+i, buf+i+1, length()-i-1);
475  }
476  (*this)-=1;
477  }
478  }
479  }
480  return *this;
481  }
482 
486  inline bool startsWith(const SWBuf &prefix) const { return !strncmp(c_str(), prefix.c_str(), prefix.size()); }
491  SWBuf &toUpper();
496  SWBuf &toLower();
497 
501  inline bool endsWith(const SWBuf &postfix) const { return (size() >= postfix.size())?!strncmp(end-postfix.size(), postfix.c_str(), postfix.size()):false; }
502 
506  inline long indexOf(const SWBuf &needle) const { const char *ch = strstr(buf, needle.c_str()); return (ch) ? ch - buf : -1; }
507 
508  inline int compare(const SWBuf &other) const { return strcmp(c_str(), other.c_str()); }
509  inline bool operator ==(const SWBuf &other) const { return compare(other) == 0; }
510  inline bool operator !=(const SWBuf &other) const { return compare(other) != 0; }
511  inline bool operator > (const SWBuf &other) const { return compare(other) > 0; }
512  inline bool operator < (const SWBuf &other) const { return compare(other) < 0; }
513  inline bool operator <=(const SWBuf &other) const { return compare(other) <= 0; }
514  inline bool operator >=(const SWBuf &other) const { return compare(other) >= 0; }
515 
519  inline bool startsWith(const char *prefix) const { return !strncmp(c_str(), prefix, strlen(prefix)); }
520 
524  inline bool endsWith(const char *postfix) const { unsigned int psize = (unsigned int)strlen(postfix); return (size() >= psize)?!strncmp(end-psize, postfix, psize):false; }
525 
526  // be sure we've been given a valid pointer to compare. If not, we return !=; specifically less-than, for lack of better options
527  inline int compare(const char *other) const { return (other?strcmp(c_str(), other):-1); }
528  inline bool operator ==(const char *other) const { return compare(other) == 0; }
529  inline bool operator !=(const char *other) const { return compare(other) != 0; }
530  inline bool operator > (const char *other) const { return other && compare(other) > 0; }
531  inline bool operator < (const char *other) const { return other && compare(other) < 0; }
532  inline bool operator <=(const char *other) const { return other && compare(other) <= 0; }
533  inline bool operator >=(const char *other) const { return other && compare(other) >= 0; }
534 };
535 
536 
537 
539 #endif
void setFillByte(char ch)
Definition: swbuf.h:146
char * buf
Definition: swbuf.h:50
#define SWORD_NAMESPACE_START
Definition: defs.h:39
SWBuf & append(const unsigned char ch)
Definition: swbuf.h:305
char & operator[](unsigned long pos)
Definition: swbuf.h:382
Definition: swbuf.h:47
unsigned long length() const
Definition: swbuf.h:197
int pos
Definition: regex.c:5534
#define SWDLLEXPORT
Definition: defs.h:171
char & charAt(unsigned long pos)
Definition: swbuf.h:168
SWBuf & trimStart()
Definition: swbuf.h:433
char * end
Definition: swbuf.h:51
SWBuf & trimEnd()
Definition: swbuf.h:438
size_t length
Definition: regex.c:7928
bool startsWith(const SWBuf &prefix) const
Definition: swbuf.h:486
void assureMore(size_t pastEnd)
Definition: swbuf.h:56
void size(unsigned long newSize)
Definition: swbuf.h:192
void resize(unsigned long len)
Definition: swbuf.h:266
SWBuf(char initVal, unsigned long initSize=0)
Definition: swbuf.h:123
void insert(unsigned long pos, const SWBuf &str, unsigned long start=0, signed long max=-1)
Definition: swbuf.h:360
bool endsWith(const SWBuf &postfix) const
Definition: swbuf.h:501
void set(const char *newVal, unsigned long maxSize=0)
Definition: swbuf.h:216
const char & operator[](unsigned long pos) const
Definition: swbuf.h:386
const char & charAt(unsigned long pos) const
Definition: swbuf.h:169
SWBuf & append(char ch)
Definition: swbuf.h:299
char * malloc()
void init()
Definition: installmgr.cpp:164
char * getRawData()
Definition: swbuf.h:379
free(preg->fastmap)
const char * c_str() const
Definition: swbuf.h:158
const char & operator[](long pos) const
Definition: swbuf.h:387
SWBuf & append(const char *str, long max=-1)
Definition: swbuf.h:274
char * realloc()
SWBuf & trim()
Definition: swbuf.h:443
void assureSize(size_t checkSize)
Definition: swbuf.h:62
void insert(unsigned long pos, char c)
Definition: swbuf.h:369
SWBuf(const SWBuf &other, unsigned long initSize=0)
Definition: swbuf.h:113
bool endsWith(const char *postfix) const
Definition: swbuf.h:524
SWBuf & append(wchar_t wch)
Definition: swbuf.h:319
void init(size_t initSize)
Definition: swbuf.h:74
SWBuf & replaceBytes(const char *targets, char newByte)
Definition: swbuf.h:467
unsigned long size() const
Definition: swbuf.h:185
const char * stripPrefix(char separator, bool endOfStringAsSeparator=false)
Definition: swbuf.h:457
SWBuf()
Definition: swbuf.h:93
bool startsWith(const char *prefix) const
Definition: swbuf.h:519
SWBuf & append(const SWBuf &str, long max=-1)
Definition: swbuf.h:292
int size
Definition: regex.c:5043
~SWBuf()
Definition: swbuf.h:135
char & charAtGuarded(unsigned long pos)
Definition: swbuf.h:165
char getFillByte()
Definition: swbuf.h:153
SWBuf(const char *initVal, unsigned long initSize=0)
Definition: swbuf.h:102
char fillByte
Definition: swbuf.h:53
void set(const SWBuf &newVal)
Definition: swbuf.h:204
#define SWORD_NAMESPACE_END
Definition: defs.h:40
char & operator[](unsigned int pos)
Definition: swbuf.h:384
long indexOf(const SWBuf &needle) const
Definition: swbuf.h:506
char & operator[](long pos)
Definition: swbuf.h:383
bool toUpper
Definition: imp2gbs.cpp:57
static char * nullStr
Definition: swbuf.h:87
char & operator[](int pos)
Definition: swbuf.h:385
int compare(const char *other) const
Definition: swbuf.h:527
const char & operator[](int pos) const
Definition: swbuf.h:389
const char & operator[](unsigned int pos) const
Definition: swbuf.h:388
void setSize(unsigned long len)
Definition: swbuf.h:255
int compare(const SWBuf &other) const
Definition: swbuf.h:508
unsigned long allocSize
Definition: swbuf.h:54
char * endAlloc
Definition: swbuf.h:52