/******************************************************************************
 * mod_uploader / ApachePostReader.cpp
 ******************************************************************************
 * Copyright (C) 2005 Tetsuya Kimata <kimata@acapulco.dyndns.org>
 *
 * All rights reserved.
 *
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any
 * damages arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any
 * purpose, including commercial applications, and to alter it and
 * redistribute it freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must
 *    not claim that you wrote the original software. If you use this
 *    software in a product, an acknowledgment in the product
 *    documentation would be appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and must
 *    not be misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source
 *    distribution.
 *
 * $Id: ApachePostReader.cpp 638 2005-09-07 21:51:26Z svn $
 *****************************************************************************/

#include "ApachePostReader.h"
#include "PostReader.h"
#include "Misc.h"

#define APR_WANT_MEMFUNC
#include "apr_want.h"

#ifdef DEBUG
#include <iostream>
#endif


/******************************************************************************
 * public メソッド
 *****************************************************************************/
ApachePostReader::ApachePostReader(apr_size_t block_size, request_rec *r,
                                   progress *progress)
    : PostReader(block_size, progress),
      request_(r),
      brigade_(apr_brigade_create(r->pool, r->connection->bucket_alloc)),
      bucket_(NULL),
      is_eos_(false)
{

}

void ApachePostReader::read(char *buffer, apr_size_t size, apr_size_t *read_size)
{
    const char *read_data;

    *read_size = 0;

    if (UNLIKELY(is_eos_)) {
        return;
    }

    if (UNLIKELY(bucket_ == NULL)) {
        get_brigade();
    } else if (UNLIKELY(bucket_ == APR_BRIGADE_SENTINEL(brigade_))) {
        apr_brigade_cleanup(brigade_);
        get_brigade();
    }

    if (UNLIKELY(APR_BUCKET_IS_EOS(bucket_))) {
        is_eos_ = true;
        return;
    }
    if (APR_BUCKET_IS_FLUSH(bucket_)) {
        bucket_ = APR_BUCKET_NEXT(bucket_);
        return read(buffer, size, read_size);
    }

    apr_bucket_read(bucket_, &read_data, read_size, APR_BLOCK_READ);
    memmove(buffer, read_data, *read_size);

    update(*read_size);

    bucket_ = APR_BUCKET_NEXT(bucket_);

    return;
}


/******************************************************************************
 * private メソッド
 *****************************************************************************/
void ApachePostReader::get_brigade()
{
    if (UNLIKELY(ap_get_brigade(request_->input_filters, brigade_, AP_MODE_READBYTES,
                                APR_BLOCK_READ, get_block_size()) != APR_SUCCESS)) {
        throw "リクエスト読み込みの準備に失敗しました．";
    }

    bucket_ = APR_BRIGADE_FIRST(brigade_);
}

// Local Variables:
// mode: c++
// buffer-file-coding-system: euc-japan-dos
// End:
