Improve string parsing code

Currently next_string and next_hexstring functions use a static
buffer in the iterator to store the value.  This value is clobbered
as soon as next_string or next_hexstring is called.  Instead,
we copy the entire line in iter_next and use it as a scratch buffer.
The only limitation is that lines of max 2048 are possible, however
these are limited to around this size by parts of the standard.
This commit is contained in:
Denis Kenzior 2009-06-15 17:41:50 -05:00
parent 69372e642e
commit b648a112f2
2 changed files with 21 additions and 16 deletions

View File

@ -43,13 +43,18 @@ gboolean g_at_result_iter_next(GAtResultIter *iter, const char *prefix)
{
char *line;
int prefix_len = prefix ? strlen(prefix) : 0;
int linelen;
while ((iter->l = iter->l->next)) {
line = iter->l->data;
linelen = strlen(line);
if (linelen > G_AT_RESULT_LINE_LENGTH_MAX)
continue;
if (prefix_len == 0) {
iter->line_pos = 0;
return TRUE;
goto out;
}
if (g_str_has_prefix(line, prefix) == FALSE)
@ -61,10 +66,15 @@ gboolean g_at_result_iter_next(GAtResultIter *iter, const char *prefix)
line[iter->line_pos] == ' ')
iter->line_pos += 1;
return TRUE;
goto out;
}
return FALSE;
out:
/* Already checked the length to be no more than buflen */
strcpy(iter->buf, line);
return TRUE;
}
const char *g_at_result_iter_raw_line(GAtResultIter *iter)
@ -116,7 +126,7 @@ gboolean g_at_result_iter_next_string(GAtResultIter *iter, const char **str)
/* Omitted string */
if (line[pos] == ',') {
end = pos;
memset(iter->buf, 0, sizeof(iter->buf));
iter->buf[pos] = '\0';
goto out;
}
@ -131,11 +141,7 @@ gboolean g_at_result_iter_next_string(GAtResultIter *iter, const char **str)
if (line[end] != '"')
return FALSE;
if (end - pos >= sizeof(iter->buf))
return FALSE;
strncpy(iter->buf, line+pos, end-pos);
memset(iter->buf + end - pos, 0, sizeof(iter->buf) - end + pos);
iter->buf[end] = '\0';
/* Skip " */
end += 1;
@ -144,7 +150,7 @@ out:
iter->line_pos = skip_to_next_field(line, end, len);
if (str)
*str = iter->buf;
*str = iter->buf + pos;
return TRUE;
}
@ -172,7 +178,7 @@ gboolean g_at_result_iter_next_hexstring(GAtResultIter *iter,
/* Omitted string */
if (line[pos] == ',') {
end = pos;
memset(iter->buf, 0, sizeof(iter->buf));
iter->buf[pos] = '\0';
goto out;
}
@ -184,19 +190,16 @@ gboolean g_at_result_iter_next_hexstring(GAtResultIter *iter,
if ((end - pos) & 1)
return FALSE;
if ((end - pos) / 2 >= sizeof(iter->buf))
return FALSE;
*length = (end - pos) / 2;
for (bufpos = iter->buf; pos < end; pos += 2)
for (bufpos = iter->buf + pos; pos < end; pos += 2)
sscanf(line + pos, "%02hhx", bufpos++);
memset(bufpos, 0, sizeof(iter->buf) - (bufpos - iter->buf));
out:
iter->line_pos = skip_to_next_field(line, end, len);
if (str)
*str = (guint8 *) iter->buf;
*str = (guint8 *) bufpos - *length;
return TRUE;
}

View File

@ -33,10 +33,12 @@ struct _GAtResult {
typedef struct _GAtResult GAtResult;
#define G_AT_RESULT_LINE_LENGTH_MAX 2048
struct _GAtResultIter {
GAtResult *result;
GSList *l;
char buf[2048];
char buf[G_AT_RESULT_LINE_LENGTH_MAX + 1];
unsigned int line_pos;
GSList pre;
};