NCDVal.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. /**
  2. * @file NCDVal.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_NCDVAL_H
  30. #define BADVPN_NCDVAL_H
  31. #include <stddef.h>
  32. #include <stdint.h>
  33. #include <misc/debug.h>
  34. #include <misc/BRefTarget.h>
  35. #include <misc/memref.h>
  36. #include <ncd/NCDStringIndex.h>
  37. #include <ncd/NCDVal_types.h>
  38. #define NCDVAL_STRING 1
  39. #define NCDVAL_LIST 2
  40. #define NCDVAL_MAP 3
  41. #define NCDVAL_PLACEHOLDER 4
  42. /**
  43. * Initializes a value memory object.
  44. * A value memory object holds memory for value structures. Values within
  45. * the memory are referenced using {@link NCDValRef} objects, which point
  46. * to values within memory objects.
  47. *
  48. * Values may be added to a memory object using functions such as
  49. * {@link NCDVal_NewString}, {@link NCDVal_NewList} and {@link NCDVal_NewMap},
  50. * and {@link NCDVal_NewCopy}, which return references to the new values within
  51. * the memory object.
  52. *
  53. * It is not possible to remove values from the memory object, or modify existing
  54. * values other than adding elements to pre-allocated slots in lists and maps.
  55. * Once a value is added, it will consume memory as long as its memory object
  56. * exists. This is by design - this code is intended and optimized for constructing
  57. * and passing around values, not for operating on them in place. In fact, al
  58. * values within a memory object are stored in a single memory buffer, as an
  59. * embedded data structure with relativepointers. For example, map values use an
  60. * embedded AVL tree.
  61. */
  62. void NCDValMem_Init (NCDValMem *o, NCDStringIndex *string_index);
  63. /**
  64. * Frees a value memory object.
  65. * All values within the memory object cease to exist, and any {@link NCDValRef}
  66. * object pointing to them must no longer be used.
  67. */
  68. void NCDValMem_Free (NCDValMem *o);
  69. /**
  70. * Initializes the memory object to be a copy of an existing memory object.
  71. * Value references from the original may be used if they are first turned
  72. * to {@link NCDValSafeRef} using {@link NCDVal_ToSafe} and back to
  73. * {@link NCDValRef} using {@link NCDVal_FromSafe} with the new memory object
  74. * specified. Alternatively, {@link NCDVal_Moved} can be used.
  75. * Returns 1 on success and 0 on failure.
  76. */
  77. int NCDValMem_InitCopy (NCDValMem *o, NCDValMem *other) WARN_UNUSED;
  78. /**
  79. * Get the string index of a value memory object.
  80. */
  81. NCDStringIndex * NCDValMem_StringIndex (NCDValMem *o);
  82. /**
  83. * Does nothing.
  84. * The value reference object must either point to a valid value within a valid
  85. * memory object, or must be an invalid reference (most functions operating on
  86. * {@link NCDValRef} implicitly require that).
  87. */
  88. void NCDVal_Assert (NCDValRef val);
  89. /**
  90. * Determines if a value reference is invalid.
  91. */
  92. int NCDVal_IsInvalid (NCDValRef val);
  93. /**
  94. * Determines if a value is a placeholder value.
  95. * The value reference must not be an invalid reference.
  96. */
  97. int NCDVal_IsPlaceholder (NCDValRef val);
  98. /**
  99. * Returns the type of the value reference, which must not be an invalid reference.
  100. * Possible values are NCDVAL_STRING, NCDVAL_LIST, NCDVAL_MAP and NCDVAL_PLACEHOLDER.
  101. * The placeholder type is only used internally in the interpreter for argument
  102. * resolution, and is never seen by modules; see {@link NCDVal_NewPlaceholder}.
  103. */
  104. int NCDVal_Type (NCDValRef val);
  105. /**
  106. * Returns an invalid reference.
  107. * An invalid reference must not be passed to any function here, except:
  108. * {@link NCDVal_Assert}, {@link NCDVal_IsInvalid}, {@link NCDVal_ToSafe},
  109. * {@link NCDVal_FromSafe}, {@link NCDVal_Moved}.
  110. */
  111. NCDValRef NCDVal_NewInvalid (void);
  112. /**
  113. * Returns a new placeholder value reference. A placeholder value is a valid value
  114. * containing an integer placeholder identifier.
  115. * This always succeeds; however, the caller must ensure the identifier is in the
  116. * range [0, NCDVAL_TOPPLID).
  117. *
  118. * The placeholder type is only used internally in the interpreter for argument
  119. * resolution, and is never seen by modules.
  120. */
  121. NCDValRef NCDVal_NewPlaceholder (NCDValMem *mem, int plid);
  122. /**
  123. * Returns the indentifier of a placeholder value.
  124. * The value reference must point to a placeholder value.
  125. */
  126. int NCDVal_PlaceholderId (NCDValRef val);
  127. /**
  128. * Copies a value into the specified memory object. The source
  129. * must not be an invalid reference, however it may reside in any memory
  130. * object (including 'mem').
  131. * Returns a reference to the copied value. On out of memory, returns
  132. * an invalid reference.
  133. */
  134. NCDValRef NCDVal_NewCopy (NCDValMem *mem, NCDValRef val);
  135. /**
  136. * Compares two values, both of which must not be invalid references.
  137. * Returns -1, 0 or 1.
  138. */
  139. int NCDVal_Compare (NCDValRef val1, NCDValRef val2);
  140. /**
  141. * Converts a value reference to a safe referece format, which remains valid
  142. * if the memory object is moved (safe references do not contain a pointer
  143. * to the memory object, unlike {@link NCDValRef} references).
  144. */
  145. NCDValSafeRef NCDVal_ToSafe (NCDValRef val);
  146. /**
  147. * Converts a safe value reference to a normal value reference.
  148. * This should be used to recover references from safe references
  149. * after the memory object is moved.
  150. */
  151. NCDValRef NCDVal_FromSafe (NCDValMem *mem, NCDValSafeRef sval);
  152. /**
  153. * Fixes a value reference after its memory object was moved.
  154. */
  155. NCDValRef NCDVal_Moved (NCDValMem *mem, NCDValRef val);
  156. /**
  157. * Determines whether a safe reference is a placeholder.
  158. */
  159. int NCDVal_IsSafeRefPlaceholder (NCDValSafeRef sval);
  160. /**
  161. * Gets the placeholder ID of a placeholder safe reference.
  162. */
  163. int NCDVal_GetSafeRefPlaceholderId (NCDValSafeRef sval);
  164. /**
  165. * Determines if the value implements the String interface.
  166. * The value reference must not be an invalid reference.
  167. */
  168. int NCDVal_IsString (NCDValRef val);
  169. /**
  170. * Determines if the value is a StoredString.
  171. * A StoredString implements the String interface.
  172. * The value reference must not be an invalid reference.
  173. */
  174. int NCDVal_IsStoredString (NCDValRef val);
  175. /**
  176. * Determines if the value is an IdString. See {@link NCDVal_NewIdString}
  177. * for details.
  178. * An IdString implements the String interface.
  179. * The value reference must not be an invalid reference.
  180. */
  181. int NCDVal_IsIdString (NCDValRef val);
  182. /**
  183. * Determines if a value is an ExternalString.
  184. * See {@link NCDVal_NewExternalString} for details.
  185. * An ExternalString implements the String interface.
  186. * The value reference must not be an invalid reference.
  187. */
  188. int NCDVal_IsExternalString (NCDValRef val);
  189. /**
  190. * Determines if a value is a String which contains no null bytes.
  191. * The value reference must not be an invalid reference.
  192. */
  193. int NCDVal_IsStringNoNulls (NCDValRef val);
  194. /**
  195. * Equivalent to NCDVal_NewStringBin(mem, data, strlen(data)).
  196. */
  197. NCDValRef NCDVal_NewString (NCDValMem *mem, const char *data);
  198. /**
  199. * Builds a new StoredString.
  200. * Returns a reference to the new value, or an invalid reference
  201. * on out of memory.
  202. * WARNING: The buffer passed must NOT be part of any value in the
  203. * memory object specified. In particular, you may NOT use this
  204. * function to copy a string that resides in the same memory object.
  205. *
  206. * A StoredString is a kind of String which is represented directly in the
  207. * value memory object.
  208. */
  209. NCDValRef NCDVal_NewStringBin (NCDValMem *mem, const uint8_t *data, size_t len);
  210. /**
  211. * See NCDVal_NewStringBin.
  212. */
  213. NCDValRef NCDVal_NewStringBinMr (NCDValMem *mem, MemRef data);
  214. /**
  215. * Builds a new StoredString of the given length with undefined contents.
  216. * You can define the contents of the string later by copying to the address
  217. * returned by {@link NCDVal_StringData}.
  218. */
  219. NCDValRef NCDVal_NewStringUninitialized (NCDValMem *mem, size_t len);
  220. /**
  221. * Builds a new IdString.
  222. * Returns a reference to the new value, or an invalid reference
  223. * on out of memory.
  224. *
  225. * An IdString is a kind of String which is represented efficiently as a string
  226. * identifier via {@link NCDStringIndex}.
  227. */
  228. NCDValRef NCDVal_NewIdString (NCDValMem *mem, NCD_string_id_t string_id);
  229. /**
  230. * Builds a new ExternalString, pointing to the given external data. A reference to
  231. * the external data is taken using {@link BRefTarget}, unless 'ref_target' is
  232. * NULL. The data must not change while this value exists.
  233. * Returns a reference to the new value, or an invalid reference
  234. * on out of memory.
  235. *
  236. * An ExternalString is a kind of String where the actual string contents are
  237. * stored outside of the value memory object.
  238. */
  239. NCDValRef NCDVal_NewExternalString (NCDValMem *mem, const char *data, size_t len,
  240. BRefTarget *ref_target);
  241. /**
  242. * Returns a pointer to the data of a String.
  243. * WARNING: the string data may not be null-terminated. To get a null-terminated
  244. * version, use {@link NCDVal_StringNullTerminate}.
  245. * The value reference must point to a String.
  246. * WARNING: the returned pointer may become invalid when any new value is inserted
  247. * into the residing memory object (due to a realloc of the value memory).
  248. */
  249. const char * NCDVal_StringData (NCDValRef string);
  250. /**
  251. * Returns the length of a String.
  252. * The value reference must point to a String.
  253. */
  254. size_t NCDVal_StringLength (NCDValRef string);
  255. /**
  256. * Returns a MemRef interface to the given string value.
  257. * WARNING: the returned pointer may become invalid when any new value is inserted
  258. * into the residing memory object (due to a realloc of the value memory).
  259. */
  260. MemRef NCDVal_StringMemRef (NCDValRef string);
  261. /**
  262. * Produces a null-terminated version of a String. On success, the result is
  263. * stored into an {@link NCDValNullTermString} structure, and the null-terminated
  264. * string is available via its 'data' member. This function may either simply pass
  265. * through the data pointer (if the string is known to be null-terminated) or
  266. * produce a null-terminated dynamically allocated copy.
  267. * On success, {@link NCDValNullTermString_Free} should be called to release any allocated
  268. * memory when the null-terminated string is no longer needed. This must be called before
  269. * the memory object is freed, because it may point to data inside the memory object.
  270. * It is guaranteed that *out is not modified on failure.
  271. * Returns 1 on success and 0 on failure.
  272. */
  273. int NCDVal_StringNullTerminate (NCDValRef string, NCDValNullTermString *out) WARN_UNUSED;
  274. /**
  275. * Returns a dummy {@link NCDValNullTermString} which can be freed using
  276. * {@link NCDValNullTermString_Free}, but need not be.
  277. */
  278. NCDValNullTermString NCDValNullTermString_NewDummy (void);
  279. /**
  280. * Releases any memory which was dynamically allocated by {@link NCDVal_StringNullTerminate}
  281. * to null-terminate a string.
  282. */
  283. void NCDValNullTermString_Free (NCDValNullTermString *o);
  284. /**
  285. * Returns the string ID of an IdString.
  286. */
  287. NCD_string_id_t NCDVal_IdStringId (NCDValRef idstring);
  288. /**
  289. * Returns the reference target of an ExternalString. This may be NULL
  290. * if the external string is not associated with a reference target.
  291. */
  292. BRefTarget * NCDVal_ExternalStringTarget (NCDValRef externalstring);
  293. /**
  294. * Determines if the String has any null bytes in its contents.
  295. */
  296. int NCDVal_StringHasNulls (NCDValRef string);
  297. /**
  298. * Determines if the String value is equal to the given null-terminated
  299. * string.
  300. * The value reference must point to a String value.
  301. */
  302. int NCDVal_StringEquals (NCDValRef string, const char *data);
  303. /**
  304. * Determines if the String is equal to the given string represented
  305. * by an {@link NCDStringIndex} identifier.
  306. */
  307. int NCDVal_StringEqualsId (NCDValRef string, NCD_string_id_t string_id);
  308. /**
  309. * Compares two String's in a manner similar to memcmp().
  310. * The startN and length arguments must refer to a valid region within
  311. * stringN, i.e. startN + length <= length_of_stringN must hold.
  312. */
  313. int NCDVal_StringMemCmp (NCDValRef string1, NCDValRef string2, size_t start1, size_t start2, size_t length);
  314. /**
  315. * Copies a part of a String to a buffer.
  316. * \a start and \a length must refer to a valid region within the string,
  317. * i.e. start + length <= length_of_string must hold.
  318. */
  319. void NCDVal_StringCopyOut (NCDValRef string, size_t start, size_t length, char *dst);
  320. /**
  321. * Determines if a part of a String is equal to the \a length bytes in \a data.
  322. * \a start and \a length must refer to a valid region within the string,
  323. * i.e. start + length <= length_of_string must hold.
  324. */
  325. int NCDVal_StringRegionEquals (NCDValRef string, size_t start, size_t length, const char *data);
  326. /**
  327. * Determines if a value is a list value.
  328. * The value reference must not be an invalid reference.
  329. */
  330. int NCDVal_IsList (NCDValRef val);
  331. /**
  332. * Builds a new list value. The 'maxcount' argument specifies how
  333. * many element slots to preallocate. Not more than that many
  334. * elements may be appended to the list using {@link NCDVal_ListAppend}.
  335. * Returns a reference to the new value, or an invalid reference
  336. * on out of memory.
  337. */
  338. NCDValRef NCDVal_NewList (NCDValMem *mem, size_t maxcount);
  339. /**
  340. * Appends a value to to the list value.
  341. * The 'list' reference must point to a list value, and the
  342. * 'elem' reference must be non-invalid and point to a value within
  343. * the same memory object as the list.
  344. * Inserting a value into a list does not in any way change it;
  345. * internally, the list only points to it.
  346. * You must not modify the element after it has been inserted into the
  347. * list.
  348. * Returns 1 on success and 0 on failure (depth limit exceeded).
  349. */
  350. int NCDVal_ListAppend (NCDValRef list, NCDValRef elem) WARN_UNUSED;
  351. /**
  352. * Returns the number of elements in a list value, i.e. the number
  353. * of times {@link NCDVal_ListAppend} was called.
  354. * The 'list' reference must point to a list value.
  355. */
  356. size_t NCDVal_ListCount (NCDValRef list);
  357. /**
  358. * Returns the maximum number of elements a list value may contain,
  359. * i.e. the 'maxcount' argument to {@link NCDVal_NewList}.
  360. * The 'list' reference must point to a list value.
  361. */
  362. size_t NCDVal_ListMaxCount (NCDValRef list);
  363. /**
  364. * Returns a reference to the value at the given position 'pos' in a list,
  365. * starting with zero.
  366. * The 'list' reference must point to a list value.
  367. * The position 'pos' must refer to an existing element, i.e.
  368. * pos < NCDVal_ListCount().
  369. */
  370. NCDValRef NCDVal_ListGet (NCDValRef list, size_t pos);
  371. /**
  372. * Returns references to elements within a list by writing them
  373. * via (NCDValRef *) variable arguments.
  374. * If 'num' == NCDVal_ListCount(), succeeds, returing 1 and writing 'num'
  375. * references, as mentioned.
  376. * If 'num' != NCDVal_ListCount(), fails, returning 0, without writing any
  377. * references
  378. */
  379. int NCDVal_ListRead (NCDValRef list, int num, ...);
  380. /**
  381. * Like NCDVal_ListRead but ignores the initial 'start' arguments,
  382. * that is, reads 'num' arguments after 'start'.
  383. * The 'start' must be <= the length of the list.
  384. */
  385. int NCDVal_ListReadStart (NCDValRef list, int start, int num, ...);
  386. /**
  387. * Like {@link NCDVal_ListRead}, but the list can contain more than 'num'
  388. * elements.
  389. */
  390. int NCDVal_ListReadHead (NCDValRef list, int num, ...);
  391. /**
  392. * Determines if a value is a map value.
  393. * The value reference must not be an invalid reference.
  394. */
  395. int NCDVal_IsMap (NCDValRef val);
  396. /**
  397. * Builds a new map value. The 'maxcount' argument specifies how
  398. * many entry slots to preallocate. Not more than that many
  399. * entries may be inserted to the map using {@link NCDVal_MapInsert}.
  400. * Returns a reference to the new value, or an invalid reference
  401. * on out of memory.
  402. */
  403. NCDValRef NCDVal_NewMap (NCDValMem *mem, size_t maxcount);
  404. /**
  405. * Inserts an entry to the map value.
  406. * The 'map' reference must point to a map value, and the
  407. * 'key' and 'val' references must be non-invalid and point to values within
  408. * the same memory object as the map.
  409. * Inserting an entry does not in any way change the 'key'and 'val';
  410. * internally, the map only points to it.
  411. * You must not modify the key after inserting it into a map. This is because
  412. * the map builds an embedded AVL tree of entries indexed by keys.
  413. * If insertion fails due to a maximum depth limit, returns 0.
  414. * Otherwise returns 1, and *out_inserted is set to 1 if the key did not
  415. * yet exist and the entry was inserted, and to 0 if it did exist and the
  416. * entry was not inserted. The 'out_inserted' pointer may be NULL, in which
  417. * case *out_inserted is never set.
  418. */
  419. int NCDVal_MapInsert (NCDValRef map, NCDValRef key, NCDValRef val, int *out_inserted) WARN_UNUSED;
  420. /**
  421. * Returns the number of entries in a map value, i.e. the number
  422. * of times {@link NCDVal_MapInsert} was called successfully.
  423. * The 'map' reference must point to a map value.
  424. */
  425. size_t NCDVal_MapCount (NCDValRef map);
  426. /**
  427. * Returns the maximum number of entries a map value may contain,
  428. * i.e. the 'maxcount' argument to {@link NCDVal_NewMap}.
  429. * The 'map' reference must point to a map value.
  430. */
  431. size_t NCDVal_MapMaxCount (NCDValRef map);
  432. /**
  433. * Determines if a map entry reference is invalid. This is used in combination
  434. * with the map iteration functions to detect the end of iteration.
  435. */
  436. int NCDVal_MapElemInvalid (NCDValMapElem me);
  437. /**
  438. * Returns a reference to the first entry in a map, with respect to some
  439. * arbitrary order.
  440. * If the map is empty, returns an invalid map entry reference.
  441. */
  442. NCDValMapElem NCDVal_MapFirst (NCDValRef map);
  443. /**
  444. * Returns a reference to the entry in a map that follows the entry referenced
  445. * by 'me', with respect to some arbitrary order.
  446. * The 'me' argument must be a non-invalid reference to an entry in the map.
  447. * If 'me' is the last entry, returns an invalid map entry reference.
  448. */
  449. NCDValMapElem NCDVal_MapNext (NCDValRef map, NCDValMapElem me);
  450. /**
  451. * Like {@link NCDVal_MapFirst}, but with respect to the order defined by
  452. * {@link NCDVal_Compare}.
  453. * Ordered iteration is slower and should only be used when needed.
  454. */
  455. NCDValMapElem NCDVal_MapOrderedFirst (NCDValRef map);
  456. /**
  457. * Like {@link NCDVal_MapNext}, but with respect to the order defined by
  458. * {@link NCDVal_Compare}.
  459. * Ordered iteration is slower and should only be used when needed.
  460. */
  461. NCDValMapElem NCDVal_MapOrderedNext (NCDValRef map, NCDValMapElem me);
  462. /**
  463. * Returns a reference to the key of the map entry referenced by 'me'.
  464. * The 'me' argument must be a non-invalid reference to an entry in the map.
  465. */
  466. NCDValRef NCDVal_MapElemKey (NCDValRef map, NCDValMapElem me);
  467. /**
  468. * Returns a reference to the value of the map entry referenced by 'me'.
  469. * The 'me' argument must be a non-invalid reference to an entry in the map.
  470. */
  471. NCDValRef NCDVal_MapElemVal (NCDValRef map, NCDValMapElem me);
  472. /**
  473. * Looks for a key in the map. The 'key' reference must be a non-invalid
  474. * value reference, and may point to a value in a different memory object
  475. * than the map.
  476. * If the key exists in the map, returns a reference to the corresponding
  477. * map entry.
  478. * If the key does not exist, returns an invalid map entry reference.
  479. */
  480. NCDValMapElem NCDVal_MapFindKey (NCDValRef map, NCDValRef key);
  481. /**
  482. * Retrieves the value reference to the value of the map entry whose key is a
  483. * string value equal to the given null-terminated string. If there is no such
  484. * entry, returns an invalid value reference.
  485. */
  486. NCDValRef NCDVal_MapGetValue (NCDValRef map, const char *key_str);
  487. /**
  488. * Builds a placeholder replacement program, which is a list of instructions for
  489. * efficiently replacing placeholders in identical values in identical memory
  490. * objects.
  491. * To actually perform replacements, make copies of the memory object of this value
  492. * using {@link NCDValMem_InitCopy}, then call {@link NCDValReplaceProg_Execute}
  493. * on the copies.
  494. * The value passed must be a valid value, and not a placeholder.
  495. * Returns 1 on success, 0 on failure.
  496. */
  497. int NCDValReplaceProg_Init (NCDValReplaceProg *o, NCDValRef val);
  498. /**
  499. * Frees the placeholder replacement program.
  500. */
  501. void NCDValReplaceProg_Free (NCDValReplaceProg *o);
  502. /**
  503. * Callback used by {@link NCDValReplaceProg_Execute} to allow the caller to produce
  504. * values of placeholders.
  505. * This function should build a new value within the memory object 'mem' (which is
  506. * the same as of the memory object where placeholders are being replaced).
  507. * On success, it should return 1, writing a valid value reference to *out.
  508. * On failure, it can either return 0, or return 1 but write an invalid value reference.
  509. * This callback must not access the memory object in any other way than building
  510. * new values in it; it must not modify any values that were already present at the
  511. * point it was called.
  512. */
  513. typedef int (*NCDVal_replace_func) (void *arg, int plid, NCDValMem *mem, NCDValRef *out);
  514. /**
  515. * Executes the replacement program, replacing placeholders in a value.
  516. * The memory object must given be identical to the memory object which was used in
  517. * {@link NCDValReplaceProg_Init}; see {@link NCDValMem_InitCopy}.
  518. * This will call the callback 'replace', which should build the values to replace
  519. * the placeholders.
  520. * Returns 1 on success and 0 on failure. On failure, the entire memory object enters
  521. * and inconsistent state and must be freed using {@link NCDValMem_Free} before
  522. * performing any other operation on it.
  523. * The program is passed by value instead of pointer because this appears to be faster.
  524. * Is is not modified in any way.
  525. */
  526. int NCDValReplaceProg_Execute (NCDValReplaceProg prog, NCDValMem *mem, NCDVal_replace_func replace, void *arg);
  527. #endif