Optimization for parsing property lists

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@9716 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
nico 2001-04-26 23:54:01 +00:00
parent 257f2020ea
commit d18f1b89b6

View file

@ -108,27 +108,32 @@ static id (*plInit)(id, SEL, unichar*, unsigned) = 0;
static SEL plSel; static SEL plSel;
static SEL cMemberSel = 0; static SEL cMemberSel = 0;
static NSCharacterSet *hexdigits = nil;
static BOOL (*hexdigitsImp)(id, SEL, unichar) = 0; #define IS_BIT_SET(a,i) ((((a) & (1<<(i)))) > 0)
static unsigned const char *hexdigitsBitmapRep = NULL;
#define GS_IS_HEXDIGIT(X) IS_BIT_SET(hexdigitsBitmapRep[(X)/8], (X) % 8)
static void setupHexdigits() static void setupHexdigits()
{ {
if (hexdigits == nil) if (hexdigitsBitmapRep == NULL)
{ {
NSCharacterSet *hexdigits;
hexdigits = [NSCharacterSet characterSetWithCharactersInString: hexdigits = [NSCharacterSet characterSetWithCharactersInString:
@"0123456789abcdefABCDEF"]; @"0123456789abcdefABCDEF"];
IF_NO_GC(RETAIN(hexdigits)); IF_NO_GC(RETAIN(hexdigits));
if (cMemberSel == 0) hexdigitsBitmapRep = [[hexdigits bitmapRepresentation] bytes];
cMemberSel = @selector(characterIsMember:);
hexdigitsImp =
(BOOL(*)(id,SEL,unichar)) [hexdigits methodForSelector: cMemberSel];
} }
} }
static NSCharacterSet *quotables = nil; static NSCharacterSet *quotables = nil;
static BOOL (*quotablesImp)(id, SEL, unichar) = 0; static unsigned const char *quotablesBitmapRep = NULL;
#define GS_IS_QUOTABLE(X) IS_BIT_SET(quotablesBitmapRep[(X)/8], (X) % 8)
static void setupQuotables() static void setupQuotables()
{ {
if (quotables == nil) if (quotablesBitmapRep == NULL)
{ {
NSMutableCharacterSet *s; NSMutableCharacterSet *s;
@ -138,26 +143,23 @@ static void setupQuotables()
[s invert]; [s invert];
quotables = [s copy]; quotables = [s copy];
RELEASE(s); RELEASE(s);
if (cMemberSel == 0) quotablesBitmapRep = [[quotables bitmapRepresentation] bytes];
cMemberSel = @selector(characterIsMember:);
quotablesImp =
(BOOL(*)(id,SEL,unichar)) [quotables methodForSelector: cMemberSel];
} }
} }
static NSCharacterSet *whitespce = nil; static unsigned const char *whitespaceBitmapRep = NULL;
static BOOL (*whitespceImp)(id, SEL, unichar) = 0; #define GS_IS_WHITESPACE(X) IS_BIT_SET(whitespaceBitmapRep[(X)/8], (X) % 8)
static void setupWhitespce()
static void setupWhitespace()
{ {
if (whitespce == nil) if (whitespaceBitmapRep == NULL)
{ {
whitespce = [NSCharacterSet characterSetWithCharactersInString: NSCharacterSet *whitespace;
@" \t\r\n\f\b"];
IF_NO_GC(RETAIN(whitespce)); whitespace = [NSCharacterSet characterSetWithCharactersInString:
if (cMemberSel == 0) @" \t\r\n\f\b"];
cMemberSel = @selector(characterIsMember:); IF_NO_GC(RETAIN(whitespace));
whitespceImp = whitespaceBitmapRep = [[whitespace bitmapRepresentation] bytes];
(BOOL(*)(id,SEL,unichar)) [whitespce methodForSelector: cMemberSel];
} }
} }
@ -1852,19 +1854,19 @@ handle_printf_atsign (FILE *stream,
if (len == 0) if (len == 0)
return self; return self;
if (whitespce == nil) if (whitespaceBitmapRep == NULL)
setupWhitespce(); setupWhitespace();
s = NSZoneMalloc(GSObjCZone(self), sizeof(unichar)*len); s = NSZoneMalloc(GSObjCZone(self), sizeof(unichar)*len);
[self getCharacters: s]; [self getCharacters: s];
while (count < len) while (count < len)
{ {
if ((*whitespceImp)(whitespce, cMemberSel, s[count])) if (GS_IS_WHITESPACE(s[count]))
{ {
count++; count++;
found = YES; found = YES;
while (count < len while (count < len
&& (*whitespceImp)(whitespce, cMemberSel, s[count])) && GS_IS_WHITESPACE(s[count]))
{ {
count++; count++;
} }
@ -1879,7 +1881,7 @@ handle_printf_atsign (FILE *stream,
else else
{ {
while (count < len while (count < len
&& !(*whitespceImp)(whitespce, cMemberSel, s[count])) && !GS_IS_WHITESPACE(s[count]))
{ {
s[count] = uni_tolower(s[count]); s[count] = uni_tolower(s[count]);
count++; count++;
@ -3086,7 +3088,7 @@ handle_printf_atsign (FILE *stream,
return; return;
} }
if (quotables == nil) if (quotablesBitmapRep == NULL)
{ {
setupQuotables(); setupQuotables();
} }
@ -3762,7 +3764,7 @@ static BOOL skipSpace(pldata *pld)
{ {
c = pld->ptr[pld->pos]; c = pld->ptr[pld->pos];
if ((*whitespceImp)(whitespce, cMemberSel, c) == NO) if (GS_IS_WHITESPACE(c) == NO)
{ {
if (c == '/' && pld->pos < pld->end - 1) if (c == '/' && pld->pos < pld->end - 1)
{ {
@ -3848,7 +3850,7 @@ static inline id parseQuotedString(pldata* pld)
shrink++; shrink++;
escaped++; escaped++;
} }
else if (hex && (*hexdigitsImp)(hexdigits, cMemberSel, c)) else if (hex && GS_IS_HEXDIGIT(c))
{ {
shrink++; shrink++;
escaped++; escaped++;
@ -3921,7 +3923,7 @@ static inline id parseQuotedString(pldata* pld)
hex = YES; hex = YES;
escaped++; escaped++;
} }
else if (hex && (*hexdigitsImp)(hexdigits, cMemberSel, c)) else if (hex && GS_IS_HEXDIGIT(c))
{ {
chars[k] <<= 4; chars[k] <<= 4;
chars[k] |= char2num(c); chars[k] |= char2num(c);
@ -3985,7 +3987,7 @@ static inline id parseUnquotedString(pldata *pld)
while (pld->pos < pld->end) while (pld->pos < pld->end)
{ {
if ((*quotablesImp)(quotables, cMemberSel, pld->ptr[pld->pos]) == YES) if (GS_IS_QUOTABLE(pld->ptr[pld->pos]) == YES)
break; break;
pld->pos++; pld->pos++;
} }
@ -4129,8 +4131,8 @@ static id parsePlItem(pldata* pld)
pld->pos++; pld->pos++;
skipSpace(pld); skipSpace(pld);
while (pld->pos < max while (pld->pos < max
&& (*hexdigitsImp)(hexdigits, cMemberSel, pld->ptr[pld->pos]) && GS_IS_HEXDIGIT(pld->ptr[pld->pos])
&& (*hexdigitsImp)(hexdigits, cMemberSel, pld->ptr[pld->pos+1])) && GS_IS_HEXDIGIT(pld->ptr[pld->pos+1]))
{ {
unsigned char byte; unsigned char byte;
@ -4304,7 +4306,7 @@ setupPl()
setupHexdigits(); setupHexdigits();
setupQuotables(); setupQuotables();
setupWhitespce(); setupWhitespace();
} }
static id static id
@ -4328,15 +4330,15 @@ GSPropertyList(NSString *string)
} }
#if HAVE_LIBXML #if HAVE_LIBXML
if (whitespce == nil) if (whitespaceBitmapRep == NULL)
{ {
setupWhitespce(); setupWhitespace();
} }
while (index < length) while (index < length)
{ {
unsigned c = [string characterAtIndex: index]; unsigned c = [string characterAtIndex: index];
if ((*whitespceImp)(whitespce, cMemberSel, c) == NO) if (GS_IS_WHITESPACE(c) == NO)
{ {
break; break;
} }