1 /**************************************************************************/ 2 /* */ 3 /* OCaml */ 4 /* */ 5 /* Xavier Leroy, projet Cristal, INRIA Rocquencourt */ 6 /* */ 7 /* Copyright 1996 Institut National de Recherche en Informatique et */ 8 /* en Automatique. */ 9 /* */ 10 /* All rights reserved. This file is distributed under the terms of */ 11 /* the GNU Lesser General Public License version 2.1, with the */ 12 /* special exception on linking described in the file LICENSE. */ 13 /* */ 14 /**************************************************************************/ 15 16 /* Buffered input/output */ 17 18 #ifndef CAML_IO_H 19 #define CAML_IO_H 20 21 #ifdef CAML_INTERNALS 22 23 #include "misc.h" 24 #include "mlvalues.h" 25 26 #ifndef IO_BUFFER_SIZE 27 #define IO_BUFFER_SIZE 65536 28 #endif 29 30 #if defined(_WIN32) 31 typedef __int64 file_offset; 32 #elif defined(HAS_OFF_T) 33 #include <sys/types.h> 34 typedef off_t file_offset; 35 #else 36 typedef long file_offset; 37 #endif 38 39 struct channel { 40 int fd; /* Unix file descriptor */ 41 file_offset offset; /* Absolute position of fd in the file */ 42 char * end; /* Physical end of the buffer */ 43 char * curr; /* Current position in the buffer */ 44 char * max; /* Logical end of the buffer (for input) */ 45 void * mutex; /* Placeholder for mutex (for systhreads) */ 46 struct channel * next, * prev;/* Double chaining of channels (flush_all) */ 47 int revealed; /* For Cash only */ 48 int old_revealed; /* For Cash only */ 49 int refcount; /* For flush_all and for Cash */ 50 int flags; /* Bitfield */ 51 char buff[IO_BUFFER_SIZE]; /* The buffer itself */ 52 char * name; /* Optional name (to report fd leaks) */ 53 }; 54 55 enum { 56 CHANNEL_FLAG_FROM_SOCKET = 1, /* For Windows */ 57 #if defined(NATIVE_CODE) && defined(WITH_SPACETIME) 58 CHANNEL_FLAG_BLOCKING_WRITE = 2, 59 #endif 60 }; 61 62 /* For an output channel: 63 [offset] is the absolute position of the beginning of the buffer [buff]. 64 For an input channel: 65 [offset] is the absolute position of the logical end of the buffer, [max]. 66 */ 67 68 /* Functions and macros that can be called from C. Take arguments of 69 type struct channel *. No locking is performed. */ 70 71 #define caml_putch(channel, ch) do{ \ 72 if ((channel)->curr >= (channel)->end) caml_flush_partial(channel); \ 73 *((channel)->curr)++ = (ch); \ 74 }while(0) 75 76 #define caml_getch(channel) \ 77 ((channel)->curr >= (channel)->max \ 78 ? caml_refill(channel) \ 79 : (unsigned char) *((channel)->curr)++) 80 81 CAMLextern struct channel * caml_open_descriptor_in (int); 82 CAMLextern struct channel * caml_open_descriptor_out (int); 83 CAMLextern void caml_close_channel (struct channel *); 84 CAMLextern int caml_channel_binary_mode (struct channel *); 85 CAMLextern value caml_alloc_channel(struct channel *chan); 86 87 CAMLextern int caml_flush_partial (struct channel *); 88 CAMLextern void caml_flush (struct channel *); 89 CAMLextern void caml_putword (struct channel *, uint32_t); 90 CAMLextern int caml_putblock (struct channel *, char *, intnat); 91 CAMLextern void caml_really_putblock (struct channel *, char *, intnat); 92 93 CAMLextern unsigned char caml_refill (struct channel *); 94 CAMLextern uint32_t caml_getword (struct channel *); 95 CAMLextern int caml_getblock (struct channel *, char *, intnat); 96 CAMLextern intnat caml_really_getblock (struct channel *, char *, intnat); 97 98 /* Extract a struct channel * from the heap object representing it */ 99 100 #define Channel(v) (*((struct channel **) (Data_custom_val(v)))) 101 102 /* The locking machinery */ 103 104 CAMLextern void (*caml_channel_mutex_free) (struct channel *); 105 CAMLextern void (*caml_channel_mutex_lock) (struct channel *); 106 CAMLextern void (*caml_channel_mutex_unlock) (struct channel *); 107 CAMLextern void (*caml_channel_mutex_unlock_exn) (void); 108 109 CAMLextern struct channel * caml_all_opened_channels; 110 111 #define Lock(channel) \ 112 if (caml_channel_mutex_lock != NULL) (*caml_channel_mutex_lock)(channel) 113 #define Unlock(channel) \ 114 if (caml_channel_mutex_unlock != NULL) (*caml_channel_mutex_unlock)(channel) 115 #define Unlock_exn() \ 116 if (caml_channel_mutex_unlock_exn != NULL) (*caml_channel_mutex_unlock_exn)() 117 118 /* Conversion between file_offset and int64_t */ 119 120 #define Val_file_offset(fofs) caml_copy_int64(fofs) 121 #define File_offset_val(v) ((file_offset) Int64_val(v)) 122 123 #endif /* CAML_INTERNALS */ 124 125 #endif /* CAML_IO_H */ 126