Michael Roth | 2345c77 | 2011-07-19 14:50:32 -0500 | [diff] [blame] | 1 | /* |
| 2 | * Core Definitions for QAPI Visitor Classes |
| 3 | * |
Eric Blake | 08f9541 | 2016-01-29 06:48:59 -0700 | [diff] [blame] | 4 | * Copyright (C) 2012-2016 Red Hat, Inc. |
Michael Roth | 2345c77 | 2011-07-19 14:50:32 -0500 | [diff] [blame] | 5 | * Copyright IBM, Corp. 2011 |
| 6 | * |
| 7 | * Authors: |
| 8 | * Anthony Liguori <aliguori@us.ibm.com> |
| 9 | * |
| 10 | * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. |
| 11 | * See the COPYING.LIB file in the top-level directory. |
| 12 | * |
| 13 | */ |
Markus Armbruster | 121d071 | 2016-06-29 10:12:57 +0200 | [diff] [blame] | 14 | |
| 15 | #ifndef QAPI_VISITOR_H |
| 16 | #define QAPI_VISITOR_H |
Michael Roth | 2345c77 | 2011-07-19 14:50:32 -0500 | [diff] [blame] | 17 | |
Markus Armbruster | eb815e2 | 2018-02-11 10:36:05 +0100 | [diff] [blame] | 18 | #include "qapi/qapi-builtin-types.h" |
Markus Armbruster | ed29bb2 | 2021-10-25 06:24:03 +0200 | [diff] [blame] | 19 | #include "qapi/qapi-types-compat.h" |
Michael Roth | 2345c77 | 2011-07-19 14:50:32 -0500 | [diff] [blame] | 20 | |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 21 | /* |
| 22 | * The QAPI schema defines both a set of C data types, and a QMP wire |
| 23 | * format. QAPI objects can contain references to other QAPI objects, |
| 24 | * resulting in a directed acyclic graph. QAPI also generates visitor |
| 25 | * functions to walk these graphs. This file represents the interface |
| 26 | * for doing work at each node of a QAPI graph; it can also be used |
| 27 | * for a virtual walk, where there is no actual QAPI C struct. |
| 28 | * |
Markus Armbruster | 554d658 | 2020-04-24 10:43:28 +0200 | [diff] [blame] | 29 | * There are four kinds of visitors: input visitors (QObject, string, |
| 30 | * and QemuOpts) parse an external representation and build the |
| 31 | * corresponding QAPI object, output visitors (QObject and string) |
| 32 | * take a QAPI object and generate an external representation, the |
| 33 | * dealloc visitor takes a QAPI object (possibly partially |
| 34 | * constructed) and recursively frees it, and the clone visitor |
| 35 | * performs a deep clone of a QAPI object. |
| 36 | * |
| 37 | * While the dealloc and QObject input/output visitors are general, |
| 38 | * the string, QemuOpts, and clone visitors have some implementation |
| 39 | * limitations; see the documentation for each visitor for more |
| 40 | * details on what it supports. Also, see visitor-impl.h for the |
| 41 | * callback contracts implemented by each visitor, and |
Markus Armbruster | b0b1313 | 2024-01-20 10:53:23 +0100 | [diff] [blame] | 42 | * docs/devel/qapi-code-gen.rst for more about the QAPI code |
Markus Armbruster | 554d658 | 2020-04-24 10:43:28 +0200 | [diff] [blame] | 43 | * generator. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 44 | * |
Eric Blake | 2c0ef9f | 2016-06-09 10:48:35 -0600 | [diff] [blame] | 45 | * All of the visitors are created via: |
| 46 | * |
Eric Blake | 3b098d5 | 2016-06-09 10:48:43 -0600 | [diff] [blame] | 47 | * Visitor *subtype_visitor_new(parameters...); |
Eric Blake | 2c0ef9f | 2016-06-09 10:48:35 -0600 | [diff] [blame] | 48 | * |
| 49 | * A visitor should be used for exactly one top-level visit_type_FOO() |
Eric Blake | 3b098d5 | 2016-06-09 10:48:43 -0600 | [diff] [blame] | 50 | * or virtual walk; if that is successful, the caller can optionally |
Markus Armbruster | 554d658 | 2020-04-24 10:43:28 +0200 | [diff] [blame] | 51 | * call visit_complete() (useful only for output visits, but safe to |
| 52 | * call on all visits). Then, regardless of success or failure, the |
| 53 | * user should call visit_free() to clean up resources. It is okay to |
| 54 | * free the visitor without completing the visit, if some other error |
| 55 | * is detected in the meantime. |
| 56 | * |
| 57 | * The clone and dealloc visitor should not be used directly outside |
| 58 | * of QAPI code. Use the qapi_free_FOO() and QAPI_CLONE() instead, |
| 59 | * described below. |
Eric Blake | 2c0ef9f | 2016-06-09 10:48:35 -0600 | [diff] [blame] | 60 | * |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 61 | * All QAPI types have a corresponding function with a signature |
| 62 | * roughly compatible with this: |
| 63 | * |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 64 | * bool visit_type_FOO(Visitor *v, const char *name, T obj, Error **errp); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 65 | * |
| 66 | * where T is FOO for scalar types, and FOO * otherwise. The scalar |
| 67 | * visitors are declared here; the remaining visitors are generated in |
Markus Armbruster | 3777d36 | 2020-04-24 10:43:24 +0200 | [diff] [blame] | 68 | * qapi-visit-MODULE.h. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 69 | * |
| 70 | * The @name parameter of visit_type_FOO() describes the relation |
| 71 | * between this QAPI value and its parent container. When visiting |
| 72 | * the root of a tree, @name is ignored; when visiting a member of an |
Markus Armbruster | ed0ba0f | 2017-04-27 10:41:25 +0200 | [diff] [blame] | 73 | * object, @name is the key associated with the value; when visiting a |
| 74 | * member of a list, @name is NULL; and when visiting the member of an |
| 75 | * alternate, @name should equal the name used for visiting the |
| 76 | * alternate. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 77 | * |
Markus Armbruster | 554d658 | 2020-04-24 10:43:28 +0200 | [diff] [blame] | 78 | * The visit_type_FOO() functions take a non-null @obj argument; they |
| 79 | * allocate *@obj during input visits, leave it unchanged during |
| 80 | * output and clone visits, and free it (recursively) during a dealloc |
| 81 | * visit. |
| 82 | * |
| 83 | * Each function also takes the customary @errp argument (see |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 84 | * qapi/error.h for details), for reporting any errors (such as if a |
| 85 | * member @name is not present, or is present but not the specified |
Markus Armbruster | 1f58424 | 2020-04-24 10:43:35 +0200 | [diff] [blame] | 86 | * type). Only input visitors can fail. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 87 | * |
Eric Blake | 68ab47e | 2016-04-28 15:45:32 -0600 | [diff] [blame] | 88 | * If an error is detected during visit_type_FOO() with an input |
Markus Armbruster | 554d658 | 2020-04-24 10:43:28 +0200 | [diff] [blame] | 89 | * visitor, then *@obj will be set to NULL for pointer types, and left |
| 90 | * unchanged for scalar types. |
| 91 | * |
| 92 | * Using an output or clone visitor with an incomplete object has |
| 93 | * undefined behavior (other than a special case for visit_type_str() |
| 94 | * treating NULL like ""), while the dealloc visitor safely handles |
| 95 | * incomplete objects. Since input visitors never produce an |
| 96 | * incomplete object, such an object is possible only by manual |
| 97 | * construction. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 98 | * |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 99 | * visit_type_FOO() returns true on success, false on error. |
| 100 | * |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 101 | * For the QAPI object types (structs, unions, and alternates), there |
Markus Armbruster | 3777d36 | 2020-04-24 10:43:24 +0200 | [diff] [blame] | 102 | * is an additional generated function in qapi-visit-MODULE.h |
| 103 | * compatible with: |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 104 | * |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 105 | * bool visit_type_FOO_members(Visitor *v, FOO *obj, Error **errp); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 106 | * |
| 107 | * for visiting the members of a type without also allocating the QAPI |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 108 | * struct. It also returns true on success, false on error. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 109 | * |
Markus Armbruster | 3777d36 | 2020-04-24 10:43:24 +0200 | [diff] [blame] | 110 | * Additionally, QAPI pointer types (structs, unions, alternates, and |
| 111 | * lists) have a generated function in qapi-types-MODULE.h compatible |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 112 | * with: |
| 113 | * |
| 114 | * void qapi_free_FOO(FOO *obj); |
| 115 | * |
Markus Armbruster | 554d658 | 2020-04-24 10:43:28 +0200 | [diff] [blame] | 116 | * Does nothing when @obj is NULL. |
| 117 | * |
| 118 | * Such objects may also be used with macro |
Eric Blake | a15fcc3 | 2016-06-09 10:48:44 -0600 | [diff] [blame] | 119 | * |
| 120 | * Type *QAPI_CLONE(Type, src); |
| 121 | * |
Markus Armbruster | 554d658 | 2020-04-24 10:43:28 +0200 | [diff] [blame] | 122 | * in order to perform a deep clone of @src. |
Eric Blake | a15fcc3 | 2016-06-09 10:48:44 -0600 | [diff] [blame] | 123 | * |
Markus Armbruster | 554d658 | 2020-04-24 10:43:28 +0200 | [diff] [blame] | 124 | * For QAPI types can that inherit from a base type, a function is |
| 125 | * generated for going from the derived type to the base type: |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 126 | * |
| 127 | * BASE *qapi_CHILD_base(CHILD *obj); |
| 128 | * |
Markus Armbruster | 554d658 | 2020-04-24 10:43:28 +0200 | [diff] [blame] | 129 | * Typical input visitor usage involves: |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 130 | * |
| 131 | * <example> |
| 132 | * Foo *f; |
| 133 | * Error *err = NULL; |
| 134 | * Visitor *v; |
| 135 | * |
Eric Blake | 3b098d5 | 2016-06-09 10:48:43 -0600 | [diff] [blame] | 136 | * v = FOO_visitor_new(...); |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 137 | * if (!visit_type_Foo(v, NULL, &f, &err)) { |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 138 | * ...handle error... |
| 139 | * } else { |
| 140 | * ...use f... |
| 141 | * } |
Eric Blake | 3b098d5 | 2016-06-09 10:48:43 -0600 | [diff] [blame] | 142 | * visit_free(v); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 143 | * qapi_free_Foo(f); |
| 144 | * </example> |
| 145 | * |
| 146 | * For a list, it is: |
| 147 | * <example> |
| 148 | * FooList *l; |
| 149 | * Error *err = NULL; |
| 150 | * Visitor *v; |
| 151 | * |
Eric Blake | 3b098d5 | 2016-06-09 10:48:43 -0600 | [diff] [blame] | 152 | * v = FOO_visitor_new(...); |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 153 | * if (!visit_type_FooList(v, NULL, &l, &err)) { |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 154 | * ...handle error... |
| 155 | * } else { |
| 156 | * for ( ; l; l = l->next) { |
| 157 | * ...use l->value... |
| 158 | * } |
| 159 | * } |
Eric Blake | 3b098d5 | 2016-06-09 10:48:43 -0600 | [diff] [blame] | 160 | * visit_free(v); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 161 | * qapi_free_FooList(l); |
| 162 | * </example> |
| 163 | * |
Markus Armbruster | 554d658 | 2020-04-24 10:43:28 +0200 | [diff] [blame] | 164 | * Typical output visitor usage: |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 165 | * |
| 166 | * <example> |
| 167 | * Foo *f = ...obtain populated object... |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 168 | * Visitor *v; |
Eric Blake | 3b098d5 | 2016-06-09 10:48:43 -0600 | [diff] [blame] | 169 | * Type *result; |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 170 | * |
Eric Blake | 3b098d5 | 2016-06-09 10:48:43 -0600 | [diff] [blame] | 171 | * v = FOO_visitor_new(..., &result); |
Markus Armbruster | 1f58424 | 2020-04-24 10:43:35 +0200 | [diff] [blame] | 172 | * visit_type_Foo(v, NULL, &f, &error_abort); |
| 173 | * visit_complete(v, &result); |
Eric Blake | 3b098d5 | 2016-06-09 10:48:43 -0600 | [diff] [blame] | 174 | * visit_free(v); |
Markus Armbruster | 1f58424 | 2020-04-24 10:43:35 +0200 | [diff] [blame] | 175 | * ...use result... |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 176 | * </example> |
| 177 | * |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 178 | * It is also possible to use the visitors to do a virtual walk, where |
Markus Armbruster | 554d658 | 2020-04-24 10:43:28 +0200 | [diff] [blame] | 179 | * no actual QAPI object is present. In this situation, decisions |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 180 | * about what needs to be walked are made by the calling code, and |
| 181 | * structured visits are split between pairs of start and end methods |
| 182 | * (where the end method must be called if the start function |
| 183 | * succeeded, even if an intermediate visit encounters an error). |
| 184 | * Thus, a virtual walk corresponding to '{ "list": [1, 2] }' looks |
| 185 | * like: |
| 186 | * |
| 187 | * <example> |
| 188 | * Visitor *v; |
| 189 | * Error *err = NULL; |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 190 | * bool ok = false; |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 191 | * int value; |
| 192 | * |
Eric Blake | 3b098d5 | 2016-06-09 10:48:43 -0600 | [diff] [blame] | 193 | * v = FOO_visitor_new(...); |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 194 | * if (!visit_start_struct(v, NULL, NULL, 0, &err)) { |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 195 | * goto out; |
| 196 | * } |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 197 | * if (!visit_start_list(v, "list", NULL, 0, &err)) { |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 198 | * goto outobj; |
| 199 | * } |
| 200 | * value = 1; |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 201 | * if (!visit_type_int(v, NULL, &value, &err)) { |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 202 | * goto outlist; |
| 203 | * } |
| 204 | * value = 2; |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 205 | * if (!visit_type_int(v, NULL, &value, &err)) { |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 206 | * goto outlist; |
| 207 | * } |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 208 | * ok = true; |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 209 | * outlist: |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 210 | * if (ok) { |
| 211 | * ok = visit_check_list(v, &err); |
Markus Armbruster | 294c906 | 2020-04-24 10:43:25 +0200 | [diff] [blame] | 212 | * } |
Eric Blake | 1158bb2 | 2016-06-09 10:48:34 -0600 | [diff] [blame] | 213 | * visit_end_list(v, NULL); |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 214 | * if (ok) { |
| 215 | * ok = visit_check_struct(v, &err); |
Eric Blake | 15c2f66 | 2016-04-28 15:45:27 -0600 | [diff] [blame] | 216 | * } |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 217 | * outobj: |
Eric Blake | 1158bb2 | 2016-06-09 10:48:34 -0600 | [diff] [blame] | 218 | * visit_end_struct(v, NULL); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 219 | * out: |
Eric Blake | 3b098d5 | 2016-06-09 10:48:43 -0600 | [diff] [blame] | 220 | * visit_free(v); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 221 | * </example> |
Markus Armbruster | 554d658 | 2020-04-24 10:43:28 +0200 | [diff] [blame] | 222 | * |
| 223 | * This file provides helpers for use by the generated |
| 224 | * visit_type_FOO(): visit_optional() for the 'has_member' field |
| 225 | * associated with optional 'member' in the C struct, |
| 226 | * visit_next_list() for advancing through a FooList linked list, and |
| 227 | * visit_is_input() for cleaning up on failure. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 228 | */ |
| 229 | |
| 230 | /*** Useful types ***/ |
| 231 | |
Eric Blake | e65d89b | 2016-02-17 23:48:23 -0700 | [diff] [blame] | 232 | /* This struct is layout-compatible with all other *List structs |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 233 | * created by the QAPI generator. It is used as a typical |
Eric Blake | e65d89b | 2016-02-17 23:48:23 -0700 | [diff] [blame] | 234 | * singly-linked list. */ |
| 235 | typedef struct GenericList { |
Michael Roth | 2345c77 | 2011-07-19 14:50:32 -0500 | [diff] [blame] | 236 | struct GenericList *next; |
Eric Blake | e65d89b | 2016-02-17 23:48:23 -0700 | [diff] [blame] | 237 | char padding[]; |
Michael Roth | 2345c77 | 2011-07-19 14:50:32 -0500 | [diff] [blame] | 238 | } GenericList; |
| 239 | |
Eric Blake | dbf1192 | 2016-02-17 23:48:29 -0700 | [diff] [blame] | 240 | /* This struct is layout-compatible with all Alternate types |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 241 | * created by the QAPI generator. */ |
Eric Blake | dbf1192 | 2016-02-17 23:48:29 -0700 | [diff] [blame] | 242 | typedef struct GenericAlternate { |
| 243 | QType type; |
| 244 | char padding[]; |
| 245 | } GenericAlternate; |
| 246 | |
Eric Blake | 2c0ef9f | 2016-06-09 10:48:35 -0600 | [diff] [blame] | 247 | /*** Visitor cleanup ***/ |
| 248 | |
| 249 | /* |
Eric Blake | 3b098d5 | 2016-06-09 10:48:43 -0600 | [diff] [blame] | 250 | * Complete the visit, collecting any output. |
| 251 | * |
| 252 | * May only be called only once after a successful top-level |
| 253 | * visit_type_FOO() or visit_end_ITEM(), and marks the end of the |
| 254 | * visit. The @opaque pointer should match the output parameter |
| 255 | * passed to the subtype_visitor_new() used to create an output |
| 256 | * visitor, or NULL for any other visitor. Needed for output |
| 257 | * visitors, but may also be called with other visitors. |
| 258 | */ |
| 259 | void visit_complete(Visitor *v, void *opaque); |
| 260 | |
| 261 | /* |
Eric Blake | 2c0ef9f | 2016-06-09 10:48:35 -0600 | [diff] [blame] | 262 | * Free @v and any resources it has tied up. |
| 263 | * |
| 264 | * May be called whether or not the visit has been successfully |
| 265 | * completed, but should not be called until a top-level |
| 266 | * visit_type_FOO() or visit_start_ITEM() has been performed on the |
| 267 | * visitor. Safe if @v is NULL. |
| 268 | */ |
| 269 | void visit_free(Visitor *v); |
| 270 | |
| 271 | |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 272 | /*** Visiting structures ***/ |
Eric Blake | 5cdc883 | 2015-12-01 22:20:52 -0700 | [diff] [blame] | 273 | |
Eric Blake | dbf1192 | 2016-02-17 23:48:29 -0700 | [diff] [blame] | 274 | /* |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 275 | * Start visiting an object @obj (struct or union). |
Eric Blake | dbf1192 | 2016-02-17 23:48:29 -0700 | [diff] [blame] | 276 | * |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 277 | * @name expresses the relationship of this object to its parent |
| 278 | * container; see the general description of @name above. |
Eric Blake | dbf1192 | 2016-02-17 23:48:29 -0700 | [diff] [blame] | 279 | * |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 280 | * @obj must be non-NULL for a real walk, in which case @size |
Eric Blake | a15fcc3 | 2016-06-09 10:48:44 -0600 | [diff] [blame] | 281 | * determines how much memory an input or clone visitor will allocate |
| 282 | * into *@obj. @obj may also be NULL for a virtual walk, in which |
| 283 | * case @size is ignored. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 284 | * |
Markus Armbruster | c5460d5 | 2020-04-24 10:43:27 +0200 | [diff] [blame] | 285 | * On failure, set *@obj to NULL and store an error through @errp. |
Markus Armbruster | 1f58424 | 2020-04-24 10:43:35 +0200 | [diff] [blame] | 286 | * Can happen only when @v is an input visitor. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 287 | * |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 288 | * Return true on success, false on failure. |
| 289 | * |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 290 | * After visit_start_struct() succeeds, the caller may visit its |
| 291 | * members one after the other, passing the member's name and address |
| 292 | * within the struct. Finally, visit_end_struct() needs to be called |
Eric Blake | 1158bb2 | 2016-06-09 10:48:34 -0600 | [diff] [blame] | 293 | * with the same @obj to clean up, even if intermediate visits fail. |
| 294 | * See the examples above. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 295 | * |
| 296 | * FIXME Should this be named visit_start_object, since it is also |
| 297 | * used for QAPI unions, and maps to JSON objects? |
| 298 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 299 | bool visit_start_struct(Visitor *v, const char *name, void **obj, |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 300 | size_t size, Error **errp); |
| 301 | |
| 302 | /* |
Eric Blake | 15c2f66 | 2016-04-28 15:45:27 -0600 | [diff] [blame] | 303 | * Prepare for completing an object visit. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 304 | * |
Markus Armbruster | 1f58424 | 2020-04-24 10:43:35 +0200 | [diff] [blame] | 305 | * On failure, store an error through @errp. Can happen only when @v |
| 306 | * is an input visitor. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 307 | * |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 308 | * Return true on success, false on failure. |
| 309 | * |
Eric Blake | 15c2f66 | 2016-04-28 15:45:27 -0600 | [diff] [blame] | 310 | * Should be called prior to visit_end_struct() if all other |
| 311 | * intermediate visit steps were successful, to allow the visitor one |
| 312 | * last chance to report errors. May be skipped on a cleanup path, |
| 313 | * where there is no need to check for further errors. |
| 314 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 315 | bool visit_check_struct(Visitor *v, Error **errp); |
Eric Blake | 15c2f66 | 2016-04-28 15:45:27 -0600 | [diff] [blame] | 316 | |
| 317 | /* |
| 318 | * Complete an object visit started earlier. |
| 319 | * |
Eric Blake | 1158bb2 | 2016-06-09 10:48:34 -0600 | [diff] [blame] | 320 | * @obj must match what was passed to the paired visit_start_struct(). |
| 321 | * |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 322 | * Must be called after any successful use of visit_start_struct(), |
| 323 | * even if intermediate processing was skipped due to errors, to allow |
| 324 | * the backend to release any resources. Destroying the visitor early |
Eric Blake | 2c0ef9f | 2016-06-09 10:48:35 -0600 | [diff] [blame] | 325 | * with visit_free() behaves as if this was implicitly called. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 326 | */ |
Eric Blake | 1158bb2 | 2016-06-09 10:48:34 -0600 | [diff] [blame] | 327 | void visit_end_struct(Visitor *v, void **obj); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 328 | |
| 329 | |
| 330 | /*** Visiting lists ***/ |
| 331 | |
| 332 | /* |
| 333 | * Start visiting a list. |
| 334 | * |
| 335 | * @name expresses the relationship of this list to its parent |
| 336 | * container; see the general description of @name above. |
| 337 | * |
Eric Blake | d9f62dd | 2016-04-28 15:45:31 -0600 | [diff] [blame] | 338 | * @list must be non-NULL for a real walk, in which case @size |
Eric Blake | a15fcc3 | 2016-06-09 10:48:44 -0600 | [diff] [blame] | 339 | * determines how much memory an input or clone visitor will allocate |
| 340 | * into *@list (at least sizeof(GenericList)). Some visitors also |
| 341 | * allow @list to be NULL for a virtual walk, in which case @size is |
Eric Blake | d9f62dd | 2016-04-28 15:45:31 -0600 | [diff] [blame] | 342 | * ignored. |
| 343 | * |
Markus Armbruster | c5460d5 | 2020-04-24 10:43:27 +0200 | [diff] [blame] | 344 | * On failure, set *@list to NULL and store an error through @errp. |
Markus Armbruster | 1f58424 | 2020-04-24 10:43:35 +0200 | [diff] [blame] | 345 | * Can happen only when @v is an input visitor. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 346 | * |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 347 | * Return true on success, false on failure. |
| 348 | * |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 349 | * After visit_start_list() succeeds, the caller may visit its members |
Markus Armbruster | 782586c | 2020-04-24 10:43:26 +0200 | [diff] [blame] | 350 | * one after the other. A real visit (where @list is non-NULL) uses |
Eric Blake | d9f62dd | 2016-04-28 15:45:31 -0600 | [diff] [blame] | 351 | * visit_next_list() for traversing the linked list, while a virtual |
Markus Armbruster | 782586c | 2020-04-24 10:43:26 +0200 | [diff] [blame] | 352 | * visit (where @list is NULL) uses other means. For each list |
Eric Blake | d9f62dd | 2016-04-28 15:45:31 -0600 | [diff] [blame] | 353 | * element, call the appropriate visit_type_FOO() with name set to |
| 354 | * NULL and obj set to the address of the value member of the list |
Eric Blake | 1158bb2 | 2016-06-09 10:48:34 -0600 | [diff] [blame] | 355 | * element. Finally, visit_end_list() needs to be called with the |
| 356 | * same @list to clean up, even if intermediate visits fail. See the |
| 357 | * examples above. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 358 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 359 | bool visit_start_list(Visitor *v, const char *name, GenericList **list, |
Eric Blake | d9f62dd | 2016-04-28 15:45:31 -0600 | [diff] [blame] | 360 | size_t size, Error **errp); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 361 | |
| 362 | /* |
| 363 | * Iterate over a GenericList during a non-virtual list visit. |
| 364 | * |
| 365 | * @size represents the size of a linked list node (at least |
| 366 | * sizeof(GenericList)). |
| 367 | * |
Eric Blake | d9f62dd | 2016-04-28 15:45:31 -0600 | [diff] [blame] | 368 | * @tail must not be NULL; on the first call, @tail is the value of |
| 369 | * *list after visit_start_list(), and on subsequent calls @tail must |
| 370 | * be the previously returned value. Should be called in a loop until |
Markus Armbruster | 81b4900 | 2019-08-02 14:23:25 +0200 | [diff] [blame] | 371 | * a NULL return; for each non-NULL return, the caller then calls the |
| 372 | * appropriate visit_type_*() for the element type of the list, with |
| 373 | * that function's name parameter set to NULL and obj set to the |
| 374 | * address of @tail->value. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 375 | */ |
Eric Blake | d9f62dd | 2016-04-28 15:45:31 -0600 | [diff] [blame] | 376 | GenericList *visit_next_list(Visitor *v, GenericList *tail, size_t size); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 377 | |
| 378 | /* |
Markus Armbruster | a4a1c70 | 2017-03-03 13:32:45 +0100 | [diff] [blame] | 379 | * Prepare for completing a list visit. |
| 380 | * |
Markus Armbruster | 1f58424 | 2020-04-24 10:43:35 +0200 | [diff] [blame] | 381 | * On failure, store an error through @errp. Can happen only when @v |
| 382 | * is an input visitor. |
Markus Armbruster | a4a1c70 | 2017-03-03 13:32:45 +0100 | [diff] [blame] | 383 | * |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 384 | * Return true on success, false on failure. |
| 385 | * |
Markus Armbruster | a4a1c70 | 2017-03-03 13:32:45 +0100 | [diff] [blame] | 386 | * Should be called prior to visit_end_list() if all other |
| 387 | * intermediate visit steps were successful, to allow the visitor one |
| 388 | * last chance to report errors. May be skipped on a cleanup path, |
| 389 | * where there is no need to check for further errors. |
| 390 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 391 | bool visit_check_list(Visitor *v, Error **errp); |
Markus Armbruster | a4a1c70 | 2017-03-03 13:32:45 +0100 | [diff] [blame] | 392 | |
| 393 | /* |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 394 | * Complete a list visit started earlier. |
| 395 | * |
Eric Blake | 1158bb2 | 2016-06-09 10:48:34 -0600 | [diff] [blame] | 396 | * @list must match what was passed to the paired visit_start_list(). |
| 397 | * |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 398 | * Must be called after any successful use of visit_start_list(), even |
| 399 | * if intermediate processing was skipped due to errors, to allow the |
| 400 | * backend to release any resources. Destroying the visitor early |
Eric Blake | 2c0ef9f | 2016-06-09 10:48:35 -0600 | [diff] [blame] | 401 | * with visit_free() behaves as if this was implicitly called. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 402 | */ |
Eric Blake | 1158bb2 | 2016-06-09 10:48:34 -0600 | [diff] [blame] | 403 | void visit_end_list(Visitor *v, void **list); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 404 | |
| 405 | |
| 406 | /*** Visiting alternates ***/ |
| 407 | |
| 408 | /* |
| 409 | * Start the visit of an alternate @obj. |
| 410 | * |
| 411 | * @name expresses the relationship of this alternate to its parent |
| 412 | * container; see the general description of @name above. |
| 413 | * |
Eric Blake | a15fcc3 | 2016-06-09 10:48:44 -0600 | [diff] [blame] | 414 | * @obj must not be NULL. Input and clone visitors use @size to |
| 415 | * determine how much memory to allocate into *@obj, then determine |
Markus Armbruster | c5460d5 | 2020-04-24 10:43:27 +0200 | [diff] [blame] | 416 | * the qtype of the next thing to be visited, and store it in |
| 417 | * (*@obj)->type. Other visitors leave @obj unchanged. |
| 418 | * |
| 419 | * On failure, set *@obj to NULL and store an error through @errp. |
Markus Armbruster | 1f58424 | 2020-04-24 10:43:35 +0200 | [diff] [blame] | 420 | * Can happen only when @v is an input visitor. |
Eric Blake | dbf1192 | 2016-02-17 23:48:29 -0700 | [diff] [blame] | 421 | * |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 422 | * Return true on success, false on failure. |
| 423 | * |
Eric Blake | 1158bb2 | 2016-06-09 10:48:34 -0600 | [diff] [blame] | 424 | * If successful, this must be paired with visit_end_alternate() with |
| 425 | * the same @obj to clean up, even if visiting the contents of the |
| 426 | * alternate fails. |
Eric Blake | dbf1192 | 2016-02-17 23:48:29 -0700 | [diff] [blame] | 427 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 428 | bool visit_start_alternate(Visitor *v, const char *name, |
Eric Blake | dbf1192 | 2016-02-17 23:48:29 -0700 | [diff] [blame] | 429 | GenericAlternate **obj, size_t size, |
Marc-André Lureau | 60390d2 | 2017-06-07 20:35:59 +0400 | [diff] [blame] | 430 | Error **errp); |
Eric Blake | dbf1192 | 2016-02-17 23:48:29 -0700 | [diff] [blame] | 431 | |
| 432 | /* |
| 433 | * Finish visiting an alternate type. |
| 434 | * |
Eric Blake | 1158bb2 | 2016-06-09 10:48:34 -0600 | [diff] [blame] | 435 | * @obj must match what was passed to the paired visit_start_alternate(). |
| 436 | * |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 437 | * Must be called after any successful use of visit_start_alternate(), |
| 438 | * even if intermediate processing was skipped due to errors, to allow |
| 439 | * the backend to release any resources. Destroying the visitor early |
Eric Blake | 2c0ef9f | 2016-06-09 10:48:35 -0600 | [diff] [blame] | 440 | * with visit_free() behaves as if this was implicitly called. |
Eric Blake | dbf1192 | 2016-02-17 23:48:29 -0700 | [diff] [blame] | 441 | * |
Eric Blake | dbf1192 | 2016-02-17 23:48:29 -0700 | [diff] [blame] | 442 | */ |
Eric Blake | 1158bb2 | 2016-06-09 10:48:34 -0600 | [diff] [blame] | 443 | void visit_end_alternate(Visitor *v, void **obj); |
Eric Blake | dbf1192 | 2016-02-17 23:48:29 -0700 | [diff] [blame] | 444 | |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 445 | |
| 446 | /*** Other helpers ***/ |
| 447 | |
| 448 | /* |
| 449 | * Does optional struct member @name need visiting? |
| 450 | * |
| 451 | * @name must not be NULL. This function is only useful between |
| 452 | * visit_start_struct() and visit_end_struct(), since only objects |
| 453 | * have optional keys. |
| 454 | * |
| 455 | * @present points to the address of the optional member's has_ flag. |
| 456 | * |
| 457 | * Input visitors set *@present according to input; other visitors |
| 458 | * leave it unchanged. In either case, return *@present for |
| 459 | * convenience. |
Eric Blake | 5cdc883 | 2015-12-01 22:20:52 -0700 | [diff] [blame] | 460 | */ |
Eric Blake | 51e72bc | 2016-01-29 06:48:54 -0700 | [diff] [blame] | 461 | bool visit_optional(Visitor *v, const char *name, bool *present); |
Eric Blake | 0426d53 | 2015-12-01 22:20:48 -0700 | [diff] [blame] | 462 | |
Eric Blake | 983f52d | 2016-04-28 15:45:09 -0600 | [diff] [blame] | 463 | /* |
Markus Armbruster | a130728 | 2021-10-28 12:25:16 +0200 | [diff] [blame] | 464 | * Should we reject member @name due to policy? |
| 465 | * |
| 466 | * @special_features is the member's special features encoded as a |
| 467 | * bitset of QapiSpecialFeature. |
Markus Armbruster | db29164 | 2021-03-18 16:55:18 +0100 | [diff] [blame] | 468 | * |
| 469 | * @name must not be NULL. This function is only useful between |
| 470 | * visit_start_struct() and visit_end_struct(), since only objects |
| 471 | * have deprecated members. |
| 472 | */ |
Markus Armbruster | a130728 | 2021-10-28 12:25:16 +0200 | [diff] [blame] | 473 | bool visit_policy_reject(Visitor *v, const char *name, |
| 474 | unsigned special_features, Error **errp); |
Markus Armbruster | db29164 | 2021-03-18 16:55:18 +0100 | [diff] [blame] | 475 | |
| 476 | /* |
Markus Armbruster | a130728 | 2021-10-28 12:25:16 +0200 | [diff] [blame] | 477 | * |
| 478 | * Should we skip member @name due to policy? |
| 479 | * |
| 480 | * @special_features is the member's special features encoded as a |
| 481 | * bitset of QapiSpecialFeature. |
Markus Armbruster | 91fa93e | 2021-03-18 16:55:11 +0100 | [diff] [blame] | 482 | * |
| 483 | * @name must not be NULL. This function is only useful between |
| 484 | * visit_start_struct() and visit_end_struct(), since only objects |
| 485 | * have deprecated members. |
| 486 | */ |
Markus Armbruster | a130728 | 2021-10-28 12:25:16 +0200 | [diff] [blame] | 487 | bool visit_policy_skip(Visitor *v, const char *name, |
| 488 | unsigned special_features); |
Markus Armbruster | 91fa93e | 2021-03-18 16:55:11 +0100 | [diff] [blame] | 489 | |
| 490 | /* |
Markus Armbruster | ed29bb2 | 2021-10-25 06:24:03 +0200 | [diff] [blame] | 491 | * Set policy for handling deprecated management interfaces. |
| 492 | * |
| 493 | * Intended use: call visit_set_policy(v, &compat_policy) when |
| 494 | * visiting management interface input or output. |
| 495 | */ |
| 496 | void visit_set_policy(Visitor *v, CompatPolicy *policy); |
| 497 | |
| 498 | /* |
Eric Blake | 983f52d | 2016-04-28 15:45:09 -0600 | [diff] [blame] | 499 | * Visit an enum value. |
| 500 | * |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 501 | * @name expresses the relationship of this enum to its parent |
| 502 | * container; see the general description of @name above. |
| 503 | * |
| 504 | * @obj must be non-NULL. Input visitors parse input and set *@obj to |
| 505 | * the enumeration value, leaving @obj unchanged on error; other |
| 506 | * visitors use *@obj but leave it unchanged. |
| 507 | * |
| 508 | * Currently, all input visitors parse text input, and all output |
| 509 | * visitors produce text output. The mapping between enumeration |
Markus Armbruster | c5460d5 | 2020-04-24 10:43:27 +0200 | [diff] [blame] | 510 | * values and strings is done by the visitor core, using @lookup. |
| 511 | * |
Markus Armbruster | 1f58424 | 2020-04-24 10:43:35 +0200 | [diff] [blame] | 512 | * On failure, store an error through @errp. Can happen only when @v |
| 513 | * is an input visitor. |
Eric Blake | 983f52d | 2016-04-28 15:45:09 -0600 | [diff] [blame] | 514 | * |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 515 | * Return true on success, false on failure. |
| 516 | * |
Eric Blake | 983f52d | 2016-04-28 15:45:09 -0600 | [diff] [blame] | 517 | * May call visit_type_str() under the hood, and the enum visit may |
| 518 | * fail even if the corresponding string visit succeeded; this implies |
Markus Armbruster | 1f58424 | 2020-04-24 10:43:35 +0200 | [diff] [blame] | 519 | * that an input visitor's visit_type_str() must have no unwelcome |
| 520 | * side effects. |
Eric Blake | 983f52d | 2016-04-28 15:45:09 -0600 | [diff] [blame] | 521 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 522 | bool visit_type_enum(Visitor *v, const char *name, int *obj, |
Marc-André Lureau | f7abe0e | 2017-08-24 10:46:10 +0200 | [diff] [blame] | 523 | const QEnumLookup *lookup, Error **errp); |
Eric Blake | 983f52d | 2016-04-28 15:45:09 -0600 | [diff] [blame] | 524 | |
Eric Blake | 68ab47e | 2016-04-28 15:45:32 -0600 | [diff] [blame] | 525 | /* |
| 526 | * Check if visitor is an input visitor. |
| 527 | */ |
| 528 | bool visit_is_input(Visitor *v); |
| 529 | |
Markus Armbruster | 8e08bf4 | 2020-04-24 10:43:29 +0200 | [diff] [blame] | 530 | /* |
| 531 | * Check if visitor is a dealloc visitor. |
| 532 | */ |
| 533 | bool visit_is_dealloc(Visitor *v); |
| 534 | |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 535 | /*** Visiting built-in types ***/ |
| 536 | |
| 537 | /* |
| 538 | * Visit an integer value. |
| 539 | * |
| 540 | * @name expresses the relationship of this integer to its parent |
| 541 | * container; see the general description of @name above. |
| 542 | * |
| 543 | * @obj must be non-NULL. Input visitors set *@obj to the value; |
| 544 | * other visitors will leave *@obj unchanged. |
Markus Armbruster | c5460d5 | 2020-04-24 10:43:27 +0200 | [diff] [blame] | 545 | * |
Markus Armbruster | 1f58424 | 2020-04-24 10:43:35 +0200 | [diff] [blame] | 546 | * On failure, store an error through @errp. Can happen only when @v |
| 547 | * is an input visitor. |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 548 | * |
| 549 | * Return true on success, false on failure. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 550 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 551 | bool visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 552 | |
| 553 | /* |
| 554 | * Visit a uint8_t value. |
| 555 | * Like visit_type_int(), except clamps the value to uint8_t range. |
| 556 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 557 | bool visit_type_uint8(Visitor *v, const char *name, uint8_t *obj, |
Eric Blake | 51e72bc | 2016-01-29 06:48:54 -0700 | [diff] [blame] | 558 | Error **errp); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 559 | |
| 560 | /* |
| 561 | * Visit a uint16_t value. |
| 562 | * Like visit_type_int(), except clamps the value to uint16_t range. |
| 563 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 564 | bool visit_type_uint16(Visitor *v, const char *name, uint16_t *obj, |
Eric Blake | 51e72bc | 2016-01-29 06:48:54 -0700 | [diff] [blame] | 565 | Error **errp); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 566 | |
| 567 | /* |
| 568 | * Visit a uint32_t value. |
| 569 | * Like visit_type_int(), except clamps the value to uint32_t range. |
| 570 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 571 | bool visit_type_uint32(Visitor *v, const char *name, uint32_t *obj, |
Eric Blake | 51e72bc | 2016-01-29 06:48:54 -0700 | [diff] [blame] | 572 | Error **errp); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 573 | |
| 574 | /* |
| 575 | * Visit a uint64_t value. |
| 576 | * Like visit_type_int(), except clamps the value to uint64_t range, |
| 577 | * that is, ensures it is unsigned. |
| 578 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 579 | bool visit_type_uint64(Visitor *v, const char *name, uint64_t *obj, |
Eric Blake | 51e72bc | 2016-01-29 06:48:54 -0700 | [diff] [blame] | 580 | Error **errp); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 581 | |
| 582 | /* |
| 583 | * Visit an int8_t value. |
| 584 | * Like visit_type_int(), except clamps the value to int8_t range. |
| 585 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 586 | bool visit_type_int8(Visitor *v, const char *name, int8_t *obj, Error **errp); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 587 | |
| 588 | /* |
| 589 | * Visit an int16_t value. |
| 590 | * Like visit_type_int(), except clamps the value to int16_t range. |
| 591 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 592 | bool visit_type_int16(Visitor *v, const char *name, int16_t *obj, |
Eric Blake | 51e72bc | 2016-01-29 06:48:54 -0700 | [diff] [blame] | 593 | Error **errp); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 594 | |
| 595 | /* |
| 596 | * Visit an int32_t value. |
| 597 | * Like visit_type_int(), except clamps the value to int32_t range. |
| 598 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 599 | bool visit_type_int32(Visitor *v, const char *name, int32_t *obj, |
Eric Blake | 51e72bc | 2016-01-29 06:48:54 -0700 | [diff] [blame] | 600 | Error **errp); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 601 | |
| 602 | /* |
| 603 | * Visit an int64_t value. |
| 604 | * Identical to visit_type_int(). |
| 605 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 606 | bool visit_type_int64(Visitor *v, const char *name, int64_t *obj, |
Eric Blake | 51e72bc | 2016-01-29 06:48:54 -0700 | [diff] [blame] | 607 | Error **errp); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 608 | |
| 609 | /* |
| 610 | * Visit a uint64_t value. |
| 611 | * Like visit_type_uint64(), except that some visitors may choose to |
| 612 | * recognize additional syntax, such as suffixes for easily scaling |
| 613 | * values. |
| 614 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 615 | bool visit_type_size(Visitor *v, const char *name, uint64_t *obj, |
Eric Blake | 51e72bc | 2016-01-29 06:48:54 -0700 | [diff] [blame] | 616 | Error **errp); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 617 | |
| 618 | /* |
| 619 | * Visit a boolean value. |
| 620 | * |
| 621 | * @name expresses the relationship of this boolean to its parent |
| 622 | * container; see the general description of @name above. |
| 623 | * |
| 624 | * @obj must be non-NULL. Input visitors set *@obj to the value; |
| 625 | * other visitors will leave *@obj unchanged. |
Markus Armbruster | c5460d5 | 2020-04-24 10:43:27 +0200 | [diff] [blame] | 626 | * |
Markus Armbruster | 1f58424 | 2020-04-24 10:43:35 +0200 | [diff] [blame] | 627 | * On failure, store an error through @errp. Can happen only when @v |
| 628 | * is an input visitor. |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 629 | * |
| 630 | * Return true on success, false on failure. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 631 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 632 | bool visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 633 | |
| 634 | /* |
| 635 | * Visit a string value. |
| 636 | * |
| 637 | * @name expresses the relationship of this string to its parent |
| 638 | * container; see the general description of @name above. |
| 639 | * |
Eric Blake | a15fcc3 | 2016-06-09 10:48:44 -0600 | [diff] [blame] | 640 | * @obj must be non-NULL. Input and clone visitors set *@obj to the |
| 641 | * value (always using "" rather than NULL for an empty string). |
| 642 | * Other visitors leave *@obj unchanged, and commonly treat NULL like |
| 643 | * "". |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 644 | * |
| 645 | * It is safe to cast away const when preparing a (const char *) value |
| 646 | * into @obj for use by an output visitor. |
| 647 | * |
Markus Armbruster | c5460d5 | 2020-04-24 10:43:27 +0200 | [diff] [blame] | 648 | * On failure, set *@obj to NULL and store an error through @errp. |
Markus Armbruster | 1f58424 | 2020-04-24 10:43:35 +0200 | [diff] [blame] | 649 | * Can happen only when @v is an input visitor. |
Markus Armbruster | c5460d5 | 2020-04-24 10:43:27 +0200 | [diff] [blame] | 650 | * |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 651 | * Return true on success, false on failure. |
| 652 | * |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 653 | * FIXME: Callers that try to output NULL *obj should not be allowed. |
| 654 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 655 | bool visit_type_str(Visitor *v, const char *name, char **obj, Error **errp); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 656 | |
| 657 | /* |
| 658 | * Visit a number (i.e. double) value. |
| 659 | * |
| 660 | * @name expresses the relationship of this number to its parent |
| 661 | * container; see the general description of @name above. |
| 662 | * |
| 663 | * @obj must be non-NULL. Input visitors set *@obj to the value; |
| 664 | * other visitors will leave *@obj unchanged. Visitors should |
| 665 | * document if infinity or NaN are not permitted. |
Markus Armbruster | c5460d5 | 2020-04-24 10:43:27 +0200 | [diff] [blame] | 666 | * |
Markus Armbruster | 1f58424 | 2020-04-24 10:43:35 +0200 | [diff] [blame] | 667 | * On failure, store an error through @errp. Can happen only when @v |
| 668 | * is an input visitor. |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 669 | * |
| 670 | * Return true on success, false on failure. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 671 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 672 | bool visit_type_number(Visitor *v, const char *name, double *obj, |
Eric Blake | 51e72bc | 2016-01-29 06:48:54 -0700 | [diff] [blame] | 673 | Error **errp); |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 674 | |
| 675 | /* |
| 676 | * Visit an arbitrary value. |
| 677 | * |
| 678 | * @name expresses the relationship of this value to its parent |
| 679 | * container; see the general description of @name above. |
| 680 | * |
| 681 | * @obj must be non-NULL. Input visitors set *@obj to the value; |
| 682 | * other visitors will leave *@obj unchanged. *@obj must be non-NULL |
| 683 | * for output visitors. |
Markus Armbruster | 8339fa2 | 2017-05-22 18:42:13 +0200 | [diff] [blame] | 684 | * |
Markus Armbruster | c5460d5 | 2020-04-24 10:43:27 +0200 | [diff] [blame] | 685 | * On failure, set *@obj to NULL and store an error through @errp. |
Markus Armbruster | 1f58424 | 2020-04-24 10:43:35 +0200 | [diff] [blame] | 686 | * Can happen only when @v is an input visitor. |
Markus Armbruster | c5460d5 | 2020-04-24 10:43:27 +0200 | [diff] [blame] | 687 | * |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 688 | * Return true on success, false on failure. |
| 689 | * |
Markus Armbruster | 8339fa2 | 2017-05-22 18:42:13 +0200 | [diff] [blame] | 690 | * Note that some kinds of input can't express arbitrary QObject. |
| 691 | * E.g. the visitor returned by qobject_input_visitor_new_keyval() |
| 692 | * can't create numbers or booleans, only strings. |
Eric Blake | adfb264 | 2016-04-28 15:45:20 -0600 | [diff] [blame] | 693 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 694 | bool visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp); |
Michael Roth | 2345c77 | 2011-07-19 14:50:32 -0500 | [diff] [blame] | 695 | |
Eric Blake | 3bc97fd | 2016-04-28 15:45:22 -0600 | [diff] [blame] | 696 | /* |
| 697 | * Visit a JSON null value. |
| 698 | * |
| 699 | * @name expresses the relationship of the null value to its parent |
| 700 | * container; see the general description of @name above. |
| 701 | * |
Markus Armbruster | d2f95f4 | 2017-06-26 18:22:59 +0200 | [diff] [blame] | 702 | * @obj must be non-NULL. Input visitors set *@obj to the value; |
| 703 | * other visitors ignore *@obj. |
Markus Armbruster | c5460d5 | 2020-04-24 10:43:27 +0200 | [diff] [blame] | 704 | * |
| 705 | * On failure, set *@obj to NULL and store an error through @errp. |
Markus Armbruster | 1f58424 | 2020-04-24 10:43:35 +0200 | [diff] [blame] | 706 | * Can happen only when @v is an input visitor. |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 707 | * |
| 708 | * Return true on success, false on failure. |
Eric Blake | 3bc97fd | 2016-04-28 15:45:22 -0600 | [diff] [blame] | 709 | */ |
Markus Armbruster | 012d4c9 | 2020-07-07 18:05:45 +0200 | [diff] [blame] | 710 | bool visit_type_null(Visitor *v, const char *name, QNull **obj, |
Markus Armbruster | d2f95f4 | 2017-06-26 18:22:59 +0200 | [diff] [blame] | 711 | Error **errp); |
Eric Blake | 3bc97fd | 2016-04-28 15:45:22 -0600 | [diff] [blame] | 712 | |
Michael Roth | 2345c77 | 2011-07-19 14:50:32 -0500 | [diff] [blame] | 713 | #endif |