static ngx_buf_t *
ngx_http_autoindex_json(ngx_http_request_t *r, ngx_array_t *entries,
    ngx_str_t *callback)
{
    size_t                       len;
    ngx_buf_t                   *b;
    ngx_uint_t                   i;
    ngx_http_autoindex_entry_t  *entry;
    len = sizeof("[" CRLF CRLF "]") - 1;
    if (callback) {
        len += sizeof("/* callback */" CRLF "();") - 1 + callback->len;
    }
    entry = entries->elts;
    for (i = 0; i < entries->nelts; i++) {
        entry[i].escape = ngx_escape_json(NULL, entry[i].name.data,
                                          entry[i].name.len);
        len += sizeof("{  }," CRLF) - 1
            + sizeof("\"name\":\"\"") - 1
            + entry[i].name.len + entry[i].escape
            + sizeof(", \"type\":\"directory\"") - 1
            + sizeof(", \"mtime\":\"Wed, 31 Dec 1986 10:00:00 GMT\"") - 1;
        if (entry[i].file) {
            len += sizeof(", \"size\":") - 1 + NGX_OFF_T_LEN;
        }
    }
    b = ngx_create_temp_buf(r->pool, len);
    if (b == NULL) {
        return NULL;
    }
    if (callback) {
        b->last = ngx_cpymem(b->last, "/* callback */" CRLF,
                             sizeof("/* callback */" CRLF) - 1);
        b->last = ngx_cpymem(b->last, callback->data, callback->len);
        *b->last++ = '(';
    }
    *b->last++ = '[';
    for (i = 0; i < entries->nelts; i++) {
        b->last = ngx_cpymem(b->last, CRLF "{ \"name\":\"",
                             sizeof(CRLF "{ \"name\":\"") - 1);
        if (entry[i].escape) {
            b->last = (u_char *) ngx_escape_json(b->last, entry[i].name.data,
                                                 entry[i].name.len);
        } else {
            b->last = ngx_cpymem(b->last, entry[i].name.data,
                                 entry[i].name.len);
        }
        b->last = ngx_cpymem(b->last, "\", \"type\":\"",
                             sizeof("\", \"type\":\"") - 1);
        if (entry[i].dir) {
            b->last = ngx_cpymem(b->last, "directory", sizeof("directory") - 1);
        } else if (entry[i].file) {
            b->last = ngx_cpymem(b->last, "file", sizeof("file") - 1);
        } else {
            b->last = ngx_cpymem(b->last, "other", sizeof("other") - 1);
        }
        b->last = ngx_cpymem(b->last, "\", \"mtime\":\"",
                             sizeof("\", \"mtime\":\"") - 1);
        b->last = ngx_http_time(b->last, entry[i].mtime);
        if (entry[i].file) {
            b->last = ngx_cpymem(b->last, "\", \"size\":",
                                 sizeof("\", \"size\":") - 1);
            b->last = ngx_sprintf(b->last, "%O", entry[i].size);
        } else {
            *b->last++ = '"';
        }
        b->last = ngx_cpymem(b->last, " },", sizeof(" },") - 1);
    }
    if (i > 0) {
        b->last--;
    }
    b->last = ngx_cpymem(b->last, CRLF "]", sizeof(CRLF "]") - 1);
    if (callback) {
        *b->last++ = ')'; *b->last++ = ';';
    }
    return b;
}
['static ngx_buf_t *\nngx_http_autoindex_json(ngx_http_request_t *r, ngx_array_t *entries,\n    ngx_str_t *callback)\n{\n    size_t                       len;\n    ngx_buf_t                   *b;\n    ngx_uint_t                   i;\n    ngx_http_autoindex_entry_t  *entry;\n    len = sizeof("[" CRLF CRLF "]") - 1;\n    if (callback) {\n        len += sizeof("/* callback */" CRLF "();") - 1 + callback->len;\n    }\n    entry = entries->elts;\n    for (i = 0; i < entries->nelts; i++) {\n        entry[i].escape = ngx_escape_json(NULL, entry[i].name.data,\n                                          entry[i].name.len);\n        len += sizeof("{  }," CRLF) - 1\n            + sizeof("\\"name\\":\\"\\"") - 1\n            + entry[i].name.len + entry[i].escape\n            + sizeof(", \\"type\\":\\"directory\\"") - 1\n            + sizeof(", \\"mtime\\":\\"Wed, 31 Dec 1986 10:00:00 GMT\\"") - 1;\n        if (entry[i].file) {\n            len += sizeof(", \\"size\\":") - 1 + NGX_OFF_T_LEN;\n        }\n    }\n    b = ngx_create_temp_buf(r->pool, len);\n    if (b == NULL) {\n        return NULL;\n    }\n    if (callback) {\n        b->last = ngx_cpymem(b->last, "/* callback */" CRLF,\n                             sizeof("/* callback */" CRLF) - 1);\n        b->last = ngx_cpymem(b->last, callback->data, callback->len);\n        *b->last++ = \'(\';\n    }\n    *b->last++ = \'[\';\n    for (i = 0; i < entries->nelts; i++) {\n        b->last = ngx_cpymem(b->last, CRLF "{ \\"name\\":\\"",\n                             sizeof(CRLF "{ \\"name\\":\\"") - 1);\n        if (entry[i].escape) {\n            b->last = (u_char *) ngx_escape_json(b->last, entry[i].name.data,\n                                                 entry[i].name.len);\n        } else {\n            b->last = ngx_cpymem(b->last, entry[i].name.data,\n                                 entry[i].name.len);\n        }\n        b->last = ngx_cpymem(b->last, "\\", \\"type\\":\\"",\n                             sizeof("\\", \\"type\\":\\"") - 1);\n        if (entry[i].dir) {\n            b->last = ngx_cpymem(b->last, "directory", sizeof("directory") - 1);\n        } else if (entry[i].file) {\n            b->last = ngx_cpymem(b->last, "file", sizeof("file") - 1);\n        } else {\n            b->last = ngx_cpymem(b->last, "other", sizeof("other") - 1);\n        }\n        b->last = ngx_cpymem(b->last, "\\", \\"mtime\\":\\"",\n                             sizeof("\\", \\"mtime\\":\\"") - 1);\n        b->last = ngx_http_time(b->last, entry[i].mtime);\n        if (entry[i].file) {\n            b->last = ngx_cpymem(b->last, "\\", \\"size\\":",\n                                 sizeof("\\", \\"size\\":") - 1);\n            b->last = ngx_sprintf(b->last, "%O", entry[i].size);\n        } else {\n            *b->last++ = \'"\';\n        }\n        b->last = ngx_cpymem(b->last, " },", sizeof(" },") - 1);\n    }\n    if (i > 0) {\n        b->last--;\n    }\n    b->last = ngx_cpymem(b->last, CRLF "]", sizeof(CRLF "]") - 1);\n    if (callback) {\n        *b->last++ = \')\'; *b->last++ = \';\';\n    }\n    return b;\n}', 'ngx_buf_t *\nngx_create_temp_buf(ngx_pool_t *pool, size_t size)\n{\n    ngx_buf_t *b;\n    b = ngx_calloc_buf(pool);\n    if (b == NULL) {\n        return NULL;\n    }\n    b->start = ngx_palloc(pool, size);\n    if (b->start == NULL) {\n        return NULL;\n    }\n    b->pos = b->start;\n    b->last = b->start;\n    b->end = b->last + size;\n    b->temporary = 1;\n    return b;\n}', 'void *\nngx_palloc(ngx_pool_t *pool, size_t size)\n{\n    if (size <= pool->max) {\n        return ngx_palloc_small(pool, size, 1);\n    }\n    return ngx_palloc_large(pool, size);\n}', 'static ngx_inline void *\nngx_palloc_small(ngx_pool_t *pool, size_t size, ngx_uint_t align)\n{\n    u_char      *m;\n    ngx_pool_t  *p;\n    p = pool->current;\n    do {\n        m = p->d.last;\n        if (align) {\n            m = ngx_align_ptr(m, NGX_ALIGNMENT);\n        }\n        if ((size_t) (p->d.end - m) >= size) {\n            p->d.last = m + size;\n            return m;\n        }\n        p = p->d.next;\n    } while (p);\n    return ngx_palloc_block(pool, size);\n}']