Making String.escaped work on exotic Unicode strings

"[email protected] [ocaml_beginners]" <[email protected]> 13 Nov 2016 07:34:27 -0800
Newsgroups gmane.comp.lang.ocaml.beginners
Message-ID <[email protected]>
The example code below shows that String.escaped does not work
on exotic strings.  How can I fix this ?
   
 In the second code snippet below, I also append my failed attempt
to use the Uutf module.

   I've also heard of Camomile, but I'd prefer a hands-on solution
explaining the principles at work rather than just use a bulky library.
 
$ echo -e "\xE2\x98\xA0" > barney
$ ocaml
        OCaml version 4.02.1

# let barneys_channel=open_in "barney";;
val barneys_channel : in_channel = <abstr>
# let m=in_channel_length(barneys_channel);;
val m : int = 4
# let my_buffer=Buffer.create m;;
val my_buffer : Buffer.t = <abstr>
# Buffer.add_channel my_buffer barneys_channel m;;
- : unit = ()
# close_in barneys_channel;;
- : unit = ()
# let strange_string=Buffer.contents my_buffer;;
val strange_string : string = "?\152?\n"
# let quoted_strange_string=String.escaped strange_string;;
val quoted_strange_string : string = "?\\152?\\n"
# let my_strange_string="?\\152?\\n";;
val my_strange_string : string = "?\\152?\\n"
# let copy_successful=(my_strange_string=strange_string);;
val copy_successful : bool = false

Second attempt (using the Uutf library) : 

# let lines ?encoding (src : [`Channel of in_channel | `String of string]) =
  let rec loop d buf acc = match Uutf.decode d with
  | `Uchar 0x000A ->
      let line = Buffer.contents buf in
      Buffer.clear buf; loop d buf (line :: acc)
  | `Uchar u -> Uutf.Buffer.add_utf_8 buf u; loop d buf acc
  | `End -> List.rev (Buffer.contents buf :: acc)
  | `Malformed _ -> Uutf.Buffer.add_utf_8 buf Uutf.u_rep; loop d buf acc
  | `Await -> assert false
  in
  let nln = `Readline 0x000A in
  loop (Uutf.decoder ~nln ?encoding src) (Buffer.create 512) []                      ;;
val lines :
  ?encoding:[< Uutf.decoder_encoding ] ->
  [ `Channel of in_channel | `String of string ] -> string list = <fun>
# lines (`String strange_string);;
- : string list = ["?\152?"; ""]
# let second_copy_successful=(strange_string="?\152?");;
val second_copy_successful : bool = false