1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
/**************************************************************************/
/* */
/* OCaml */
/* */
/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
/* */
/* Copyright 1996 Institut National de Recherche en Informatique et */
/* en Automatique. */
/* */
/* All rights reserved. This file is distributed under the terms of */
/* the GNU Lesser General Public License version 2.1, with the */
/* special exception on linking described in the file LICENSE. */
/* */
/**************************************************************************/
/* Buffered input/output */
#ifndef CAML_IO_H
#define CAML_IO_H
#ifdef CAML_INTERNALS
#include "camlatomic.h"
#include "misc.h"
#include "mlvalues.h"
#ifndef _MSC_VER
#include "platform.h"
#else
/* We avoid including platform.h (which is really only necessary here to declare
caml_plat_mutex) because that would end up pulling in pthread.h but we want
to hide it on the MSVC port as it is not the native way to handle threads.
So we inline here just the implementation of caml_plat_mutex on that port,
this should be kept in sync */
#include <stdint.h>
typedef intptr_t caml_plat_mutex;
#endif
#ifndef IO_BUFFER_SIZE
#define IO_BUFFER_SIZE 65536
#endif
#if defined(_WIN32)
typedef __int64 file_offset;
#else
#include <sys/types.h>
typedef off_t file_offset;
#endif
struct channel {
int fd; /* Unix file descriptor */
file_offset offset; /* Absolute position of fd in the file */
char * end; /* Physical end of the buffer */
char * curr; /* Current position in the buffer */
char * max; /* Logical end of the buffer (for input) */
caml_plat_mutex mutex; /* Mutex protecting buffer */
struct channel * next, * prev;/* Double chaining of channels (flush_all) */
uintnat refcount; /* Number of custom blocks owning the channel */
int flags; /* Bitfield */
char * buff; /* The buffer */
char * name; /* Optional name (to report fd leaks) */
};
enum {
CHANNEL_FLAG_FROM_SOCKET = 1, /* For Windows */
CHANNEL_FLAG_MANAGED_BY_GC = 4, /* Free and close using GC finalization */
CHANNEL_TEXT_MODE = 8, /* "Text mode" for Windows and Cygwin */
CHANNEL_FLAG_UNBUFFERED = 16 /* Unbuffered (for output channels only) */
};
/* For an output channel:
[offset] is the absolute position of the beginning of the buffer [buff].
For an input channel:
[offset] is the absolute position of the logical end of the buffer, [max].
*/
/* Creating and closing channels from C */
CAMLextern struct channel * caml_open_descriptor_in (int);
CAMLextern struct channel * caml_open_descriptor_out (int);
CAMLextern void caml_close_channel (struct channel *);
CAMLextern file_offset caml_channel_size (struct channel *);
CAMLextern void caml_seek_in (struct channel *, file_offset);
CAMLextern void caml_seek_out (struct channel *, file_offset);
CAMLextern file_offset caml_pos_in (struct channel *);
CAMLextern file_offset caml_pos_out (struct channel *);
/* I/O on channels from C. The channel must be locked (see below) before
calling any of the functions and macros below */
CAMLextern value caml_alloc_channel(struct channel *chan);
CAMLextern int caml_channel_binary_mode (struct channel *);
CAMLextern int caml_flush_partial (struct channel *);
CAMLextern void caml_flush (struct channel *);
CAMLextern void caml_flush_if_unbuffered (struct channel *);
CAMLextern void caml_putch(struct channel *, int);
CAMLextern void caml_putword (struct channel *, uint32_t);
CAMLextern int caml_putblock (struct channel *, char *, intnat);
CAMLextern void caml_really_putblock (struct channel *, char *, intnat);
CAMLextern unsigned char caml_refill (struct channel *);
CAMLextern unsigned char caml_getch(struct channel *);
CAMLextern uint32_t caml_getword (struct channel *);
CAMLextern int caml_getblock (struct channel *, char *, intnat);
CAMLextern intnat caml_really_getblock (struct channel *, char *, intnat);
/* Extract a struct channel * from the heap object representing it */
#define Channel(v) (*((struct channel **) (Data_custom_val(v))))
/* The locking machinery */
CAMLextern void caml_channel_lock(struct channel *);
CAMLextern void caml_channel_unlock(struct channel *);
/* Lock and Unlock are compatibility aliases for OCaml<5.2.
Remove whenever 5.2 is old enough. (See #12792.) */
#define Lock(channel) caml_channel_lock(channel)
#define Unlock(channel) caml_channel_unlock(channel)
CAMLextern void caml_channel_cleanup_on_raise(void);
CAMLextern struct channel * caml_all_opened_channels;
/* Conversion between file_offset and int64_t */
#define Val_file_offset(fofs) caml_copy_int64(fofs)
#define File_offset_val(v) ((file_offset) Int64_val(v))
/* Primitives required by the Unix library */
CAMLextern value caml_ml_open_descriptor_in(value fd);
CAMLextern value caml_ml_open_descriptor_out(value fd);
CAMLextern value caml_ml_open_descriptor_in_with_flags(int fd, int flags);
CAMLextern value caml_ml_open_descriptor_out_with_flags(int fd, int flags);
#endif /* CAML_INTERNALS */
#endif /* CAML_IO_H */
|