Delete all Trailing spaces in code.
[reactos.git] / rosapps / smartpdf / poppler / goo / GooString.h
1 //========================================================================
2 //
3 // GooString.h
4 //
5 // Simple variable-length string type.
6 //
7 // Copyright 1996-2003 Glyph & Cog, LLC
8 //
9 //========================================================================
10
11 #ifndef GSTRING_H
12 #define GSTRING_H
13
14 #ifdef USE_GCC_PRAGMAS
15 #pragma interface
16 #endif
17
18 #include <stdlib.h> // for NULL
19 #include "gtypes.h"
20 #include "GooMutex.h"
21
22 class GooString {
23 public:
24
25 // Create an empty string.
26 GooString();
27
28 // Create a string from a C string.
29 GooString(const char *sA);
30
31 // Create a string from <lengthA> chars at <sA>. This string
32 // can contain null characters.
33 GooString(const char *sA, int lengthA);
34
35 // Create a string from <lengthA> chars at <idx> in <str>.
36 GooString(GooString *str, int idx, int lengthA);
37
38 // Set content of a string to concatination of <s1> and <s2>. They can both
39 // be NULL. if <s1Len> or <s2Len> is CALC_STRING_LEN, then length of the string
40 // will be calculated with strlen(). Otherwise we assume they are a valid
41 // length of string (or its substring)
42
43 /* @note: gnu g++ fix */
44 GooString* Set(const char *s1, int s1Len=CALC_STRING_LEN, const char *s2=NULL, int s2Len=CALC_STRING_LEN);
45
46 /* original code line:
47 * GooString* GooString::Set(const char *s1, int s1Len=CALC_STRING_LEN, const char *s2=NULL, int s2Len=CALC_STRING_LEN);
48 */
49
50 GooString(GooString *str);
51
52 // Return a newly allocated copy of the string
53 GooString *copy() { return new GooString(this); }
54
55 // Concatenate two strings.
56 GooString(GooString *str1, GooString *str2);
57
58 // Convert an integer to a string.
59 static GooString *fromInt(int x);
60
61 ~GooString();
62
63 // Get length.
64 int getLength() const { return length; }
65
66 // Get C string.
67 char *getCString() const { return s; }
68
69 // Get <i>th character.
70 char getChar(int i) { return s[i]; }
71
72 // Change <i>th character.
73 void setChar(int i, char c) { s[i] = c; }
74
75 // Clear string to zero length.
76 GooString *clear();
77
78 // Append a character or string.
79 GooString *append(char c);
80 GooString *append(GooString *str);
81 GooString *append(const char *str, int lengthA=CALC_STRING_LEN);
82
83 // Insert a character or string.
84 GooString *insert(int i, char c);
85 GooString *insert(int i, GooString *str);
86 GooString *insert(int i, const char *str, int lengthA=CALC_STRING_LEN);
87
88 // Delete a character or range of characters.
89 GooString *del(int i, int n = 1);
90
91 // Convert string to all-upper/all-lower case.
92 GooString *upperCase();
93 GooString *lowerCase();
94
95 // Compare two strings: -1:< 0:= +1:>
96 int cmp(GooString *str);
97 int cmpN(GooString *str, int n);
98 int cmp(const char *sA);
99 int cmpN(const char *sA, int n);
100
101 GBool hasUnicodeMarker(void);
102
103 // a special value telling that the length of the string is not given
104 // so it must be calculated from the strings
105 static const int CALC_STRING_LEN = -1;
106
107 private:
108 // you can tweak this number for a different speed/memory usage tradeoffs.
109 // In libc malloc() rounding is 16 so it's best to choose a value that
110 // results in sizeof(GooString) be a multiple of 16.
111 // 24 makes sizeof(GooString) to be 32.
112 static const int STR_STATIC_SIZE = 24;
113
114 int roundedSize(int len);
115
116 char sStatic[STR_STATIC_SIZE];
117 int length;
118 char *s;
119
120 void resize(int newLength);
121 };
122
123 //Uncomment if you want to gather stats on hit rate of the cache
124 //#define CALC_OBJECT_STRING_CACHE_STATS 1
125
126 /* A cache for GooString. You can think of it as a custom allocator
127 for GooString(). Use alloc() to get a new GooString() and free() to free
128 existing GooString(). It keeps last GooStringCache::CACHE_SIZE free()ed
129 strings in a cache (which is a stack) and satisfies the alloc()s from
130 the cache first, thus saves free()/malloc() cycle.
131 It's used by Object::free()/Object::init*() and works great for them
132 because they recycle strings like crazy.
133 */
134 class GooStringCache
135 {
136 public:
137 GooStringCache() {
138 inCache = 0;
139 #ifdef CALC_OBJECT_STRING_CACHE_STATS
140 totalAllocs = 0;
141 allocsFromCache = 0;
142 #endif
143 #if MULTITHREADED
144 gInitMutex(&mutex);
145 #endif
146 }
147
148 ~GooStringCache() {
149 for (int i=0; i<inCache; i++) {
150 delete stringsCached[i];
151 }
152 #if MULTITHREADED
153 gDestroyMutex(&mutex);
154 #endif
155 }
156
157 GooString *alloc(GooString *str) {
158 return alloc(str->getCString(), str->getLength());
159 }
160
161 // alloc and free are called a lot, so make them inline
162 GooString *alloc(const char *txt, int strLen = GooString::CALC_STRING_LEN) {
163 GooString *res = NULL;
164 #if MULTITHREADED
165 gLockMutex(&mutex);
166 #endif
167 #ifdef CALC_OBJECT_STRING_CACHE_STATS
168 ++totalAllocs;
169 #endif
170 if (inCache > 0) {
171 // pop the value from the top of the stack
172 res = stringsCached[inCache-1];
173 res->Set(txt, strLen);
174 --inCache;
175 #ifdef CALC_OBJECT_STRING_CACHE_STATS
176 ++allocsFromCache;
177 #endif
178 goto Exit;
179 } else {
180 res = new GooString(txt, strLen);
181 goto Exit;
182 }
183 Exit:
184 #if MULTITHREADED
185 gUnlockMutex(&mutex);
186 #endif
187 return res;
188 }
189
190 void free(GooString *str) {
191 #if MULTITHREADED
192 gLockMutex(&mutex);
193 #endif
194 if (inCache < CACHE_SIZE) {
195 // put the value at the top of the stack
196 stringsCached[inCache] = str;
197 ++inCache;
198 } else {
199 // cache is full
200 delete str;
201 }
202 #if MULTITHREADED
203 gUnlockMutex(&mutex);
204 #endif
205 }
206 private:
207 // CACHE_SIZE size affects 2 things:
208 // - alloc() hit ratio i.e. how many alloc()s can be satisfied from cache
209 // as opposed to allocating new GooString() with generic malloc()
210 // This is a *very* effective cache. I get 99.98% alloc() hit ratio even
211 // with CACHE_SIZE of 8. 95% with CACHE_SIZE of 4
212 // - how often we call delete on GooString(). When cache is full, we delete
213 // strings the usual way. When CACHE_SIZE grows, we hit delete less
214 // 64 is chosen by gut feeling, might use some tweaking
215 static const int CACHE_SIZE = 64;
216
217 #ifdef CALC_OBJECT_STRING_CACHE_STATS
218 int totalAllocs;
219 int allocsFromCache;
220 #endif
221 int inCache;
222 // you can think of it as a stack, we only add something to the top
223 // or take it from the top
224 GooString *stringsCached[CACHE_SIZE];
225 #if MULTITHREADED
226 GooMutex mutex;
227 #endif
228 };
229
230 #endif