7653fd06e3e6b1dd2d1ed30f6321dba2e069a22b
[swftools.git] / GString.cc
1 //========================================================================
2 //
3 // GString.cc
4 //
5 // Simple variable-length string type.
6 //
7 // Copyright 1996-2003 Glyph & Cog, LLC
8 //
9 //========================================================================
10
11 #include <aconf.h>
12
13 #ifdef USE_GCC_PRAGMAS
14 #pragma implementation
15 #endif
16
17 #include <stdlib.h>
18 #include <stddef.h>
19 #include <string.h>
20 #include <ctype.h>
21 #include "gtypes.h"
22 #include "GString.h"
23
24 static inline int size(int len) {
25   int delta;
26
27   delta = len < 256 ? 7 : 255;
28   return ((len + 1) + delta) & ~delta;
29 }
30
31 inline void GString::resize(int length1) {
32   char *s1;
33
34   if (!s) {
35     s = new char[size(length1)];
36   } else if (size(length1) != size(length)) {
37     s1 = new char[size(length1)];
38     memcpy(s1, s, length + 1);
39     delete[] s;
40     s = s1;
41   }
42 }
43
44 GString::GString() {
45   s = NULL;
46   resize(length = 0);
47   s[0] = '\0';
48 }
49
50 GString::GString(const char *sA) {
51   int n = strlen(sA);
52
53   s = NULL;
54   resize(length = n);
55   memcpy(s, sA, n + 1);
56 }
57
58 GString::GString(const char *sA, int lengthA) {
59   s = NULL;
60   resize(length = lengthA);
61   memcpy(s, sA, length * sizeof(char));
62   s[length] = '\0';
63 }
64
65 GString::GString(GString *str, int idx, int lengthA) {
66   s = NULL;
67   resize(length = lengthA);
68   memcpy(s, str->getCString() + idx, length);
69   s[length] = '\0';
70 }
71
72 GString::GString(GString *str) {
73   s = NULL;
74   resize(length = str->getLength());
75   memcpy(s, str->getCString(), length + 1);
76 }
77
78 GString::GString(GString *str1, GString *str2) {
79   int n1 = str1->getLength();
80   int n2 = str2->getLength();
81
82   s = NULL;
83   resize(length = n1 + n2);
84   memcpy(s, str1->getCString(), n1);
85   memcpy(s + n1, str2->getCString(), n2 + 1);
86 }
87
88 GString *GString::fromInt(int x) {
89   char buf[24]; // enough space for 64-bit ints plus a little extra
90   GBool neg;
91   Guint y;
92   int i;
93
94   i = 24;
95   if (x == 0) {
96     buf[--i] = '0';
97   } else {
98     if ((neg = x < 0)) {
99       y = (Guint)-x;
100     } else {
101       y = (Guint)x;
102     }
103     while (i > 0 && y > 0) {
104       buf[--i] = '0' + y % 10;
105       y /= 10;
106     }
107     if (neg && i > 0) {
108       buf[--i] = '-';
109     }
110   }
111   return new GString(buf + i, 24 - i);
112 }
113
114 GString::~GString() {
115   delete[] s;
116 }
117
118 GString *GString::clear() {
119   s[length = 0] = '\0';
120   resize(0);
121   return this;
122 }
123
124 GString *GString::append(char c) {
125   resize(length + 1);
126   s[length++] = c;
127   s[length] = '\0';
128   return this;
129 }
130
131 GString *GString::append(GString *str) {
132   int n = str->getLength();
133
134   resize(length + n);
135   memcpy(s + length, str->getCString(), n + 1);
136   length += n;
137   return this;
138 }
139
140 GString *GString::append(const char *str) {
141   int n = strlen(str);
142
143   resize(length + n);
144   memcpy(s + length, str, n + 1);
145   length += n;
146   return this;
147 }
148
149 GString *GString::append(const char *str, int lengthA) {
150   resize(length + lengthA);
151   memcpy(s + length, str, lengthA);
152   length += lengthA;
153   s[length] = '\0';
154   return this;
155 }
156
157 GString *GString::insert(int i, char c) {
158   int j;
159
160   resize(length + 1);
161   for (j = length + 1; j > i; --j)
162     s[j] = s[j-1];
163   s[i] = c;
164   ++length;
165   return this;
166 }
167
168 GString *GString::insert(int i, GString *str) {
169   int n = str->getLength();
170   int j;
171
172   resize(length + n);
173   for (j = length; j >= i; --j)
174     s[j+n] = s[j];
175   memcpy(s+i, str->getCString(), n);
176   length += n;
177   return this;
178 }
179
180 GString *GString::insert(int i, const char *str) {
181   int n = strlen(str);
182   int j;
183
184   resize(length + n);
185   for (j = length; j >= i; --j)
186     s[j+n] = s[j];
187   memcpy(s+i, str, n);
188   length += n;
189   return this;
190 }
191
192 GString *GString::insert(int i, const char *str, int lengthA) {
193   int j;
194
195   resize(length + lengthA);
196   for (j = length; j >= i; --j)
197     s[j+lengthA] = s[j];
198   memcpy(s+i, str, lengthA);
199   length += lengthA;
200   return this;
201 }
202
203 GString *GString::del(int i, int n) {
204   int j;
205
206   if (n > 0) {
207     if (i + n > length) {
208       n = length - i;
209     }
210     for (j = i; j <= length - n; ++j) {
211       s[j] = s[j + n];
212     }
213     resize(length -= n);
214   }
215   return this;
216 }
217
218 GString *GString::upperCase() {
219   int i;
220
221   for (i = 0; i < length; ++i) {
222     if (islower(s[i]))
223       s[i] = toupper(s[i]);
224   }
225   return this;
226 }
227
228 GString *GString::lowerCase() {
229   int i;
230
231   for (i = 0; i < length; ++i) {
232     if (isupper(s[i]))
233       s[i] = tolower(s[i]);
234   }
235   return this;
236 }