]> xenbits.xensource.com Git - xcp/xen-api-libs.git/commitdiff
[rpc-light] Add the marshalling/unmarshalling json code from xenclient.
authorThomas Gazagnaire <thomas.gazagnaire@citrix.com>
Tue, 13 Oct 2009 11:05:40 +0000 (12:05 +0100)
committerThomas Gazagnaire <thomas.gazagnaire@citrix.com>
Tue, 13 Oct 2009 11:05:40 +0000 (12:05 +0100)
Tpc-light is not compiled by default, so that should not interfere with the build system.

Signed-off-by: Thomas Gazagnaire <thomas.gazagnaire@citrix.com>
rpc-light/Makefile
rpc-light/jsonrpc.ml
rpc-light/jsonrpc.mli

index eca521fa995e7abf346ce75c1c61610ba46828ce..01904fa946c72b60f9866282881208244444dc86 100644 (file)
@@ -1,47 +1,64 @@
 OCAMLC = ocamlfind ocamlc
 OCAMLOPT = ocamlfind ocamlopt
 OCAMLFLAGS = -annot
+PACKS = xmlm
 
 ICAMLP4=-I $(shell ocamlfind query camlp4) -I $(shell ocamlfind query type-conv)
 
 .PHONY: all clean
-all: pa_rpc.cma xmlrpc.cma xmlrpc.cmxa
+all: pa_rpc.cma xmlrpc.cmi xmlrpc.cma xmlrpc.cmxa jsonrpc.cmi jsonrpc.cmxa jsonrpc.cma
+
 
 pa_rpc.cma: rpc.cmo pa_rpc.cmo
        $(OCAMLC) -a $(ICAMLP4) -o $@ $^
 
-xmlrpc.cmxa: rpc.cmx xmlrpc.cmx
+pa_rpc.cmo: pa_rpc.ml
+       $(OCAMLC) $(OCAMLFLAGS) -c -package camlp4,type-conv -pp "camlp4orf" $(ICAMLP4) $@ $<
+
+
+
+rpc.cmx: rpc.ml
+       $(OCAMLOPT) $(OCAMLFLAGS) -c -o $@ $<
+
+rpc.cmo: rpc.ml
+       $(OCAMLC) $(OCAMLFLAGS) -c -o $@ $<
+
+
+
+%.cmxa: rpc.cmx %.cmx
        $(OCAMLOPT) -a -o $@ $^
 
-xmlrpc.cma: rpc.cmo xmlrpc.cmo
+%.cma: rpc.cmo %.cmo
        $(OCAMLC) -a -o $@ $^
 
 
-xmlrpc.cmx: xmlrpc.ml xmlrpc.cmi
-       $(OCAMLOPT) $(OCAMLFLAGS) -c -I ../xml-light2 -o $@ $<
 
-xmlrpc.cmo: xmlrpc.ml xmlrpc.cmi
-       $(OCAMLC) $(OCAMLFLAGES) -c -I ../xml-light2 -o $@ $<
+xmlrpc.cmx: xmlrpc.ml xmlrpc.cmi rpc.ml
+       $(OCAMLOPT) $(OCAMLFLAGS) -package $(PACKS) -c -o $@ $<
 
-xmlrpc.cmi: xmlrpc.mli
-       $(OCAMLOPT) $(OCAMLFLAGS) -c -I ../xml-light2 -o $@ $<
+xmlrpc.cmo: xmlrpc.ml xmlrpc.cmi rpc.ml
+       $(OCAMLC) $(OCAMLFLAGS) -package $(PACKS) -c -o $@ $<
 
+xmlrpc.cmi: xmlrpc.mli rpc.ml
+       $(OCAMLOPT) $(OCAMLFLAGS) -package $(PACKS) -c -o $@ $<
 
-rpc.cmx: rpc.ml
-       $(OCAMLOPT) $(OCAMLFLAGS) -c -o $@ $<
 
-rpc.cmo: rpc.ml
-       $(OCAMLC) $(OCAMLFLAGS) -c -o $@ $<
+jsonrpc.cmx: jsonrpc.ml jsonrpc.cmi rpc.ml
+       $(OCAMLOPT) $(OCAMLFLAGS) -c -o $@ $<
 
+jsonrpc.cmo: jsonrpc.ml jsonrpc.cmi rpc.ml
+       $(OCAMLC) $(OCAMLFLAGS) -c  -o $@ $<
 
