aboutsummaryrefslogtreecommitdiff
path: root/src/json/json_gnsrecord.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/json/json_gnsrecord.c')
-rw-r--r--src/json/json_gnsrecord.c232
1 files changed, 156 insertions, 76 deletions
diff --git a/src/json/json_gnsrecord.c b/src/json/json_gnsrecord.c
index cbdc0ff91..eef9e0e79 100644
--- a/src/json/json_gnsrecord.c
+++ b/src/json/json_gnsrecord.c
@@ -28,12 +28,46 @@
28#include "gnunet_json_lib.h" 28#include "gnunet_json_lib.h"
29 29
30#define GNUNET_JSON_GNSRECORD_VALUE "value" 30#define GNUNET_JSON_GNSRECORD_VALUE "value"
31#define GNUNET_JSON_GNSRECORD_RECORD_DATA "data"
31#define GNUNET_JSON_GNSRECORD_TYPE "record_type" 32#define GNUNET_JSON_GNSRECORD_TYPE "record_type"
32#define GNUNET_JSON_GNSRECORD_EXPIRATION_TIME "expiration_time" 33#define GNUNET_JSON_GNSRECORD_EXPIRATION_TIME "expiration_time"
33#define GNUNET_JSON_GNSRECORD_FLAG "flag" 34#define GNUNET_JSON_GNSRECORD_FLAG "flag"
34#define GNUNET_JSON_GNSRECORD_RECORD_NAME "record_name" 35#define GNUNET_JSON_GNSRECORD_RECORD_NAME "record_name"
35#define GNUNET_JSON_GNSRECORD_NEVER "never" 36#define GNUNET_JSON_GNSRECORD_NEVER "never"
36 37
38struct GnsRecordInfo
39{
40 char **name;
41
42 unsigned int *rd_count;
43
44 struct GNUNET_GNSRECORD_Data **rd;
45};
46
47
48static void
49cleanup_recordinfo (struct GnsRecordInfo *gnsrecord_info)
50{
51 if (NULL != gnsrecord_info)
52 {
53 if (NULL != *(gnsrecord_info->rd))
54 {
55 for (int i = 0; i < *(gnsrecord_info->rd_count); i++)
56 {
57 if (NULL != (*(gnsrecord_info->rd))[i].data)
58 GNUNET_free ((char *) (*(gnsrecord_info->rd))[i].data);
59 }
60 GNUNET_free (*(gnsrecord_info->rd));
61 *(gnsrecord_info->rd) = NULL;
62 }
63 if (NULL != *(gnsrecord_info->name))
64 GNUNET_free (*(gnsrecord_info->name));
65 *(gnsrecord_info->name) = NULL;
66 GNUNET_free (gnsrecord_info);
67 }
68
69}
70
37 71
38/** 72/**
39 * Parse given JSON object to gns record 73 * Parse given JSON object to gns record
@@ -44,114 +78,156 @@
44 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error 78 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
45 */ 79 */
46static int 80static int
47parse_gnsrecordobject (void *cls, 81parse_record (json_t *data, struct GNUNET_GNSRECORD_Data *rd)
48 json_t *root,
49 struct GNUNET_JSON_Specification *spec)
50{ 82{
51 struct GNUNET_GNSRECORD_Data *gnsrecord_object;
52 struct GNUNET_TIME_Absolute abs_expiration_time; 83 struct GNUNET_TIME_Absolute abs_expiration_time;
53 struct GNUNET_TIME_Relative rel_expiration_time; 84 struct GNUNET_TIME_Relative rel_expiration_time;
54 int unpack_state=0;
55 const char *value; 85 const char *value;
56 const char *expiration_time;
57 const char *record_type; 86 const char *record_type;
58 const char *name; 87 const char *expiration_time;
59 int flag; 88 int flag;
60 void *rdata = NULL; 89 int unpack_state = 0;
61 size_t rdata_size;
62 90
63 GNUNET_assert(NULL != root);
64 if(!json_is_object(root))
65 {
66 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
67 "Error json is not array nor object!\n");
68 return GNUNET_SYSERR;
69 }
70 //interpret single gns record 91 //interpret single gns record
71 unpack_state = json_unpack(root, 92 unpack_state = json_unpack (data,
72 "{s:s, s:s, s:s, s?:i, s:s!}", 93 "{s:s, s:s, s:s, s?:i!}",
73 GNUNET_JSON_GNSRECORD_VALUE, &value, 94 GNUNET_JSON_GNSRECORD_VALUE,
74 GNUNET_JSON_GNSRECORD_TYPE, &record_type, 95 &value,
75 GNUNET_JSON_GNSRECORD_EXPIRATION_TIME, &expiration_time, 96 GNUNET_JSON_GNSRECORD_TYPE,
76 GNUNET_JSON_GNSRECORD_FLAG, &flag, 97 &record_type,
77 GNUNET_JSON_GNSRECORD_RECORD_NAME, &name); 98 GNUNET_JSON_GNSRECORD_EXPIRATION_TIME,
99 &expiration_time,
100 GNUNET_JSON_GNSRECORD_FLAG,
101 &flag);
78 if (0 != unpack_state) 102 if (0 != unpack_state)
79 { 103 {
80 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 104 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
81 "Error json object has a wrong format!\n"); 105 "Error gnsdata object has a wrong format!\n");
82 return GNUNET_SYSERR; 106 return GNUNET_SYSERR;
83 } 107 }
84 gnsrecord_object = GNUNET_new (struct GNUNET_GNSRECORD_Data); 108 rd->record_type = GNUNET_GNSRECORD_typename_to_number (record_type);
85 gnsrecord_object->record_type = GNUNET_GNSRECORD_typename_to_number(record_type); 109 if (UINT32_MAX == rd->record_type)
86 if (UINT32_MAX == gnsrecord_object->record_type)
87 { 110 {
88 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Unsupported type\n"); 111 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unsupported type\n");
89 GNUNET_free(gnsrecord_object);
90 return GNUNET_SYSERR; 112 return GNUNET_SYSERR;
91 } 113 }
92 if (GNUNET_OK 114 if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (rd->record_type,
93 != GNUNET_GNSRECORD_string_to_value (gnsrecord_object->record_type, 115 value,
94 value, 116 (void**)&rd->data,
95 &rdata, 117 &rd->data_size))
96 &rdata_size))
97 { 118 {
98 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Value invalid for record type\n"); 119 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Value invalid for record type\n");
99 GNUNET_free(gnsrecord_object);
100 return GNUNET_SYSERR; 120 return GNUNET_SYSERR;
101 } 121 }
102 122
103 gnsrecord_object->data = rdata;
104 gnsrecord_object->data_size = rdata_size;
105
106 if (0 == strcmp (expiration_time, GNUNET_JSON_GNSRECORD_NEVER)) 123 if (0 == strcmp (expiration_time, GNUNET_JSON_GNSRECORD_NEVER))
107 { 124 {
108 gnsrecord_object->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; 125 rd->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
109 } 126 }
110 else if (GNUNET_OK 127 else if (GNUNET_OK ==
111 == GNUNET_STRINGS_fancy_time_to_absolute (expiration_time, 128 GNUNET_STRINGS_fancy_time_to_absolute (expiration_time,
112 &abs_expiration_time)) 129 &abs_expiration_time))
113 { 130 {
114 gnsrecord_object->expiration_time = abs_expiration_time.abs_value_us; 131 rd->expiration_time = abs_expiration_time.abs_value_us;
115 } 132 }
116 else if (GNUNET_OK 133 else if (GNUNET_OK ==
117 == GNUNET_STRINGS_fancy_time_to_relative (expiration_time, 134 GNUNET_STRINGS_fancy_time_to_relative (expiration_time,
118 &rel_expiration_time)) 135 &rel_expiration_time))
119 { 136 {
120 gnsrecord_object->expiration_time = rel_expiration_time.rel_value_us; 137 rd->expiration_time = rel_expiration_time.rel_value_us;
121 } 138 }
122 else 139 else
123 { 140 {
124 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Expiration time invalid\n"); 141 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Expiration time invalid\n");
125 GNUNET_free_non_null(rdata);
126 GNUNET_free(gnsrecord_object);
127 return GNUNET_SYSERR; 142 return GNUNET_SYSERR;
128 } 143 }
129 gnsrecord_object->flags = (enum GNUNET_GNSRECORD_Flags)flag; 144 rd->flags = (enum GNUNET_GNSRECORD_Flags) flag;
130 *(struct GNUNET_GNSRECORD_Data **) spec->ptr = gnsrecord_object;
131 return GNUNET_OK; 145 return GNUNET_OK;
132} 146}
133 147
148
134/** 149/**
135 * Cleanup data left from parsing RSA public key. 150 * Parse given JSON object to gns record
136 * 151 *
137 * @param cls closure, NULL 152 * @param cls closure, NULL
138 * @param[out] spec where to free the data 153 * @param root the json object representing data
154 * @param spec where to write the data
155 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
139 */ 156 */
140static void 157static int
141clean_gnsrecordobject (void *cls, struct GNUNET_JSON_Specification *spec) 158parse_record_data (struct GnsRecordInfo *gnsrecord_info, json_t *data)
142{ 159{
143 struct GNUNET_GNSRECORD_Data **gnsrecord_object; 160 GNUNET_assert (NULL != data);
144 gnsrecord_object = (struct GNUNET_GNSRECORD_Data **) spec->ptr; 161 if (! json_is_array (data))
145 if (NULL != *gnsrecord_object)
146 { 162 {
147 if (NULL != (*gnsrecord_object)->data) 163 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
148 GNUNET_free((char*)(*gnsrecord_object)->data); 164 "Error gns record data JSON is not an array!\n");
165 return GNUNET_SYSERR;
166 }
167 *(gnsrecord_info->rd_count) = json_array_size (data);
168 *(gnsrecord_info->rd) = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Data) *
169 json_array_size (data));
170 size_t index;
171 json_t *value;
172 json_array_foreach (data, index, value)
173 {
174 if (GNUNET_OK != parse_record (value, &(*(gnsrecord_info->rd))[index]))
175 return GNUNET_SYSERR;
176 }
177 return GNUNET_OK;
178}
149 179
150 GNUNET_free(*gnsrecord_object); 180
151 *gnsrecord_object = NULL; 181static int
182parse_gnsrecordobject (void *cls,
183 json_t *root,
184 struct GNUNET_JSON_Specification *spec)
185{
186 struct GnsRecordInfo *gnsrecord_info;
187 int unpack_state = 0;
188 const char *name;
189 json_t *data;
190
191 GNUNET_assert (NULL != root);
192 if (! json_is_object (root))
193 {
194 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
195 "Error record JSON is not an object!\n");
196 return GNUNET_SYSERR;
197 }
198 //interpret single gns record
199 unpack_state = json_unpack (root,
200 "{s:s, s:o!}",
201 GNUNET_JSON_GNSRECORD_RECORD_NAME,
202 &name,
203 GNUNET_JSON_GNSRECORD_RECORD_DATA,
204 &data);
205 if (0 != unpack_state)
206 {
207 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
208 "Error namestore records object has a wrong format!\n");
209 return GNUNET_SYSERR;
152 } 210 }
211 gnsrecord_info = (struct GnsRecordInfo *) spec->ptr;
212 *(gnsrecord_info->name) = GNUNET_strdup (name);
213 return parse_record_data (gnsrecord_info, data);
153} 214}
154 215
216
217/**
218 * Cleanup data left from parsing the record.
219 *
220 * @param cls closure, NULL
221 * @param[out] spec where to free the data
222 */
223static void
224clean_gnsrecordobject (void *cls, struct GNUNET_JSON_Specification *spec)
225{
226 struct GnsRecordInfo *gnsrecord_info = (struct GnsRecordInfo *) spec->ptr;
227 cleanup_recordinfo (gnsrecord_info);
228}
229
230
155/** 231/**
156 * JSON Specification for GNS Records. 232 * JSON Specification for GNS Records.
157 * 233 *
@@ -159,17 +235,21 @@ clean_gnsrecordobject (void *cls, struct GNUNET_JSON_Specification *spec)
159 * @return JSON Specification 235 * @return JSON Specification
160 */ 236 */
161struct GNUNET_JSON_Specification 237struct GNUNET_JSON_Specification
162GNUNET_JSON_spec_gnsrecord_data (struct GNUNET_GNSRECORD_Data **gnsrecord_object) 238GNUNET_JSON_spec_gnsrecord (struct GNUNET_GNSRECORD_Data **rd,
239 unsigned int *rd_count,
240 char **name)
163{ 241{
164 struct GNUNET_JSON_Specification ret = { 242 struct GnsRecordInfo *gnsrecord_info = GNUNET_new (struct GnsRecordInfo);
165 .parser = &parse_gnsrecordobject, 243 gnsrecord_info->rd = rd;
166 .cleaner = &clean_gnsrecordobject, 244 gnsrecord_info->name = name;
167 .cls = NULL, 245 gnsrecord_info->rd_count = rd_count;
168 .field = NULL, 246 struct GNUNET_JSON_Specification ret = {.parser = &parse_gnsrecordobject,
169 .ptr = gnsrecord_object, 247 .cleaner = &clean_gnsrecordobject,
170 .ptr_size = 0, 248 .cls = NULL,
171 .size_ptr = NULL 249 .field = NULL,
172 }; 250 .ptr = (struct GnsRecordInfo *)
173 *gnsrecord_object = NULL; 251 gnsrecord_info,
252 .ptr_size = 0,
253 .size_ptr = NULL};
174 return ret; 254 return ret;
175} 255}