summaryrefslogtreecommitdiff
path: root/testsuite/tests/basic-io-2/io.ml
blob: 016ac1549b2776c577f91e42d9b6d07962998f26 (plain)
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
(* TEST
  arguments = "io.ml"
  readonly_files = "test-file-short-lines"
*)

(* Test a file copy function *)

let test msg funct f1 f2 =
  print_string msg; print_newline();
  funct f1 f2;
  if Sys.command ("cmp " ^ f1 ^ " " ^ f2) = 0
  then print_string "passed"
  else print_string "FAILED";
  print_newline()

(* File copy with constant-sized chunks *)

let copy_file sz infile ofile =
  let ic = open_in_bin infile in
  let oc = open_out_bin ofile in
  let buffer = Bytes.create sz in
  let rec copy () =
    let n = input ic buffer 0 sz in
    if n = 0 then () else begin
      output oc buffer 0 n;
      copy ()
    end in
  copy();
  close_in ic;
  close_out oc

(* File copy with random-sized chunks *)

let copy_random sz infile ofile =
  let ic = open_in_bin infile in
  let oc = open_out_bin ofile in
  let buffer = Bytes.create sz in
  let rec copy () =
    let s = 1 + Random.int sz in
    let n = input ic buffer 0 s in
    if n = 0 then () else begin
      output oc buffer 0 n;
      copy ()
    end in
  copy();
  close_in ic;
  close_out oc

(* File copy line per line *)

let copy_line infile ofile =
  let ic = open_in_bin infile in
  let oc = open_out_bin ofile in
  try
    while true do
      output_string oc (input_line ic); output_char oc '\n'
    done
  with End_of_file ->
    close_in ic;
    close_out oc

(* Backward copy, with lots of seeks *)

let copy_seek chunksize infile ofile =
  let ic = open_in_bin infile in
  let oc = open_out_bin ofile in
  let size = in_channel_length ic in
  let buffer = Bytes.create chunksize in
  for i = (size - 1) / chunksize downto 0 do
    seek_in ic (i * chunksize);
    seek_out oc (i * chunksize);
    let n = input ic buffer 0 chunksize in
    output oc buffer 0 n
  done;
  close_in ic;
  close_out oc

(* Create long lines of text *)

let make_lines ofile =
  let oc = open_out_bin ofile in
  for i = 1 to 256 do
    output_string oc (String.make (i*64) '.'); output_char oc '\n'
  done;
  close_out oc

(* The test *)

let _ =
  let src = Sys.argv.(1) in
  let testio = Filename.temp_file "testio" "" in
  let lines = Filename.temp_file "lines" "" in
  test "16-byte chunks" (copy_file 16) src testio;
  test "256-byte chunks" (copy_file 256) src testio;
  test "4096-byte chunks" (copy_file 4096) src testio;
  test "65536-byte chunks" (copy_file 65536) src testio;
  test "19-byte chunks" (copy_file 19) src testio;
  test "263-byte chunks" (copy_file 263) src testio;
  test "4011-byte chunks" (copy_file 4011) src testio;
  test "0...8192 byte chunks" (copy_random 8192) src testio;
  test "line per line, short lines" copy_line "test-file-short-lines" testio;
  make_lines lines;
  test "line per line, short and long lines" copy_line lines testio;
  test "backwards, 4096-byte chunks" (copy_seek 4096) src testio;
  test "backwards, 64-byte chunks" (copy_seek 64) src testio;
  Sys.remove lines;
  Sys.remove testio;
  exit 0