/** BEGIN COPYRIGHT BLOCK
 * Copyright (C) 2001 Sun Microsystems, Inc.  Used by permission.
 * Copyright (C) 2005 Red Hat, Inc.
 * All rights reserved.
 *
 * This program 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; version 2
 * of the License.
 *
 * This program 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 program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 * END COPYRIGHT BLOCK **/
#ifndef BASE_BUFFER_H
#define BASE_BUFFER_H

#ifndef NOINTNSAPI
#define INTNSAPI
#endif /* !NOINTNSAPI */

/*
 * buffer.h: For performing buffered I/O on a file or socket descriptor.
 * 
 * This is an abstraction to allow I/O to be performed regardless of the
 * current system. That way, an integer file descriptor can be used under 
 * UNIX but a stdio FILE structure could be used on systems which don't
 * support that or don't support it as efficiently.
 * 
 * Two abstractions are defined: A file buffer, and a network buffer. A
 * distinction is made so that mmap() can be used on files (but is not
 * required). Also, the file buffer takes a file name as the object to 
 * open instead of a file descriptor. A lot of the network buffering
 * is almost an exact duplicate of the non-mmap file buffering.
 * 
 * If an error occurs, system-independent means to obtain an error string
 * are also provided. However, if the underlying system is UNIX the error
 * may not be accurate in a threaded environment.
 * 
 * Rob McCool
 * 
 */

#ifndef NETSITE_H
#include "../netsite.h"
#endif /* !NETSITE_H */

#ifndef BASE_FILE_H
#include "file.h"
#endif /* !BASE_FILE_H */

#ifndef PUBLIC_BASE_BUFFER_H
#include "public/base/buffer.h"
#endif /* !PUBLIC_BASE_BUFFER_H */

#ifdef INTNSAPI

/* --- Begin function prototypes --- */

NSPR_BEGIN_EXTERN_C

/*
 * buffer_open opens a new buffer reading the specified file, with an I/O
 * buffer of size sz, and returns a new buffer structure which will hold
 * the data.
 *
 * If FILE_UNIX_MMAP is defined, this may return NULL. If it does, check 
 * system_errmsg to get a message about the error.
 */

NSAPI_PUBLIC filebuf_t *INTfilebuf_open(SYS_FILE fd, int sz);

/*
 * filebuf_open_nostat is a convenience function for mmap() buffer opens,
 * if you happen to have the stat structure already.
 */

/*
 * filebuf_create is a convenience function if the file is already open
 * or mmap'd.  It creates a new filebuf for use with the mmap'd file.
 * If mmap_ptr is NULL, or MMAP is not supported on this system, it 
 * creates a buffer with buffer size bufsz.
 */
NSAPI_PUBLIC
filebuf_t *INTfilebuf_create(SYS_FILE fd, caddr_t mmap_ptr, int mmap_len, 
                             int bufsz);

#ifdef FILE_MMAP
#include <sys/stat.h>
NSAPI_PUBLIC 
filebuf_t *INTfilebuf_open_nostat(SYS_FILE fd, int sz, struct stat *finfo);
#endif /* FILE_MMAP */

#ifdef XP_WIN32
NSAPI_PUBLIC 
filebuf_t *INTpipebuf_open(SYS_FILE fd, int sz, struct stat *finfo);
#endif /* XP_WIN32 */

/*
 * buffer_next loads size more bytes into the given buffer and returns the
 * first one, or BUFFER_EOF on EOF and BUFFER_ERROR on error.
 */

#ifndef FILE_MMAP
NSAPI_PUBLIC int INTfilebuf_next(filebuf_t *buf, int advance);
#endif /* !FILE_MMAP */
#ifdef XP_WIN32 
NSAPI_PUBLIC int INTpipebuf_next(filebuf_t *buf, int advance);
#endif /* XP_WIN32 */

#ifdef XP_WIN32
NSAPI_PUBLIC void	INTpipebuf_close(filebuf_t *buf);
#endif /* XP_WIN32 */

/*
 * buffer_grab will set the buffer's inbuf array to an array of sz bytes 
 * from the buffer's associated object. It returns the number of bytes 
 * actually read (between 1 and sz). It returns IO_EOF upon EOF or IO_ERROR
 * upon error. The cursize entry of the structure will reflect the size
 * of the iobuf array.
 * 
 * The buffer will take care of allocation and deallocation of this array.
 */

NSAPI_PUBLIC int INTfilebuf_grab(filebuf_t *buf, int sz);
#ifdef XP_WIN32
NSAPI_PUBLIC int INTpipebuf_grab(filebuf_t *buf, int sz);
#endif /* XP_WIN32 */


/*
 * filebuf_buf2sd assumes that nothing has been read from the filebuf, 
 * and just sends the file out to the given socket. Returns IO_ERROR on error
 * and the number of bytes sent otherwise.
 *
 * Does not currently support you having read from the buffer previously. This
 * can be changed transparently.
 */

NSAPI_PUBLIC int INTfilebuf_buf2sd(filebuf_t *buf, SYS_NETFD sd);

#ifdef XP_WIN32

/*
 * NT pipe version of filebuf_buf2sd.
 */
NSAPI_PUBLIC int INTpipebuf_buf2sd(filebuf_t *buf, SYS_NETFD sd, int len);

#endif /* XP_WIN32 */

NSPR_END_EXTERN_C

#ifdef FILE_MMAP
#define filebuf_open_nostat INTfilebuf_open_nostat
#endif /* FILE_MMAP */
#define filebuf_open INTfilebuf_open
#define filebuf_close INTfilebuf_close
#define filebuf_next INTfilebuf_next
#define filebuf_grab INTfilebuf_grab
#define filebuf_create INTfilebuf_create
#define filebuf_buf2sd INTfilebuf_buf2sd

#ifdef XP_WIN32
#define pipebuf_open INTpipebuf_open
#define pipebuf_close INTpipebuf_close
#define pipebuf_next INTpipebuf_next
#define pipebuf_grab INTpipebuf_grab
#define pipebuf_buf2sd INTpipebuf_buf2sd
#endif /* XP_WIN32 */

#endif /* INTNSAPI */

#endif /* !BASE_BUFFER_H */
