Dict.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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. typedef struct Dict_Entry Dict_Entry_t;
  22. struct Dict_Entry {
  23. Dict_Entry_t* 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. Object* Dict_putObject(Dict* dictionary,
  90. const String* key,
  91. Object* value,
  92. struct Allocator* allocator);
  93. /**
  94. * Insert an integer into a dictionary.
  95. *
  96. * @param putIntoThis the dictionary to insert an entry into.
  97. * @param key the reference key to use for putting the entry in the dictionary.
  98. * @param value the integer to insert. int64_t is an alias to int64_t.
  99. * @param allocator the means to get memory for storing the dictionary entry wrapper.
  100. * @return if the key already exists in the dictionary then the value which was
  101. * displaced by the put, otherwise NULL.
  102. */
  103. Object* Dict_putInt(Dict* putIntoThis,
  104. const String* key,
  105. int64_t value,
  106. struct Allocator* allocator);
  107. #define Dict_putIntC(putHere, key, val, alloc) \
  108. Dict_putInt(putHere, String_new(key, alloc), val, alloc)
  109. /**
  110. * Insert a String object into another dictionary.
  111. * NOTE: This will not copy the given object, only add a pointer to it in the dictionary.
  112. *
  113. * @param putIntoThis the dictionary to insert an entry into.
  114. * @param key the reference key to use for putting the entry in the dictionary.
  115. * @param value the string to insert.
  116. * @param allocator the means to get memory for storing the dictionary entry wrapper.
  117. * @return if the key already exists in the dictionary then the value which was
  118. * displaced by the put, otherwise NULL.
  119. */
  120. Object* Dict_putString(Dict* putIntoThis,
  121. const String* key,
  122. String* value,
  123. struct Allocator* allocator);
  124. #define Dict_putStringC(putHere, key, val, alloc) \
  125. Dict_putString(putHere, String_new(key, alloc), val, alloc)
  126. #define Dict_putStringCC(putHere, key, val, alloc) \
  127. Dict_putStringC(putHere, key, String_new(val, alloc), alloc)
  128. /**
  129. * Insert a Dictionary object into another dictionary.
  130. * NOTE: This will not copy the given object, only add a pointer to it in the dictionary.
  131. *
  132. * @param putIntoThis the dictionary to insert an entry into.
  133. * @param key the reference key to use for putting the entry in the dictionary.
  134. * @param value the value to insert.
  135. * @param allocator the memory allocator to use for getting memory for the entry.
  136. * @return if the key already exists in the dictionary then the value which was
  137. * displaced by the put, otherwise NULL.
  138. */
  139. Object* Dict_putDict(Dict* putIntoThis,
  140. const String* key,
  141. Dict* value,
  142. struct Allocator* allocator);
  143. #define Dict_putDictC(putHere, key, val, alloc) \
  144. Dict_putDict(putHere, String_new(key, alloc), val, alloc)
  145. /**
  146. * Insert a List object into a dictionary.
  147. * NOTE: This will not copy the given object, only add a pointer to it in the dictionary.
  148. *
  149. * @param putIntoThis the dictionary to insert an entry into.
  150. * @param key the reference key to use for putting the entry in the dictionary.
  151. * @param value the list to insert.
  152. * @param allocator the memory allocator to use for getting memory for the entry.
  153. * @return if the key already exists in the dictionary then the value which was
  154. * displaced by the put, otherwise NULL.
  155. */
  156. Object* Dict_putList(Dict* putIntoThis,
  157. const String* key,
  158. List* value,
  159. struct Allocator* allocator);
  160. #define Dict_putListC(putHere, key, val, alloc) \
  161. Dict_putList(putHere, String_new(key, alloc), val, alloc)
  162. /*----------------------- Constructors -----------------------*/
  163. /**
  164. * Create a new bencoded dictionary type.
  165. *
  166. * @param allocator the place to allocate the memory for storing the dictionary.
  167. */
  168. Dict* Dict_new(struct Allocator* allocator);
  169. /**
  170. * Create a dictionary on the stack.
  171. *
  172. * @param entryKey the key which must be a string.
  173. * @param value the value which must be an object.
  174. * @param next another Dict, can be used to chain Dict_CONST() calls.
  175. * @return a Dict. NOTE: This does *NOT* return a Dict*, just a Dict.
  176. */
  177. #define Dict_CONST(entryKey, value, nextDict) \
  178. (&(struct Dict_Entry) { \
  179. .key = entryKey, \
  180. .val = value, \
  181. .next = nextDict \
  182. })
  183. #define Dict_OBJ(x) (&(Object) { .type = Object_DICT, .as.dictionary = x })
  184. #endif