
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>


#define NGX_NONE      1


ngx_inline static int ngx_output_chain_need_to_copy(ngx_output_chain_ctx_t *ctx,
                                                    ngx_hunk_t *hunk);
static int ngx_output_chain_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src,
                                      int sendfile);


int ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
{
    int           rc, last;
    ssize_t       size, hsize;
    ngx_chain_t  *cl, *out, **last_out;

    /*
     * the short path for the case when the chain ctx->in is empty
     * and the incoming chain is empty too or it has the single hunk
     * that does not require the copy
     */

    if (ctx->in == NULL) {

        if (in == NULL) {
            return ctx->output_filter(ctx->output_ctx, in);
        }

        if (in->next == NULL
            && (!ngx_output_chain_need_to_copy(ctx, in->hunk)))
        {
            return ctx->output_filter(ctx->output_ctx, in);
        }
    }

    /* add the incoming hunk to the chain ctx->in */

    if (in) {
        if (ngx_chain_add_copy(ctx->pool, &ctx->in, in) == NGX_ERROR) {
            return NGX_ERROR;
        }
    }

    last = NGX_NONE;
    out = NULL;
    last_out = &out;

    for ( ;; ) {

        while (ctx->in) {

            if (!ngx_output_chain_need_to_copy(ctx, ctx->in->hunk)) {

                /* move the chain link to the chain out */

                cl = ctx->in;
                ctx->in = cl->next;

                *last_out = cl;
                last_out = &cl->next;
                cl->next = NULL;

                continue;
            }

            if (ctx->hunk == NULL) {

                /* get the free hunk */

                if (ctx->free) {
                    ctx->hunk = ctx->free->hunk;
                    ctx->free = ctx->free->next;

                } else if (ctx->hunks < ctx->bufs.num) {

                    size = ctx->bufs.size;

                    if (ctx->in->hunk->type & NGX_HUNK_LAST) {

                        hsize = ngx_hunk_size(ctx->in->hunk);

                        if (hsize < ctx->bufs.size) {

                           /*
                            * allocate small temp hunk for the small last hunk
                            * or its small last part
                            */

                            size = hsize;

                        } else if (ctx->bufs.num == 1
                                   && (hsize < ctx->bufs.size
                                                     + (ctx->bufs.size >> 2)))
                        {
                            /*
                             * allocate a temp hunk that equals
                             * to the last hunk if the last hunk size is lesser
                             * than 1.25 of bufs.size and a temp hunk is single
                             */

                            size = hsize;
                        }
                    }

                    ngx_test_null(ctx->hunk,
                                  ngx_create_temp_hunk(ctx->pool, size, 0, 0),
                                  NGX_ERROR);
                    ctx->hunk->tag = ctx->tag;
                    ctx->hunk->type |= NGX_HUNK_RECYCLED;
                    ctx->hunks++;

                } else {
                    break;
                }
            }

            rc = ngx_output_chain_copy_hunk(ctx->hunk, ctx->in->hunk,
                                            ctx->sendfile);

            if (rc == NGX_ERROR) {
                return rc;
            }

            if (rc == NGX_AGAIN) {
                if (out) {
                    break;
                }
                return rc;
            }

            /* delete the completed hunk from the chain ctx->in */

            if (ngx_hunk_size(ctx->in->hunk) == 0) {
                ctx->in = ctx->in->next;
            }

            ngx_alloc_link_and_set_hunk(cl, ctx->hunk, ctx->pool, NGX_ERROR);
            *last_out = cl;
            last_out = &cl->next;
            ctx->hunk = NULL;

            if (ctx->free == NULL) {
                break;
            }
        }

        if (out == NULL && last != NGX_NONE) {
            return last;
        }

        last = ctx->output_filter(ctx->output_ctx, out);

        ngx_chain_update_chains(&ctx->free, &ctx->busy, &out, ctx->tag);
        last_out = &out;
    }
}


ngx_inline static int ngx_output_chain_need_to_copy(ngx_output_chain_ctx_t *ctx,
                                                    ngx_hunk_t *hunk)
{
    if (ngx_hunk_special(hunk)) {
        return 0;
    }

    if (!ctx->sendfile && (!(hunk->type & NGX_HUNK_IN_MEMORY))) {
        return 1;
    }

    if (ctx->need_in_memory && (!(hunk->type & NGX_HUNK_IN_MEMORY))) {
        return 1;
    }


    if (ctx->need_in_temp && (hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP))) {
        return 1;
    }

    return 0;
}


static int ngx_output_chain_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src,
                                      int sendfile)
{
    ssize_t  n, size;

    size = ngx_hunk_size(src);

    if (size > (dst->end - dst->pos)) {
        size = dst->end - dst->pos;
    }

    if (src->type & NGX_HUNK_IN_MEMORY) {
        ngx_memcpy(dst->pos, src->pos, size);
        src->pos += size;
        dst->last += size;

        if (src->type & NGX_HUNK_FILE) {
            src->file_pos += size;
        }

        if ((src->type & NGX_HUNK_LAST) && src->pos == src->last) {
            dst->type |= NGX_HUNK_LAST;
        }

    } else {
        n = ngx_read_file(src->file, dst->pos, size, src->file_pos);

if (n == 0) {
ngx_log_debug(src->file->log, "READ: %qd:%qd %X:%X %X:%X" _
              src->file_pos _ src->file_last _
              dst->pos _ dst->last _ dst->start _ dst->end);
}

        if (n == NGX_ERROR) {
            return n;
        }

#if (NGX_FILE_AIO_READ)
        if (n == NGX_AGAIN) {
            return n;
        }
#endif

        if (n != size) {
            ngx_log_error(NGX_LOG_ALERT, src->file->log, 0,
                          ngx_read_file_n " reads only %d of %d from file",
                          n, size);
            if (n == 0) {
                return NGX_ERROR;
            }
        }

        src->file_pos += n;
        dst->last += n;

        if (!sendfile) {
            dst->type &= ~NGX_HUNK_FILE;
        }

        if ((src->type & NGX_HUNK_LAST) && src->file_pos == src->file_last) {
            dst->type |= NGX_HUNK_LAST;
        }
    }

    return NGX_OK;
}


int ngx_chain_write(void *data, ngx_chain_t *in)
{
    ngx_chain_write_ctx_t *ctx = data;

    ngx_chain_t  *cl;


    for (/* void */; in; in = in->next) {
        ngx_alloc_link_and_set_hunk(cl, in->hunk, ctx->pool, NGX_ERROR);
        *ctx->last = cl;
        ctx->last = &cl->next;
    }

    ctx->out = ngx_write_chain(ctx->connection, ctx->out);

    if (ctx->out == NGX_CHAIN_ERROR) {
        return NGX_ERROR;
    }

    if (ctx->out == NULL) {
        ctx->last = &ctx->out;
        return NGX_OK;
    }

    return NGX_AGAIN;
}
