summaryrefslogtreecommitdiff
path: root/byterun
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>2002-03-02 09:16:39 +0000
committerXavier Leroy <xavier.leroy@inria.fr>2002-03-02 09:16:39 +0000
commitbddfe5d0cecccc8aa995fe95c4af5cbc41743747 (patch)
tree5ca9135daa03b182b678b4ca01092f103be27549 /byterun
parent00d7dbf924dccb864a839fdfa86001e9fe48142e (diff)
downloadocaml-bddfe5d0cecccc8aa995fe95c4af5cbc41743747.tar.gz
Ajout operations sur gros fichiers
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@4474 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'byterun')
-rw-r--r--byterun/ints.c6
-rw-r--r--byterun/io.c81
-rw-r--r--byterun/io.h18
-rw-r--r--byterun/sys.c2
4 files changed, 94 insertions, 13 deletions
diff --git a/byterun/ints.c b/byterun/ints.c
index e9ad194014..b28807bc57 100644
--- a/byterun/ints.c
+++ b/byterun/ints.c
@@ -267,10 +267,6 @@ CAMLexport int64 Int64_val(value v)
return buffer.j;
}
-CAMLexport void Store_int64(value v, int64 i)
-{
-}
-
#endif
static int int64_compare(value v1, value v2)
@@ -452,7 +448,7 @@ CAMLprim value int64_float_of_bits(value vi)
#else
static char int64_error[] =
- "The type Int64.t is not supported on this platform";
+ "The type int64 is not supported on this platform";
value copy_int64(int64 i)
{ invalid_argument(int64_error); }
diff --git a/byterun/io.c b/byterun/io.c
index 1b2b413c7a..614f63db96 100644
--- a/byterun/io.c
+++ b/byterun/io.c
@@ -15,10 +15,15 @@
/* Buffered input/output. */
+#define _FILE_OFFSET_BITS 64
+
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <string.h>
+#if !macintosh
+#include <sys/types.h>
+#endif
#include "config.h"
#ifdef HAS_UNISTD
#include <unistd.h>
@@ -104,9 +109,9 @@ CAMLexport void close_channel(struct channel *channel)
stat_free(channel);
}
-CAMLexport long channel_size(struct channel *channel)
+CAMLexport file_offset channel_size(struct channel *channel)
{
- long end;
+ file_offset end;
end = lseek(channel->fd, 0, SEEK_END);
if (end == -1 ||
@@ -240,7 +245,7 @@ CAMLexport void really_putblock(struct channel *channel, char *p, long int len)
}
}
-CAMLexport void seek_out(struct channel *channel, long int dest)
+CAMLexport void seek_out(struct channel *channel, file_offset dest)
{
flush(channel);
if (lseek(channel->fd, dest, 0) != dest) sys_error(NO_ARG);
@@ -337,7 +342,7 @@ CAMLexport int really_getblock(struct channel *chan, char *p, long int n)
return (n == 0);
}
-CAMLexport void seek_in(struct channel *channel, long int dest)
+CAMLexport void seek_in(struct channel *channel, file_offset dest)
{
if (dest >= channel->offset - (channel->max - channel->buff) &&
dest <= channel->offset) {
@@ -486,9 +491,25 @@ CAMLprim value caml_close_channel(value vchannel)
return Val_unit;
}
+/* EOVERFLOW is the Unix98 error indicating that a file position or file
+ size is not representable.
+ ERANGE is the ANSI C error indicating that some argument to some
+ function is out of range. This is less precise than EOVERFLOW,
+ but guaranteed to be defined on all ANSI C environments. */
+#ifndef EOVERFLOW
+#define EOVERFLOW ERANGE
+#endif
+
CAMLprim value caml_channel_size(value vchannel)
{
- return Val_long(channel_size(Channel(vchannel)));
+ file_offset size = channel_size(Channel(vchannel));
+ if (size > Max_long) { errno = EOVERFLOW; sys_error(NO_ARG); }
+ return Val_long(size);
+}
+
+CAMLprim value caml_channel_size_64(value vchannel)
+{
+ return Val_file_offset(channel_size(Channel(vchannel)));
}
CAMLprim value caml_set_binary_mode(value vchannel, value mode)
@@ -578,9 +599,25 @@ CAMLprim value caml_seek_out(value vchannel, value pos)
return Val_unit;
}
+CAMLprim value caml_seek_out_64(value vchannel, value pos)
+{
+ struct channel * channel = Channel(vchannel);
+ Lock(channel);
+ seek_out(channel, File_offset_val(pos));
+ Unlock(channel);
+ return Val_unit;
+}
+
CAMLprim value caml_pos_out(value vchannel)
{
- return Val_long(pos_out(Channel(vchannel)));
+ file_offset pos = pos_out(Channel(vchannel));
+ if (pos > Max_long) { errno = EOVERFLOW; sys_error(NO_ARG); }
+ return Val_long(pos);
+}
+
+CAMLprim value caml_pos_out_64(value vchannel)
+{
+ return Val_file_offset(pos_out(Channel(vchannel)));
}
CAMLprim value caml_input_char(value vchannel)
@@ -649,9 +686,25 @@ CAMLprim value caml_seek_in(value vchannel, value pos)
return Val_unit;
}
+CAMLprim value caml_seek_in_64(value vchannel, value pos)
+{
+ struct channel * channel = Channel(vchannel);
+ Lock(channel);
+ seek_in(channel, File_offset_val(pos));
+ Unlock(channel);
+ return Val_unit;
+}
+
CAMLprim value caml_pos_in(value vchannel)
{
- return Val_long(pos_in(Channel(vchannel)));
+ file_offset pos = pos_in(Channel(vchannel));
+ if (pos > Max_long) { errno = EOVERFLOW; sys_error(NO_ARG); }
+ return Val_long(pos);
+}
+
+CAMLprim value caml_pos_in_64(value vchannel)
+{
+ return Val_file_offset(pos_in(Channel(vchannel)));
}
CAMLprim value caml_input_scan_line(value vchannel)
@@ -664,3 +717,17 @@ CAMLprim value caml_input_scan_line(value vchannel)
Unlock(channel);
return Val_long(res);
}
+
+/* Conversion between file_offset and int64 */
+
+#ifndef ARCH_INT64_TYPE
+CAMLexport value Val_file_offset(file_offset fofs)
+{
+ invalid_argument("The type int64 is not supported on this platform");
+}
+
+CAMLexport file_offset File_offset_val(value v)
+{
+ invalid_argument("The type int64 is not supported on this platform");
+}
+#endif
diff --git a/byterun/io.h b/byterun/io.h
index 04bfd28c12..83c61ed629 100644
--- a/byterun/io.h
+++ b/byterun/io.h
@@ -26,9 +26,15 @@
#define IO_BUFFER_SIZE 4096
#endif
+#ifdef HAS_OFF_T
+typedef off_t file_offset;
+#else
+typedef long file_offset;
+#endif
+
struct channel {
int fd; /* Unix file descriptor */
- long offset; /* Absolute position of fd in the file */
+ 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) */
@@ -93,4 +99,14 @@ CAMLextern void (*channel_mutex_unlock_exn) (void);
#define Unlock_exn() \
if (channel_mutex_unlock_exn != NULL) (*channel_mutex_unlock_exn)()
+/* Conversion between file_offset and int64 */
+
+#ifdef ARCH_INT64_TYPE
+#define Val_file_offset(fofs) copy_int64(fofs)
+#define File_offset_val(v) ((file_offset) Int64_val(v))
+#else
+CAMLextern value Val_file_offset(file_offset fofs);
+CAMLextern file_offset File_offset_val(value v);
+#endif
+
#endif /* _io_ */
diff --git a/byterun/sys.c b/byterun/sys.c
index cb70ba345a..9261bce497 100644
--- a/byterun/sys.c
+++ b/byterun/sys.c
@@ -15,6 +15,8 @@
/* Basic system calls */
+#define _FILE_OFFSET_BITS 64
+
#include <errno.h>
#include <fcntl.h>
#include <signal.h>