| 
									
										
										
										
											2017-08-25 12:59:01 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * QLit literal qobject | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright IBM, Corp. 2009 | 
					
						
							|  |  |  |  * Copyright (c) 2013, 2015, 2017 Red Hat Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Authors: | 
					
						
							|  |  |  |  *  Anthony Liguori   <aliguori@us.ibm.com> | 
					
						
							|  |  |  |  *  Markus Armbruster <armbru@redhat.com> | 
					
						
							|  |  |  |  *  Marc-André Lureau <marcandre.lureau@redhat.com> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. | 
					
						
							|  |  |  |  * See the COPYING.LIB file in the top-level directory. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "qemu/osdep.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "qapi/qmp/qlit.h"
 | 
					
						
							| 
									
										
										
										
											2018-02-01 12:18:35 +01:00
										 |  |  | #include "qapi/qmp/qbool.h"
 | 
					
						
							| 
									
										
										
										
											2018-02-01 12:18:38 +01:00
										 |  |  | #include "qapi/qmp/qlist.h"
 | 
					
						
							| 
									
										
										
										
											2018-02-01 12:18:36 +01:00
										 |  |  | #include "qapi/qmp/qnum.h"
 | 
					
						
							| 
									
										
										
										
											2018-02-01 12:18:35 +01:00
										 |  |  | #include "qapi/qmp/qdict.h"
 | 
					
						
							|  |  |  | #include "qapi/qmp/qstring.h"
 | 
					
						
							| 
									
										
										
										
											2018-03-05 18:29:50 +01:00
										 |  |  | #include "qapi/qmp/qnull.h"
 | 
					
						
							| 
									
										
										
										
											2017-08-25 12:59:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-25 12:59:10 +02:00
										 |  |  | static bool qlit_equal_qdict(const QLitObject *lhs, const QDict *qdict) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; lhs->value.qdict[i].key; i++) { | 
					
						
							|  |  |  |         QObject *obj = qdict_get(qdict, lhs->value.qdict[i].key); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!qlit_equal_qobject(&lhs->value.qdict[i].value, obj)) { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Note: the literal qdict must not contain duplicates, this is
 | 
					
						
							|  |  |  |      * considered a programming error and it isn't checked here. */ | 
					
						
							|  |  |  |     if (qdict_size(qdict) != i) { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-25 12:59:11 +02:00
										 |  |  | static bool qlit_equal_qlist(const QLitObject *lhs, const QList *qlist) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QListEntry *e; | 
					
						
							|  |  |  |     int i = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QLIST_FOREACH_ENTRY(qlist, e) { | 
					
						
							|  |  |  |         QObject *obj = qlist_entry_obj(e); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!qlit_equal_qobject(&lhs->value.qlist[i], obj)) { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         i++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return !e && lhs->value.qlist[i].type == QTYPE_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-25 12:59:06 +02:00
										 |  |  | bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs) | 
					
						
							| 
									
										
										
										
											2017-08-25 12:59:01 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (!rhs || lhs->type != qobject_type(rhs)) { | 
					
						
							| 
									
										
										
										
											2017-08-25 12:59:05 +02:00
										 |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2017-08-25 12:59:01 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (lhs->type) { | 
					
						
							| 
									
										
										
										
											2017-08-25 12:59:07 +02:00
										 |  |  |     case QTYPE_QBOOL: | 
					
						
							| 
									
										
										
										
											2018-02-24 16:40:29 +01:00
										 |  |  |         return lhs->value.qbool == qbool_get_bool(qobject_to(QBool, rhs)); | 
					
						
							| 
									
										
										
										
											2017-08-25 12:59:01 +02:00
										 |  |  |     case QTYPE_QNUM: | 
					
						
							| 
									
										
										
										
											2018-02-24 16:40:29 +01:00
										 |  |  |         return lhs->value.qnum ==  qnum_get_int(qobject_to(QNum, rhs)); | 
					
						
							| 
									
										
										
										
											2017-08-25 12:59:01 +02:00
										 |  |  |     case QTYPE_QSTRING: | 
					
						
							|  |  |  |         return (strcmp(lhs->value.qstr, | 
					
						
							| 
									
										
										
										
											2018-02-24 16:40:29 +01:00
										 |  |  |                        qstring_get_str(qobject_to(QString, rhs))) == 0); | 
					
						
							| 
									
										
										
										
											2017-08-25 12:59:10 +02:00
										 |  |  |     case QTYPE_QDICT: | 
					
						
							| 
									
										
										
										
											2018-02-24 16:40:29 +01:00
										 |  |  |         return qlit_equal_qdict(lhs, qobject_to(QDict, rhs)); | 
					
						
							| 
									
										
										
										
											2017-08-25 12:59:11 +02:00
										 |  |  |     case QTYPE_QLIST: | 
					
						
							| 
									
										
										
										
											2018-02-24 16:40:29 +01:00
										 |  |  |         return qlit_equal_qlist(lhs, qobject_to(QList, rhs)); | 
					
						
							| 
									
										
										
										
											2017-08-25 12:59:07 +02:00
										 |  |  |     case QTYPE_QNULL: | 
					
						
							|  |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2017-08-25 12:59:01 +02:00
										 |  |  |     default: | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-25 12:59:05 +02:00
										 |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2017-08-25 12:59:01 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-05 18:29:50 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | QObject *qobject_from_qlit(const QLitObject *qlit) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     switch (qlit->type) { | 
					
						
							|  |  |  |     case QTYPE_QNULL: | 
					
						
							|  |  |  |         return QOBJECT(qnull()); | 
					
						
							|  |  |  |     case QTYPE_QNUM: | 
					
						
							|  |  |  |         return QOBJECT(qnum_from_int(qlit->value.qnum)); | 
					
						
							|  |  |  |     case QTYPE_QSTRING: | 
					
						
							|  |  |  |         return QOBJECT(qstring_from_str(qlit->value.qstr)); | 
					
						
							|  |  |  |     case QTYPE_QDICT: { | 
					
						
							|  |  |  |         QDict *qdict = qdict_new(); | 
					
						
							|  |  |  |         QLitDictEntry *e; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (e = qlit->value.qdict; e->key; e++) { | 
					
						
							|  |  |  |             qdict_put_obj(qdict, e->key, qobject_from_qlit(&e->value)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return QOBJECT(qdict); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     case QTYPE_QLIST: { | 
					
						
							|  |  |  |         QList *qlist = qlist_new(); | 
					
						
							|  |  |  |         QLitObject *e; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (e = qlit->value.qlist; e->type != QTYPE_NONE; e++) { | 
					
						
							|  |  |  |             qlist_append_obj(qlist, qobject_from_qlit(e)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return QOBJECT(qlist); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     case QTYPE_QBOOL: | 
					
						
							|  |  |  |         return QOBJECT(qbool_from_bool(qlit->value.qbool)); | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         assert(0); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | } |