File: json.ml

package info (click to toggle)
pplacer 1.1~alpha19-4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 5,056 kB
  • sloc: ml: 20,927; ansic: 9,002; python: 1,641; makefile: 171; xml: 50; sh: 33
file content (79 lines) | stat: -rw-r--r-- 2,115 bytes parent folder | download | duplicates (2)
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
open Ppatteries
open Jsontype

let of_string ?fname s =
  let lexbuf = Lexing.from_string s in
  Sparse.wrap_of_fname_opt fname (Jsonparse.parse Jsonlex.token) lexbuf

let of_file fname =
  let fobj = MaybeZipped.open_in fname in
  let input s n =
    try
      IO.input fobj s 0 n
    with BatIO.No_more_input -> 0
  in
  let lexbuf = Lexing.from_function input in
  let ret = Sparse.file_parse_wrap
    fname
    (Jsonparse.parse Jsonlex.token)
    lexbuf
  in
  IO.close_in fobj;
  ret

let to_escape = Str.regexp "\\([\\\\\"/\b\012\n\r\t]\\)"
let quote = Str.global_substitute to_escape begin fun s ->
  match Str.replace_matched "\\1" s with
    | "\\" -> "\\\\"
    | "\"" -> "\\\""
    | "/" -> "\\/"
    | "\b" -> "\\b"
    | "\012" -> "\\f"
    | "\n" -> "\\n"
    | "\r" -> "\\r"
    | "\t" -> "\\t"
    | s -> failwith ("invalid " ^ s)
end

let rec to_formatter ff o =
  let rec aux = function
    | Bool b -> Format.fprintf ff "%s" (string_of_bool b)
    | Int i -> Format.fprintf ff "%d" i
    | Float f -> Format.fprintf ff "%.12g" f
    | String s -> Format.fprintf ff "\"%s\"" (quote s)
    | Object o ->
      Format.fprintf ff "@[<2>{@,";
      let _ = Hashtbl.fold (fun k v is_first ->
        if not is_first then Format.fprintf ff ",@ ";
        Format.fprintf ff "\"%s\":@ " (quote k);
        aux v;
        false
      ) o true in ();
      Format.fprintf ff "@]@,}"
    | Array o ->
      Format.fprintf ff "@[<2>[@,";
      let _ = List.fold_left (fun is_first o ->
        if not is_first then Format.fprintf ff ",@ ";
        aux o;
        false
      ) true o in ();
      Format.fprintf ff "@]@,]"
    | Null -> Format.fprintf ff "null"
  in
  Format.fprintf ff "@[";
  aux o;
  Format.fprintf ff "@]@."

let to_string o =
  let buf = Buffer.create 256 in
  to_formatter (Format.formatter_of_buffer buf) o;
  Buffer.contents buf

let to_file name o =
  let file = MaybeZipped.open_out name in
  let formatter= Format.make_formatter
    (fun s p l -> let _ = IO.output file (Bytes.of_string s) p l in ())
    (fun () -> IO.flush file)
  in
  to_formatter formatter o;
  close_out file