/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * Robin J. Maxwell 11-22-96
 * Fredrik Roubert <roubert@google.com> 2010-07-23
 * Matt Austern <austern@google.com> 2010-07-23
 */

#include "prstrms.h"

#include <cstdio>
#include <cstring>
#include <ios>
#include <new>

using std::ios_base;
using std::iostream;
using std::istream;
using std::nothrow;
using std::ostream;
using std::streambuf;
using std::streamsize;


PRfilebuf::PRfilebuf():
    _fd(NULL),
    _opened(false),
    _allocated(false),
    _unbuffered(false),
    _user_buf(false),
    _buf_base(NULL),
    _buf_end(NULL) { }


PRfilebuf::PRfilebuf(PRFileDesc *fd):
    _fd(fd),
    _opened(false),
    _allocated(false),
    _unbuffered(false),
    _user_buf(false),
    _buf_base(NULL),
    _buf_end(NULL) { }


PRfilebuf::PRfilebuf(PRFileDesc *fd, char_type *ptr, streamsize len):
    _fd(fd),
    _opened(false),
    _allocated(false),
    _unbuffered(false),
    _user_buf(false),
    _buf_base(NULL),
    _buf_end(NULL)
{
    setbuf(ptr, len);
}


PRfilebuf::~PRfilebuf()
{
    if (_opened) {
        close();
    } else {
        sync();
    }
    if (_allocated) {
        delete _buf_base;
    }
}


PRfilebuf *PRfilebuf::open(
    const char *name, ios_base::openmode flags, PRIntn mode)
{
    if (_fd != NULL) {
        return NULL;  // Error if already open.
    }

    // Translate flags argument.
    PRIntn prflags = 0;
    bool ate = (flags & ios_base::ate) != 0;
    flags &= ~(ios_base::ate | ios_base::binary);

    // TODO: The flag PR_CREATE_FILE should probably be used for the cases
    // (out), (out|app), (out|trunc) and (in|out|trunc) as the C++ standard
    // specifies that these cases should open files 'as if by using fopen with
    // "w"'. But adding that flag here will cause the unit test to leave files
    // behind after running (which might or might not be an error in the unit
    // test) so the matter needs further investigation before any changes are
    // made. The old prstreams implementation used the non-standard flag
    // ios::nocreate to control the use of PR_CREATE_FILE.

    if (flags == (ios_base::out)) {
        prflags = PR_WRONLY | PR_TRUNCATE;
    } else if (flags == (ios_base::out | ios_base::app)) {
        prflags = PR_RDWR | PR_APPEND;
    } else if (flags == (ios_base::out | ios_base::trunc)) {
        prflags = PR_WRONLY | PR_TRUNCATE;
    } else if (flags == (ios_base::in)) {
        prflags = PR_RDONLY;
    } else if (flags == (ios_base::in | ios_base::out)) {
        prflags = PR_RDWR;
    } else if (flags == (ios_base::in | ios_base::out | ios_base::trunc)) {
        prflags = PR_RDWR | PR_TRUNCATE;
    } else {
        return NULL;  // Unrecognized flag combination.
    }

    if ((_fd = PR_Open(name, prflags, mode)) == NULL) {
        return NULL;
    }

    _opened = true;

    if (ate &&
            seekoff(0, ios_base::end, flags) == pos_type(traits_type::eof())) {
        close();
        return NULL;
    }

    return this;
}


PRfilebuf *PRfilebuf::attach(PRFileDesc *fd)
{
    if (_fd != NULL) {
        return NULL;  // Error if already open.
    }

    _opened = false;
    _fd = fd;
    return this;
}


PRfilebuf *PRfilebuf::close()
{
    if (_fd == NULL)
        return NULL;

    int status = sync();

    if (PR_Close(_fd) == PR_FAILURE ||
            traits_type::eq_int_type(status, traits_type::eof())) {
        return NULL;
    }

    _fd = NULL;
    return this;
}


streambuf *PRfilebuf::setbuf(char_type *ptr, streamsize len)
{
    if (is_open() && _buf_end) {
        return NULL;
    }

    if (!ptr || len <= 0) {
        _unbuffered = true;
    } else {
        setb(ptr, ptr + len, false);
    }

    return this;
}


