source: cpp/frams/util/sstring-simple.cpp @ 793

Last change on this file since 793 was 793, checked in by Maciej Komosinski, 6 years ago

Code formatting

  • Property svn:eol-style set to native
File size: 5.1 KB
Line 
1#include "sstring.h"
2#include <common/nonstd_stl.h>
3#include "extvalue.h"
4#include <assert.h>
5
6void SString::initEmpty()
7{
8        txt = NULL; used = 0; size = 0;
9}
10
11SString::SString()
12{
13        initEmpty();
14}
15
16SString::~SString()
17{
18        resize(0);
19}
20
21SString::SString(int x)
22{
23        initEmpty();
24        if (x)
25                ensureSize(x + 1);
26}
27
28SString::SString(const char *t, int t_len)
29{
30        initEmpty();
31        if (!t) return;
32        copyFrom(t, t_len);
33}
34
35SString::SString(const SString &from)
36{
37        initEmpty();
38        operator=(from);
39}
40
41SString::SString(SString&& from)
42{
43        txt = from.txt; size = from.size; used = from.used;
44        from.txt = NULL; from.size = 0; from.used = 0;
45}
46
47void SString::resize(int newsize)
48{
49        if (newsize == size) return;
50        txt = (char*)realloc(txt, newsize);
51        size = newsize;
52}
53
54void SString::ensureSize(int needed)
55{
56        if (size > needed) return;
57        resize((size > 0) ? (needed + needed / 2 + 1) : (needed + 1));
58}
59
60char *SString::directWrite(int ensuresize)
61{
62        ensureSize(ensuresize);
63        appending = used;
64        return txt;
65}
66
67char *SString::directAppend(int maxappend)
68{
69        ensureSize(used + maxappend);
70        appending = used;
71        return txt + appending;
72}
73
74void SString::endWrite(int newlength)
75{
76        if (newlength < 0) newlength = strlen(txt);
77        else txt[newlength] = 0;
78        used = newlength;
79        assert(used < size);
80}
81
82void SString::endAppend(int newappend)
83{
84        if (newappend < 0) newappend = strlen(txt + appending);
85        else txt[appending + newappend] = 0;
86        used = appending + newappend;
87        assert(used < size);
88}
89
90////////////// append /////////////////
91
92void SString::operator+=(const char *s)
93{
94        if (!s) return;
95        int x = strlen(s);
96        if (!x) return;
97        append(s, x);
98}
99
100void SString::append(const char *t, int n)
101{
102        if (!n) return;
103        ensureSize(used + n);
104        memmove(txt + used, t, n);
105        used += n;
106        txt[used] = 0;
107}
108
109void SString::operator+=(const SString&s)
110{
111        append(s.c_str(), s.len());
112}
113
114SString SString::operator+(const SString& s) const
115{
116        SString ret(len() + s.len());
117        ret = *this;
118        ret += s;
119        return ret;
120}
121
122/////////////////////////////
123
124void SString::copyFrom(const char *ch, int chlen)
125{
126        if (!ch) chlen = 0;
127        else if (chlen < 0) chlen = strlen(ch);
128        if (chlen)
129        {
130                ensureSize(chlen);
131                memmove(txt, ch, chlen);
132                txt[chlen] = 0;
133                used = chlen;
134        }
135        else
136        {
137                if (txt)
138                {
139                        txt[0] = 0;
140                        used = 0;
141                }
142        }
143}
144
145void SString::operator=(const char *ch)
146{
147        copyFrom(ch);
148}
149
150void SString::operator=(const SString&s)
151{
152        if (&s == this) return;
153        copyFrom(s.c_str(), s.len());
154}
155
156///////////////////////////////////////
157
158SString SString::substr(int begin, int length) const
159{
160        if (begin < 0) { length += begin; begin = 0; }
161        if (length >= (len() - begin)) length = len() - begin;
162        if (length <= 0) return SString();
163        if (length == len()) return *this;
164        return SString((*this)(begin), length);
165}
166
167///////////////////////////////////////
168
169bool SString::equals(const SString& s) const
170{
171        if (this == &s) return true;
172        if (len() != s.len()) return false;
173        return strcmp(getPtr(), s.getPtr()) == 0;
174}
175
176///////////////////////////////////////
177
178int SString::indexOf(int character, int start) const
179{
180        const char *found = strchr(getPtr() + start, character);
181        return found ? found - getPtr() : -1;
182}
183
184int SString::indexOf(const char *substring, int start) const
185{
186        const char *found = strstr(getPtr() + start, substring);
187        return found ? found - getPtr() : -1;
188}
189
190int SString::indexOf(const SString & substring, int start) const
191{
192        const char *found = strstr(getPtr() + start, substring.c_str());
193        return found ? found - getPtr() : -1;
194}
195
196bool SString::getNextToken(int& pos, SString &token, char separator) const
197{
198        if (pos >= len()) { token = 0; return false; }
199        int p1 = pos, p2;
200        const char *t1 = getPtr() + pos;
201        const char *t2 = strchr(t1, separator);
202        if (t2) pos = (p2 = (t2 - getPtr())) + 1; else p2 = pos = len();
203        strncpy(token.directWrite(p2 - p1), t1, p2 - p1);
204        token.endWrite(p2 - p1);
205        return true;
206}
207
208bool SString::startsWith(const char *pattern) const
209{
210        const char *t = this->c_str();
211        for (; *pattern; pattern++, t++)
212                if (*t != *pattern) return false;
213        return true;
214}
215
216SString SString::valueOf(int i)
217{
218        return SString::sprintf("%d", i);
219}
220SString SString::valueOf(long i)
221{
222        return SString::sprintf("%d", i);
223}
224SString SString::valueOf(double d)
225{
226        SString tmp = SString::sprintf("%.15g", d);
227        if ((!strchr(tmp.c_str(), '.')) && (!strchr(tmp.c_str(), 'e'))) tmp += ".0";
228        return tmp;
229}
230SString SString::valueOf(const SString& s)
231{
232        return s;
233}
234
235SString SString::sprintf(const char* format, ...)
236{
237        int n, size = 30;
238        va_list ap;
239
240        SString ret;
241
242#ifdef USE_VSCPRINTF
243        va_start(ap, format);
244        size = _vscprintf(format, ap);
245        va_end(ap);
246#endif
247
248        while (1)
249        {
250                char* p = ret.directWrite(size);
251                assert(p != NULL);
252                size = ret.directMaxLen() + 1;
253                /* Try to print in the allocated space. */
254                va_start(ap, format);
255                n = vsnprintf(p, size, format, ap);
256                va_end(ap);
257                /* If that worked, return the string. */
258                if (n > -1 && n < size)
259                {
260                        ret.endWrite(n);
261                        return ret;
262                }
263                /* Else try again with more space. */
264#ifdef VSNPRINTF_RETURNS_REQUIRED_SIZE
265                if (n > -1)    /* glibc 2.1 */
266                        size = n; /* precisely what is needed */
267                else           /* glibc 2.0 */
268#endif
269                        size *= 2;  /* twice the old size */
270        }
271}
272
273SString &SString::empty()
274{
275        static SString empty;
276        return empty;
277}
Note: See TracBrowser for help on using the repository browser.