-pa_rpc.cmo: pa_rpc.ml
-       $(OCAMLC) $(OCAMLFLAGS) -c -package camlp4,type-conv -pp "camlp4orf" $(ICAMLP4) $@ $<
+jsonrpc.cmi: jsonrpc.mli rpc.ml
+       $(OCAMLOPT) $(OCAMLFLAGS) -c -o $@ $<
 
 
 .PHONY: install
 install: rpc.cmi pa_rpc.cma xmlrpc.cma xmlrpc.cmxa
        cp META-xmlrpc META
        ocamlfind install -destdir $(DESTDIR)$(shell ocamlfind printconf destdir) xmlrpc META xmlrpc.cma xmlrpc.cmxa xmlrpc.cmi rpc.cmi xmlrpc.cmx rpc.cmx xmlrpc.a xmlrpc.o
+       cp META-jsonrpc META
+       ocamlfind install -destdir $(DESTDIR)$(shell ocamlfind printconf destdir) jsonrpc META jsonrpc.cma jsonrpc.cmxa jsonrpc.cmi rpc.cmi jsonrpc.cmx rpc.cmx jsonrpc.a jsonrpc.o
        cp META-rpc-light META
        ocamlfind install -destdir $(DESTDIR)$(shell ocamlfind printconf destdir) rpc-light META pa_rpc.cma pa_rpc.cmi
        rm META
@@ -49,6 +66,7 @@ install: rpc.cmi pa_rpc.cma xmlrpc.cma xmlrpc.cmxa
 .PHONY: uninstall
 uninstall:
        ocamlfind remove xmlrpc
+       ocamlfind remove jsonrpc
        ocamlfind remove rpc-light
 
 clean:
index 55cf8b5fe15abd70551a4ac637457e4e182b626b..623470465e1bd9151b3e5797efc032613389f629 100644 (file)
@@ -1,5 +1,7 @@
 (*
- * Copyright (C) 2006-2009 Citrix Systems Inc.
+ * Copyright (C) 2009      Citrix Ltd.
+ * Author Prashanth Mundkur <firstname.lastname@citrix.com>
+ * Author Vincent Hanquez   <firstname.lastname@citrix.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published
@@ -12,8 +14,6 @@
  * GNU Lesser General Public License for more details.
  *)
 
-open Rpc
-
 let rec list_iter_between f o = function
        | []   -> ()
        | [h]  -> f h
@@ -43,18 +43,18 @@ let escape_string s =
 
 let rec to_fct t f =
        match t with
-       | Int i    -> f (Printf.sprintf "%Ld" i)
-       | Bool b   -> f (string_of_bool b)
-       | Float r  -> f (Printf.sprintf "%f" r)
-       | String s -> f (escape_string s)
-       | Null     -> f "null"
-       | Enum a   ->
+       | Rpc.Int i    -> f (Printf.sprintf "%Ld" i)
+       | Rpc.Double r -> f (Printf.sprintf "%f" r)
+       | Rpc.String s -> f (escape_string s)
+       | Rpc.Bool b   -> f (string_of_bool b)
+       | Rpc.Nil      -> f "null"
+       | Rpc.Array a  ->
                f "[";
                list_iter_between (fun i -> to_fct i f) (fun () -> f ", ") a;
                f "]";
-       | Dict a   ->
+       | Rpc.Struct a ->
                f "{";
-               list_iter_between (fun (k, v) -> to_fct (String k) f; f ": "; to_fct v f)
+               list_iter_between (fun (k, v) -> to_fct (Rpc.String k) f; f ": "; to_fct v f)
                                  (fun () -> f ", ") a;
                f "}"
 
@@ -66,33 +66,7 @@ let to_string t =
        to_buffer t buf;
        Buffer.contents buf
 
-let new_id =
-       let count = ref 0L in
-       (fun () -> count := Int64.add 1L !count; !count)
-
-let string_of_call call =
-       let json = Dict [
-               "method", String call.name;
-               "params", Enum call.params;
-               "id", Int (new_id ());
-       ] in
-       to_string json
-
-let string_of_response response =
-       let json =
-               if response.Rpc.success then
-                       Dict [
-                               "result", response.Rpc.contents;
-                               "error", Null;
-                               "id", Int 0L
-                       ]
-               else
-                       Dict [
-                               "result", Null;
-                               "error", response.Rpc.contents;
-                               "id", Int 0L
-                       ] in
-       to_string json
+
 
 type error =
        | Unexpected_char of int * char * (* json type *) string
@@ -122,13 +96,13 @@ module Parser = struct
                | Expect_object_elem_colon
                | Expect_comma_or_end
                | Expect_object_key
