NCDVal.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  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. * WARNING: the returned pointer may become invalid when any new value is inserted
  244. * into the residing memory object (due to a realloc of the value memory).
  245. */
  246. const char * NCDVal_StringData (NCDValRef string);
  247. /**
  248. * Returns the length of a String.
  249. * The value reference must point to a String.
  250. */
  251. size_t NCDVal_StringLength (NCDValRef string);
  252. /**
  253. * Returns a MemRef interface to the given string value.
  254. * WARNING: the returned pointer may become invalid when any new value is inserted
  255. * into the residing memory object (due to a realloc of the value memory).
  256. */
  257. MemRef NCDVal_StringMemRef (NCDValRef string);
  258. /**
  259. * Produces a null-terminated version of a String. On success, the result is
  260. * stored into an {@link NCDValNullTermString} structure, and the null-terminated
  261. * string is available via its 'data' member. This function may either simply pass
  262. * through the data pointer (if the string is known to be null-terminated) or
  263. * produce a null-terminated dynamically allocated copy.
  264. * On success, {@link NCDValNullTermString_Free} should be called to release any allocated
  265. * memory when the null-terminated string is no longer needed. This must be called before
  266. * the memory object is freed, because it may point to data inside the memory object.
  267. * It is guaranteed that *out is not modified on failure.
  268. * Returns 1 on success and 0 on failure.
  269. */
  270. int NCDVal_StringNullTerminate (NCDValRef string, NCDValNullTermString *out) WARN_UNUSED;
  271. /**
  272. * Returns a dummy {@link NCDValNullTermString} which can be freed using
  273. * {@link NCDValNullTermString_Free}, but need not be.
  274. */
  275. NCDValNullTermString NCDValNullTermString_NewDummy (void);
  276. /**
  277. * Releases any memory which was dynamically allocated by {@link NCDVal_StringNullTerminate}
  278. * to null-terminate a string.
  279. */
  280. void NCDValNullTermString_Free (NCDValNullTermString *o);
  281. /**
  282. * Returns the string ID and the string index of an IdString.
  283. * Both the \a out_string_id and \a out_string_index pointers must be non-NULL.
  284. */
  285. void NCDVal_IdStringGet (NCDValRef idstring, NCD_string_id_t *out_string_id,
  286. NCDStringIndex **out_string_index);
  287. /**
  288. * Returns the string ID of an IdString.
  289. */
  290. NCD_string_id_t NCDVal_IdStringId (NCDValRef idstring);
  291. /**
  292. * Returns the string index of an IdString.
  293. */
  294. NCDStringIndex * NCDVal_IdStringStringIndex (NCDValRef idstring);
  295. /**
  296. * Returns the reference target of an ExternalString. This may be NULL
  297. * if the external string is not associated with a reference target.
  298. */
  299. BRefTarget * NCDVal_ExternalStringTarget (NCDValRef externalstring);
  300. /**
  301. * Determines if the String has any null bytes in its contents.
  302. */
  303. int NCDVal_StringHasNulls (NCDValRef string);
  304. /**
  305. * Determines if the String value is equal to the given null-terminated
  306. * string.
  307. * The value reference must point to a String value.
  308. */
  309. int NCDVal_StringEquals (NCDValRef string, const char *data);
  310. /**
  311. * Determines if the String is equal to the given string represented
  312. * by an {@link NCDStringIndex} identifier.
  313. * NOTE: \a string_index must be equal to the string_index of every ID-string
  314. * that exist within this memory object.
  315. */
  316. int NCDVal_StringEqualsId (NCDValRef string, NCD_string_id_t string_id,
  317. NCDStringIndex *string_index);
  318. /**
  319. * Compares two String's in a manner similar to memcmp().
  320. * The startN and length arguments must refer to a valid region within
  321. * stringN, i.e. startN + length <= length_of_stringN must hold.
  322. */
  323. int NCDVal_StringMemCmp (NCDValRef string1, NCDValRef string2, size_t start1, size_t start2, size_t length);
  324. /**
  325. * Copies a part of a String to a buffer.
  326. * \a start and \a length must refer to a valid region within the string,
  327. * i.e. start + length <= length_of_string must hold.
  328. */
  329. void NCDVal_StringCopyOut (NCDValRef string, size_t start, size_t length, char *dst);
  330. /**
  331. * Determines if a part of a String is equal to the \a length bytes in \a data.
  332. * \a start and \a length must refer to a valid region within the string,
  333. * i.e. start + length <= length_of_string must hold.
  334. */
  335. int NCDVal_StringRegionEquals (NCDValRef string, size_t start, size_t length, const char *data);
  336. /**
  337. * Determines if a value is a list value.
  338. * The value reference must not be an invalid reference.
  339. */
  340. int NCDVal_IsList (NCDValRef val);
  341. /**
  342. * Builds a new list value. The 'maxcount' argument specifies how
  343. * many element slots to preallocate. Not more than that many
  344. * elements may be appended to the list using {@link NCDVal_ListAppend}.
  345. * Returns a reference to the new value, or an invalid reference
  346. * on out of memory.
  347. */
  348. NCDValRef NCDVal_NewList (NCDValMem *mem, size_t maxcount);
  349. /**
  350. * Appends a value to to the list value.
  351. * The 'list' reference must point to a list value, and the
  352. * 'elem' reference must be non-invalid and point to a value within
  353. * the same memory object as the list.
  354. * Inserting a value into a list does not in any way change it;
  355. * internally, the list only points to it.
  356. * You must not modify the element after it has been inserted into the
  357. * list.
  358. * Returns 1 on success and 0 on failure (depth limit exceeded).
  359. */
  360. int NCDVal_ListAppend (NCDValRef list, NCDValRef elem) WARN_UNUSED;
  361. /**
  362. * Returns the number of elements in a list value, i.e. the number
  363. * of times {@link NCDVal_ListAppend} was called.
  364. * The 'list' reference must point to a list value.
  365. */
  366. size_t NCDVal_ListCount (NCDValRef list);
  367. /**
  368. * Returns the maximum number of elements a list value may contain,
  369. * i.e. the 'maxcount' argument to {@link NCDVal_NewList}.
  370. * The 'list' reference must point to a list value.
  371. */
  372. size_t NCDVal_ListMaxCount (NCDValRef list);
  373. /**
  374. * Returns a reference to the value at the given position 'pos' in a list,
  375. * starting with zero.
  376. * The 'list' reference must point to a list value.
  377. * The position 'pos' must refer to an existing element, i.e.
  378. * pos < NCDVal_ListCount().
  379. */
  380. NCDValRef NCDVal_ListGet (NCDValRef list, size_t pos);
  381. /**
  382. * Returns references to elements within a list by writing them
  383. * via (NCDValRef *) variable arguments.
  384. * If 'num' == NCDVal_ListCount(), succeeds, returing 1 and writing 'num'
  385. * references, as mentioned.
  386. * If 'num' != NCDVal_ListCount(), fails, returning 0, without writing any
  387. * references
  388. */
  389. int NCDVal_ListRead (NCDValRef list, int num, ...);
  390. /**
  391. * Like {@link NCDVal_ListRead}, but the list can contain more than 'num'
  392. * elements.
  393. */
  394. int NCDVal_ListReadHead (NCDValRef list, int num, ...);
  395. /**
  396. * Determines if a value is a map value.
  397. * The value reference must not be an invalid reference.
  398. */
  399. int NCDVal_IsMap (NCDValRef val);
  400. /**
  401. * Builds a new map value. The 'maxcount' argument specifies how
  402. * many entry slots to preallocate. Not more than that many
  403. * entries may be inserted to the map using {@link NCDVal_MapInsert}.
  404. * Returns a reference to the new value, or an invalid reference
  405. * on out of memory.
  406. */
  407. NCDValRef NCDVal_NewMap (NCDValMem *mem, size_t maxcount);
  408. /**
  409. * Inserts an entry to the map value.
  410. * The 'map' reference must point to a map value, and the
  411. * 'key' and 'val' references must be non-invalid and point to values within
  412. * the same memory object as the map.
  413. * Inserting an entry does not in any way change the 'key'and 'val';
  414. * internally, the map only points to it.
  415. * You must not modify the key after inserting it into a map. This is because
  416. * the map builds an embedded AVL tree of entries indexed by keys.
  417. * If insertion fails due to a maximum depth limit, returns 0.
  418. * Otherwise returns 1, and *out_inserted is set to 1 if the key did not
  419. * yet exist and the entry was inserted, and to 0 if it did exist and the
  420. * entry was not inserted. The 'out_inserted' pointer may be NULL, in which
  421. * case *out_inserted is never set.
  422. */
  423. int NCDVal_MapInsert (NCDValRef map, NCDValRef key, NCDValRef val, int *out_inserted) WARN_UNUSED;
  424. /**
  425. * Returns the number of entries in a map value, i.e. the number
  426. * of times {@link NCDVal_MapInsert} was called successfully.
  427. * The 'map' reference must point to a map value.
  428. */
  429. size_t NCDVal_MapCount (NCDValRef map);
  430. /**
  431. * Returns the maximum number of entries a map value may contain,
  432. * i.e. the 'maxcount' argument to {@link NCDVal_NewMap}.
  433. * The 'map' reference must point to a map value.
  434. */
  435. size_t NCDVal_MapMaxCount (NCDValRef map);
  436. /**
  437. * Determines if a map entry reference is invalid. This is used in combination
  438. * with the map iteration functions to detect the end of iteration.
  439. */
  440. int NCDVal_MapElemInvalid (NCDValMapElem me);
  441. /**
  442. * Returns a reference to the first entry in a map, with respect to some
  443. * arbitrary order.
  444. * If the map is empty, returns an invalid map entry reference.
  445. */
  446. NCDValMapElem NCDVal_MapFirst (NCDValRef map);
  447. /**
  448. * Returns a reference to the entry in a map that follows the entry referenced
  449. * by 'me', with respect to some arbitrary order.
  450. * The 'me' argument must be a non-invalid reference to an entry in the map.
  451. * If 'me' is the last entry, returns an invalid map entry reference.
  452. */
  453. NCDValMapElem NCDVal_MapNext (NCDValRef map, NCDValMapElem me);
  454. /**
  455. * Like {@link NCDVal_MapFirst}, but with respect to the order defined by
  456. * {@link NCDVal_Compare}.
  457. * Ordered iteration is slower and should only be used when needed.
  458. */
  459. NCDValMapElem NCDVal_MapOrderedFirst (NCDValRef map);
  460. /**
  461. * Like {@link NCDVal_MapNext}, but with respect to the order defined by
  462. * {@link NCDVal_Compare}.
  463. * Ordered iteration is slower and should only be used when needed.
  464. */
  465. NCDValMapElem NCDVal_MapOrderedNext (NCDValRef map, NCDValMapElem me);
  466. /**
  467. * Returns a reference to the key of the map entry referenced by 'me'.
  468. * The 'me' argument must be a non-invalid reference to an entry in the map.
  469. */
  470. NCDValRef NCDVal_MapElemKey (NCDValRef map, NCDValMapElem me);
  471. /**
  472. * Returns a reference to the value of the map entry referenced by 'me'.
  473. * The 'me' argument must be a non-invalid reference to an entry in the map.
  474. */
  475. NCDValRef NCDVal_MapElemVal (NCDValRef map, NCDValMapElem me);
  476. /**
  477. * Looks for a key in the map. The 'key' reference must be a non-invalid
  478. * value reference, and may point to a value in a different memory object
  479. * than the map.
  480. * If the key exists in the map, returns a reference to the corresponding
  481. * map entry.
  482. * If the key does not exist, returns an invalid map entry reference.
  483. */
  484. NCDValMapElem NCDVal_MapFindKey (NCDValRef map, NCDValRef key);
  485. /**
  486. * Retrieves the value reference to the value of the map entry whose key is a
  487. * string value equal to the given null-terminated string. If there is no such
  488. * entry, returns an invalid value reference.
  489. */
  490. NCDValRef NCDVal_MapGetValue (NCDValRef map, const char *key_str);
  491. /**
  492. * Builds a placeholder replacement program, which is a list of instructions for
  493. * efficiently replacing placeholders in identical values in identical memory
  494. * objects.
  495. * To actually perform replacements, make copies of the memory object of this value
  496. * using {@link NCDValMem_InitCopy}, then call {@link NCDValReplaceProg_Execute}
  497. * on the copies.
  498. * The value passed must be a valid value, and not a placeholder.
  499. * Returns 1 on success, 0 on failure.
  500. */
  501. int NCDValReplaceProg_Init (NCDValReplaceProg *o, NCDValRef val);
  502. /**
  503. * Frees the placeholder replacement program.
  504. */
  505. void NCDValReplaceProg_Free (NCDValReplaceProg *o);
  506. /**
  507. * Callback used by {@link NCDValReplaceProg_Execute} to allow the caller to produce
  508. * values of placeholders.
  509. * This function should build a new value within the memory object 'mem' (which is
  510. * the same as of the memory object where placeholders are being replaced).
  511. * On success, it should return 1, writing a valid value reference to *out.
  512. * On failure, it can either return 0, or return 1 but write an invalid value reference.
  513. * This callback must not access the memory object in any other way than building
  514. * new values in it; it must not modify any values that were already present at the
  515. * point it was called.
  516. */
  517. typedef int (*NCDVal_replace_func) (void *arg, int plid, NCDValMem *mem, NCDValRef *out);
  518. /**
  519. * Executes the replacement program, replacing placeholders in a value.
  520. * The memory object must given be identical to the memory object which was used in
  521. * {@link NCDValReplaceProg_Init}; see {@link NCDValMem_InitCopy}.
  522. * This will call the callback 'replace', which should build the values to replace
  523. * the placeholders.
  524. * Returns 1 on success and 0 on failure. On failure, the entire memory object enters
  525. * and inconsistent state and must be freed using {@link NCDValMem_Free} before
  526. * performing any other operation on it.
  527. * The program is passed by value instead of pointer because this appears to be faster.
  528. * Is is not modified in any way.
  529. */
  530. int NCDValReplaceProg_Execute (NCDValReplaceProg prog, NCDValMem *mem, NCDVal_replace_func replace, void *arg);
  531. #endif