NCDVal.h 22 KB

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