-               | Done of t
+               | Done of Rpc.t
 
        type int_value =
-               | IObject of (string * t) list
-               | IObject_needs_key of (string * t) list
-               | IObject_needs_value of (string * t) list * string
-               | IArray of t list
+               | IObject of (string * Rpc.t) list
+               | IObject_needs_key of (string * Rpc.t) list
+               | IObject_needs_value of (string * Rpc.t) list * string
+               | IArray of Rpc.t list
 
        type parse_state = {
                mutable cursor: cursor;
@@ -182,9 +156,10 @@ module Parser = struct
                | _ -> false
 
        let is_valid_unescaped_char c =
-               match c with
-                       | '"' | '\\' | '\b' | '\x0c' | '\n' | '\r' | '\t' -> false
-                       | _ -> true
+               match (Char.code c) with
+                       | 0x22 | 0x5c -> false
+                       | x when 0x20 <= x && x <= 0x7f -> true  (* only ASCII for now *)
+                       | _ -> false
 
        let clist_to_string cs =
                let len = List.length cs in
@@ -224,7 +199,7 @@ module Parser = struct
        let finish_value s v =
                match s.stack, v with
                | [], _ -> s.cursor <- Done v
-               | IObject_needs_key fields :: tl, String key ->
+               | IObject_needs_key fields :: tl, Rpc.String key ->
                        s.stack <- IObject_needs_value (fields, key) :: tl;
                        s.cursor <- Expect_object_elem_colon
                | IObject_needs_value (fields, key) :: tl, _ ->
@@ -238,8 +213,8 @@ module Parser = struct
 
        let pop_stack s =
                match s.stack with
-               | IObject fields :: tl -> s.stack <- tl; finish_value s (Dict (List.rev fields))
-               | IArray l :: tl       -> s.stack <- tl; finish_value s (Enum (List.rev l))
+               | IObject fields :: tl -> s.stack <- tl; finish_value s (Rpc.Struct (List.rev fields))
+               | IArray l :: tl       -> s.stack <- tl; finish_value s (Rpc.Array (List.rev l))
                | io :: tl             -> raise_internal_error s ("unexpected " ^ (ivalue_to_str io) ^ " on stack at pop_stack")
                | []                   -> raise_internal_error s "empty stack at pop_stack"
 
@@ -258,7 +233,7 @@ module Parser = struct
                        let str = tostring_with_leading_zero_check is in
                        let int = try Int64.of_string str
                        with Failure _ -> raise_invalid_value s str "int" in
-                       finish_value s (Int int) in
+                       finish_value s (Rpc.Int int) in
                let finish_int_exp is es =
                        let int = tostring_with_leading_zero_check is in
                        let exp = clist_to_string (List.rev es) in
@@ -268,14 +243,14 @@ module Parser = struct
                       returning float is more uniform. *)
                        let float = try float_of_string str
                        with Failure _ -> raise_invalid_value s str "float" in
-                       finish_value s (Float float) in
+                       finish_value s (Rpc.Double float) in
                let finish_float is fs =
                        let int = tostring_with_leading_zero_check is in
                        let frac = clist_to_string (List.rev fs) in
                        let str = Printf.sprintf "%s.%s" int frac in
                        let float = try float_of_string str
                        with Failure _ -> raise_invalid_value s str "float" in
-                       finish_value s (Float float) in
+                       finish_value s (Rpc.Double float) in
                let finish_float_exp is fs es =
                        let int = tostring_with_leading_zero_check is in
                        let frac = clist_to_string (List.rev fs) in
@@ -283,7 +258,7 @@ module Parser = struct
                        let str = Printf.sprintf "%s.%se%s" int frac exp in
                        let float = try float_of_string str
                        with Failure _ -> raise_invalid_value s str "float" in
-                       finish_value s (Float float) in
+                       finish_value s (Rpc.Double float) in
 
                match s.cursor with
                | Start ->
@@ -315,14 +290,14 @@ module Parser = struct
                        (match c, rem with
                        | 'u', 3 -> s.cursor <- In_null 2
                        | 'l', 2 -> s.cursor <- In_null 1
-                       | 'l', 1 -> finish_value s Null
+                       | 'l', 1 -> finish_value s Rpc.Nil
                        | _ -> raise_unexpected_char s c "null")
 
                | In_true rem ->
                        (match c, rem with
                        | 'r', 3 -> s.cursor <- In_true 2
                        | 'u', 2 -> s.cursor <- In_true 1
-                       | 'e', 1 -> finish_value s (Bool true)
+                       | 'e', 1 -> finish_value s (Rpc.Bool true)
                        | _ -> raise_unexpected_char s c "true")
 
                | In_false rem ->
