NCDVal.h 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  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/maxalign.h>
  35. #include <misc/cstring.h>
  36. #include <misc/BRefTarget.h>
  37. #include <ncd/NCDStringIndex.h>
  38. // these are implementation details. The interface is defined below.
  39. #define NCDVAL_FASTBUF_SIZE 64
  40. #define NCDVAL_MAXIDX INT_MAX
  41. #define NCDVAL_MINIDX INT_MIN
  42. #define NCDVAL_TOPPLID (-1 - NCDVAL_MINIDX)
  43. typedef int NCDVal__idx;
  44. typedef struct {
  45. char *buf;
  46. NCDVal__idx size;
  47. NCDVal__idx used;
  48. NCDVal__idx first_ref;
  49. NCDVal__idx first_cms_link;
  50. union {
  51. char fastbuf[NCDVAL_FASTBUF_SIZE];
  52. bmax_align_t align_max;
  53. };
  54. } NCDValMem;
  55. typedef struct {
  56. NCDValMem *mem;
  57. NCDVal__idx idx;
  58. } NCDValRef;
  59. typedef struct {
  60. NCDVal__idx idx;
  61. } NCDValSafeRef;
  62. typedef struct {
  63. NCDVal__idx elemidx;
  64. } NCDValMapElem;
  65. struct NCDVal__instr;
  66. typedef struct {
  67. struct NCDVal__instr *instrs;
  68. size_t num_instrs;
  69. } NCDValReplaceProg;
  70. typedef struct {
  71. char *data;
  72. int is_allocated;
  73. } NCDValNullTermString;
  74. typedef struct {
  75. char *data;
  76. int is_allocated;
  77. } NCDValContString;
  78. //
  79. #define NCDVAL_STRING 1
  80. #define NCDVAL_LIST 2
  81. #define NCDVAL_MAP 3
  82. #define NCDVAL_PLACEHOLDER 4
  83. /**
  84. * Initializes a value memory object.
  85. * A value memory object holds memory for value structures. Values within
  86. * the memory are referenced using {@link NCDValRef} objects, which point
  87. * to values within memory objects.
  88. *
  89. * Values may be added to a memory object using functions such as
  90. * {@link NCDVal_NewString}, {@link NCDVal_NewList} and {@link NCDVal_NewMap},
  91. * and {@link NCDVal_NewCopy}, which return references to the new values within
  92. * the memory object.
  93. *
  94. * It is not possible to remove values from the memory object, or modify existing
  95. * values other than adding elements to pre-allocated slots in lists and maps.
  96. * Once a value is added, it will consume memory as long as its memory object
  97. * exists. This is by design - this code is intended and optimized for constructing
  98. * and passing around values, not for operating on them in place. In fact, al
  99. * values within a memory object are stored in a single memory buffer, as an
  100. * embedded data structure with relativepointers. For example, map values use an
  101. * embedded AVL tree.
  102. */
  103. void NCDValMem_Init (NCDValMem *o);
  104. /**
  105. * Frees a value memory object.
  106. * All values within the memory object cease to exist, and any {@link NCDValRef}
  107. * object pointing to them must no longer be used.
  108. */
  109. void NCDValMem_Free (NCDValMem *o);
  110. /**
  111. * Initializes the memory object to be a copy of an existing memory object.
  112. * Value references from the original may be used if they are first turned
  113. * to {@link NCDValSafeRef} using {@link NCDVal_ToSafe} and back to
  114. * {@link NCDValRef} using {@link NCDVal_FromSafe} with the new memory object
  115. * specified. Alternatively, {@link NCDVal_Moved} can be used.
  116. * Returns 1 on success and 0 on failure.
  117. */
  118. int NCDValMem_InitCopy (NCDValMem *o, NCDValMem *other) WARN_UNUSED;
  119. /**
  120. * For each internal link (e.g. list element) to a ComposedString in the memory
  121. * object, copies the ComposedString to some kind ContinuousString, and updates
  122. * the link to point to the new ContinuousString.
  123. * Additionally, if *\a root_val points to a ComposedString, copies it to a new
  124. * ContinuousString and updates *\a root_val to point to it.
  125. * \a root_val must be non-NULL and *\a root_val must not be an invalid value
  126. * reference.
  127. * Returns 1 on success and 0 on failure. On failure, some strings may have
  128. * been converted, but the memory object is left in a consistent state.
  129. */
  130. int NCDValMem_ConvertNonContinuousStrings (NCDValMem *o, NCDValRef *root_val) WARN_UNUSED;
  131. /**
  132. * Does nothing.
  133. * The value reference object must either point to a valid value within a valid
  134. * memory object, or must be an invalid reference (most functions operating on
  135. * {@link NCDValRef} implicitly require that).
  136. */
  137. void NCDVal_Assert (NCDValRef val);
  138. /**
  139. * Determines if a value reference is invalid.
  140. */
  141. int NCDVal_IsInvalid (NCDValRef val);
  142. /**
  143. * Determines if a value is a placeholder value.
  144. * The value reference must not be an invalid reference.
  145. */
  146. int NCDVal_IsPlaceholder (NCDValRef val);
  147. /**
  148. * Returns the type of the value reference, which must not be an invalid reference.
  149. * Possible values are NCDVAL_STRING, NCDVAL_LIST, NCDVAL_MAP and NCDVAL_PLACEHOLDER.
  150. * The placeholder type is only used internally in the interpreter for argument
  151. * resolution, and is never seen by modules; see {@link NCDVal_NewPlaceholder}.
  152. */
  153. int NCDVal_Type (NCDValRef val);
  154. /**
  155. * Returns an invalid reference.
  156. * An invalid reference must not be passed to any function here, except:
  157. * {@link NCDVal_Assert}, {@link NCDVal_IsInvalid}, {@link NCDVal_ToSafe},
  158. * {@link NCDVal_FromSafe}, {@link NCDVal_Moved}.
  159. */
  160. NCDValRef NCDVal_NewInvalid (void);
  161. /**
  162. * Returns a new placeholder value reference. A placeholder value is a valid value
  163. * containing an integer placeholder identifier.
  164. * This always succeeds; however, the caller must ensure the identifier is in the
  165. * range [0, NCDVAL_TOPPLID).
  166. *
  167. * The placeholder type is only used internally in the interpreter for argument
  168. * resolution, and is never seen by modules.
  169. */
  170. NCDValRef NCDVal_NewPlaceholder (NCDValMem *mem, int plid);
  171. /**
  172. * Returns the indentifier of a placeholder value.
  173. * The value reference must point to a placeholder value.
  174. */
  175. int NCDVal_PlaceholderId (NCDValRef val);
  176. /**
  177. * Copies a value into the specified memory object. The source
  178. * must not be an invalid reference, however it may reside in any memory
  179. * object (including 'mem').
  180. * Returns a reference to the copied value. On out of memory, returns
  181. * an invalid reference.
  182. */
  183. NCDValRef NCDVal_NewCopy (NCDValMem *mem, NCDValRef val);
  184. /**
  185. * Compares two values, both of which must not be invalid references.
  186. * Returns -1, 0 or 1.
  187. */
  188. int NCDVal_Compare (NCDValRef val1, NCDValRef val2);
  189. /**
  190. * Converts a value reference to a safe referece format, which remains valid
  191. * if the memory object is moved (safe references do not contain a pointer
  192. * to the memory object, unlike {@link NCDValRef} references).
  193. */
  194. NCDValSafeRef NCDVal_ToSafe (NCDValRef val);
  195. /**
  196. * Converts a safe value reference to a normal value reference.
  197. * This should be used to recover references from safe references
  198. * after the memory object is moved.
  199. */
  200. NCDValRef NCDVal_FromSafe (NCDValMem *mem, NCDValSafeRef sval);
  201. /**
  202. * Fixes a value reference after its memory object was moved.
  203. */
  204. NCDValRef NCDVal_Moved (NCDValMem *mem, NCDValRef val);
  205. /**
  206. * Determines whether a safe reference is a placeholder.
  207. */
  208. int NCDVal_IsSafeRefPlaceholder (NCDValSafeRef sval);
  209. /**
  210. * Gets the placeholder ID of a placeholder safe reference.
  211. */
  212. int NCDVal_GetSafeRefPlaceholderId (NCDValSafeRef sval);
  213. /**
  214. * Determines if all strings within this value are ContinuousString's,
  215. * by recusively walking the entire value.
  216. * If all strings are ContinuousString's, returns 1; if there is at least
  217. * one string which is not a ContinuousString, returns 0.
  218. * The value reference must not be an invalid reference.
  219. */
  220. int NCDVal_HasOnlyContinuousStrings (NCDValRef val);
  221. /**
  222. * Determines if the value implements the String interface.
  223. * The value reference must not be an invalid reference.
  224. */
  225. int NCDVal_IsString (NCDValRef val);
  226. /**
  227. * Determines if the value implements the ContinuousString interface.
  228. * A ContinuousString also implements the String interface.
  229. * The value reference must not be an invalid reference.
  230. */
  231. int NCDVal_IsContinuousString (NCDValRef val);
  232. /**
  233. * Determines if the value is a StoredString.
  234. * A StoredString implements the ContinuousString interface.
  235. * The value reference must not be an invalid reference.
  236. */
  237. int NCDVal_IsStoredString (NCDValRef val);
  238. /**
  239. * Determines if the value is an IdString. See {@link NCDVal_NewIdString}
  240. * for details.
  241. * An IdString implements the ContinuousString interface.
  242. * The value reference must not be an invalid reference.
  243. */
  244. int NCDVal_IsIdString (NCDValRef val);
  245. /**
  246. * Determines if a value is an ExternalString.
  247. * See {@link NCDVal_NewExternalString} for details.
  248. * An ExternalString implements the ContinuousString interface.
  249. * The value reference must not be an invalid reference.
  250. */
  251. int NCDVal_IsExternalString (NCDValRef val);
  252. /**
  253. * Determines if a value is a ComposedString.
  254. * A ComposedString implements the String interface.
  255. */
  256. int NCDVal_IsComposedString (NCDValRef val);
  257. /**
  258. * Determines if a value is a String which contains no null bytes.
  259. * The value reference must not be an invalid reference.
  260. */
  261. int NCDVal_IsStringNoNulls (NCDValRef val);
  262. /**
  263. * Equivalent to NCDVal_NewStringBin(mem, data, strlen(data)).
  264. */
  265. NCDValRef NCDVal_NewString (NCDValMem *mem, const char *data);
  266. /**
  267. * Builds a new StoredString.
  268. * Returns a reference to the new value, or an invalid reference
  269. * on out of memory.
  270. * WARNING: The buffer passed must NOT be part of any value in the
  271. * memory object specified. In particular, you may NOT use this
  272. * function to copy a string that resides in the same memory object.
  273. *
  274. * A StoredString is a kind of ContinuousString which is represented directly in the
  275. * value memory object.
  276. */
  277. NCDValRef NCDVal_NewStringBin (NCDValMem *mem, const uint8_t *data, size_t len);
  278. /**
  279. * Builds a new StoredString of the given length with undefined contents.
  280. * You can define the contents of the string later by copying to the address
  281. * returned by {@link NCDVal_StringData}.
  282. */
  283. NCDValRef NCDVal_NewStringUninitialized (NCDValMem *mem, size_t len);
  284. /**
  285. * Builds a new IdString.
  286. * Returns a reference to the new value, or an invalid reference
  287. * on out of memory.
  288. *
  289. * An IdString is a kind of ContinuousString which is represented efficiently as a string
  290. * identifier via {@link NCDStringIndex}.
  291. */
  292. NCDValRef NCDVal_NewIdString (NCDValMem *mem, NCD_string_id_t string_id,
  293. NCDStringIndex *string_index);
  294. /**
  295. * Builds a new ExternalString, pointing to the given external data. A reference to
  296. * the external data is taken using {@link BRefTarget}, unless 'ref_target' is
  297. * NULL. The data must not change while this value exists.
  298. * Returns a reference to the new value, or an invalid reference
  299. * on out of memory.
  300. *
  301. * An ExternalString is a kind of ContinuousString where the actual string contents are
  302. * stored outside of the value memory object.
  303. */
  304. NCDValRef NCDVal_NewExternalString (NCDValMem *mem, const char *data, size_t len,
  305. BRefTarget *ref_target);
  306. /**
  307. * Callback function which is called for ComposedString's to access the underlying string resource.
  308. * \a user is whatever was passed to 'resource.user' in {@link NCDVal_NewComposedString}.
  309. * \a offset is the offset from the beginning of the string exposed by the resource; it will be
  310. * >= 'offset' and < 'offset' + 'length' as given to NCDVal_NewComposedString.
  311. * This callback must set *\a out_data and *\a out_length to represent a continuous (sub-)region
  312. * of the string that starts at the byte at index \a offset. The pointed-to data must remain
  313. * valid and unchanged until all references to the string resource are released.
  314. * \a *out_data must be set to non-NULL and *\a out_length must be set to greater than zero,
  315. * since the conditions above imply that there is at least one byte available from \a offset.
  316. */
  317. typedef void (*NCDVal_ComposedString_func_getptr) (void *user, size_t offset, const char **out_data, size_t *out_length);
  318. /**
  319. * Structure representing a string resource used by ComposedString's,
  320. * to simplify {@link NCDVal_NewComposedString} and {@link NCDVal_ComposedStringResource}.
  321. */
  322. typedef struct {
  323. NCDVal_ComposedString_func_getptr func_getptr;
  324. void *user;
  325. BRefTarget *ref_target;
  326. } NCDValComposedStringResource;
  327. /**
  328. * Returns a cstring referencing a range within a {@link NCDValComposedStringResource}.
  329. * \a offset and \a length specify the range within the resource which the returned
  330. * cstring will reference. To reference the contents of a ComposedString, use:
  331. * - resource = NCDVal_ComposedStringResource(composedstring),
  332. * - offset = NCDVal_ComposedStringOffset(composedstring),
  333. * - length = NCDVal_StringLength(composedstring).
  334. *
  335. * The returned cstring is valid as long as the resource is not released. Note that
  336. * a reference to resource.ref_target may need to be taken to ensure the resource
  337. * is not released while it is being referenced by the returned cstring (unless
  338. * resource.ref_target is NULL).
  339. */
  340. b_cstring NCDValComposedStringResource_Cstring (NCDValComposedStringResource resource, size_t offset, size_t length);
  341. /**
  342. * Builds a new ComposedString from a string resource.
  343. * A reference to the underlying string resource via the {@link BRefTarget} object
  344. * specified in 'resource.ref_target'.
  345. *
  346. * A ComposedString is a kind of String with an abstract representation exposed via the
  347. * {@link NCDVal_ComposedString_func_getptr} callback.
  348. */
  349. NCDValRef NCDVal_NewComposedString (NCDValMem *mem, NCDValComposedStringResource resource, size_t offset, size_t length);
  350. /**
  351. * Returns a pointer to the data of a ContinuousString.
  352. * WARNING: the string data may not be null-terminated. To get a null-terminated
  353. * version, use {@link NCDVal_StringNullTerminate}.
  354. * The value reference must point to a ContinuousString.
  355. */
  356. const char * NCDVal_StringData (NCDValRef contstring);
  357. /**
  358. * Returns the length of a String.
  359. * The value reference must point to a String.
  360. */
  361. size_t NCDVal_StringLength (NCDValRef string);
  362. /**
  363. * Returns a {@link b_cstring} interface to the given string value.
  364. * The returned cstring is valid as long as the memory object exists.
  365. * However, if the memory object is moved or copied, the cstring is
  366. * invalid in the new or moved (respectively) memory object.
  367. */
  368. b_cstring NCDVal_StringCstring (NCDValRef string);
  369. /**
  370. * Produces a null-terminated continuous version of a String. On success, the result is
  371. * stored into an {@link NCDValNullTermString} structure, and the null-terminated
  372. * string is available via its 'data' member. This function may either simply pass
  373. * through the data pointer (if the string is known to be continuous and null-terminated) or
  374. * produce a null-terminated dynamically allocated copy.
  375. * On success, {@link NCDValNullTermString_Free} should be called to release any allocated
  376. * memory when the null-terminated string is no longer needed. This must be called before
  377. * the memory object is freed, because it may point to data inside the memory object.
  378. * It is guaranteed that *out is not modified on failure.
  379. * Returns 1 on success and 0 on failure.
  380. */
  381. int NCDVal_StringNullTerminate (NCDValRef string, NCDValNullTermString *out) WARN_UNUSED;
  382. /**
  383. * Returns a dummy {@link NCDValNullTermString} which can be freed using
  384. * {@link NCDValNullTermString_Free}, but need not be.
  385. */
  386. NCDValNullTermString NCDValNullTermString_NewDummy (void);
  387. /**
  388. * Releases any memory which was dynamically allocated by {@link NCDVal_StringNullTerminate}
  389. * to null-terminate a string.
  390. */
  391. void NCDValNullTermString_Free (NCDValNullTermString *o);
  392. /**
  393. * Produces a continuous version of a String. On success, the result is stored into an
  394. * {@link NCDValContString} structure, and the continuous string is available via its
  395. * 'data' member. This function may either simply pass through the data pointer (if the
  396. * string is known to be continuous) or produce a continuous dynamically allocated copy.
  397. * On success, {@link NCDValContString_Free} should be called to release any allocated
  398. * memory when the continuous string is no longer needed. This must be called before
  399. * the memory object is freed, because it may point to data inside the memory object.
  400. * It is guaranteed that *out is not modified on failure.
  401. * Returns 1 on success and 0 on failure.
  402. */
  403. int NCDVal_StringContinuize (NCDValRef string, NCDValContString *out) WARN_UNUSED;
  404. /**
  405. * Returns a dummy {@link NCDValContString} which can be freed using
  406. * {@link NCDValContString_Free}, but need not be.
  407. */
  408. NCDValContString NCDValContString_NewDummy (void);
  409. /**
  410. * Releases any memory which was dynamically allocated by {@link NCDVal_StringContinuize}
  411. * to continuize a string.
  412. */
  413. void NCDValContString_Free (NCDValContString *o);
  414. /**
  415. * Returns the string ID and the string index of an IdString.
  416. * Both the \a out_string_id and \a out_string_index pointers must be non-NULL.
  417. */
  418. void NCDVal_IdStringGet (NCDValRef idstring, NCD_string_id_t *out_string_id,
  419. NCDStringIndex **out_string_index);
  420. /**
  421. * Returns the string ID of an IdString.
  422. */
  423. NCD_string_id_t NCDVal_IdStringId (NCDValRef idstring);
  424. /**
  425. * Returns the string index of an IdString.
  426. */
  427. NCDStringIndex * NCDVal_IdStringStringIndex (NCDValRef idstring);
  428. /**
  429. * Returns the reference target of an ExternalString. This may be NULL
  430. * if the external string is not associated with a reference target.
  431. */
  432. BRefTarget * NCDVal_ExternalStringTarget (NCDValRef externalstring);
  433. /**
  434. * Returns the underlying string resource of a ComposedString.
  435. */
  436. NCDValComposedStringResource NCDVal_ComposedStringResource (NCDValRef composedstring);
  437. /**
  438. * Returns the resource offset of a ComposedString.
  439. */
  440. size_t NCDVal_ComposedStringOffset (NCDValRef composedstring);
  441. /**
  442. * Determines if the String has any null bytes in its contents.
  443. */
  444. int NCDVal_StringHasNulls (NCDValRef string);
  445. /**
  446. * Determines if the String value is equal to the given null-terminated
  447. * string.
  448. * The value reference must point to a String value.
  449. */
  450. int NCDVal_StringEquals (NCDValRef string, const char *data);
  451. /**
  452. * Determines if the String is equal to the given string represented
  453. * by an {@link NCDStringIndex} identifier.
  454. * NOTE: \a string_index must be equal to the string_index of every ID-string
  455. * that exist within this memory object.
  456. */
  457. int NCDVal_StringEqualsId (NCDValRef string, NCD_string_id_t string_id,
  458. NCDStringIndex *string_index);
  459. /**
  460. * Compares two String's in a manner similar to memcmp().
  461. * The startN and length arguments must refer to a valid region within
  462. * stringN, i.e. startN + length <= length_of_stringN must hold.
  463. */
  464. int NCDVal_StringMemCmp (NCDValRef string1, NCDValRef string2, size_t start1, size_t start2, size_t length);
  465. /**
  466. * Copies a part of a String to a buffer.
  467. * \a start and \a length must refer to a valid region within the string,
  468. * i.e. start + length <= length_of_string must hold.
  469. */
  470. void NCDVal_StringCopyOut (NCDValRef string, size_t start, size_t length, char *dst);
  471. /**
  472. * Determines if a part of a String is equal to the \a length bytes in \a data.
  473. * \a start and \a length must refer to a valid region within the string,
  474. * i.e. start + length <= length_of_string must hold.
  475. */
  476. int NCDVal_StringRegionEquals (NCDValRef string, size_t start, size_t length, const char *data);
  477. /**
  478. * Determines if a value is a list value.
  479. * The value reference must not be an invalid reference.
  480. */
  481. int NCDVal_IsList (NCDValRef val);
  482. /**
  483. * Builds a new list value. The 'maxcount' argument specifies how
  484. * many element slots to preallocate. Not more than that many
  485. * elements may be appended to the list using {@link NCDVal_ListAppend}.
  486. * Returns a reference to the new value, or an invalid reference
  487. * on out of memory.
  488. */
  489. NCDValRef NCDVal_NewList (NCDValMem *mem, size_t maxcount);
  490. /**
  491. * Appends a value to to the list value.
  492. * The 'list' reference must point to a list value, and the
  493. * 'elem' reference must be non-invalid and point to a value within
  494. * the same memory object as the list.
  495. * Inserting a value into a list does not in any way change it;
  496. * internally, the list only points to it.
  497. * You must not modify the element after it has been inserted into the
  498. * list.
  499. * Returns 1 on success and 0 on failure (depth limit exceeded).
  500. */
  501. int NCDVal_ListAppend (NCDValRef list, NCDValRef elem) WARN_UNUSED;
  502. /**
  503. * Returns the number of elements in a list value, i.e. the number
  504. * of times {@link NCDVal_ListAppend} was called.
  505. * The 'list' reference must point to a list value.
  506. */
  507. size_t NCDVal_ListCount (NCDValRef list);
  508. /**
  509. * Returns the maximum number of elements a list value may contain,
  510. * i.e. the 'maxcount' argument to {@link NCDVal_NewList}.
  511. * The 'list' reference must point to a list value.
  512. */
  513. size_t NCDVal_ListMaxCount (NCDValRef list);
  514. /**
  515. * Returns a reference to the value at the given position 'pos' in a list,
  516. * starting with zero.
  517. * The 'list' reference must point to a list value.
  518. * The position 'pos' must refer to an existing element, i.e.
  519. * pos < NCDVal_ListCount().
  520. */
  521. NCDValRef NCDVal_ListGet (NCDValRef list, size_t pos);
  522. /**
  523. * Returns references to elements within a list by writing them
  524. * via (NCDValRef *) variable arguments.
  525. * If 'num' == NCDVal_ListCount(), succeeds, returing 1 and writing 'num'
  526. * references, as mentioned.
  527. * If 'num' != NCDVal_ListCount(), fails, returning 0, without writing any
  528. * references
  529. */
  530. int NCDVal_ListRead (NCDValRef list, int num, ...);
  531. /**
  532. * Like {@link NCDVal_ListRead}, but the list can contain more than 'num'
  533. * elements.
  534. */
  535. int NCDVal_ListReadHead (NCDValRef list, int num, ...);
  536. /**
  537. * Determines if a value is a map value.
  538. * The value reference must not be an invalid reference.
  539. */
  540. int NCDVal_IsMap (NCDValRef val);
  541. /**
  542. * Builds a new map value. The 'maxcount' argument specifies how
  543. * many entry slots to preallocate. Not more than that many
  544. * entries may be inserted to the map using {@link NCDVal_MapInsert}.
  545. * Returns a reference to the new value, or an invalid reference
  546. * on out of memory.
  547. */
  548. NCDValRef NCDVal_NewMap (NCDValMem *mem, size_t maxcount);
  549. /**
  550. * Inserts an entry to the map value.
  551. * The 'map' reference must point to a map value, and the
  552. * 'key' and 'val' references must be non-invalid and point to values within
  553. * the same memory object as the map.
  554. * Inserting an entry does not in any way change the 'key'and 'val';
  555. * internally, the map only points to it.
  556. * You must not modify the key after inserting it into a map. This is because
  557. * the map builds an embedded AVL tree of entries indexed by keys.
  558. * If insertion fails due to a maximum depth limit, returns 0.
  559. * Otherwise returns 1, and *out_inserted is set to 1 if the key did not
  560. * yet exist and the entry was inserted, and to 0 if it did exist and the
  561. * entry was not inserted. The 'out_inserted' pointer may be NULL, in which
  562. * case *out_inserted is never set.
  563. */
  564. int NCDVal_MapInsert (NCDValRef map, NCDValRef key, NCDValRef val, int *out_inserted) WARN_UNUSED;
  565. /**
  566. * Returns the number of entries in a map value, i.e. the number
  567. * of times {@link NCDVal_MapInsert} was called successfully.
  568. * The 'map' reference must point to a map value.
  569. */
  570. size_t NCDVal_MapCount (NCDValRef map);
  571. /**
  572. * Returns the maximum number of entries a map value may contain,
  573. * i.e. the 'maxcount' argument to {@link NCDVal_NewMap}.
  574. * The 'map' reference must point to a map value.
  575. */
  576. size_t NCDVal_MapMaxCount (NCDValRef map);
  577. /**
  578. * Determines if a map entry reference is invalid. This is used in combination
  579. * with the map iteration functions to detect the end of iteration.
  580. */
  581. int NCDVal_MapElemInvalid (NCDValMapElem me);
  582. /**
  583. * Returns a reference to the first entry in a map, with respect to some
  584. * arbitrary order.
  585. * If the map is empty, returns an invalid map entry reference.
  586. */
  587. NCDValMapElem NCDVal_MapFirst (NCDValRef map);
  588. /**
  589. * Returns a reference to the entry in a map that follows the entry referenced
  590. * by 'me', with respect to some arbitrary order.
  591. * The 'me' argument must be a non-invalid reference to an entry in the map.
  592. * If 'me' is the last entry, returns an invalid map entry reference.
  593. */
  594. NCDValMapElem NCDVal_MapNext (NCDValRef map, NCDValMapElem me);
  595. /**
  596. * Like {@link NCDVal_MapFirst}, but with respect to the order defined by
  597. * {@link NCDVal_Compare}.
  598. * Ordered iteration is slower and should only be used when needed.
  599. */
  600. NCDValMapElem NCDVal_MapOrderedFirst (NCDValRef map);
  601. /**
  602. * Like {@link NCDVal_MapNext}, but with respect to the order defined by
  603. * {@link NCDVal_Compare}.
  604. * Ordered iteration is slower and should only be used when needed.
  605. */
  606. NCDValMapElem NCDVal_MapOrderedNext (NCDValRef map, NCDValMapElem me);
  607. /**
  608. * Returns a reference to the key of the map entry referenced by 'me'.
  609. * The 'me' argument must be a non-invalid reference to an entry in the map.
  610. */
  611. NCDValRef NCDVal_MapElemKey (NCDValRef map, NCDValMapElem me);
  612. /**
  613. * Returns a reference to the value of the map entry referenced by 'me'.
  614. * The 'me' argument must be a non-invalid reference to an entry in the map.
  615. */
  616. NCDValRef NCDVal_MapElemVal (NCDValRef map, NCDValMapElem me);
  617. /**
  618. * Looks for a key in the map. The 'key' reference must be a non-invalid
  619. * value reference, and may point to a value in a different memory object
  620. * than the map.
  621. * If the key exists in the map, returns a reference to the corresponding
  622. * map entry.
  623. * If the key does not exist, returns an invalid map entry reference.
  624. */
  625. NCDValMapElem NCDVal_MapFindKey (NCDValRef map, NCDValRef key);
  626. /**
  627. * Retrieves the value reference to the value of the map entry whose key is a
  628. * string value equal to the given null-terminated string. If there is no such
  629. * entry, returns an invalid value reference.
  630. */
  631. NCDValRef NCDVal_MapGetValue (NCDValRef map, const char *key_str);
  632. /**
  633. * Builds a placeholder replacement program, which is a list of instructions for
  634. * efficiently replacing placeholders in identical values in identical memory
  635. * objects.
  636. * To actually perform replacements, make copies of the memory object of this value
  637. * using {@link NCDValMem_InitCopy}, then call {@link NCDValReplaceProg_Execute}
  638. * on the copies.
  639. * The value passed must be a valid value, and not a placeholder.
  640. * Returns 1 on success, 0 on failure.
  641. */
  642. int NCDValReplaceProg_Init (NCDValReplaceProg *o, NCDValRef val);
  643. /**
  644. * Frees the placeholder replacement program.
  645. */
  646. void NCDValReplaceProg_Free (NCDValReplaceProg *o);
  647. /**
  648. * Callback used by {@link NCDValReplaceProg_Execute} to allow the caller to produce
  649. * values of placeholders.
  650. * This function should build a new value within the memory object 'mem' (which is
  651. * the same as of the memory object where placeholders are being replaced).
  652. * On success, it should return 1, writing a valid value reference to *out.
  653. * On failure, it can either return 0, or return 1 but write an invalid value reference.
  654. * This callback must not access the memory object in any other way than building
  655. * new values in it; it must not modify any values that were already present at the
  656. * point it was called.
  657. */
  658. typedef int (*NCDVal_replace_func) (void *arg, int plid, NCDValMem *mem, NCDValRef *out);
  659. /**
  660. * Executes the replacement program, replacing placeholders in a value.
  661. * The memory object must given be identical to the memory object which was used in
  662. * {@link NCDValReplaceProg_Init}; see {@link NCDValMem_InitCopy}.
  663. * This will call the callback 'replace', which should build the values to replace
  664. * the placeholders.
  665. * Returns 1 on success and 0 on failure. On failure, the entire memory object enters
  666. * and inconsistent state and must be freed using {@link NCDValMem_Free} before
  667. * performing any other operation on it.
  668. * The program is passed by value instead of pointer because this appears to be faster.
  669. * Is is not modified in any way.
  670. */
  671. int NCDValReplaceProg_Execute (NCDValReplaceProg prog, NCDValMem *mem, NCDVal_replace_func replace, void *arg);
  672. #endif