diff options
author | Peter Breitenlohner <peb@mppmu.mpg.de> | 2013-03-12 10:54:16 +0000 |
---|---|---|
committer | Peter Breitenlohner <peb@mppmu.mpg.de> | 2013-03-12 10:54:16 +0000 |
commit | 36111117efd25ddfcacb581627711fdf64878512 (patch) | |
tree | 85fd379c02653a514bc39270c0476f1582a88e12 /Build/source/libs/poppler/poppler-0.22.2/goo/GooString.cc | |
parent | 452dd8250d717d1fc8ee7040699231b070d2eb8b (diff) |
poppler 0.22.2
git-svn-id: svn://tug.org/texlive/trunk@29353 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/poppler/poppler-0.22.2/goo/GooString.cc')
-rw-r--r-- | Build/source/libs/poppler/poppler-0.22.2/goo/GooString.cc | 935 |
1 files changed, 935 insertions, 0 deletions
diff --git a/Build/source/libs/poppler/poppler-0.22.2/goo/GooString.cc b/Build/source/libs/poppler/poppler-0.22.2/goo/GooString.cc new file mode 100644 index 00000000000..d35161d87ad --- /dev/null +++ b/Build/source/libs/poppler/poppler-0.22.2/goo/GooString.cc @@ -0,0 +1,935 @@ +//======================================================================== +// +// GooString.cc +// +// Simple variable-length string type. +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +//======================================================================== +// +// Modified under the Poppler project - http://poppler.freedesktop.org +// +// All changes made under the Poppler project to this file are licensed +// under GPL version 2 or later +// +// Copyright (C) 2006 Kristian Høgsberg <krh@redhat.com> +// Copyright (C) 2006 Krzysztof Kowalczyk <kkowalczyk@gmail.com> +// Copyright (C) 2007 Jeff Muizelaar <jeff@infidigm.net> +// Copyright (C) 2008-2011 Albert Astals Cid <aacid@kde.org> +// Copyright (C) 2011 Kenji Uno <ku@digitaldolphins.jp> +// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it> +// Copyright (C) 2012 Adrian Johnson <ajohnson@redneon.com> +// Copyright (C) 2012 Pino Toscano <pino@kde.org> +// +// To see a description of the changes please see the Changelog file that +// came with your tarball or type make ChangeLog if you are building from git +// +//======================================================================== + +#include <config.h> + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include <stdlib.h> +#include <stddef.h> +#include <string.h> +#include <ctype.h> +#include <assert.h> +#include <math.h> +#include "gmem.h" +#include "GooString.h" + +static const int MAXIMUM_DOUBLE_PREC = 16; + +//------------------------------------------------------------------------ + +union GooStringFormatArg { + int i; + Guint ui; + long l; + Gulong ul; +#ifdef LLONG_MAX + long long ll; +#endif +#ifdef ULLONG_MAX + unsigned long long ull; +#endif + double f; + char c; + char *s; + GooString *gs; +}; + +enum GooStringFormatType { + fmtIntDecimal, + fmtIntHex, + fmtIntHexUpper, + fmtIntOctal, + fmtIntBinary, + fmtUIntDecimal, + fmtUIntHex, + fmtUIntHexUpper, + fmtUIntOctal, + fmtUIntBinary, + fmtLongDecimal, + fmtLongHex, + fmtLongHexUpper, + fmtLongOctal, + fmtLongBinary, + fmtULongDecimal, + fmtULongHex, + fmtULongHexUpper, + fmtULongOctal, + fmtULongBinary, +#ifdef LLONG_MAX + fmtLongLongDecimal, + fmtLongLongHex, + fmtLongLongHexUpper, + fmtLongLongOctal, + fmtLongLongBinary, +#endif +#ifdef ULLONG_MAX + fmtULongLongDecimal, + fmtULongLongHex, + fmtULongLongHexUpper, + fmtULongLongOctal, + fmtULongLongBinary, +#endif + fmtDouble, + fmtDoubleTrimSmallAware, + fmtDoubleTrim, + fmtChar, + fmtString, + fmtGooString, + fmtSpace +}; + +static const char *formatStrings[] = { + "d", "x", "X", "o", "b", "ud", "ux", "uX", "uo", "ub", + "ld", "lx", "lX", "lo", "lb", "uld", "ulx", "ulX", "ulo", "ulb", +#ifdef LLONG_MAX + "lld", "llx", "llX", "llo", "llb", +#endif +#ifdef ULLONG_MAX + "ulld", "ullx", "ullX", "ullo", "ullb", +#endif + "f", "gs", "g", + "c", + "s", + "t", + "w", + NULL +}; + +//------------------------------------------------------------------------ + +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; +} + +// Make sure that the buffer is big enough to contain <newLength> characters +// plus terminating 0. +// We assume that if this is being called from the constructor, <s> was set +// to NULL and <length> 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 { + // allocate a rounded amount + if (s == sStatic) + s1 = (char*)gmalloc(roundedSize(newLength)); + else + s1 = (char*)grealloc(s, roundedSize(newLength)); + } + if (s == sStatic || s1 == sStatic) { + // copy the minimum, we only need to if are moving to or + // from sStatic. + // assert(s != s1) the roundedSize condition ensures this + if (newLength < length) { + memcpy(s1, s, newLength); + } else { + memcpy(s1, s, length); + } + if (s != sStatic) + gfree(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; + length = 0; + Set(NULL); +} + +GooString::GooString(const char *sA) { + s = NULL; + length = 0; + Set(sA, CALC_STRING_LEN); +} + +GooString::GooString(const char *sA, int lengthA) { + s = NULL; + length = 0; + Set(sA, lengthA); +} + +GooString::GooString(GooString *str, int idx, int lengthA) { + s = NULL; + length = 0; + assert(idx + lengthA <= str->length); + Set(str->getCString() + idx, lengthA); +} + +GooString::GooString(const GooString *str) { + s = NULL; + length = 0; + Set(str->getCString(), str->length); +} + +GooString::GooString(GooString *str1, GooString *str2) { + s = NULL; + length = 0; + Set(str1->getCString(), str1->length, str2->getCString(), str2->length); +} + +GooString *GooString::fromInt(int x) { + char buf[24]; // enough space for 64-bit ints plus a little extra + char *p; + int len; + formatInt(x, buf, sizeof(buf), gFalse, 0, 10, &p, &len); + return new GooString(p, len); +} + +GooString *GooString::format(const char *fmt, ...) { + va_list argList; + GooString *s; + + s = new GooString(); + va_start(argList, fmt); + s->appendfv(fmt, argList); + va_end(argList); + return s; +} + +GooString *GooString::formatv(const char *fmt, va_list argList) { + GooString *s; + + s = new GooString(); + s->appendfv(fmt, argList); + return s; +} + +GooString::~GooString() { + if (s != sStatic) + gfree(s); +} + +GooString *GooString::clear() { + resize(0); + return this; +} + +GooString *GooString::append(char c) { + return append((const char*)&c, 1); +} + +GooString *GooString::append(GooString *str) { + 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 + prevLen, str, lengthA); + return this; +} + +GooString *GooString::appendf(const char *fmt, ...) { + va_list argList; + + va_start(argList, fmt); + appendfv(fmt, argList); + va_end(argList); + return this; +} + +GooString *GooString::appendfv(const char *fmt, va_list argList) { + GooStringFormatArg *args; + int argsLen, argsSize; + GooStringFormatArg arg; + int idx, width, prec; + GBool reverseAlign, zeroFill; + GooStringFormatType ft; + char buf[65]; + int len, i; + const char *p0, *p1; + char *str; + + argsLen = 0; + argsSize = 8; + args = (GooStringFormatArg *)gmallocn(argsSize, sizeof(GooStringFormatArg)); + + p0 = fmt; + while (*p0) { + if (*p0 == '{') { + ++p0; + if (*p0 == '{') { + ++p0; + append('{'); + } else { + + // parse the format string + if (!(*p0 >= '0' && *p0 <= '9')) { + break; + } + idx = *p0 - '0'; + for (++p0; *p0 >= '0' && *p0 <= '9'; ++p0) { + idx = 10 * idx + (*p0 - '0'); + } + if (*p0 != ':') { + break; + } + ++p0; + if (*p0 == '-') { + reverseAlign = gTrue; + ++p0; + } else { + reverseAlign = gFalse; + } + width = 0; + zeroFill = *p0 == '0'; + for (; *p0 >= '0' && *p0 <= '9'; ++p0) { + width = 10 * width + (*p0 - '0'); + } + if (width < 0) { + width = 0; + } + if (*p0 == '.') { + ++p0; + prec = 0; + for (; *p0 >= '0' && *p0 <= '9'; ++p0) { + prec = 10 * prec + (*p0 - '0'); + } + } else { + prec = 0; + } + for (ft = (GooStringFormatType)0; + formatStrings[ft]; + ft = (GooStringFormatType)(ft + 1)) { + if (!strncmp(p0, formatStrings[ft], strlen(formatStrings[ft]))) { + break; + } + } + if (!formatStrings[ft]) { + break; + } + p0 += strlen(formatStrings[ft]); + if (*p0 != '}') { + break; + } + ++p0; + + // fetch the argument + if (idx > argsLen) { + break; + } + if (idx == argsLen) { + if (argsLen == argsSize) { + argsSize *= 2; + args = (GooStringFormatArg *)greallocn(args, argsSize, + sizeof(GooStringFormatArg)); + } + switch (ft) { + case fmtIntDecimal: + case fmtIntHex: + case fmtIntHexUpper: + case fmtIntOctal: + case fmtIntBinary: + case fmtSpace: + args[argsLen].i = va_arg(argList, int); + break; + case fmtUIntDecimal: + case fmtUIntHex: + case fmtUIntHexUpper: + case fmtUIntOctal: + case fmtUIntBinary: + args[argsLen].ui = va_arg(argList, Guint); + break; + case fmtLongDecimal: + case fmtLongHex: + case fmtLongHexUpper: + case fmtLongOctal: + case fmtLongBinary: + args[argsLen].l = va_arg(argList, long); + break; + case fmtULongDecimal: + case fmtULongHex: + case fmtULongHexUpper: + case fmtULongOctal: + case fmtULongBinary: + args[argsLen].ul = va_arg(argList, Gulong); + break; +#ifdef LLONG_MAX + case fmtLongLongDecimal: + case fmtLongLongHex: + case fmtLongLongHexUpper: + case fmtLongLongOctal: + case fmtLongLongBinary: + args[argsLen].ll = va_arg(argList, long long); + break; +#endif +#ifdef ULLONG_MAX + case fmtULongLongDecimal: + case fmtULongLongHex: + case fmtULongLongHexUpper: + case fmtULongLongOctal: + case fmtULongLongBinary: + args[argsLen].ull = va_arg(argList, unsigned long long); + break; +#endif + case fmtDouble: + case fmtDoubleTrim: + case fmtDoubleTrimSmallAware: + args[argsLen].f = va_arg(argList, double); + break; + case fmtChar: + args[argsLen].c = (char)va_arg(argList, int); + break; + case fmtString: + args[argsLen].s = va_arg(argList, char *); + break; + case fmtGooString: + args[argsLen].gs = va_arg(argList, GooString *); + break; + } + ++argsLen; + } + + // format the argument + arg = args[idx]; + switch (ft) { + case fmtIntDecimal: + formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 10, &str, &len); + break; + case fmtIntHex: + formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 16, &str, &len); + break; + case fmtIntHexUpper: + formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 16, &str, &len, + gTrue); + break; + case fmtIntOctal: + formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 8, &str, &len); + break; + case fmtIntBinary: + formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 2, &str, &len); + break; + case fmtUIntDecimal: + formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 10, + &str, &len); + break; + case fmtUIntHex: + formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 16, + &str, &len); + break; + case fmtUIntHexUpper: + formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 16, + &str, &len, gTrue); + break; + case fmtUIntOctal: + formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 8, &str, &len); + break; + case fmtUIntBinary: + formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 2, &str, &len); + break; + case fmtLongDecimal: + formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 10, &str, &len); + break; + case fmtLongHex: + formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 16, &str, &len); + break; + case fmtLongHexUpper: + formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 16, &str, &len, + gTrue); + break; + case fmtLongOctal: + formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 8, &str, &len); + break; + case fmtLongBinary: + formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 2, &str, &len); + break; + case fmtULongDecimal: + formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 10, + &str, &len); + break; + case fmtULongHex: + formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 16, + &str, &len); + break; + case fmtULongHexUpper: + formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 16, + &str, &len, gTrue); + break; + case fmtULongOctal: + formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 8, &str, &len); + break; + case fmtULongBinary: + formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 2, &str, &len); + break; +#ifdef LLONG_MAX + case fmtLongLongDecimal: + formatInt(arg.ll, buf, sizeof(buf), zeroFill, width, 10, &str, &len); + break; + case fmtLongLongHex: + formatInt(arg.ll, buf, sizeof(buf), zeroFill, width, 16, &str, &len); + break; + case fmtLongLongHexUpper: + formatInt(arg.ll, buf, sizeof(buf), zeroFill, width, 16, &str, &len, + gTrue); + break; + case fmtLongLongOctal: + formatInt(arg.ll, buf, sizeof(buf), zeroFill, width, 8, &str, &len); + break; + case fmtLongLongBinary: + formatInt(arg.ll, buf, sizeof(buf), zeroFill, width, 2, &str, &len); + break; +#endif +#ifdef ULLONG_MAX + case fmtULongLongDecimal: + formatUInt(arg.ull, buf, sizeof(buf), zeroFill, width, 10, + &str, &len); + break; + case fmtULongLongHex: + formatUInt(arg.ull, buf, sizeof(buf), zeroFill, width, 16, + &str, &len); + break; + case fmtULongLongHexUpper: + formatUInt(arg.ull, buf, sizeof(buf), zeroFill, width, 16, + &str, &len, gTrue); + break; + case fmtULongLongOctal: + formatUInt(arg.ull, buf, sizeof(buf), zeroFill, width, 8, + &str, &len); + break; + case fmtULongLongBinary: + formatUInt(arg.ull, buf, sizeof(buf), zeroFill, width, 2, + &str, &len); + break; +#endif + case fmtDouble: + formatDouble(arg.f, buf, sizeof(buf), prec, gFalse, &str, &len); + break; + case fmtDoubleTrim: + formatDouble(arg.f, buf, sizeof(buf), prec, gTrue, &str, &len); + break; + case fmtDoubleTrimSmallAware: + formatDoubleSmallAware(arg.f, buf, sizeof(buf), prec, gTrue, &str, &len); + break; + case fmtChar: + buf[0] = arg.c; + str = buf; + len = 1; + reverseAlign = !reverseAlign; + break; + case fmtString: + str = arg.s; + len = strlen(str); + reverseAlign = !reverseAlign; + break; + case fmtGooString: + str = arg.gs->getCString(); + len = arg.gs->getLength(); + reverseAlign = !reverseAlign; + break; + case fmtSpace: + str = buf; + len = 0; + width = arg.i; + break; + } + + // append the formatted arg, handling width and alignment + if (!reverseAlign && len < width) { + for (i = len; i < width; ++i) { + append(' '); + } + } + append(str, len); + if (reverseAlign && len < width) { + for (i = len; i < width; ++i) { + append(' '); + } + } + } + + } else if (*p0 == '}') { + ++p0; + if (*p0 == '}') { + ++p0; + } + append('}'); + + } else { + for (p1 = p0 + 1; *p1 && *p1 != '{' && *p1 != '}'; ++p1) ; + append(p0, p1 - p0); + p0 = p1; + } + } + + gfree(args); + return this; +} + +static const char lowerCaseDigits[17] = "0123456789abcdef"; +static const char upperCaseDigits[17] = "0123456789ABCDEF"; + +#ifdef LLONG_MAX +void GooString::formatInt(long long x, char *buf, int bufSize, + GBool zeroFill, int width, int base, + char **p, int *len, GBool upperCase) { +#else +void GooString::formatInt(long x, char *buf, int bufSize, + GBool zeroFill, int width, int base, + char **p, int *len, GBool upperCase) { +#endif + const char *vals = upperCase ? upperCaseDigits : lowerCaseDigits; + GBool neg; + int start, i, j; + + i = bufSize; + if ((neg = x < 0)) { + x = -x; + } + start = neg ? 1 : 0; + if (x == 0) { + buf[--i] = '0'; + } else { + while (i > start && x) { + buf[--i] = vals[x % base]; + x /= base; + } + } + if (zeroFill) { + for (j = bufSize - i; i > start && j < width - start; ++j) { + buf[--i] = '0'; + } + } + if (neg) { + buf[--i] = '-'; + } + *p = buf + i; + *len = bufSize - i; +} + +#ifdef ULLONG_MAX +void GooString::formatUInt(unsigned long long x, char *buf, int bufSize, + GBool zeroFill, int width, int base, + char **p, int *len, GBool upperCase) { +#else +void GooString::formatUInt(Gulong x, char *buf, int bufSize, + GBool zeroFill, int width, int base, + char **p, int *len, GBool upperCase) { +#endif + const char *vals = upperCase ? upperCaseDigits : lowerCaseDigits; + int i, j; + + i = bufSize; + if (x == 0) { + buf[--i] = '0'; + } else { + while (i > 0 && x) { + buf[--i] = vals[x % base]; + x /= base; + } + } + if (zeroFill) { + for (j = bufSize - i; i > 0 && j < width; ++j) { + buf[--i] = '0'; + } + } + *p = buf + i; + *len = bufSize - i; +} + +void GooString::formatDouble(double x, char *buf, int bufSize, int prec, + GBool trim, char **p, int *len) { + GBool neg, started; + double x2; + int d, i, j; + + if ((neg = x < 0)) { + x = -x; + } + x = floor(x * pow(10.0, prec) + 0.5); + i = bufSize; + started = !trim; + for (j = 0; j < prec && i > 1; ++j) { + x2 = floor(0.1 * (x + 0.5)); + d = (int)floor(x - 10 * x2 + 0.5); + if (started || d != 0) { + buf[--i] = '0' + d; + started = gTrue; + } + x = x2; + } + if (i > 1 && started) { + buf[--i] = '.'; + } + if (i > 1) { + do { + x2 = floor(0.1 * (x + 0.5)); + d = (int)floor(x - 10 * x2 + 0.5); + buf[--i] = '0' + d; + x = x2; + } while (i > 1 && x); + } + if (neg) { + buf[--i] = '-'; + } + *p = buf + i; + *len = bufSize - i; +} + +void GooString::formatDoubleSmallAware(double x, char *buf, int bufSize, int prec, + GBool trim, char **p, int *len) +{ + double absX = fabs(x); + if (absX >= 0.1) { + formatDouble(x, buf, bufSize, prec, trim, p, len); + } else { + while (absX < 0.1 && prec < MAXIMUM_DOUBLE_PREC) + { + absX = absX * 10; + prec++; + } + formatDouble(x, buf, bufSize, prec, trim, p, len); + } +} + +GooString *GooString::insert(int i, char c) { + return insert(i, (const char*)&c, 1); +} + +GooString *GooString::insert(int i, GooString *str) { + return insert(i, str->getCString(), str->getLength()); +} + +GooString *GooString::insert(int i, const char *str, int lengthA) { + int prevLen = length; + if (CALC_STRING_LEN == lengthA) + lengthA = strlen(str); + + resize(length + lengthA); + memmove(s+i+lengthA, s+i, prevLen-i); + memcpy(s+i, str, lengthA); + return this; +} + +GooString *GooString::del(int i, int n) { + int j; + + if (i >= 0 && n > 0 && i + n > 0) { + if (i + n > length) { + n = length - i; + } + for (j = i; j <= length - n; ++j) { + s[j] = s[j + n]; + } + resize(length - n); + } + return this; +} + +GooString *GooString::upperCase() { + int i; + + for (i = 0; i < length; ++i) { + if (islower(s[i])) + s[i] = toupper(s[i]); + } + return this; +} + +GooString *GooString::lowerCase() { + int i; + + for (i = 0; i < length; ++i) { + if (isupper(s[i])) + s[i] = tolower(s[i]); + } + return this; +} + +int GooString::cmp(GooString *str) const { + int n1, n2, i, x; + char *p1, *p2; + + n1 = length; + n2 = str->length; + for (i = 0, p1 = s, p2 = str->s; i < n1 && i < n2; ++i, ++p1, ++p2) { + x = *p1 - *p2; + if (x != 0) { + return x; + } + } + return n1 - n2; +} + +int GooString::cmpN(GooString *str, int n) const { + int n1, n2, i, x; + char *p1, *p2; + + n1 = length; + n2 = str->length; + for (i = 0, p1 = s, p2 = str->s; + i < n1 && i < n2 && i < n; + ++i, ++p1, ++p2) { + x = *p1 - *p2; + if (x != 0) { + return x; + } + } + if (i == n) { + return 0; + } + return n1 - n2; +} + +int GooString::cmp(const char *sA) const { + int n1, i, x; + const char *p1, *p2; + + n1 = length; + for (i = 0, p1 = s, p2 = sA; i < n1 && *p2; ++i, ++p1, ++p2) { + x = *p1 - *p2; + if (x != 0) { + return x; + } + } + if (i < n1) { + return 1; + } + if (*p2) { + return -1; + } + return 0; +} + +int GooString::cmpN(const char *sA, int n) const { + int n1, i, x; + const char *p1, *p2; + + n1 = length; + for (i = 0, p1 = s, p2 = sA; i < n1 && *p2 && i < n; ++i, ++p1, ++p2) { + x = *p1 - *p2; + if (x != 0) { + return x; + } + } + if (i == n) { + return 0; + } + if (i < n1) { + return 1; + } + if (*p2) { + return -1; + } + return 0; +} + +GBool GooString::hasUnicodeMarker(void) +{ + return length > 1 && (s[0] & 0xff) == 0xfe && (s[1] & 0xff) == 0xff; +} + +GooString *GooString::sanitizedName(GBool psmode) +{ + GooString *name; + char buf[8]; + int i; + char c; + + name = new GooString(); + + if (psmode) + { + // ghostscript chokes on names that begin with out-of-limits + // numbers, e.g., 1e4foo is handled correctly (as a name), but + // 1e999foo generates a limitcheck error + c = getChar(0); + if (c >= '0' && c <= '9') { + name->append('f'); + } + } + + for (i = 0; i < getLength(); ++i) { + c = getChar(i); + if (c <= (char)0x20 || c >= (char)0x7f || + c == ' ' || + c == '(' || c == ')' || c == '<' || c == '>' || + c == '[' || c == ']' || c == '{' || c == '}' || + c == '/' || c == '%' || c == '#') { + sprintf(buf, "#%02x", c & 0xff); + name->append(buf); + } else { + name->append(c); + } + } + return name; +} |