added gfxmatrix_transform()
[swftools.git] / pdf2swf / xpdf / 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     if (length1 < length) {
39       memcpy(s1, s, length1);
40       s1[length1] = '\0';
41     } else {
42       memcpy(s1, s, length + 1);
43     }
44     delete[] s;
45     s = s1;
46   }
47 }
48
49 GString::GString() {
50   s = NULL;
51   resize(length = 0);
52   s[0] = '\0';
53 }
54
55 GString::GString(const char *sA) {
56   int n = strlen(sA);
57
58   s = NULL;
59   resize(length = n);
60   memcpy(s, sA, n + 1);
61 }
62
63 GString::GString(const char *sA, int lengthA) {
64   s = NULL;
65   resize(length = lengthA);
66   memcpy(s, sA, length * sizeof(char));
67   s[length] = '\0';
68 }
69
70 GString::GString(GString *str, int idx, int lengthA) {
71   s = NULL;
72   resize(length = lengthA);
73   memcpy(s, str->getCString() + idx, length);
74   s[length] = '\0';
75 }
76
77 GString::GString(GString *str) {
78   s = NULL;
79   resize(length = str->getLength());
80   memcpy(s, str->getCString(), length + 1);
81 }
82
83 GString::GString(GString *str1, GString *str2) {
84   int n1 = str1->getLength();
85   int n2 = str2->getLength();
86
87   s = NULL;
88   resize(length = n1 + n2);
89   memcpy(s, str1->getCString(), n1);
90   memcpy(s + n1, str2->getCString(), n2 + 1);
91 }
92
93 GString *GString::fromInt(int x) {
94   char buf[24]; // enough space for 64-bit ints plus a little extra
95   GBool neg;
96   Guint y;
97   int i;
98
99   i = 24;
100   if (x == 0) {
101     buf[--i] = '0';
102   } else {
103     if ((neg = x < 0)) {
104       y = (Guint)-x;
105     } else {
106       y = (Guint)x;
107     }
108     while (i > 0 && y > 0) {
109       buf[--i] = '0' + y % 10;
110       y /= 10;
111     }
112     if (neg && i > 0) {
113       buf[--i] = '-';
114     }
115   }
116   return new GString(buf + i, 24 - i);
117 }
118
119 GString::~GString() {
120   delete[] s;
121 }
122
123 GString *GString::clear() {
124   s[length = 0] = '\0';
125   resize(0);
126   return this;
127 }
128
129 GString *GString::append(char c) {
130   resize(length + 1);
131   s[length++] = c;
132   s[length] = '\0';
133   return this;
134 }
135
136 GString *GString::append(GString *str) {
137   int n = str->getLength();
138
139   resize(length + n);
140   memcpy(s + length, str->getCString(), n + 1);
141   length += n;
142   return this;
143 }
144
145 GString *GString::append(const char *str) {
146   int n = strlen(str);
147
148   resize(length + n);
149   memcpy(s + length, str, n + 1);
150   length += n;
151   return this;
152 }
153
154 GString *GString::append(const char *str, int lengthA) {
155   resize(length + lengthA);
156   memcpy(s + length, str, lengthA);
157   length += lengthA;
158   s[length] = '\0';
159   return this;
160 }
161
162 GString *GString::insert(int i, char c) {
163   int j;
164
165   resize(length + 1);
166   for (j = length + 1; j > i; --j)
167     s[j] = s[j-1];
168   s[i] = c;
169   ++length;
170   return this;
171 }
172
173 GString *GString::insert(int i, GString *str) {
174   int n = str->getLength();
175   int j;
176
177   resize(length + n);
178   for (j = length; j >= i; --j)
179     s[j+n] = s[j];
180   memcpy(s+i, str->getCString(), n);
181   length += n;
182   return this;
183 }
184
185 GString *GString::insert(int i, const char *str) {
186   int n = strlen(str);
187   int j;
188
189   resize(length + n);
190   for (j = length; j >= i; --j)
191     s[j+n] = s[j];
192   memcpy(s+i, str, n);
193   length += n;
194   return this;
195 }
196
197 GString *GString::insert(int i, const char *str, int lengthA) {
198   int j;
199
200   resize(length + lengthA);
201   for (j = length; j >= i; --j)
202     s[j+lengthA] = s[j];
203   memcpy(s+i, str, lengthA);
204   length += lengthA;
205   return this;
206 }
207
208 GString *GString::del(int i, int n) {
209   int j;
210
211   if (n > 0) {
212     if (i + n > length) {
213       n = length - i;
214     }
215     for (j = i; j <= length - n; ++j) {
216       s[j] = s[j + n];
217     }
218     resize(length -= n);
219   }
220   return this;
221 }
222
223 GString *GString::upperCase() {
224   int i;
225
226   for (i = 0; i < length; ++i) {
227     if (islower(s[i]))
228       s[i] = toupper(s[i]);
229   }
230   return this;
231 }
232
233 GString *GString::lowerCase() {
234   int i;
235
236   for (i = 0; i < length; ++i) {
237     if (isupper(s[i]))
238       s[i] = tolower(s[i]);
239   }
240   return this;
241 }
242
243 int GString::cmp(GString *str) {
244   int n1, n2, i, x;
245   char *p1, *p2;
246
247   n1 = length;
248   n2 = str->length;
249   for (i = 0, p1 = s, p2 = str->s; i < n1 && i < n2; ++i, ++p1, ++p2) {
250     x = *p1 - *p2;
251     if (x != 0) {
252       return x;
253     }
254   }
255   return n1 - n2;
256 }
257
258 int GString::cmpN(GString *str, int n) {
259   int n1, n2, i, x;
260   char *p1, *p2;
261
262   n1 = length;
263   n2 = str->length;
264   for (i = 0, p1 = s, p2 = str->s;
265        i < n1 && i < n2 && i < n;
266        ++i, ++p1, ++p2) {
267     x = *p1 - *p2;
268     if (x != 0) {
269       return x;
270     }
271   }
272   if (i == n) {
273     return 0;
274   }
275   return n1 - n2;
276 }
277
278 int GString::cmp(const char *sA) {
279   int n1, i, x;
280   const char *p1, *p2;
281
282   n1 = length;
283   for (i = 0, p1 = s, p2 = sA; i < n1 && *p2; ++i, ++p1, ++p2) {
284     x = *p1 - *p2;
285     if (x != 0) {
286       return x;
287     }
288   }
289   if (i < n1) {
290     return 1;
291   }
292   if (*p2) {
293     return -1;
294   }
295   return 0;
296 }
297
298 int GString::cmpN(const char *sA, int n) {
299   int n1, i, x;
300   const char *p1, *p2;
301
302   n1 = length;
303   for (i = 0, p1 = s, p2 = sA; i < n1 && *p2 && i < n; ++i, ++p1, ++p2) {
304     x = *p1 - *p2;
305     if (x != 0) {
306       return x;
307     }
308   }
309   if (i == n) {
310     return 0;
311   }
312   if (i < n1) {
313     return 1;
314   }
315   if (*p2) {
316     return -1;
317   }
318   return 0;
319 }