| 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 26 * POSSIBILITY OF SUCH DAMAGE. |
26 * POSSIBILITY OF SUCH DAMAGE. |
| 27 */ |
27 */ |
| 28 |
28 |
| |
29 #include <stdio.h> |
| |
30 |
| 29 #include "json.h" |
31 #include "json.h" |
| |
32 |
| |
33 /* ---------------- Obj to JSON serialization functions ---------------------*/ |
| 30 |
34 |
| 31 CxJsonValue* dbuObjectToJson(DBUClass *type, void *obj, const CxAllocator *a) { |
35 CxJsonValue* dbuObjectToJson(DBUClass *type, void *obj, const CxAllocator *a) { |
| 32 return dbuObjectToJson2(type, obj, a, false, false); |
36 return dbuObjectToJson2(type, obj, a, false, false); |
| 33 } |
37 } |
| 34 |
38 |
| 121 i = cxMapIteratorValues(type->obj_fields); |
125 i = cxMapIteratorValues(type->obj_fields); |
| 122 } |
126 } |
| 123 |
127 |
| 124 return value; |
128 return value; |
| 125 } |
129 } |
| |
130 |
| |
131 |
| |
132 /* --------------- Json to Obj deserialization functions --------------------*/ |
| |
133 |
| |
134 void* dbuJsonToObject(DBUClass *type, const CxAllocator *a, CxJsonValue *value) { |
| |
135 if(!cxJsonIsObject(value)) { |
| |
136 return NULL; |
| |
137 } |
| |
138 if(!a) { |
| |
139 a = cxDefaultAllocator; |
| |
140 } |
| |
141 |
| |
142 void *obj = cxMalloc(a, type->obj_size); |
| |
143 if(obj) { |
| |
144 memset(obj, 0, type->obj_size); |
| |
145 } |
| |
146 |
| |
147 char buf[64]; |
| |
148 int len = 0; |
| |
149 |
| |
150 CxMapIterator i = cxMapIterator(value->object); |
| |
151 cx_foreach(CxMapEntry *, entry, i) { |
| |
152 DBUField *field = cxMapGet(type->fields, entry->key); |
| |
153 if(!field) { |
| |
154 continue; |
| |
155 } |
| |
156 |
| |
157 len = 0; |
| |
158 |
| |
159 CxJsonValue *child = entry->value; |
| |
160 switch(child->type) { |
| |
161 case CX_JSON_LITERAL: { |
| |
162 if(child->literal == CX_JSON_NULL) { |
| |
163 if(field->initObjValue) { |
| |
164 field->initObjValue(field, a, obj, NULL); |
| |
165 } |
| |
166 break; |
| |
167 } else { |
| |
168 int b = child->literal == CX_JSON_TRUE; |
| |
169 if(field->initIntValue) { |
| |
170 field->initIntValue(field, a, obj, b); |
| |
171 continue; |
| |
172 } else { |
| |
173 len = snprintf(buf, 64, "%d", b); |
| |
174 } |
| |
175 } |
| |
176 break; |
| |
177 } |
| |
178 case CX_JSON_INTEGER: { |
| |
179 if(field->initIntValue) { |
| |
180 field->initIntValue(field, a, obj, child->integer); |
| |
181 } else { |
| |
182 len = snprintf(buf, 64, "%" PRId64, child->integer); |
| |
183 } |
| |
184 break; |
| |
185 } |
| |
186 case CX_JSON_NUMBER: { |
| |
187 if(field->initDoubleValue) { |
| |
188 field->initDoubleValue(field, a, obj, child->number); |
| |
189 } else { |
| |
190 len = snprintf(buf, 64, "%f", child->number); |
| |
191 } |
| |
192 break; |
| |
193 } |
| |
194 case CX_JSON_STRING: { |
| |
195 cxmutstr str = child->string; |
| |
196 if(field->initValue(field, a, obj, str.ptr, str.length)) { |
| |
197 free(obj); // TODO: improve obj cleanup |
| |
198 return NULL; |
| |
199 } |
| |
200 break; |
| |
201 } |
| |
202 case CX_JSON_OBJECT: { |
| |
203 // TODO |
| |
204 break; |
| |
205 } |
| |
206 case CX_JSON_ARRAY: { |
| |
207 // TODO |
| |
208 break; |
| |
209 } |
| |
210 default: break; |
| |
211 } |
| |
212 |
| |
213 if(len > 0) { |
| |
214 if(field->initValue(field, a, obj, buf, len)) { |
| |
215 // TODO: completely cleanup obj |
| |
216 free(obj); |
| |
217 return NULL; |
| |
218 } |
| |
219 } |
| |
220 } |
| |
221 |
| |
222 return obj; |
| |
223 } |