Compatibility.ml 1.64 KB
Newer Older
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
module Bytes = struct

  include Bytes

  let escaped s =
    let n = ref 0 in
    for i = 0 to length s - 1 do
      n := !n +
        (match unsafe_get s i with
         | '\"' | '\\' | '\n' | '\t' | '\r' | '\b' -> 2
         | ' ' .. '~' -> 1
         | _ -> 4)
    done;
    if !n = length s then copy s else begin
      let s' = create !n in
      n := 0;
      for i = 0 to length s - 1 do
        begin match unsafe_get s i with
        | ('\"' | '\\') as c ->
            unsafe_set s' !n '\\'; incr n; unsafe_set s' !n c
        | '\n' ->
            unsafe_set s' !n '\\'; incr n; unsafe_set s' !n 'n'
        | '\t' ->
            unsafe_set s' !n '\\'; incr n; unsafe_set s' !n 't'
        | '\r' ->
            unsafe_set s' !n '\\'; incr n; unsafe_set s' !n 'r'
        | '\b' ->
            unsafe_set s' !n '\\'; incr n; unsafe_set s' !n 'b'
        | (' ' .. '~') as c -> unsafe_set s' !n c
        | c ->
            let a = Char.code c in
            unsafe_set s' !n '\\';
            incr n;
            unsafe_set s' !n (Char.chr (48 + a / 100));
            incr n;
            unsafe_set s' !n (Char.chr (48 + (a / 10) mod 10));
            incr n;
            unsafe_set s' !n (Char.chr (48 + a mod 10));
        end;
        incr n
      done;
      s'
    end

end

module String = struct

  open String

  let escaped s =
    let rec escape_if_needed s n i =
      if i >= n then s else
        match unsafe_get s i with
        | '\"' | '\\' | '\000'..'\031' | '\127'.. '\255' ->
            Bytes.unsafe_to_string (Bytes.escaped (Bytes.unsafe_of_string s))
        | _ -> escape_if_needed s n (i+1)
    in
    escape_if_needed s (length s) 0

end