diff -u goo/GooString.cc \kjk\src\sumatrapdf\poppler\goo/GooString.cc --- goo/GooString.cc 2006-02-28 09:25:00.000000000 -0800 +++ \kjk\src\sumatrapdf\poppler\goo/GooString.cc 2006-08-13 03:47:49.145750000 -0700 @@ -18,76 +18,119 @@ #include #include #include +#include #include "gtypes.h" #include "GooString.h" -static inline int size(int len) { +int inline GooString::roundedSize(int len) { int delta; - + if (len <= STR_STATIC_SIZE-1) + return STR_STATIC_SIZE; delta = len < 256 ? 7 : 255; return ((len + 1) + delta) & ~delta; } -inline void GooString::resize(int length1) { - char *s1; - - if (!s) { - s = new char[size(length1)]; - } else if (size(length1) != size(length)) { - s1 = new char[size(length1)]; - if (length1 < length) { - memcpy(s1, s, length1); - s1[length1] = '\0'; - } else { - memcpy(s1, s, length + 1); +// Make sure that the buffer is big enough to contain characters +// plus terminating 0. +// We assume that if this is being called from the constructor, was set +// to NULL and was set to 0 to indicate unused string before calling us. +void inline GooString::resize(int newLength) { + char *s1 = s; + + if (!s || (roundedSize(length) != roundedSize(newLength))) { + // requires re-allocating data for string + if (newLength < STR_STATIC_SIZE) + s1 = sStatic; + else + s1 = new char[roundedSize(newLength)]; + + // we had to re-allocate the memory, so copy the content of previous + // buffer into a new buffer + if (s) { + if (newLength < length) { + memcpy(s1, s, newLength); + } else { + memcpy(s1, s, length); + } } - delete[] s; - s = s1; + if (s != sStatic) + delete[] s; } + + s = s1; + length = newLength; + s[length] = '\0'; +} + +GooString* GooString::Set(const char *s1, int s1Len, const char *s2, int s2Len) +{ + int newLen = 0; + char *p; + + if (s1) { + if (CALC_STRING_LEN == s1Len) { + s1Len = strlen(s1); + } else + assert(s1Len >= 0); + newLen += s1Len; + } + + if (s2) { + if (CALC_STRING_LEN == s2Len) { + s2Len = strlen(s2); + } else + assert(s2Len >= 0); + newLen += s2Len; + } + + resize(newLen); + p = s; + if (s1) { + memcpy(p, s1, s1Len); + p += s1Len; + } + if (s2) { + memcpy(p, s2, s2Len); + p += s2Len; + } + return this; } GooString::GooString() { s = NULL; - resize(length = 0); - s[0] = '\0'; + length = 0; + Set(NULL); } GooString::GooString(const char *sA) { - int n = strlen(sA); - s = NULL; - resize(length = n); - memcpy(s, sA, n + 1); + length = 0; + Set(sA, CALC_STRING_LEN); } GooString::GooString(const char *sA, int lengthA) { s = NULL; - resize(length = lengthA); - memcpy(s, sA, length * sizeof(char)); - s[length] = '\0'; + length = 0; + Set(sA, lengthA); } GooString::GooString(GooString *str, int idx, int lengthA) { s = NULL; - resize(length = lengthA); - memcpy(s, str->getCString() + idx, length); - s[length] = '\0'; + length = 0; + assert(idx + lengthA < str->length); + Set(str->getCString() + idx, lengthA); } GooString::GooString(GooString *str) { s = NULL; - resize(length = str->getLength()); - memcpy(s, str->getCString(), length + 1); + length = 0; + Set(str->getCString(), str->length); } GooString::GooString(GooString *str1, GooString *str2) { - int n1 = str1->getLength(); - int n2 = str2->getLength(); - s = NULL; - resize(length = n1 + n2); - memcpy(s, str1->getCString(), n1); - memcpy(s + n1, str2->getCString(), n2 + 1); + length = 0; + Set(str1->getCString(), str1->length, str2->getCString(), str2->length); } GooString *GooString::fromInt(int x) { @@ -117,91 +160,50 @@ } GooString::~GooString() { - delete[] s; + if (s != sStatic) + delete[] s; } GooString *GooString::clear() { - s[length = 0] = '\0'; resize(0); return this; } GooString *GooString::append(char c) { - resize(length + 1); - s[length++] = c; - s[length] = '\0'; - return this; + return append((const char*)&c, 1); } GooString *GooString::append(GooString *str) { - int n = str->getLength(); - - resize(length + n); - memcpy(s + length, str->getCString(), n + 1); - length += n; - return this; -} - -GooString *GooString::append(const char *str) { - int n = strlen(str); - - resize(length + n); - memcpy(s + length, str, n + 1); - length += n; - return this; + return append(str->getCString(), str->getLength()); } GooString *GooString::append(const char *str, int lengthA) { + int prevLen = length; + if (CALC_STRING_LEN == lengthA) + lengthA = strlen(str); resize(length + lengthA); - memcpy(s + length, str, lengthA); - length += lengthA; - s[length] = '\0'; + memcpy(s + prevLen, str, lengthA); return this; } GooString *GooString::insert(int i, char c) { - int j; - - resize(length + 1); - for (j = length + 1; j > i; --j) - s[j] = s[j-1]; - s[i] = c; - ++length; - return this; + return insert(i, (const char*)&c, 1); } GooString *GooString::insert(int i, GooString *str) { - int n = str->getLength(); - int j; - - resize(length + n); - for (j = length; j >= i; --j) - s[j+n] = s[j]; - memcpy(s+i, str->getCString(), n); - length += n; - return this; -} - -GooString *GooString::insert(int i, const char *str) { - int n = strlen(str); - int j; - - resize(length + n); - for (j = length; j >= i; --j) - s[j+n] = s[j]; - memcpy(s+i, str, n); - length += n; - return this; + return insert(i, str->getCString(), str->getLength()); } GooString *GooString::insert(int i, const char *str, int lengthA) { int j; + int prevLen = length; + if (CALC_STRING_LEN == lengthA) + lengthA = strlen(str); resize(length + lengthA); - for (j = length; j >= i; --j) + for (j = prevLen; j >= i; --j) s[j+lengthA] = s[j]; memcpy(s+i, str, lengthA); - length += lengthA; return this; } @@ -215,7 +217,7 @@ for (j = i; j <= length - n; ++j) { s[j] = s[j + n]; } - resize(length -= n); + resize(length - n); } return this; } diff -u goo/GooString.h \kjk\src\sumatrapdf\poppler\goo/GooString.h --- goo/GooString.h 2006-02-28 09:25:00.000000000 -0800 +++ \kjk\src\sumatrapdf\poppler\goo/GooString.h 2006-08-13 03:47:49.145750000 -0700 @@ -15,6 +15,7 @@ #pragma interface #endif +#include // for NULL #include "gtypes.h" class GooString { @@ -33,6 +34,12 @@ // Create a string from chars at in . GooString(GooString *str, int idx, int lengthA); + // Set content of a string to concatination of and . They can both + // be NULL. if or is CALC_STRING_LEN, then length of the string + // will be calculated with strlen(). Otherwise we assume they are a valid + // length of string (or its substring) + GooString* GooString::Set(const char *s1, int s1Len=CALC_STRING_LEN, const char *s2=NULL, int s2Len=CALC_STRING_LEN); + // Copy a string. GooString(GooString *str); GooString *copy() { return new GooString(this); } @@ -64,14 +71,12 @@ // Append a character or string. GooString *append(char c); GooString *append(GooString *str); - GooString *append(const char *str); - GooString *append(const char *str, int lengthA); + GooString *append(const char *str, int lengthA=CALC_STRING_LEN); // Insert a character or string. GooString *insert(int i, char c); GooString *insert(int i, GooString *str); - GooString *insert(int i, const char *str); - GooString *insert(int i, const char *str, int lengthA); + GooString *insert(int i, const char *str, int lengthA=CALC_STRING_LEN); // Delete a character or range of characters. GooString *del(int i, int n = 1); @@ -89,11 +94,22 @@ GBool hasUnicodeMarker(void); private: + // you can tweak this number for a different speed/memory usage tradeoffs. + // In libc malloc() rounding is 16 so it's best to choose a value that + // results in sizeof(GooString) be a multiple of 16. + // 24 makes sizeof(GooString) to be 32. + static const int STR_STATIC_SIZE = 24; + // a special value telling that the length of the string is not given + // so it must be calculated from the strings + static const int CALC_STRING_LEN = -1; + + int roundedSize(int len); + char sStatic[STR_STATIC_SIZE]; int length; char *s; - void resize(int length1); + void resize(int newLength); }; #endif diff -u goo/gmem.c \kjk\src\sumatrapdf\poppler\goo/gmem.c --- goo/gmem.c 2006-02-28 10:59:58.000000000 -0800 +++ \kjk\src\sumatrapdf\poppler\goo/gmem.c 2006-08-13 00:42:57.505125000 -0700 @@ -196,8 +196,7 @@ } } #else - if (p) - free(p); + free(p); #endif } diff -u goo/gmem.h \kjk\src\sumatrapdf\poppler\goo/gmem.h --- goo/gmem.h 2005-08-27 01:43:44.000000000 -0700 +++ \kjk\src\sumatrapdf\poppler\goo/gmem.h 2006-08-13 00:44:22.161375000 -0700 @@ -37,7 +37,7 @@ extern void *greallocn(void *p, int nObjs, int objSize); /* - * Same as free, but checks for and ignores NULL pointers. + * #ifdef DEBUG_MEM, adds debuging info. If not, same as free. */ extern void gfree(void *p);