/* -*- c++ -*- */
/*
 * Copyright (C) 2010 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef ANDROID_ASTL_STREAMBUF__
#define ANDROID_ASTL_STREAMBUF__

#include <char_traits.h>

namespace std {

/**
 * Basic implementation of streambuf. The STL standard defines a
 * basic_streambuf template that gets specialized for char and
 * wchar. Since Android supports only char, we don't use a template
 * here.
 * Only output ops are supported.
 * There are only 2 public entry points:
 *  - sputc
 *  - sputn
 */

class streambuf
{
  public:
    typedef char_traits<char>       traits_type;
    typedef traits_type::char_type  char_type;
    typedef traits_type::int_type   int_type;
    typedef streampos               pos_type;
    typedef streamoff               off_type;

  public:
    virtual ~streambuf();

    /**
     * Entry points for derived buffer functions. The public version
     * pubfoo dispatch to the protected foo member functions.
     * @return -1 on failure.
     */
    int pubsync() { return this->sync(); }

    /**
     * Entry point for all single-character output functions.
     */
    int_type sputc(char_type c) {
        // TODO: Should not rely on sputn, this is a temp implementation.
        this->sputn(&c, 1);
        return traits_type::to_int_type(c);
    }

    /**
     * Write str[0] to str[n-1] to output sequence. Stops if sputc
     * would return traits_type::eof().
     * @param str  A buffer area.
     * @param num  Maximum number of characters to write.
     * @return The number of characters written.
     */
    streamsize sputn(const char_type* str, streamsize num) {
        return this->xsputn(str, num);
    }

  protected:
    streambuf();


    /**
     *  Access to the put area.
     *  - pbase() returns the beginning pointer for the output sequence.
     *  - pptr() returns the next pointer for the output sequence.
     *  - epptr() returns the end pointer for the output sequence.
     *  - pbump(int) Advance the write postion in the output sequence.
     */
    char_type* pbase() const { return mPutBeg; }
    char_type* pptr() const { return mPutCurr; }
    char_type* epptr() const { return mPutEnd; }
    void pbump(int num) {
        if (mPutCurr + num > mPutCurr && mPutCurr + num <= mPutEnd) {
            mPutCurr += num;
        }
    }

    /**
     * Set the 3 write pointers.
     */
    void setp(char_type* beg, char_type* end) {
        if (end >= beg) {
            mPutBeg = mPutCurr = beg;
            mPutEnd = end;
        }
    }

    /**
     * Sync buffer array. Provided by derived class.
     * @return -1 on failure.
     */
    virtual int sync() { return 0; }

    /**
     * See sputn. Provided by derived class.
     */
    virtual streamsize xsputn(const char_type* str, streamsize num);

    /**
     * Consumes one char from the buffer, writes to the controlled
     * sequence if possible. This is called when the buffer is
     * full. Typically the impl will flush the buffer, write the
     * character 'c'.
     * Provided by derived class.
     * @return traits::eof() in case of error, anything else otherwise.
     */
    virtual int_type overflow(int_type /* c */ = traits_type::eof())
    { return traits_type::eof(); }

    /**
     * Minimal abstraction for an internal buffer.
     *  -  put == output == write
     */
    char_type* 		mPutBeg;    // Start of put area.
    char_type* 		mPutCurr;   // Current put area.
    char_type* 		mPutEnd;    // End of put area.

  private:
    // No copy constructors.
    streambuf(const streambuf& sb);
    streambuf& operator=(const streambuf&) { return *this; }
};

}  // namespace std

#endif
