1 /*
2  *
3  *  C++ Portable Types Library (PTypes)
4  *  Version 2.1.1  Released 27-Jun-2007
5  *
6  *  Copyright (C) 2001-2007 Hovik Melikyan
7  *
8  *  http://www.melikyan.com/ptypes/
9  *
10  */
11 
12 #include <stdlib.h>
13 #include <string.h>
14 #include <limits.h>  // for INT_MAX
15 
16 #include "ptypes.h"
17 
18 
19 PTYPES_BEGIN
20 
21 
initialize(const char * s1,int len1,const char * s2,int len2)22 void string::initialize(const char* s1, int len1, const char* s2, int len2)
23 {
24     if (len1 <= 0)
25         initialize(s2, len2);
26     else if (len2 <= 0)
27         initialize(s1, len1);
28     else
29     {
30         _alloc(len1 + len2);
31         memcpy(data, s1, len1);
32         memcpy(data + len1, s2, len2);
33     }
34 }
35 
36 
concat(string & s,const char * sc,int catlen)37 void ptdecl concat(string& s, const char* sc, int catlen)
38 {
39     if (length(s) == 0)
40         s.assign(sc, catlen);
41     else if (catlen > 0)
42     {
43         int oldlen = length(s);
44 
45         // we must check this before calling setlength(), since
46         // the buffer pointer may be changed during reallocation
47         if (s.data == sc)
48         {
49             setlength(s, oldlen + catlen);
50             memmove(s.data + oldlen, s.data, catlen);
51         }
52         else
53         {
54             setlength(s, oldlen + catlen);
55             memmove(s.data + oldlen, sc, catlen);
56         }
57     }
58 }
59 
60 
concat(string & s,const char * sc)61 void ptdecl concat(string& s, const char* sc)
62 {
63     concat(s, sc, hstrlen(sc));
64 }
65 
66 
concat(string & s,char c)67 void ptdecl concat(string& s, char c)
68 {
69     if (length(s) == 0)
70         s.assign(c);
71     else
72     {
73         setlength(s, length(s) + 1);
74         s.data[length(s) - 1] = c;
75     }
76 }
77 
78 
concat(string & s,const string & s1)79 void ptdecl concat(string& s, const string& s1)
80 {
81     if (length(s) == 0)
82         s = s1;
83     else if (length(s1) > 0)
84         concat(s, s1.data, length(s1));
85 }
86 
87 
contains(const char * s1,int s1len,const string & s,int at)88 bool ptdecl contains(const char* s1, int s1len, const string& s, int at)
89 {
90     return (s1len >= 0) && (at >= 0) && (at + s1len <= length(s))
91         && (s1len == 0 || memcmp(s.data + at, s1, s1len) == 0);
92 }
93 
94 
contains(const char * s1,const string & s,int at)95 bool ptdecl contains(const char* s1, const string& s, int at)
96 {
97     return contains(s1, hstrlen(s1), s, at);
98 }
99 
100 
contains(char s1,const string & s,int at)101 bool ptdecl contains(char s1, const string& s, int at)
102 {
103     return (at >= 0) && (at < length(s)) && (s.data[at] == s1);
104 }
105 
106 
contains(const string & s1,const string & s,int at)107 bool ptdecl contains(const string& s1, const string& s, int at)
108 {
109     return contains(s1.data, length(s1), s, at);
110 }
111 
112 
operator +(const char * sc) const113 string string::operator+ (const char* sc) const
114 {
115     if (length(*this) == 0)
116         return string(sc);
117     else
118         return string(data, length(*this), sc, hstrlen(sc));
119 }
120 
121 
operator +(char c) const122 string string::operator+ (char c) const
123 {
124     if (length(*this) == 0)
125         return string(c);
126     else
127         return string(data, length(*this), &c, 1);
128 }
129 
130 
operator +(const string & s) const131 string string::operator+ (const string& s) const
132 {
133     if (length(*this) == 0)
134         return s;
135     else if (length(s) == 0)
136         return *this;
137     else
138         return string(data, length(*this), s.data, length(s));
139 }
140 
141 
operator +(const char * sc,const string & s)142 string ptdecl operator+ (const char* sc, const string& s)
143 {
144     if (length(s) == 0)
145         return string(sc);
146     else
147         return string(sc, hstrlen(sc), s.data, length(s));
148 }
149 
150 
operator +(char c,const string & s)151 string ptdecl operator+ (char c, const string& s)
152 {
153     if (length(s) == 0)
154         return string(c);
155     else
156         return string(&c, 1, s.data, length(s));
157 }
158 
159 
operator ==(const string & s) const160 bool string::operator== (const string& s) const
161 {
162     return (length(*this) == length(s))
163         && ((length(*this) == 0) || (memcmp(data, s.data, length(*this)) == 0));
164 }
165 
166 
operator ==(char c) const167 bool string::operator== (char c) const
168 {
169     return (length(*this) == 1) && (data[0] == c);
170 }
171 
172 
copy(const string & s,int from,int cnt)173 string ptdecl copy(const string& s, int from, int cnt)
174 {
175     string t;
176     if (length(s) > 0 && from >= 0 && from < length(s))
177     {
178         int l = imin(cnt, length(s) - from);
179         if (from == 0 && l == length(s))
180             t = s;
181         else if (l > 0)
182         {
183             t._alloc(l);
184             memmove(t.data, s.data + from, l);
185             t.data[l] = 0;
186         }
187     }
188     return t;
189 }
190 
191 
copy(const string & s,int from)192 string ptdecl copy(const string& s, int from)
193 {
194     return copy(s, from, INT_MAX);
195 }
196 
197 
ins(const char * s1,int s1len,string & s,int at)198 void ptdecl ins(const char* s1, int s1len, string& s, int at)
199 {
200     int curlen = length(s);
201     if (s1len > 0 && at >= 0 && at <= curlen)
202     {
203         if (curlen == 0)
204             s.assign(s1, s1len);
205         else
206         {
207             setlength(s, curlen + s1len);
208             int t = length(s) - at - s1len;
209             char* p = s.data + at;
210             if (t > 0)
211                 memmove(p + s1len, p, t);
212             memmove(p, s1, s1len);
213         }
214     }
215 }
216 
217 
ins(const char * sc,string & s,int at)218 void ptdecl ins(const char* sc, string& s, int at)
219 {
220     ins(sc, hstrlen(sc), s, at);
221 }
222 
223 
ins(char c,string & s,int at)224 void ptdecl ins(char c, string& s, int at)
225 {
226     ins(&c, 1, s, at);
227 }
228 
229 
ins(const string & s1,string & s,int at)230 void ptdecl ins(const string& s1, string& s, int at)
231 {
232     ins(s1.data, length(s1), s, at);
233 }
234 
235 
del(string & s,int from,int cnt)236 void ptdecl del(string& s, int from, int cnt)
237 {
238     int l = length(s);
239     int d = l - from;
240     if (from >= 0 && d > 0 && cnt > 0)
241     {
242         if (cnt < d)
243         {
244             unique(s);
245             memmove(s.data + from, s.data + from + cnt, d - cnt);
246         }
247         else
248             cnt = d;
249         setlength(s, l - cnt);
250     }
251 }
252 
253 
del(string & s,int from)254 void ptdecl del(string& s, int from)
255 {
256     setlength(s, from);
257 }
258 
259 
pos(const char * sc,const string & s)260 int ptdecl pos(const char* sc, const string& s)
261 {
262     const char* t = (char*)strstr(s.data, sc);
263     return (t == NULL ? (-1) : (t - s.data));
264 }
265 
266 
pos(char c,const string & s)267 int ptdecl pos(char c, const string& s)
268 {
269     const char* t = (char*)strchr(s.data, c);
270     return (t == NULL ? (-1) : (t - s.data));
271 }
272 
273 
rpos(char c,const string & s)274 int ptdecl rpos(char c, const string& s)
275 {
276     const char* t = (char*)strrchr(s.data, c);
277     return (t == NULL ? (-1) : (t - s.data));
278 }
279 
280 
281 PTYPES_END
282