> +static apr_status_t apr_json_decode_boolean(apr_json_scanner_t * self, int 
> *retval)
> +{
> +    if (self->p >= self->e)
> +        return APR_EOF;
> +
> +    if (self->e - self->p >= 4 && strncmp("true", self->p, 4) == 0 &&
> +        (self->p == self->e ||

(self->p == self) is always false since (self->e - self->p >= 4),
(self->e - self->p == 4) maybe?

> +                (!isalnum(((unsigned char *)self->p)[4]) &&
> +                        ((unsigned char *)self->p)[4] != '_'))) {

> +        self->p += 4;
> +        *retval = 1;
> +        return APR_SUCCESS;
> +    }
> +    else if (self->e - self->p >= 5 && strncmp("false", self->p, 5) == 0 &&
> +             (self->p == self->e ||

Likewise.

> +                     (!isalnum(((unsigned char *)self->p)[5]) &&
> +                             ((unsigned char *)self->p)[5] != '_'))) {
> +        self->p += 5;
> +        *retval = 0;
> +        return APR_SUCCESS;
> +    }
> +    return APR_BADCH;
> +}
> +
> +static apr_status_t apr_json_decode_number(apr_json_scanner_t * self, 
> apr_json_value_t * retval)
> +{
[]

Determining 'treat_as_float' looks costly so far.

> +
> +    if (treat_as_float) {
> +        retval->type = APR_JSON_DOUBLE;
> +        retval->value.dnumber = strtod(self->p, NULL);
> +    }
> +    else {
> +        retval->type = APR_JSON_LONG;
> +        retval->value.lnumber = strtol(self->p, NULL, 10);
> +    }

Can't we simply try strtol() and then strtod() if the former failed?

> +
> +out:
> +    self->p = p;
> +    return status;
> +}
> +
> +static apr_status_t apr_json_decode_null(apr_json_scanner_t * self)
> +{
> +    if (self->e - self->p >= 4 && strncmp("null", self->p, 4) == 0 &&
> +        (self->p == self->e ||

(self->e - self->p == 4)?

> +                (!isalnum(((unsigned char *)self->p)[4]) &&
> +                        ((unsigned char *)self->p)[4] != '_'))) {
> +        self->p += 4;
> +        return APR_SUCCESS;
> +    }
> +    return APR_BADCH;
> +}
> +
> +static apr_status_t apr_json_decode_space(apr_json_scanner_t * self,
> +        const char **space)
> +{
> +    const char *p = self->p;
> +    char *s;
> +    int len = 0;
> +
> +    *space = NULL;
> +
> +    if (self->p >= self->e) {
> +        return APR_SUCCESS;
> +    }
> +
> +    while (p < self->e && isspace(*(unsigned char *)p)) {
> +        p++;
> +        len++;
> +    }
> +
> +    if (self->flags & APR_JSON_FLAGS_WHITESPACE) {
> +        if (len) {
> +            *space = s = apr_palloc(self->pool, len + 1);
> +
> +            while (self->p < self->e && isspace(*(unsigned char *) self->p)) 
> {
> +                *s++ = *self->p++;
> +            }
> +            *s = 0;
> +
> +        }

A single pass (and auto-doubling apr_array of char) could work here too.

> +    } else {
> +        self->p = p;
> +    }
> +
> +    return APR_SUCCESS;
> +}

Reply via email to