/* This is part of libio/iostream, providing -*- C++ -*- input/output.
Copyright (C) 1993, 1995, 1999 Free Software Foundation

This file is part of the GNU IO Library.  This library is free
software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option)
any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this library; see the file COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

As a special exception, if you link this library with files
compiled with a GNU compiler to produce an executable, this does not cause
the resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License.

Written by Per Bothner (bothner@cygnus.com). */

#include "iostreamP.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "builtinbuf.h"

void filebuf::init()
{
  _IO_file_init(this);
}

filebuf::filebuf()
{
  _IO_file_init(this);
}

#if !_IO_UNIFIED_JUMPTABLES
/* This is like "new filebuf()", but it uses the _IO_file_jump jumptable,
   for eficiency. */

filebuf* filebuf::__new()
{
  filebuf *fb = new filebuf;
  _IO_JUMPS(fb) = &_IO_file_jumps;
  fb->_vtable() = builtinbuf_vtable;
  return fb;
}
#endif

filebuf::filebuf(int fd)
{
  _IO_file_init(this);
  _IO_file_attach(this, fd);
}

filebuf::filebuf(int fd, char* p, int len)
{
  _IO_file_init(this);
  _IO_file_attach(this, fd);
  setbuf(p, len);
}

filebuf::~filebuf()
{
  if (_IO_file_is_open(this))
    {
      _IO_do_flush (this);
      if (!(xflags() & _IO_DELETE_DONT_CLOSE))
	_IO_SYSCLOSE (this);
    }
}

filebuf* filebuf::open(const char *filename, ios::openmode mode, int prot)
{
  if (_IO_file_is_open (this))
    return NULL;
  int posix_mode;
  int read_write;
  if (mode & ios::app)
    mode |= ios::out;
  if ((mode & (ios::in|ios::out)) == (ios::in|ios::out)) {
    posix_mode = O_RDWR;
    read_write = 0;
  }
  else if (mode & ios::out)
    posix_mode = O_WRONLY, read_write = _IO_NO_READS;
  else if (mode & (int)ios::in)
    posix_mode = O_RDONLY, read_write = _IO_NO_WRITES;
  else
    posix_mode = 0, read_write = _IO_NO_READS+_IO_NO_WRITES;
  if (mode & ios::binary)
    {
      mode &= ~ios::binary;
#ifdef O_BINARY
      /* This is a (mis-)feature of DOS/Windows C libraries. */
      posix_mode |= O_BINARY;
#endif
    }
  if ((mode & (int)ios::trunc) || mode == (int)ios::out)
    posix_mode |= O_TRUNC;
  if (mode & ios::app)
    posix_mode |= O_APPEND, read_write |= _IO_IS_APPENDING;
  if (!(mode & (int)ios::nocreate) && mode != ios::in)
    posix_mode |= O_CREAT;
  if (mode & (int)ios::noreplace)
    posix_mode |= O_EXCL;
#if _G_HAVE_IO_FILE_OPEN
  if (!_IO_file_open (this, filename, posix_mode, prot, 
		      read_write, 0))
    return NULL;
  if (mode & ios::ate) {
    if (pubseekoff(0, ios::end) == EOF) {
      _IO_un_link (this);
      return NULL;
    }
  }
  return this;
#else
  int fd = ::open(filename, posix_mode, prot);
  if (fd < 0)
    return NULL;
  _fileno = fd;
  xsetflags(read_write, _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
  if (mode & ios::ate) {
    if (pubseekoff(0, ios::end) == EOF)
      return NULL;
  }
  _IO_link_in(this);
  return this;
#endif
}

filebuf* filebuf::open(const char *filename, const char *mode)
{
#if _G_IO_IO_FILE_VERSION == 0x20001
  return (filebuf*)_IO_file_fopen(this, filename, mode, 0);
#else
  return (filebuf*)_IO_file_fopen(this, filename, mode);
#endif
}

filebuf* filebuf::attach(int fd)
{
  return (filebuf*)_IO_file_attach(this, fd);
}

streambuf* filebuf::setbuf(char* p, int len)
{
  return (streambuf*)_IO_file_setbuf (this, p, len);
}

int filebuf::doallocate() { return _IO_file_doallocate(this); }

int filebuf::overflow(int c)
{
  return _IO_file_overflow(this, c);
}

int filebuf::underflow()
{
  return _IO_file_underflow(this);
}

int filebuf::sync()
{
  return _IO_file_sync(this);
}

streampos filebuf::seekoff(streamoff offset, _seek_dir dir, int mode)
{
  return _IO_file_seekoff (this, offset, dir, mode);
}

filebuf* filebuf::close()
{
  return (_IO_file_close_it(this) ? (filebuf*)NULL : this);
}

streamsize filebuf::sys_read(char* buf, streamsize size)
{
  return _IO_file_read(this, buf, size);
}

streampos filebuf::sys_seek(streamoff offset, _seek_dir dir)
{
  return _IO_file_seek(this, offset, dir);
}

streamsize filebuf::sys_write(const char *buf, streamsize n)
{
  return _IO_file_write (this, buf, n);
}

int filebuf::sys_stat(void* st)
{
  return _IO_file_stat (this, st);
}

int filebuf::sys_close()
{
  return _IO_file_close (this);
}

streamsize filebuf::xsputn(const char *s, streamsize n)
{
  return _IO_file_xsputn(this, s, n);
}

streamsize filebuf::xsgetn(char *s, streamsize n)
{
    // FIXME: OPTIMIZE THIS (specifically, when unbuffered()).
    return streambuf::xsgetn(s, n);
}

// Non-ANSI AT&T-ism:  Default open protection.
const int filebuf::openprot = 0644;