streambuf::pos_type PRfilebuf::seekoff(
    off_type offset, ios_base::seekdir dir, ios_base::openmode /*flags*/)
{
    if (PR_GetDescType(_fd) != PR_DESC_FILE) {
        return traits_type::eof();
    }

    PRSeekWhence whence;
    PRInt64 pos;

    switch (dir) {
        case ios_base::beg: whence = PR_SEEK_SET; break;
        case ios_base::cur: whence = PR_SEEK_CUR; break;
        case ios_base::end: whence = PR_SEEK_END; break;
        default:
            return traits_type::eof();  // This should never happen.
    }

    if (traits_type::eq_int_type(sync(), traits_type::eof())) {
        return traits_type::eof();
    }

    if ((pos = PR_Seek64(_fd, offset, whence)) == -1) {
        return traits_type::eof();
    }

    return pos;
}


int PRfilebuf::sync()
{
    if (_fd == NULL) {
        return traits_type::eof();
    }

    if (!_unbuffered) {
        // Sync write area.
        PRInt32 waiting;
        if ((waiting = pptr() - pbase()) != 0) {
            PRInt32 nout;
            if ((nout = PR_Write(_fd, pbase(), waiting)) != waiting) {
                if (nout > 0) {
                    // Should set _pptr -= nout.
                    pbump(-nout);
                    memmove(pbase(), pbase() + nout, waiting - nout);
                }
                return traits_type::eof();
            }
        }
        setp(NULL, NULL);  // Empty put area.

        if (PR_GetDescType(_fd) == PR_DESC_FILE) {
            // Sockets can't seek; don't need this.
            PROffset64 avail;
            if ((avail = in_avail()) > 0) {
                if (PR_Seek64(_fd, -avail, PR_SEEK_CUR) != -1) {
                    return traits_type::eof();
                }
            }
        }
        setg(NULL, NULL, NULL);  // Empty get area.
    }

    return 0;
}


streambuf::int_type PRfilebuf::underflow()
{
    PRInt32 count;
    char_type byte;

    if (gptr() != NULL && gptr() < egptr()) {
        return traits_type::to_int_type(*gptr());
    }

    // Make sure there is a reserve area.
    if (!_unbuffered && _buf_base == NULL && !allocate()) {
        return traits_type::eof();
    }

    // Sync before new buffer created below.
    if (traits_type::eq_int_type(sync(), traits_type::eof())) {
        return traits_type::eof();
    }

    if (_unbuffered) {
        if (PR_Read(_fd, &byte, 1) <= 0) {
            return traits_type::eof();
        }

        return traits_type::to_int_type(byte);
    }

    if ((count = PR_Read(_fd, _buf_base, _buf_end - _buf_base)) <= 0) {
        return traits_type::eof();  // Reached EOF.
    }

    setg(_buf_base, _buf_base, _buf_base + count);
    return traits_type::to_int_type(*gptr());
}


streambuf::int_type PRfilebuf::overflow(int_type c)
{
    // Make sure there is a reserve area.
    if (!_unbuffered && _buf_base == NULL && !allocate()) {
        return traits_type::eof();
    }

    // Sync before new buffer created below.
    if (traits_type::eq_int_type(sync(), traits_type::eof())) {
        return traits_type::eof();
    }

    if (!_unbuffered) {
        setp(_buf_base, _buf_end);
    }

    if (!traits_type::eq_int_type(c, traits_type::eof())) {
        // Extract the byte to be written.
        // (Required on big-endian architectures.)
        char_type byte = traits_type::to_char_type(c);
        if (!_unbuffered && pptr() < epptr()) {  // Guard against recursion.
            return sputc(byte);
        } else {
            if (PR_Write(_fd, &byte, 1) != 1) {
                return traits_type::eof();
            }
        }
    }

    return traits_type::not_eof(c);
}


