Dict.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #ifndef Dict_H
  16. #define Dict_H
  17. #include "memory/Allocator.h"
  18. #include "benc/Object.h"
  19. #include "util/Linker.h"
  20. Linker_require("benc/Dict.c");
  21. struct Dict_Entry;
  22. struct Dict_Entry {
  23. struct Dict_Entry* next;
  24. String* key;
  25. Object* val;
  26. };
  27. /**
  28. * Remove an entry from the dictionary.
  29. *
  30. * @param dictionary the dictionary to remove the entry from.
  31. * @param key the key which the entry is entered under.
  32. * @return 1 if there was an entry removed, 0 if there was not.
  33. */
  34. int32_t Dict_remove(Dict* dictionary, const String* key);
  35. /*----------------------- Size Functions -----------------------*/
  36. /**
  37. * Get the number of entries in a dictionary.
  38. *
  39. * @param a dictionary
  40. * @return the number of entries in the dictionary or -1 if the dictionary argument is NULL.
  41. */
  42. int32_t Dict_size(const Dict* dictionary);
  43. /*----------------------- Walk the Dictionary -----------------------*/
  44. #define Dict_forEach(_dict, _key) \
  45. for (struct Dict_Entry* e = *_dict; e && (_key = e->key); e = e->next)
  46. // CHECKFILES_IGNORE
  47. /*----------------------- Dictionary Lookup Functions -----------------------*/
  48. /**
  49. * Lookup an integer value from a dictionary, if the value is not present
  50. * or is not an integer type then NULL is returned.
  51. *
  52. * @param dictionary the dictionary to look the entry up in.
  53. * @param key the key to look the entry up with.
  54. * @return an integer which is in the dictionary under the given key or else NULL.
  55. */
  56. int64_t* Dict_getInt(const Dict* dictionary, const String* key);
  57. #define Dict_getIntC(getFromHere, key) Dict_getInt(getFromHere, String_CONST(key))
  58. /**
  59. * Lookup a string value from a dictionary, if the value is not present
  60. * or is not a string type then NULL is returned.
  61. *
  62. * @param dictionary the dictionary to look the entry up in.
  63. * @param key the key to look the entry up with.
  64. * @return a string which is in the dictionary under the given key or else NULL.
  65. */
  66. String* Dict_getString(const Dict* dictionary, const String* key);
  67. #define Dict_getStringC(getFromHere, key) Dict_getString(getFromHere, String_CONST(key))
  68. /**
  69. * Lookup a dictionary value from another dictionary, if the value is not present
  70. * or is not a dictionary type then NULL is returned.
  71. *
  72. * @param dictionary the dictionary to look the entry up in.
  73. * @param key the key to look the entry up with.
  74. * @return a dictionary which is in the dictionary under the given key or else NULL.
  75. */
  76. Dict* Dict_getDict(const Dict* dictionary, const String* key);
  77. #define Dict_getDictC(getFromHere, key) Dict_getDict(getFromHere, String_CONST(key))
  78. /**
  79. * Lookup a list value from a dictionary, if the value is not present
  80. * or is not a list type then NULL is returned.
  81. *
  82. * @param dictionary the dictionary to look the entry up in.
  83. * @param key the key to look the entry up with.
  84. * @return a list which is in the dictionary under the given key or else NULL.
  85. */
  86. List* Dict_getList(const Dict* dictionary, const String* key);
  87. #define Dict_getListC(getFromHere, key) Dict_getList(getFromHere, String_CONST(key))
  88. /*----------------------- Dictionary Put Functions -----------------------*/
  89. /**
  90. * Insert an integer into a dictionary.
  91. *
  92. * @param putIntoThis the dictionary to insert an entry into.
  93. * @param key the reference key to use for putting the entry in the dictionary.
  94. * @param value the integer to insert. int64_t is an alias to int64_t.
  95. * @param allocator the means to get memory for storing the dictionary entry wrapper.
  96. * @return if the key already exists in the dictionary then the value which was
  97. * displaced by the put, otherwise NULL.
  98. */
  99. Object* Dict_putInt(Dict* putIntoThis,
  100. const String* key,
  101. int64_t value,
  102. struct Allocator* allocator);
  103. #define Dict_putIntC(putHere, key, val, alloc) \
  104. Dict_putInt(putHere, String_new(key, alloc), val, alloc)
  105. /**
  106. * Insert a String object into another dictionary.
  107. * NOTE: This will not copy the given object, only add a pointer to it in the dictionary.
  108. *
  109. * @param putIntoThis the dictionary to insert an entry into.
  110. * @param key the reference key to use for putting the entry in the dictionary.
  111. * @param value the string to insert.
  112. * @param allocator the means to get memory for storing the dictionary entry wrapper.
  113. * @return if the key already exists in the dictionary then the value which was
  114. * displaced by the put, otherwise NULL.
  115. */
  116. Object* Dict_putString(Dict* putIntoThis,
  117. const String* key,
  118. String* value,
  119. struct Allocator* allocator);
  120. #define Dict_putStringC(putHere, key, val, alloc) \
  121. Dict_putString(putHere, String_new(key, alloc), val, alloc)
  122. #define Dict_putStringCC(putHere, key, val, alloc) \
  123. Dict_putStringC(putHere, key, String_new(val, alloc), alloc)
  124. /**
  125. * Insert a Dictionary object into another dictionary.
  126. * NOTE: This will not copy the given object, only add a pointer to it in the dictionary.
  127. *
  128. * @param putIntoThis the dictionary to insert an entry into.
  129. * @param key the reference key to use for putting the entry in the dictionary.
  130. * @param value the value to insert.
  131. * @param allocator the memory allocator to use for getting memory for the entry.
  132. * @return if the key already exists in the dictionary then the value which was
  133. * displaced by the put, otherwise NULL.
  134. */
  135. Object* Dict_putDict(Dict* putIntoThis,
  136. const String* key,
  137. Dict* value,
  138. struct Allocator* allocator);
  139. #define Dict_putDictC(putHere, key, val, alloc) \
  140. Dict_putDict(putHere, String_new(key, alloc), val, alloc)
  141. /**
  142. * Insert a List object into a dictionary.
  143. * NOTE: This will not copy the given object, only add a pointer to it in the dictionary.
  144. *
  145. * @param putIntoThis the dictionary to insert an entry into.
  146. * @param key the reference key to use for putting the entry in the dictionary.
  147. * @param value the list to insert.
  148. * @param allocator the memory allocator to use for getting memory for the entry.
  149. * @return if the key already exists in the dictionary then the value which was
  150. * displaced by the put, otherwise NULL.
  151. */
  152. Object* Dict_putList(Dict* putIntoThis,
  153. const String* key,
  154. List* value,
  155. struct Allocator* allocator);
  156. #define Dict_putListC(putHere, key, val, alloc) \
  157. Dict_putList(putHere, String_new(key, alloc), val, alloc)
  158. /*----------------------- Constructors -----------------------*/
  159. /**
  160. * Create a new bencoded dictionary type.
  161. *
  162. * @param allocator the place to allocate the memory for storing the dictionary.
  163. */
  164. Dict* Dict_new(struct Allocator* allocator);
  165. /**
  166. * Create a dictionary on the stack.
  167. *
  168. * @param entryKey the key which must be a string.
  169. * @param value the value which must be an object.
  170. * @param next another Dict, can be used to chain Dict_CONST() calls.
  171. * @return a Dict. NOTE: This does *NOT* return a Dict*, just a Dict.
  172. */
  173. #define Dict_CONST(entryKey, value, nextDict) \
  174. (&(struct Dict_Entry) { \
  175. .key = entryKey, \
  176. .val = value, \
  177. .next = nextDict \
  178. })
  179. #define Dict_OBJ(x) (&(Object) { .type = Object_DICT, .as.dictionary = x })
  180. #endif