source: cpp/gdk/sstring.cpp @ 97

Last change on this file since 97 was 92, checked in by Maciej Komosinski, 11 years ago

SString::valueOf(value) can handle more argument types

  • Property svn:eol-style set to native
File size: 6.0 KB
Line 
1// This file is a part of the Framsticks GDK library.
2// Copyright (C) 2002-2011  Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.framsticks.com/ for further information.
4
5
6#include "sstring.h"
7#include "nonstd_stl.h"
8#include "extvalue.h"
9
10static int guessMemSize(int request, int memhint)
11{
12if (memhint>=0)
13        return request+memhint;
14else
15        return request+min(request/2,10000)+8;
16}
17
18SBuf::SBuf()
19{
20txt="";
21size=used=0;
22refcount=1;
23}
24
25SBuf::SBuf(int initsize, int memhint)
26{
27size=guessMemSize(initsize,memhint);
28if (size>0)     { txt=(char*)malloc(size+1); txt[0]=0; }
29        else    txt="";
30used=0;
31refcount=1;
32}
33
34SBuf::~SBuf()
35{
36freeBuf();
37}
38
39void SBuf::initEmpty()
40{
41txt="";
42used=size=0;
43refcount=1;
44}
45
46void SBuf::freeBuf()
47{
48if (!size) return;
49free(txt); used=0;
50}
51
52void SBuf::copyFrom(const char *ch,int chlen,int memhint)
53{
54if (chlen==-1) chlen=strlen(ch);
55if (chlen>0)
56{
57if (chlen<size)
58        {
59        memcpy(txt,ch,chlen);
60        }
61else
62        {
63        size=guessMemSize(chlen,memhint);
64        char *newtxt=(char*)malloc(size+1);
65        memcpy(newtxt,ch,chlen);
66        free(txt);
67        txt=newtxt;
68        }
69}
70txt[chlen]=0;
71used=chlen;
72}
73
74void SBuf::append(const char *ch,int chlen)
75{ // doesn't check anything!
76memcpy(txt+used,ch,chlen);
77used+=chlen;
78txt[used]=0;
79}
80
81void SBuf::ensureSize(int needed, int memhint)
82{
83if (size>=needed) return;
84needed=guessMemSize(needed,memhint);
85txt=(char*)realloc(txt,needed+1);
86size=needed;
87}
88
89/////////////////////////////////////////////
90
91SString::SString()
92{
93initEmpty();
94}
95
96SString::~SString()
97{
98detach();
99}
100
101SString::SString(int x)
102{
103buf=new SBuf(x);
104}
105
106SString::SString(const char *t,int t_len)
107{
108initEmpty();
109if (!t) return;
110copyFrom(t,t_len);
111}
112
113SString::SString(const SString &from)
114{
115buf=from.buf;
116if (buf->size) buf->refcount++;
117memhint=-1;
118}
119
120void SString::initEmpty()
121{
122buf=&SBuf::empty();
123memhint=-1;
124}
125
126void SString::memoryHint(int howbig)
127{
128memhint=howbig;
129}
130       
131void SString::detachEmpty(int ensuresize)
132{
133if (buf==&SBuf::empty()) { buf=new SBuf(ensuresize,memhint); return; }
134if (buf->refcount<2) buf->ensureSize(ensuresize,memhint);
135else
136        {
137        buf->refcount--;
138        buf=new SBuf(ensuresize,memhint);
139        }
140}
141
142void SString::detach()
143{
144if (buf==&SBuf::empty()) return;
145if (!--buf->refcount) delete buf;
146}
147
148void SString::detachCopy(int ensuresize)
149{
150if (buf==&SBuf::empty()) { buf=new SBuf(ensuresize,memhint); return; }
151if (buf->refcount<2)
152        {
153        buf->ensureSize(ensuresize,memhint);
154        return;
155        }
156buf->refcount--;
157SBuf *newbuf=new SBuf(ensuresize,memhint);
158newbuf->copyFrom(buf->txt,min(ensuresize,buf->used),memhint);
159buf=newbuf;
160}
161
162char *SString::directWrite(int ensuresize)
163{
164if (ensuresize<0) ensuresize=len();
165detachCopy(ensuresize);
166appending=buf->used;
167return buf->txt;
168}
169
170/*
171char *SString::directWrite()
172{
173return directWrite(buf->used);
174}
175*/
176char *SString::directAppend(int maxappend)
177{
178detachCopy(buf->used+maxappend);
179appending=buf->used;
180return buf->txt+appending;
181}
182
183void SString::endWrite(int newlength)
184{
185if (newlength<0) newlength=strlen(buf->txt);
186else buf->txt[newlength]=0;
187buf->used=newlength;
188}
189
190void SString::endAppend(int newappend)
191{
192if (newappend<0) newappend=strlen(buf->txt+appending);
193else buf->txt[appending+newappend]=0;
194buf->used=appending+newappend;
195}
196
197////////////// append /////////////////
198
199void SString::operator+=(const char *s)
200{
201if (!s) return;
202int x=strlen(s);
203if (!x) return;
204append(s,x);
205}
206
207void SString::append(const char *txt,int count)
208{
209if (!count) return;
210detachCopy(buf->used+count);
211buf->append(txt,count);
212}
213
214void SString::operator+=(const SString&s)
215{
216append((const char*)s,s.len());
217}
218
219SString SString::operator+(const SString& s) const
220{
221SString ret(*this);
222ret+=s;
223return ret;
224}
225
226/////////////////////////////
227
228void SString::copyFrom(const char *ch,int chlen)
229{
230if (!ch) chlen=0;
231else if (chlen<0) chlen=strlen(ch);
232detachEmpty(chlen);
233memcpy(buf->txt,ch,chlen);
234buf->txt[chlen]=0; buf->used=chlen;
235}
236
237void SString::operator=(const char *ch)
238{
239copyFrom(ch);
240}
241
242void SString::operator=(const SString&s)
243{
244if (s.buf==buf) return;
245detach();
246buf=s.buf;
247if (buf->size) buf->refcount++;
248}
249///////////////////////////////////////
250
251SString SString::substr(int begin, int length) const
252{
253if (begin<0) { length+=begin; begin=0; }
254if (length>=(len()-begin)) length=len()-begin;
255if (length<=0) return SString();
256if (length==len()) return *this;
257return SString((*this)(begin),length);
258}
259
260///////////////////////////////////////
261
262int SString::equals(const SString& s) const
263{
264if (s.buf==buf) return 1;
265return !strcmp(buf->txt,s.buf->txt);
266}
267
268///////////////////////////////////////
269
270int SString::indexOf(int character,int start) const
271{
272const char *found=strchr(buf->txt+start,character);
273return found?found-buf->txt:-1;
274}
275
276int SString::indexOf(const char *substring,int start) const
277{
278char *found=strstr(buf->txt+start,substring);
279return found?found-buf->txt:-1;
280}
281
282int SString::indexOf(const SString & substring,int start) const
283{
284char *found=strstr(buf->txt+start,((const char*)substring));
285return found?found-buf->txt:-1;
286}
287
288int SString::getNextToken (int& pos,SString &token,char separator) const
289{
290if (pos>=len()) {token=0;return 0;}
291int p1=pos,p2;
292const char *t1=buf->txt+pos;
293const char *t2=strchr(t1,separator);
294if (t2) pos=(p2=(t2-buf->txt))+1; else p2=pos=len();
295strncpy(token.directWrite(p2-p1),t1,p2-p1);
296token.endWrite(p2-p1);
297return 1;
298}
299
300int SString::startsWith(const char *pattern) const
301{
302const char *t=(const char*)(*this);
303for (;*pattern;pattern++,t++)
304        if (*t != *pattern) return 0;
305return 1;
306}
307
308const SString& SString::valueOf(int i)
309{
310static SString t;
311sprintf(t.directWrite(20),"%d",i); t.endWrite();
312return t;
313}
314const SString& SString::valueOf(long i)
315{
316static SString t;
317sprintf(t.directWrite(20),"%d",i); t.endWrite();
318return t;
319}
320const SString& SString::valueOf(double d)
321{
322static SString t;
323sprintf(t.directWrite(20),"%g",d); t.endWrite();
324return t;
325}
326const SString& SString::valueOf(const SString& s)
327{
328return s;
329}
330SString SString::valueOf(const ExtValue& v)
331{
332return v.getString();
333}
334SString SString::valueOf(const ExtObject& v)
335{
336return v.toString();
337}
338
339SString &SString::empty()
340{
341static SString empty;
342return empty;
343}
344
345SBuf &SBuf::empty()
346{
347static SBuf empty;
348return empty;
349}
Note: See TracBrowser for help on using the repository browser.