speed up PL_WritePropertyList by ~3x.

This commit is contained in:
Bill Currie 2007-05-13 03:13:01 +00:00 committed by Jeff Teunissen
parent b5809eaa4f
commit a72f2046f5
3 changed files with 75 additions and 32 deletions

View file

@ -67,6 +67,13 @@ void dstring_delete (dstring_t *dstr);
large enough to hold size bytes (rounded up to the next 1kB boundary)
*/
void dstring_adjust (dstring_t *dstr);
/** Open up a hole in the string buffer. The contents of the opened hole
are undefined.
\param dstr the dstring in which to open the hole.
\param len the size of the hole to open.
\return pointer to the beginning of the opened hole.
*/
char *dstring_reserve (dstring_t *dstr, unsigned len);
/** Copy len bytes from data into the dstring, replacing any existing data.
*/
void dstring_copy (dstring_t *dstr, const char *data, unsigned int len);
@ -104,6 +111,15 @@ char *dstring_freeze (dstring_t *dstr);
dstring_t *_dstring_newstr (dstring_mem_t *mem);
dstring_t *dstring_newstr (void);
//@}
/** Open up a hole in the string buffer. The contents of the opened hole
are undefined. The size of the opened hole will be 1 bigger than specified
allowing for a null terminator.
\param dstr the dstring in which to open the hole.
\param len the size of the hole to open.
\return pointer to the current null terminator or beginning of the
opened hole if there was no terminator.
*/
char *dstring_reservestr (dstring_t *dstr, unsigned len);
/** Copy the null terminated string into the dstring. Replaces any existing
data.
The dstring does not have to be null terminated but will become so.

View file

@ -103,6 +103,14 @@ dstring_adjust (dstring_t *dstr)
}
}
VISIBLE char *
dstring_reserve (dstring_t *dstr, unsigned len)
{
dstr->size += len;
dstring_adjust (dstr);
return dstr->str + dstr->size - len;
}
VISIBLE void
dstring_copy (dstring_t *dstr, const char *data, unsigned int len)
{
@ -209,6 +217,17 @@ dstring_newstr (void)
return _dstring_newstr (&dstring_default_mem);
}
VISIBLE char *
dstring_reservestr (dstring_t *dstr, unsigned len)
{
int pos = dstr->size;
if (pos && !dstr->str[pos - 1])
pos--;
dstr->size = pos + len + 1;
dstring_adjust (dstr);
return dstr->str + pos;
}
VISIBLE void
dstring_copystr (dstring_t *dstr, const char *str)
{

View file

@ -811,71 +811,79 @@ PL_GetPropertyList (const char *string)
static void
write_tabs (dstring_t *dstr, int num)
{
int len = strlen (dstr->str);
char *tabs = dstring_reservestr (dstr, num);
dstr->size = len + num + 1;
dstring_adjust (dstr);
memset (dstr->str + len, '\t', num);
dstr->str[len + num] = 0;
memset (tabs, '\t', num);
tabs[num] = 0;
}
static void
write_string (dstring_t *dstr, const char *str)
{
const char *s;
char c;
int len = 0;
char *dst;
int quoted = 0;
for (s = str; *s && !is_quotable (*s); s++)
;
if (!*s) {
dstring_appendstr (dstr, str);
for (s = str; *s; s++) {
if (is_quotable (*s))
quoted = 1;
len++;
}
if (!quoted) {
dst = dstring_reservestr (dstr, len);
strcpy (dst, str);
return;
}
dstring_appendstr (dstr, "\"");
// assume worst case of all octal chars plus two quotes.
dst = dstring_reservestr (dstr, strlen (str) * 4 + 2);
*dst++= '\"';
while (*str) {
for (s = str; (*s && isascii ((byte) *s) && isprint ((byte) *s)
&& *s != '\\' && *s != '\"'); s++)
;
dstring_appendsubstr (dstr, str, s - str);
if (*s) {
switch (*s) {
if (*str && isascii ((byte) *str) && isprint ((byte) *str)
&& *str != '\\' && *str != '\"') {
*dst++ = *str++;
continue;
}
if (*str) {
switch (*str) {
case '\"':
case '\\':
c = *s;
*dst++ = *str;
break;
case '\n':
c = 'n';
*dst++ = 'n';
break;
case '\a':
c = 'a';
*dst++ = 'a';
break;
case '\b':
c = 'b';
*dst++ = 'b';
break;
case '\f':
c = 'f';
*dst++ = 'f';
break;
case '\r':
c = 'r';
*dst++ = 'r';
break;
case '\t':
c = 't';
*dst++ = 't';
break;
case '\v':
c = 'v';
*dst++ = 'v';
break;
default:
c = 0;
dasprintf (dstr, "\\%03o", (byte) *s);
*dst++ = '\\';
*dst++ = '0' + ((((byte) *str) >> 6) & 3);
*dst++ = '0' + ((((byte) *str) >> 3) & 7);
*dst++ = '0' + (((byte) *str) & 7);
break;
}
if (c)
dasprintf (dstr, "\\%c", c);
s++;
str++;
}
str = s;
}
dstring_appendstr (dstr, "\"");
*dst++ = '\"';
*dst++ = 0;
dstr->size = dst - dstr->str;
}
static void