static apr_status_t apr_json_decode_object()

in json/apr_json_decode.c [428:524]


static apr_status_t apr_json_decode_object(apr_json_scanner_t * self,
        apr_json_value_t *json, apr_json_object_t ** retval)
{
    apr_status_t status = APR_SUCCESS;

    apr_json_object_t *object = apr_pcalloc(self->pool,
            sizeof(apr_json_object_t));
    APR_RING_INIT(&object->list, apr_json_kv_t, link);
    object->hash = apr_hash_make(self->pool);

    *retval = object;

    if (self->p >= self->e) {
        return APR_EOF;
    }

    if (self->level <= 0) {
        return APR_EINVAL;
    }
    self->level--;

    self->p++; /* toss of the leading { */

    for (;;) {
        apr_json_value_t *key;
        apr_json_value_t *value;

        if (self->p == self->e) {
            status = APR_EOF;
            goto out;
        }

        if (*self->p == '}') {
            self->p++;
            break;
        }

        key = apr_json_value_create(self->pool);
        if ((status = apr_json_decode_space(self, &key->pre)))
            goto out;

        if (self->p == self->e) {
            status = APR_EOF;
            goto out;
        }
        if (*self->p != '"') {
            status = APR_BADCH;
            goto out;
        }

        key->type = APR_JSON_STRING;
        if ((status = apr_json_decode_string(self, &key->value.string)))
            goto out;

        if ((status = apr_json_decode_space(self, &key->post)))
            goto out;

        if (self->p == self->e) {
            status = APR_EOF;
            goto out;
        }
        if (*self->p != ':') {
            status = APR_BADCH;
            goto out;
        }

        self->p++; /* eat the ':' */

        if (self->p == self->e) {
            status = APR_EOF;
            goto out;
        }

        if ((status = apr_json_decode_value(self, &value)))
            goto out;

        apr_json_object_set_ex(json, key, value, self->pool);

        if (self->p == self->e) {
            status = APR_EOF;
            goto out;
        }

        if (*self->p == ',') {
            self->p++;
        }
        else if (*self->p != '}') {
            status = APR_BADCH;
            goto out;
        }
    }

    self->level++;

out:
    return status;
}