summaryrefslogtreecommitdiffstats
path: root/stdlib
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>2002-02-11 13:49:36 +0000
committerXavier Leroy <xavier.leroy@inria.fr>2002-02-11 13:49:36 +0000
commit7f765d521eb9014f42fdf0a83d3c31be897d8dd6 (patch)
treee2a4c64b02a5de6de9eac2d7fb0ff9eab6038616 /stdlib
parentbca8197e9ef78de214afee66bf0a03022307268a (diff)
Reimplementation de input_line pour meilleures performances sur longues lignes (PR#813)
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@4374 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'stdlib')
-rw-r--r--stdlib/pervasives.ml44
1 files changed, 27 insertions, 17 deletions
diff --git a/stdlib/pervasives.ml b/stdlib/pervasives.ml
index ce0a33744..a13c925f3 100644
--- a/stdlib/pervasives.ml
+++ b/stdlib/pervasives.ml
@@ -310,23 +310,33 @@ let really_input ic s ofs len =
external input_scan_line : in_channel -> int = "caml_input_scan_line"
-let rec input_line chan =
- let n = input_scan_line chan in
- if n = 0 then (* n = 0: we are at EOF *)
- raise End_of_file
- else if n > 0 then begin (* n > 0: newline found in buffer *)
- let res = string_create (n-1) in
- ignore (unsafe_input chan res 0 (n-1));
- ignore (input_char chan); (* skip the newline *)
- res
- end else begin (* n < 0: newline not found *)
- let beg = string_create (-n) in
- ignore(unsafe_input chan beg 0 (-n));
- try
- beg ^ input_line chan
- with End_of_file ->
- beg
- end
+let input_line chan =
+ let rec build_result buf pos = function
+ [] -> buf
+ | hd :: tl ->
+ let len = string_length hd in
+ string_blit hd 0 buf (pos - len) len;
+ build_result buf (pos - len) tl in
+ let rec scan accu len =
+ let n = input_scan_line chan in
+ if n = 0 then begin (* n = 0: we are at EOF *)
+ match accu with
+ [] -> raise End_of_file
+ | _ -> build_result (string_create len) len accu
+ end else if n > 0 then begin (* n > 0: newline found in buffer *)
+ let res = string_create (n-1) in
+ ignore (unsafe_input chan res 0 (n-1));
+ ignore (input_char chan); (* skip the newline *)
+ match accu with
+ [] -> res
+ | _ -> let len = len + n - 1 in
+ build_result (string_create len) len (res :: accu)
+ end else begin (* n < 0: newline not found *)
+ let beg = string_create (-n) in
+ ignore(unsafe_input chan beg 0 (-n));
+ scan (beg :: accu) (len - n)
+ end
+ in scan [] 0
external input_byte : in_channel -> int = "caml_input_char"
external input_binary_int : in_channel -> int = "caml_input_int"