1995-08-09 08:06:35 -07:00
|
|
|
/***********************************************************************/
|
|
|
|
/* */
|
1996-04-30 07:53:58 -07:00
|
|
|
/* Objective Caml */
|
1995-08-09 08:06:35 -07:00
|
|
|
/* */
|
|
|
|
/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
|
|
|
|
/* */
|
1996-04-30 07:53:58 -07:00
|
|
|
/* Copyright 1996 Institut National de Recherche en Informatique et */
|
1999-11-17 10:59:06 -08:00
|
|
|
/* en Automatique. All rights reserved. This file is distributed */
|
|
|
|
/* under the terms of the GNU Library General Public License. */
|
1995-08-09 08:06:35 -07:00
|
|
|
/* */
|
|
|
|
/***********************************************************************/
|
|
|
|
|
|
|
|
/* $Id$ */
|
|
|
|
|
1995-05-04 03:15:53 -07:00
|
|
|
/* Buffered input/output */
|
|
|
|
|
|
|
|
#ifndef _io_
|
|
|
|
#define _io_
|
|
|
|
|
|
|
|
|
|
|
|
#include "misc.h"
|
|
|
|
#include "mlvalues.h"
|
|
|
|
|
|
|
|
#ifndef IO_BUFFER_SIZE
|
|
|
|
#define IO_BUFFER_SIZE 4096
|
|
|
|
#endif
|
|
|
|
|
|
|
|
struct channel {
|
|
|
|
int fd; /* Unix file descriptor */
|
|
|
|
long offset; /* Absolute position of fd in the file */
|
|
|
|
char * end; /* Physical end of the buffer */
|
1996-04-18 09:29:57 -07:00
|
|
|
char * curr; /* Current position in the buffer */
|
|
|
|
char * max; /* Logical end of the buffer (for input) */
|
1997-08-29 08:37:22 -07:00
|
|
|
void * mutex; /* Placeholder for mutex (for systhreads) */
|
2001-10-09 08:14:01 -07:00
|
|
|
struct channel * next; /* Linear chaining of channels (flush_all) */
|
|
|
|
int revealed; /* For Cash only */
|
|
|
|
int old_revealed; /* For Cash only */
|
2001-11-13 07:41:18 -08:00
|
|
|
int refcount; /* For flush_all and for Cash */
|
1997-08-29 08:37:22 -07:00
|
|
|
char buff[IO_BUFFER_SIZE]; /* The buffer itself */
|
1995-05-04 03:15:53 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
/* For an output channel:
|
|
|
|
[offset] is the absolute position of the beginning of the buffer [buff].
|
|
|
|
For an input channel:
|
1996-04-18 09:29:57 -07:00
|
|
|
[offset] is the absolute position of the logical end of the buffer, [max].
|
1995-05-04 03:15:53 -07:00
|
|
|
*/
|
|
|
|
|
1997-08-29 08:37:22 -07:00
|
|
|
/* Functions and macros that can be called from C. Take arguments of
|
|
|
|
type struct channel *. No locking is performed. */
|
|
|
|
|
2001-08-13 06:53:51 -07:00
|
|
|
#define putch(channel, ch) do{ \
|
|
|
|
if ((channel)->curr >= (channel)->end) flush_partial(channel); \
|
|
|
|
*((channel)->curr)++ = (ch); \
|
|
|
|
}while(0)
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
#define getch(channel) \
|
|
|
|
((channel)->curr >= (channel)->max \
|
|
|
|
? refill(channel) \
|
|
|
|
: (unsigned char) *((channel))->curr++)
|
|
|
|
|
2001-10-09 08:14:01 -07:00
|
|
|
CAMLextern struct channel * open_descriptor_in (int);
|
|
|
|
CAMLextern struct channel * open_descriptor_out (int);
|
2001-08-28 07:47:48 -07:00
|
|
|
CAMLextern void close_channel (struct channel *);
|
|
|
|
CAMLextern int channel_binary_mode (struct channel *);
|
1996-04-18 09:29:57 -07:00
|
|
|
|
2001-08-28 07:47:48 -07:00
|
|
|
CAMLextern int flush_partial (struct channel *);
|
|
|
|
CAMLextern void flush (struct channel *);
|
|
|
|
CAMLextern void putword (struct channel *, uint32);
|
|
|
|
CAMLextern int putblock (struct channel *, char *, long);
|
|
|
|
CAMLextern void really_putblock (struct channel *, char *, long);
|
1996-04-18 09:29:57 -07:00
|
|
|
|
2001-08-28 07:47:48 -07:00
|
|
|
CAMLextern unsigned char refill (struct channel *);
|
|
|
|
CAMLextern uint32 getword (struct channel *);
|
|
|
|
CAMLextern int getblock (struct channel *, char *, long);
|
|
|
|
CAMLextern int really_getblock (struct channel *, char *, long);
|
1995-05-04 03:15:53 -07:00
|
|
|
|
1997-08-29 08:37:22 -07:00
|
|
|
/* Extract a struct channel * from the heap object representing it */
|
|
|
|
|
2000-02-10 06:04:59 -08:00
|
|
|
#define Channel(v) (*((struct channel **) (Data_custom_val(v))))
|
1997-08-29 08:37:22 -07:00
|
|
|
|
|
|
|
/* The locking machinery */
|
|
|
|
|
2001-08-28 07:47:48 -07:00
|
|
|
CAMLextern void (*channel_mutex_free) (struct channel *);
|
|
|
|
CAMLextern void (*channel_mutex_lock) (struct channel *);
|
|
|
|
CAMLextern void (*channel_mutex_unlock) (struct channel *);
|
|
|
|
CAMLextern void (*channel_mutex_unlock_exn) (void);
|
1997-08-29 08:37:22 -07:00
|
|
|
|
|
|
|
#define Lock(channel) \
|
|
|
|
if (channel_mutex_lock != NULL) (*channel_mutex_lock)(channel)
|
|
|
|
#define Unlock(channel) \
|
|
|
|
if (channel_mutex_unlock != NULL) (*channel_mutex_unlock)(channel)
|
|
|
|
#define Unlock_exn() \
|
|
|
|
if (channel_mutex_unlock_exn != NULL) (*channel_mutex_unlock_exn)()
|
|
|
|
|
1995-05-04 03:15:53 -07:00
|
|
|
#endif /* _io_ */
|