dictionary.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /* libanode: the Anode C reference implementation
  2. * Copyright (C) 2009-2010 Adam Ierymenko <[email protected]>
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>. */
  16. /* This is a simple string hash table suitable for small tables such as zone
  17. * files or HTTP header lists. */
  18. #ifndef _ANODE_DICTIONARY_H
  19. #define _ANODE_DICTIONARY_H
  20. #include "misc.h"
  21. /* This is a fixed hash table and is designed for relatively small numbers
  22. * of keys for things like zone files. */
  23. #define ANODE_DICTIONARY_FIXED_HASH_TABLE_SIZE 16
  24. #define ANODE_DICTIONARY_FIXED_HASH_TABLE_MASK 15
  25. /* Computes a hash code for a string and returns the hash bucket */
  26. static inline unsigned int AnodeDictionary__get_bucket(const char *s)
  27. {
  28. unsigned int hc = 3;
  29. while (*s)
  30. hc = ((hc << 4) + hc) + (unsigned int)*(s++);
  31. return ((hc ^ (hc >> 4)) & ANODE_DICTIONARY_FIXED_HASH_TABLE_MASK);
  32. }
  33. /* Case insensitive version of get_bucket */
  34. static inline unsigned int AnodeDictionary__get_bucket_ci(const char *s)
  35. {
  36. unsigned int hc = 3;
  37. while (*s)
  38. hc = ((hc << 4) + hc) + (unsigned int)Anode_tolower(*(s++));
  39. return ((hc ^ (hc >> 4)) & ANODE_DICTIONARY_FIXED_HASH_TABLE_MASK);
  40. }
  41. struct AnodeDictionaryEntry
  42. {
  43. char *key;
  44. char *value;
  45. struct AnodeDictionaryEntry *next;
  46. };
  47. struct AnodeDictionary
  48. {
  49. struct AnodeDictionaryEntry *ht[ANODE_DICTIONARY_FIXED_HASH_TABLE_SIZE];
  50. unsigned int size;
  51. int case_sensitive;
  52. };
  53. static inline void AnodeDictionary_init(struct AnodeDictionary *d,int case_sensitive)
  54. {
  55. Anode_zero((void *)d,sizeof(struct AnodeDictionary));
  56. d->case_sensitive = case_sensitive;
  57. }
  58. void AnodeDictionary_clear(struct AnodeDictionary *d);
  59. static inline void AnodeDictionary_destroy(struct AnodeDictionary *d)
  60. {
  61. AnodeDictionary_clear(d);
  62. }
  63. void AnodeDictionary_put(struct AnodeDictionary *d,const char *key,const char *value);
  64. static inline const char *AnodeDictionary_get(struct AnodeDictionary *d,const char *key)
  65. {
  66. struct AnodeDictionaryEntry *e;
  67. unsigned int bucket = (d->case_sensitive) ? AnodeDictionary__get_bucket(key) : AnodeDictionary__get_bucket_ci(key);
  68. e = d->ht[bucket];
  69. while (e) {
  70. if ((d->case_sensitive ? Anode_streq(key,e->key) : Anode_strcaseeq(key,e->key)))
  71. return e->value;
  72. e = e->next;
  73. }
  74. return (const char *)0;
  75. }
  76. static inline void AnodeDictionary_iterate(
  77. struct AnodeDictionary *d,
  78. void *arg,
  79. int (*func)(void *,const char *,const char *))
  80. {
  81. struct AnodeDictionaryEntry *e;
  82. unsigned int bucket;
  83. for(bucket=0;bucket<ANODE_DICTIONARY_FIXED_HASH_TABLE_SIZE;++bucket) {
  84. e = d->ht[bucket];
  85. while (e) {
  86. if (!func(arg,e->key,e->value))
  87. return;
  88. e = e->next;
  89. }
  90. }
  91. }
  92. void AnodeDictionary_read(
  93. struct AnodeDictionary *d,
  94. char *in,
  95. const char *line_breaks,
  96. const char *kv_breaks,
  97. const char *comment_chars,
  98. char escape_char,
  99. int trim_whitespace_from_keys,
  100. int trim_whitespace_from_values);
  101. long AnodeDictionary_write(
  102. struct AnodeDictionary *d,
  103. char *out,
  104. long out_size,
  105. const char *line_break,
  106. const char *kv_break);
  107. #endif