mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
speed up PL_WritePropertyList by ~3x.
This commit is contained in:
parent
b5809eaa4f
commit
a72f2046f5
3 changed files with 75 additions and 32 deletions
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue