mirror of https://github.com/nealey/irc-bot
Make Ocs_port use the type system better
This commit is contained in:
parent
41b96164b1
commit
33d30c694d
|
@ -2,62 +2,58 @@
|
||||||
|
|
||||||
open Ocs_error
|
open Ocs_error
|
||||||
|
|
||||||
type port_impl =
|
type port =
|
||||||
| Input_channel of in_channel
|
| Input_channel of in_channel * char option ref
|
||||||
| Output_channel of out_channel
|
| Output_channel of out_channel
|
||||||
| Input_string of string * int ref
|
| Input_string of (string * int ref) * char option ref
|
||||||
| Output_string of Buffer.t
|
| Output_string of Buffer.t
|
||||||
|
|
||||||
type port = {
|
|
||||||
ungot : char option ref;
|
|
||||||
impl : port_impl;
|
|
||||||
}
|
|
||||||
|
|
||||||
let is_input p =
|
let is_input p =
|
||||||
match p.impl with
|
match p with
|
||||||
| Input_string _
|
| Input_string _
|
||||||
| Input_channel _ -> true
|
| Input_channel _ -> true
|
||||||
| _ -> false
|
| _ -> false
|
||||||
|
|
||||||
let is_output p =
|
let is_output p =
|
||||||
match p.impl with
|
match p with
|
||||||
| Output_string _
|
| Output_string _
|
||||||
| Output_channel _ -> true
|
| Output_channel _ -> true
|
||||||
| _ -> false
|
| _ -> false
|
||||||
|
|
||||||
let getc p =
|
let getc p =
|
||||||
match (!(p.ungot), p.impl) with
|
match p with
|
||||||
| (Some c, _) ->
|
| Input_channel (_, ({contents = Some c} as ungot))
|
||||||
p.ungot := None;
|
| Input_string (_, ({contents = Some c} as ungot)) ->
|
||||||
|
ungot := None;
|
||||||
Some c
|
Some c
|
||||||
| (None, Input_string (str, pos)) ->
|
| Input_channel (chan, {contents = None}) ->
|
||||||
if !pos >= (String.length str) then
|
|
||||||
None
|
|
||||||
else
|
|
||||||
let c = str.[!pos] in
|
|
||||||
pos := !pos + 1;
|
|
||||||
Some c
|
|
||||||
| (None, Input_channel chan) ->
|
|
||||||
begin
|
begin
|
||||||
try
|
try
|
||||||
Some (input_char chan)
|
Some (input_char chan)
|
||||||
with End_of_file ->
|
with End_of_file ->
|
||||||
None
|
None
|
||||||
end
|
end
|
||||||
|
| Input_string ((str, pos), {contents = None}) ->
|
||||||
|
if !pos >= (String.length str) then
|
||||||
|
None
|
||||||
|
else
|
||||||
|
let c = str.[!pos] in
|
||||||
|
pos := !pos + 1;
|
||||||
|
Some c
|
||||||
| _ ->
|
| _ ->
|
||||||
None
|
None
|
||||||
|
|
||||||
let flush p =
|
let flush p =
|
||||||
match p.impl with
|
match p with
|
||||||
| Output_channel chan ->
|
| Output_channel chan ->
|
||||||
Pervasives.flush chan
|
Pervasives.flush chan
|
||||||
| _ ->
|
| _ ->
|
||||||
()
|
()
|
||||||
|
|
||||||
let close p =
|
let close p =
|
||||||
p.ungot := None;
|
match p with
|
||||||
match p.impl with
|
| Input_channel (chan, ungot) ->
|
||||||
| Input_channel chan ->
|
ungot := None;
|
||||||
close_in chan
|
close_in chan
|
||||||
| Output_channel chan ->
|
| Output_channel chan ->
|
||||||
close_out chan
|
close_out chan
|
||||||
|
@ -65,16 +61,21 @@ let close p =
|
||||||
()
|
()
|
||||||
|
|
||||||
let ungetc p c =
|
let ungetc p c =
|
||||||
p.ungot := Some c
|
match p with
|
||||||
|
| Input_channel (_, ungot)
|
||||||
|
| Input_string (_, ungot) ->
|
||||||
|
ungot := Some c
|
||||||
|
| _ ->
|
||||||
|
()
|
||||||
|
|
||||||
let char_ready p =
|
let char_ready p =
|
||||||
match (!(p.ungot), p.impl) with
|
match p with
|
||||||
| (Some _, Input_string _)
|
| Input_string (_, {contents = Some _})
|
||||||
| (Some _, Input_channel _) ->
|
| Input_channel (_, {contents = Some _}) ->
|
||||||
true
|
true
|
||||||
| (None, Input_string (str, pos)) ->
|
| Input_string ((str, pos), {contents = None}) ->
|
||||||
!pos < (String.length str)
|
!pos < (String.length str)
|
||||||
| (None, Input_channel chan) ->
|
| Input_channel (chan, {contents = None}) ->
|
||||||
let fd = Unix.descr_of_in_channel chan in
|
let fd = Unix.descr_of_in_channel chan in
|
||||||
let (r, _, _) = Unix.select [fd] [] [] 0.0 in
|
let (r, _, _) = Unix.select [fd] [] [] 0.0 in
|
||||||
List.length r > 0
|
List.length r > 0
|
||||||
|
@ -82,7 +83,7 @@ let char_ready p =
|
||||||
false
|
false
|
||||||
|
|
||||||
let putc p c =
|
let putc p c =
|
||||||
match p.impl with
|
match p with
|
||||||
| Output_string buf ->
|
| Output_string buf ->
|
||||||
Buffer.add_char buf c
|
Buffer.add_char buf c
|
||||||
| Output_channel chan ->
|
| Output_channel chan ->
|
||||||
|
@ -91,7 +92,7 @@ let putc p c =
|
||||||
()
|
()
|
||||||
|
|
||||||
let puts p s =
|
let puts p s =
|
||||||
match p.impl with
|
match p with
|
||||||
| Output_string buf ->
|
| Output_string buf ->
|
||||||
Buffer.add_string buf s
|
Buffer.add_string buf s
|
||||||
| Output_channel chan ->
|
| Output_channel chan ->
|
||||||
|
@ -99,11 +100,9 @@ let puts p s =
|
||||||
| _ ->
|
| _ ->
|
||||||
()
|
()
|
||||||
|
|
||||||
let input_port ch =
|
let input_port ch = Input_channel (ch, ref None)
|
||||||
{ ungot = ref None; impl = Input_channel ch }
|
|
||||||
|
|
||||||
let output_port ch =
|
let output_port ch = Output_channel ch
|
||||||
{ ungot = ref None; impl = Output_channel ch }
|
|
||||||
|
|
||||||
let open_input_port name =
|
let open_input_port name =
|
||||||
try
|
try
|
||||||
|
@ -117,14 +116,12 @@ let open_output_port name =
|
||||||
with Sys_error err ->
|
with Sys_error err ->
|
||||||
raise (Error ("unable to open '" ^ name ^ "' for output: " ^ err))
|
raise (Error ("unable to open '" ^ name ^ "' for output: " ^ err))
|
||||||
|
|
||||||
let open_input_string s =
|
let open_input_string s = Input_string ((s, ref 0), ref None)
|
||||||
{ ungot = ref None; impl = Input_string (s, ref 0) }
|
|
||||||
|
|
||||||
let open_output_string () =
|
let open_output_string () =Output_string (Buffer.create 256)
|
||||||
{ ungot = ref None; impl = Output_string (Buffer.create 256) }
|
|
||||||
|
|
||||||
let get_output_string p =
|
let get_output_string p =
|
||||||
match p.impl with
|
match p with
|
||||||
| Output_string buf ->
|
| Output_string buf ->
|
||||||
Buffer.contents buf
|
Buffer.contents buf
|
||||||
| _ ->
|
| _ ->
|
||||||
|
|
Loading…
Reference in New Issue