ffi: fix support for generated calls with generic types (for Java FFI)
[nit.git] / lib / json / json_reader.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2012-2013 Alexis Laferrière <alexis.laf@xymus.net>
4 #
5 # This file is free software, which comes along with NIT. This software is
6 # distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
7 # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8 # PARTICULAR PURPOSE. You can modify it is you want, provided this header
9 # is kept unaltered, and a notification of the changes is added.
10 # You are allowed to redistribute it and sell it, alone or is a part of
11 # another product.
12
13 # Deserialisation from the Json format to Nit objects
14 module json_reader
15
16 intrude import jsonable
17
18 in "C Header" `{
19 #define __STRICT_ANSI__
20 #include <json/json.h>
21 `}
22
23 redef class String
24 # Deserializes this String and return its value as a Map[String, nullable Jsonable]
25 # On error, null is returned.
26 fun json_to_object : nullable Map[String, nullable Jsonable] import NativeString.to_s, JsonObject.json_to_map `{
27 char *native_recv;
28 json_object *jobj;
29 nullable_Map_of_String_nullable_Jsonable map;
30
31 native_recv = String_to_cstring( recv );
32 jobj = json_tokener_parse( native_recv );
33 map = JsonObject_json_to_map( jobj );
34
35 /*json_object_put( jobj );*/
36 return map;
37 `}
38 end
39
40 redef extern class JsonObject
41 # Get this json object as a Map
42 private fun json_to_map : nullable Map[String, nullable Jsonable] import NativeString.to_s, String.to_cstring, HashMap[String,nullable Jsonable], HashMap[String,nullable Jsonable].[]=, json_cross, HashMap[String, nullable Jsonable].as(nullable Map[String, nullable Jsonable]) `{
43 HashMap_of_String_nullable_Jsonable map;
44 String nit_key;
45 nullable_Jsonable nit_val;
46 enum json_type type;
47
48 map = new_HashMap_of_String_nullable_Jsonable();
49
50 { /* prevents "mixed declaration and code" warning for C90 */
51 json_object_object_foreach( recv, key, val ) {
52 nit_key = NativeString_to_s( key );
53
54 if ( val == NULL ) type = json_type_null;
55 else type = json_object_get_type( val );
56
57 nit_val = JsonObject_json_cross( val, type );
58
59 HashMap_of_String_nullable_Jsonable__index_assign( map, nit_key, nit_val );
60 }
61 }
62
63 return HashMap_of_String_nullable_Jsonable_as_nullable_Map_of_String_nullable_Jsonable( map );
64 `}
65
66 # Get this json object as a Bool
67 private fun json_to_bool : Bool `{
68 return json_object_get_boolean( recv );
69 `}
70
71 # Get this json object as a Float
72 private fun json_to_float : Float `{
73 return json_object_get_double( recv );
74 `}
75
76 # Get this json object as an Int
77 private fun json_to_int : Int `{
78 return json_object_get_int( recv );
79 `}
80
81 # Get this json object as a Sequence
82 private fun json_to_sequence : Sequence[nullable Jsonable] import Array[nullable Jsonable], Array[nullable Jsonable].push, json_cross, Array[nullable Jsonable].as(Sequence[nullable Jsonable]) `{
83 array_list* jlist;
84 json_object* jobj;
85 nullable_Jsonable obj;
86 Array_of_nullable_Jsonable dest;
87 int i;
88 int len;
89 enum json_type type;
90
91 jlist = json_object_get_array( recv );
92 len = json_object_array_length( recv );
93 dest = new_Array_of_nullable_Jsonable();
94 for ( i = 0; i < len; i ++ ) {
95 jobj = json_object_array_get_idx( recv, i );
96 if ( jobj == NULL ) type = json_type_null;
97 else type = json_object_get_type( jobj );
98 obj = JsonObject_json_cross( jobj, type );
99 Array_of_nullable_Jsonable_push( dest, obj );
100 }
101
102 return Array_of_nullable_Jsonable_as_Sequence_of_nullable_Jsonable( dest );
103 `}
104
105 # Get this json object as a String
106 private fun json_to_string : String import NativeString.to_s `{
107 const char *cstring;
108 cstring = json_object_get_string( recv );
109 return NativeString_to_s( (char*)cstring );
110 `}
111
112 # Intermediate function to convert to gt this Json object as a given type.
113 # Imlemented in Nit because Nit should manage all possible typing-related work.
114 private fun json_cross( json_type : Int ) : nullable Jsonable
115 do
116 if json_type == 0 then # null
117 return null
118 else if json_type == 1 then # Bool
119 return json_to_bool
120 else if json_type == 2 then # Float
121 return json_to_float
122 else if json_type == 3 then # Int
123 return json_to_int
124 else if json_type == 4 then # Map
125 return json_to_map
126 else if json_type == 5 then # Sequence
127 return json_to_sequence
128 else if json_type == 6 then # String
129 return json_to_string
130 else
131 print "WARNING: Unrecongnized json object type id: {json_type}"
132 return null
133 end
134 end
135 end