First successful JSON round trip
This commit is contained in:
parent
33d17cd9a5
commit
d4f0bd202d
77
cpdfJSON.ml
77
cpdfJSON.ml
|
@ -1,3 +1,5 @@
|
||||||
|
(*FIXME failwiths -> Pdf.PDFError or similar *)
|
||||||
|
(*FIXME flprintfs to eprintf *)
|
||||||
open Pdfutil
|
open Pdfutil
|
||||||
|
|
||||||
module J = Tjjson
|
module J = Tjjson
|
||||||
|
@ -9,13 +11,26 @@ let soi = string_of_int
|
||||||
let string_of_float _ = failwith "use sof"
|
let string_of_float _ = failwith "use sof"
|
||||||
let string_of_int _ = failwith "use soi"
|
let string_of_int _ = failwith "use soi"
|
||||||
|
|
||||||
|
let rec object_of_json = function
|
||||||
|
| J.Null -> P.Null
|
||||||
|
| J.Bool b -> P.Boolean b
|
||||||
|
| J.Number n -> Pdf.Indirect (int_of_string n)
|
||||||
|
| J.String s -> P.String s
|
||||||
|
| J.Array objs -> P.Array (map object_of_json objs)
|
||||||
|
| J.Object ["I", J.Number i] -> P.Integer (int_of_string i)
|
||||||
|
| J.Object ["F", J.Number f] -> P.Real (float_of_string f)
|
||||||
|
| J.Object ["N", J.String n] -> P.Name n
|
||||||
|
| J.Object ["S", J.Array [dict; J.String data]] ->
|
||||||
|
P.Stream (ref (object_of_json dict, P.Got (Pdfio.bytes_of_string data)))
|
||||||
|
| J.Object elts -> P.Dictionary (map (fun (n, o) -> (n, object_of_json o)) elts)
|
||||||
|
|
||||||
let rec json_of_object pdf fcs no_stream_data = function
|
let rec json_of_object pdf fcs no_stream_data = function
|
||||||
| P.Null -> J.String "null"
|
| P.Null -> J.Null
|
||||||
| P.Boolean b -> J.Bool b
|
| P.Boolean b -> J.Bool b
|
||||||
| P.Integer i -> J.Number (soi i)
|
| P.Integer i -> J.Object [("I", J.Number (soi i))]
|
||||||
| P.Real r -> J.Number (sof r)
|
| P.Real r -> J.Object [("F", J.Number (sof r))]
|
||||||
| P.String s -> J.String s
|
| P.String s -> J.String s
|
||||||
| P.Name n -> J.String n
|
| P.Name n -> J.Object [("N", J.String n)]
|
||||||
| P.Array objs -> J.Array (map (json_of_object pdf fcs no_stream_data) objs)
|
| P.Array objs -> J.Array (map (json_of_object pdf fcs no_stream_data) objs)
|
||||||
| P.Dictionary elts ->
|
| P.Dictionary elts ->
|
||||||
iter
|
iter
|
||||||
|
@ -41,8 +56,8 @@ let rec json_of_object pdf fcs no_stream_data = function
|
||||||
match stream with P.Got b -> Pdfio.string_of_bytes b | P.ToGet _ -> "failure: toget"
|
match stream with P.Got b -> Pdfio.string_of_bytes b | P.ToGet _ -> "failure: toget"
|
||||||
end
|
end
|
||||||
in
|
in
|
||||||
json_of_object pdf fcs no_stream_data (P.Array [P.Dictionary dict; P.String str])
|
json_of_object pdf fcs no_stream_data (P.Dictionary [("S", P.Array [P.Dictionary dict; P.String str])])
|
||||||
| P.Stream _ -> J.String "error: stream with not-a-dictioary"
|
| P.Stream _ -> J.String "error: stream with not-a-dictionary"
|
||||||
| P.Indirect i ->
|
| P.Indirect i ->
|
||||||
begin match P.lookup_obj pdf i with
|
begin match P.lookup_obj pdf i with
|
||||||
| P.Stream {contents = (P.Dictionary dict as d, _)} ->
|
| P.Stream {contents = (P.Dictionary dict as d, _)} ->
|
||||||
|
@ -197,9 +212,12 @@ let json_of_pdf parse_content no_stream_data pdf =
|
||||||
let trailerdict = (0, json_of_object pdf (fun x -> ()) no_stream_data pdf.P.trailerdict) in
|
let trailerdict = (0, json_of_object pdf (fun x -> ()) no_stream_data pdf.P.trailerdict) in
|
||||||
let parameters =
|
let parameters =
|
||||||
(-1, json_of_object pdf (fun x -> ()) false
|
(-1, json_of_object pdf (fun x -> ()) false
|
||||||
(Pdf.Dictionary [("/CPDFJSONformatversion", Pdf.Integer 1);
|
(Pdf.Dictionary [("/CPDFJSONformatversion", Pdf.Integer 2);
|
||||||
("/CPDFJSONcontentparsed", Pdf.Boolean parse_content);
|
("/CPDFJSONcontentparsed", Pdf.Boolean parse_content);
|
||||||
("/CPDFJSONstreamdataincluded", Pdf.Boolean (not no_stream_data))]))
|
("/CPDFJSONstreamdataincluded", Pdf.Boolean (not no_stream_data));
|
||||||
|
("/CPDFJSONmajorpdfversion", Pdf.Integer pdf.Pdf.major);
|
||||||
|
("/CPDFJSONminorpdfversion", Pdf.Integer pdf.Pdf.minor);
|
||||||
|
]))
|
||||||
in
|
in
|
||||||
let content_streams = ref [] in
|
let content_streams = ref [] in
|
||||||
let fcs n = content_streams := n::!content_streams in
|
let fcs n = content_streams := n::!content_streams in
|
||||||
|
@ -239,22 +257,55 @@ let json_of_pdf parse_content no_stream_data pdf =
|
||||||
pairs_parsed)
|
pairs_parsed)
|
||||||
|
|
||||||
let pdf_of_json json =
|
let pdf_of_json json =
|
||||||
let major = 0 in
|
(*flprint (J.show json);
|
||||||
let minor = 1 in
|
flprint "\n";*)
|
||||||
let root = 2 in
|
let objs = match json with J.Array objs -> objs | _ -> failwith "bad json top level" in
|
||||||
|
let params = ref Pdf.Null in
|
||||||
|
let trailerdict = ref Pdf.Null in
|
||||||
|
let objects =
|
||||||
|
option_map
|
||||||
|
(function
|
||||||
|
| J.Array [J.Number n; o] ->
|
||||||
|
let objnum = int_of_string n in
|
||||||
|
begin match objnum with
|
||||||
|
| -1 -> params := object_of_json o; None
|
||||||
|
| 0 -> trailerdict := object_of_json o; None
|
||||||
|
| n when n < 0 -> None
|
||||||
|
| n -> Some (n, object_of_json o)
|
||||||
|
end
|
||||||
|
| _ -> failwith "json bad obj")
|
||||||
|
objs
|
||||||
|
in
|
||||||
|
(*List.iter (fun (i, o) -> flprint (soi i); flprint "\n"; flprint (Pdfwrite.string_of_pdf o); flprint "\n") objects;*)
|
||||||
|
let major =
|
||||||
|
match Pdf.lookup_direct (Pdf.empty ()) "/CPDFJSONmajorpdfversion" !params with
|
||||||
|
Some (Pdf.Integer i) -> i | _ -> failwith "bad major version"
|
||||||
|
in
|
||||||
|
let minor =
|
||||||
|
match Pdf.lookup_direct (Pdf.empty ()) "/CPDFJSONminorpdfversion" !params with
|
||||||
|
Some (Pdf.Integer i) -> i | _ -> failwith "bad minor version"
|
||||||
|
in
|
||||||
|
(*flprint (Pdfwrite.string_of_pdf !trailerdict);*)
|
||||||
|
let root =
|
||||||
|
match !trailerdict with Pdf.Dictionary d ->
|
||||||
|
begin match lookup "/Root" d with
|
||||||
|
Some (Pdf.Indirect i) -> i | _ -> failwith "bad root"
|
||||||
|
end
|
||||||
|
| _ -> failwith "bad root 2"
|
||||||
|
in
|
||||||
let objmap = P.pdfobjmap_empty () in
|
let objmap = P.pdfobjmap_empty () in
|
||||||
|
List.iter (fun (k, v) -> Hashtbl.add objmap k (ref (P.Parsed v), 0)) objects;
|
||||||
let objects =
|
let objects =
|
||||||
{P.maxobjnum = 0;
|
{P.maxobjnum = 0;
|
||||||
P.parse = None;
|
P.parse = None;
|
||||||
P.pdfobjects = objmap;
|
P.pdfobjects = objmap;
|
||||||
P.object_stream_ids = Hashtbl.create 0}
|
P.object_stream_ids = Hashtbl.create 0}
|
||||||
in
|
in
|
||||||
let trailerdict = P.Null in
|
|
||||||
{P.major;
|
{P.major;
|
||||||
P.minor;
|
P.minor;
|
||||||
P.root;
|
P.root;
|
||||||
P.objects;
|
P.objects;
|
||||||
P.trailerdict;
|
P.trailerdict = !trailerdict;
|
||||||
P.was_linearized = false;
|
P.was_linearized = false;
|
||||||
P.saved_encryption = None}
|
P.saved_encryption = None}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue