NCDObject.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /**
  2. * @file NCDObject.h
  3. * @author Ambroz Bizjak <ambrop7@gmail.com>
  4. *
  5. * @section LICENSE
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. Neither the name of the author nor the
  15. * names of its contributors may be used to endorse or promote products
  16. * derived from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  22. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  25. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. */
  29. #ifndef BADVPN_NCDOBJECT_H
  30. #define BADVPN_NCDOBJECT_H
  31. #include <stddef.h>
  32. #include <misc/debug.h>
  33. #include <structure/LinkedList0.h>
  34. #include <ncd/NCDVal_types.h>
  35. #include <ncd/NCDStringIndex.h>
  36. #include <ncd/static_strings.h>
  37. /**
  38. * Represents an NCD object.
  39. * Objects expose the following functionalities:
  40. * - resolving variables by name,
  41. * - resolving objects by name,
  42. * - provide information for calling method-like statements.
  43. *
  44. * The NCDObject structure must not be stored persistently; it is only
  45. * valid at the time it was obtained, and any change of state in the
  46. * execution of the NCD program may render the object invalid.
  47. * However, the structure does not contain any resources, and can freely
  48. * be passed around by value.
  49. */
  50. typedef struct NCDObject_s NCDObject;
  51. /**
  52. * Serves as an anchor point for NCDObjRef weak references.
  53. * A callback produces the temporary NCDObject values on demand.
  54. */
  55. typedef struct NCDPersistentObj_s NCDPersistentObj;
  56. /**
  57. * A weak reference to an NCDPersistentObj.
  58. * This means that the existence of a reference does not prevent
  59. * the NCDPersistentObj from going away, rather when it goes away
  60. * the NCDObjRef becomes a broken reference - any further
  61. * dereference operations will fail "gracefully".
  62. */
  63. typedef struct NCDObjRef_s NCDObjRef;
  64. /**
  65. * Callback function for variable resolution requests.
  66. *
  67. * @param obj const pointer to the NCDObject this is being called for.
  68. * {@link NCDObject_DataPtr} and {@link NCDObject_DataInt} can be
  69. * used to retrieve state information which was passed to
  70. * {@link NCDObject_Build} or {@link NCDObject_BuildFull}.
  71. * @param name name of the variable being resolved, in form of an {@link NCDStringIndex}
  72. * string identifier
  73. * @param mem pointer to the memory object where the resulting value should be
  74. * constructed
  75. * @param out_value If the variable exists, *out_value should be set to the value
  76. * reference to the result value. If the variable exists but there
  77. * was an error constructing the value, should be set to an
  78. * invalid value reference. Can be modified even if the variable
  79. * does not exist.
  80. * @return 1 if the variable exists, 0 if not
  81. */
  82. typedef int (*NCDObject_func_getvar) (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out_value);
  83. /**
  84. * Callback function for object resolution requests.
  85. *
  86. * @param obj const pointer to the NCDObject this is being called for.
  87. * {@link NCDObject_DataPtr} and {@link NCDObject_DataInt} can be
  88. * used to retrieve state information which was passed to
  89. * {@link NCDObject_Build} or {@link NCDObject_BuildFull}.
  90. * @param name name of the object being resolved, in form of an {@link NCDStringIndex}
  91. * string identifier
  92. * @param out_object If the object exists, *out_object should be set to the result
  93. * object. Can be modified even if the object does not exist.
  94. * @return 1 if the object exists, 0 if not
  95. */
  96. typedef int (*NCDObject_func_getobj) (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object);
  97. /**
  98. * A callback of NCDPersistentObj which produces the corresponding temporary
  99. * NCDObject value.
  100. */
  101. typedef NCDObject (*NCDPersistentObj_func_retobj) (NCDPersistentObj const *pobj);
  102. struct NCDObject_s {
  103. NCD_string_id_t type;
  104. int data_int;
  105. void *data_ptr;
  106. void *method_user;
  107. NCDObject_func_getvar func_getvar;
  108. NCDObject_func_getobj func_getobj;
  109. NCDPersistentObj *pobj;
  110. };
  111. struct NCDPersistentObj_s {
  112. NCDPersistentObj_func_retobj func_retobj;
  113. LinkedList0 refs_list;
  114. };
  115. struct NCDObjRef_s {
  116. NCDPersistentObj *pobj;
  117. LinkedList0Node refs_list_node;
  118. };
  119. /**
  120. * Basic object construction function.
  121. * This is equivalent to calling {@link NCDObject_BuildFull} with data_int=0,
  122. * method_user=data_ptr and pobj=NULL. See that function for detailed documentation.
  123. */
  124. NCDObject NCDObject_Build (NCD_string_id_t type, void *data_ptr, NCDObject_func_getvar func_getvar, NCDObject_func_getobj func_getobj);
  125. /**
  126. * Constructs an {@link NCDObject} structure.
  127. * This is the full version where all supported parameters have to be provided.
  128. * In most cases, {@link NCDObject_Build} will suffice.
  129. *
  130. * @param type type of the object for the purpose of calling method-like statements
  131. * on the object, in form of an {@link NCDStringIndex} string identifier.
  132. * May be set to -1 if the object has no methods.
  133. * @param data_ptr state-keeping pointer which can be restored from callbacks using
  134. * {@link NCDObject_DataPtr}
  135. * @param data_int state-keeping integer which can be restored from callbacks using
  136. * {@link NCDObject_DataInt}
  137. * @param method_user state-keeping pointer to be passed to new method-like statements
  138. * created using this object. The value of this argument will be
  139. * available as params->method_user within the {@link NCDModule_func_new2}
  140. * module backend callback.
  141. * @param func_getvar callback for resolving variables within the object. This must not
  142. * be NULL; if the object exposes no variables, pass {@link NCDObject_no_getvar}.
  143. * @param func_getobj callback for resolving objects within the object. This must not
  144. * be NULL; if the object exposes no objects, pass {@link NCDObject_no_getobj}.
  145. * @param pobj pointer to an NCDPersistentObj, serving as a reference anchor for this
  146. * object. NULL if references are not supported by the object.
  147. * @return an NCDObject structure encapsulating the information given
  148. */
  149. NCDObject NCDObject_BuildFull (NCD_string_id_t type, void *data_ptr, int data_int, void *method_user, NCDObject_func_getvar func_getvar, NCDObject_func_getobj func_getobj, NCDPersistentObj *pobj);
  150. /**
  151. * Returns the 'type' attribute; see {@link NCDObject_BuildFull}.
  152. */
  153. NCD_string_id_t NCDObject_Type (const NCDObject *o);
  154. /**
  155. * Returns the 'data_ptr' attribute; see {@link NCDObject_BuildFull}.
  156. */
  157. void * NCDObject_DataPtr (const NCDObject *o);
  158. /**
  159. * Returns the 'data_int' attribute; see {@link NCDObject_BuildFull}.
  160. */
  161. int NCDObject_DataInt (const NCDObject *o);
  162. /**
  163. * Returns the 'method_user' attribute; see {@link NCDObject_BuildFull}.
  164. */
  165. void * NCDObject_MethodUser (const NCDObject *o);
  166. /**
  167. * Attempts to resolve a variable within the object.
  168. * This just calls {@link NCDObject_func_getvar}, but also has some assertions to detect
  169. * incorrect behavior of the callback.
  170. */
  171. int NCDObject_GetVar (const NCDObject *o, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out_value) WARN_UNUSED;
  172. /**
  173. * Attempts to resolve an object within the object.
  174. * This just calls {@link NCDObject_func_getobj}, but also has some assertions to detect
  175. * incorrect behavior of the callback.
  176. */
  177. int NCDObject_GetObj (const NCDObject *o, NCD_string_id_t name, NCDObject *out_object) WARN_UNUSED;
  178. /**
  179. * Returns a pointer to the NCDPersistentObj pointer for this
  180. * object (if any).
  181. */
  182. NCDPersistentObj * NCDObject_Pobj (const NCDObject *o);
  183. /**
  184. * Resolves a variable expression starting with this object.
  185. * A variable expression is usually represented in dotted form,
  186. * e.g. object1.object2.variable (for a named variable) or object1.object2.object3
  187. * (for an empty string variable). This function however receives the expression
  188. * as an array of string identifiers.
  189. *
  190. * Consult the implementation for exact semantics of variable expression resolution.
  191. *
  192. * @param o object to start the resolution with
  193. * @param names pointer to an array of names for the resolution. May be NULL if num_names is 0.
  194. * @param num_names number in names in the array
  195. * @param mem pointer to the memory object where the resulting value
  196. * should be constructed
  197. * @param out_value If the variable exists, *out_value will be set to the value
  198. * reference to the result value. If the variable exists but there
  199. * was an error constructing the value, will be set to an
  200. * invalid value reference. May be modified even if the variable
  201. * does not exist.
  202. * @return 1 if the variable exists, 0 if not
  203. */
  204. int NCDObject_ResolveVarExprCompact (const NCDObject *o, const NCD_string_id_t *names, size_t num_names, NCDValMem *mem, NCDValRef *out_value) WARN_UNUSED;
  205. /**
  206. * Resolves an object expression starting with this object.
  207. * An object expression is usually represented in dotted form,
  208. * e.g. object1.object2.object3. This function however receives the expression
  209. * as an array of string identifiers.
  210. *
  211. * Consult the implementation for exact semantics of object expression resolution.
  212. *
  213. * @param o object to start the resolution with
  214. * @param names pointer to an array of names for the resolution. May be NULL if num_names is 0.
  215. * @param num_names number in names in the array
  216. * @param out_object If the object exists, *out_object will be set to the result
  217. * object. May be modified even if the object does not exist.
  218. * @return 1 if the object exists, 0 if not
  219. */
  220. int NCDObject_ResolveObjExprCompact (const NCDObject *o, const NCD_string_id_t *names, size_t num_names, NCDObject *out_object) WARN_UNUSED;
  221. /**
  222. * Returns 0. This can be used as a dummy variable resolution callback.
  223. */
  224. int NCDObject_no_getvar (const NCDObject *obj, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out_value);
  225. /**
  226. * Returns 0. This can be used as a dummy object resolution callback.
  227. */
  228. int NCDObject_no_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object);
  229. /**
  230. * Initializes an NCDPersistentObj, an anchor point for NCDObjRef
  231. * refrences.
  232. *
  233. * @param func_retobj callback for producing NCDObject temporary objects
  234. */
  235. void NCDPersistentObj_Init (NCDPersistentObj *o, NCDPersistentObj_func_retobj func_retobj);
  236. /**
  237. * Frees the NCDPersistentObj.
  238. * This breaks any NCDObjRef references referencing this object.
  239. * This means that any further NCDObjRef_Deref calls on those
  240. * references will fail.
  241. */
  242. void NCDPersistentObj_Free (NCDPersistentObj *o);
  243. /**
  244. * Initializes an object reference.
  245. *
  246. * @param pobj the NCDPersistentObj for the reference, or NULL to make
  247. * a broken reference
  248. */
  249. void NCDObjRef_Init (NCDObjRef *o, NCDPersistentObj *pobj);
  250. /**
  251. * Frees the object reference.
  252. */
  253. void NCDObjRef_Free (NCDObjRef *o);
  254. /**
  255. * Dereferences the object reference.
  256. * Note that the refernce will be broken if the originally
  257. * reference NCDPersistentObj was freed.
  258. *
  259. * @param res on success, *res will be set to the resulting NCDObject
  260. * @return 1 on success, 0 on failure (broken reference)
  261. */
  262. int NCDObjRef_Deref (NCDObjRef *o, NCDObject *res) WARN_UNUSED;
  263. #endif