@@ -330,7 +305,7 @@ module Parser = struct
                        | 'a', 4 -> s.cursor <- In_false 3
                        | 'l', 3 -> s.cursor <- In_false 2
                        | 's', 2 -> s.cursor <- In_false 1
-                       | 'e', 1 -> finish_value s (Bool false)
+                       | 'e', 1 -> finish_value s (Rpc.Bool false)
                        | _ -> raise_unexpected_char s c "false")
 
                | In_int is ->
@@ -367,7 +342,7 @@ module Parser = struct
                | In_string cs ->
                        (match c with
                        | '\\' -> s.cursor <- In_string_control cs
-                       | '"' -> finish_value s (String (clist_to_string (List.rev cs)))
+                       | '"' -> finish_value s (Rpc.String (clist_to_string (List.rev cs)))
                        | _ when is_valid_unescaped_char c -> s.cursor <- In_string (c :: cs)
                        | _ ->  raise_unexpected_char s c "string")
                        
@@ -396,7 +371,7 @@ module Parser = struct
                | Expect_object_elem_start ->
                        (match c with
                        | '"' -> s.stack <- (IObject_needs_key []) :: s.stack; s.cursor <- In_string []
-                       | '}' -> finish_value s (Dict [])
+                       | '}' -> finish_value s (Rpc.Struct [])
                        | _ when is_space c -> update_line_num s c
                        | _ -> raise_unexpected_char s c "object_start")
 
@@ -431,7 +406,7 @@ module Parser = struct
                | Done _ -> raise_internal_error s "parse called when parse_state is 'Done'"
 
        type parse_result =
-               | Json_value of t * (* number of consumed bytes *) int
+               | Json_value of Rpc.t * (* number of consumed bytes *) int
                | Json_parse_incomplete of parse_state
 
        let parse_substring state str ofs len =
@@ -481,40 +456,3 @@ module Parser = struct
 end
 
 let of_string = Parser.of_string
-
-exception Malformed_method_request of string
-exception Malformed_method_response of string
-
-let get name dict =
-       if List.mem_assoc name dict then
-               List.assoc name dict
-       else begin
-               Printf.eprintf "%s was not found in the dictionnary\n" name;
-               let str = List.map (fun (n,_) -> Printf.sprintf "%s=..." n) dict in
-               let str = Printf.sprintf "{%s}" (String.concat "," str) in
-               raise (Malformed_method_request str)
-       end
-
-let call_of_string str =
-       match of_string str with
-       | Dict d ->
-               let name = match get "method" d with String s -> s | _ -> raise (Malformed_method_request str) in
-               let params = match get "params" d with Enum l -> l | _ -> raise (Malformed_method_request str) in
-               let (_:int64) = match get "id" d with Int i -> i | _ -> raise (Malformed_method_request str) in
-               call name params
-       | _ -> raise (Malformed_method_request str)
-
-let response_of_string str =
-       match of_string str with
-       | Dict d ->
-                 let result = get "result" d in
-                 let error = get "error" d in
-                 let (_:int64) = match get "id" d with Int i -> i | _ -> raise (Malformed_method_response str) in
-                 begin match result, error with
-                         | Null, Null -> raise (Malformed_method_response str)
-                         | Null, v    -> failure v
-                         | v, Null    -> success v
-                         | _          -> raise (Malformed_method_response str)
-                 end
-       | _ -> raise (Malformed_method_response str)
-
index 076472b9cc0edd181c2bc4c29935f489627dca19..3d2b33e75d20c1061f3895922c06fb9e560e170b 100644 (file)
@@ -1,25 +1,11 @@
-(*
- * Copyright (C) 2006-2009 Citrix Systems Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; version 2.1 only. with the special
- * exception on linking described in file LICENSE.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *)
+       type error =
+               | Unexpected_char of int * char * (* json type *) string
+               | Invalid_value of int * (* value *) string * (* json type *) string
+               | Invalid_leading_zero of int * string
+               | Unterminated_value of int * string
+               | Internal_error of int * string
+
+exception Parse_error of error
 
 val to_string : Rpc.t -> string
 val of_string : string -> Rpc.t
-
-val string_of_call: Rpc.call -> string
-val call_of_string: string -> Rpc.call
-
-val string_of_response: Rpc.response -> string
-val response_of_string: string -> Rpc.response
-
-
-