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