bool PRfilebuf::allocate()
{
    char_type *buf = new(nothrow) char_type[BUFSIZ];
    if (buf == NULL) {
        return false;
    }

    setb(buf, buf + BUFSIZ, true);
    return true;
}


void PRfilebuf::setb(char_type *buf_base, char_type *buf_end, bool user_buf)
{
    if (_buf_base && !_user_buf) {
        delete[] _buf_base;
    }

    _buf_base = buf_base;
    _buf_end = buf_end;
    _user_buf = user_buf;
}


PRifstream::PRifstream():
    istream(NULL),
    _filebuf()
{
    init(&_filebuf);
}


PRifstream::PRifstream(PRFileDesc *fd):
    istream(NULL),
    _filebuf(fd)
{
    init(&_filebuf);
}


PRifstream::PRifstream(PRFileDesc *fd, char_type *ptr, streamsize len):
    istream(NULL),
    _filebuf(fd, ptr, len)
{
    init(&_filebuf);
}


PRifstream::PRifstream(const char *name, openmode flags, PRIntn mode):
    istream(NULL),
    _filebuf()
{
    init(&_filebuf);
    if (!_filebuf.open(name, flags | in, mode)) {
        setstate(failbit);
    }
}


PRifstream::~PRifstream() { }


void PRifstream::open(const char *name, openmode flags, PRIntn mode)
{
    if (is_open() || !_filebuf.open(name, flags | in, mode)) {
        setstate(failbit);
    }
}


void PRifstream::attach(PRFileDesc *fd)
{
    if (!_filebuf.attach(fd)) {
        setstate(failbit);
    }
}


void PRifstream::close()
{
    if (_filebuf.close() == NULL) {
        setstate(failbit);
    }
}


PRofstream::PRofstream():
    ostream(NULL),
    _filebuf()
{
    init(&_filebuf);
}


PRofstream::PRofstream(PRFileDesc *fd):
    ostream(NULL),
    _filebuf(fd)
{
    init(&_filebuf);
}


PRofstream::PRofstream(PRFileDesc *fd, char_type *ptr, streamsize len):
    ostream(NULL),
    _filebuf(fd, ptr, len)
{
    init(&_filebuf);
}


PRofstream::PRofstream(const char *name, openmode flags, PRIntn mode):
    ostream(NULL),
    _filebuf()
{
    init(&_filebuf);
    if (!_filebuf.open(name, flags | out, mode)) {
        setstate(failbit);
    }
}


PRofstream::~PRofstream() { }


void PRofstream::open(const char *name, openmode flags, PRIntn mode)
{
    if (is_open() || !_filebuf.open(name, flags | out, mode)) {
        setstate(failbit);
    }
}


void PRofstream::attach(PRFileDesc *fd)
{
    if (!_filebuf.attach(fd)) {
        setstate(failbit);
    }
}


void PRofstream::close()
{
    if (_filebuf.close() == NULL) {
        setstate(failbit);
    }
}


PRfstream::PRfstream():
    iostream(NULL),
    _filebuf()
{
    init(&_filebuf);
}


PRfstream::PRfstream(PRFileDesc *fd):
    iostream(NULL),
    _filebuf(fd)
{
    init(&_filebuf);
}


PRfstream::PRfstream(PRFileDesc *fd, char_type *ptr, streamsize len):
    iostream(NULL),
    _filebuf(fd, ptr, len)
{
    init(&_filebuf);
}


PRfstream::PRfstream(const char *name, openmode flags, PRIntn mode):
    iostream(NULL),
    _filebuf()
{
    init(&_filebuf);
    if (!_filebuf.open(name, flags | in | out, mode)) {
        setstate(failbit);
    }
}


PRfstream::~PRfstream() { }


void PRfstream::open(const char *name, openmode flags, PRIntn mode)
{
    if (is_open() || !_filebuf.open(name, flags | in | out, mode)) {
        setstate(failbit);
    }
}


void PRfstream::attach(PRFileDesc *fd)
{
    if (!_filebuf.attach(fd)) {
        setstate(failbit);
    }
}


void PRfstream::close()
{
    if (_filebuf.close() == NULL) {
        setstate(failbit);
    }
}
