1 //========================================================================
5 // Simple variable-length string type.
7 // Copyright 1996-2003 Glyph & Cog, LLC
9 //========================================================================
14 #ifdef USE_GCC_PRAGMAS
18 #include <stdlib.h> // for NULL
25 // Create an empty string.
28 // Create a string from a C string.
29 GooString(const char *sA
);
31 // Create a string from <lengthA> chars at <sA>. This string
32 // can contain null characters.
33 GooString(const char *sA
, int lengthA
);
35 // Create a string from <lengthA> chars at <idx> in <str>.
36 GooString(GooString
*str
, int idx
, int lengthA
);
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)
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
);
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);
50 GooString(GooString
*str
);
52 // Return a newly allocated copy of the string
53 GooString
*copy() { return new GooString(this); }
55 // Concatenate two strings.
56 GooString(GooString
*str1
, GooString
*str2
);
58 // Convert an integer to a string.
59 static GooString
*fromInt(int x
);
64 int getLength() const { return length
; }
67 char *getCString() const { return s
; }
69 // Get <i>th character.
70 char getChar(int i
) { return s
[i
]; }
72 // Change <i>th character.
73 void setChar(int i
, char c
) { s
[i
] = c
; }
75 // Clear string to zero length.
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
);
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
);
88 // Delete a character or range of characters.
89 GooString
*del(int i
, int n
= 1);
91 // Convert string to all-upper/all-lower case.
92 GooString
*upperCase();
93 GooString
*lowerCase();
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
);
101 GBool
hasUnicodeMarker(void);
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;
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;
114 int roundedSize(int len
);
116 char sStatic
[STR_STATIC_SIZE
];
120 void resize(int newLength
);
123 //Uncomment if you want to gather stats on hit rate of the cache
124 //#define CALC_OBJECT_STRING_CACHE_STATS 1
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.
139 #ifdef CALC_OBJECT_STRING_CACHE_STATS
149 for (int i
=0; i
<inCache
; i
++) {
150 delete stringsCached
[i
];
153 gDestroyMutex(&mutex
);
157 GooString
*alloc(GooString
*str
) {
158 return alloc(str
->getCString(), str
->getLength());
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
;
167 #ifdef CALC_OBJECT_STRING_CACHE_STATS
171 // pop the value from the top of the stack
172 res
= stringsCached
[inCache
-1];
173 res
->Set(txt
, strLen
);
175 #ifdef CALC_OBJECT_STRING_CACHE_STATS
180 res
= new GooString(txt
, strLen
);
185 gUnlockMutex(&mutex
);
190 void free(GooString
*str
) {
194 if (inCache
< CACHE_SIZE
) {
195 // put the value at the top of the stack
196 stringsCached
[inCache
] = str
;
203 gUnlockMutex(&mutex
);
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;
217 #ifdef CALC_OBJECT_STRING_CACHE_STATS
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
];