> +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;
> +}