(no subject)
May. 1st, 2011 12:56 pmКто там объекты-классы-методы не любит? Покритикуйте и предложите вариант получше:
class virtual typeinfot ['a] =
object (self)
method virtual tyname : tyname;
method virtual tyver : tyver;
method virtual to_string : 'a -> string;
method to_output
(f_output : Substring.t -> IO.m unit)
(v : 'a)
: IO.m unit
=
f_output (Substring.of_string (self#to_string v))
;
method from_input
(tyver : tyver)
len
(f_input : Substring.t -> IO.m unit)
: IO.m 'a
=
if tyver <> self#tyver
then
IO.error (ty_ver_error
~tyname:self#tyname ~expected:self#tyver ~got:tyver)
else
let str = String.make len '\x00' in
f_input (Substring.of_string str) >>= fun () ->
try
IO.return (self#from_string tyver str)
with
[ e -> IO.error e ]
;
(* raises exception on failure, returns deserialized
value and the rest of the string on success. *)
method virtual from_substring
: tyver -> Substring.t -> ('a * Substring.t);
method from_string tyver str =
let (v, _rest) = self#from_substring tyver
(Substring.of_string str) in
v
;
end
;
class marshal ['a] ?(closures=False) ~name ~ver =
let flags =
if closures then [Marshal.Closures] else []
in
object (self)
inherit typeinfot ['a];
method tyname = name;
method tyver = ver;
method to_string (v : 'a) = Marshal.to_string v flags;
method from_substring got_tyver s =
if got_tyver <> self#tyver
then
raise (ty_ver_error
~tyname:self#tyname
~expected:self#tyver
~got:got_tyver)
else
let len = s.Substring.len in
if len < Marshal.header_size
then
raise (deserialize_error self#tyname
"marshal: less than header_size bytes")
else
let str = s.Substring.str in
let ofs = s.Substring.ofs in
let total_size = Marshal.total_size str ofs in
if len < total_size
then
raise (deserialize_error self#tyname
"marshal: less than total_size bytes")
else
let v = ((Marshal.from_string str ofs) : 'a) in
let rest = Substring.cut_first s total_size in
(v, rest)
;
end
;