reshash.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. *
  6. * License: GPL (version 3 or any later version).
  7. * See LICENSE for details.
  8. * END COPYRIGHT BLOCK **/
  9. #ifdef HAVE_CONFIG_H
  10. #include <config.h>
  11. #endif
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include "reshash.h"
  16. /* ======================== Value with Language list ==================== */
  17. int
  18. ValueAddLanguageItem(ValueNode *node, char *value, char *language)
  19. {
  20. ValueNode *prev, *pvalue;
  21. if (node == NULL)
  22. return 0;
  23. if (language == NULL || *language == '\0') {
  24. /* should be added to default value */
  25. return 0;
  26. }
  27. prev = pvalue = node;
  28. while (pvalue != NULL) {
  29. if ((pvalue->language == NULL) ||
  30. (strcmp(pvalue->language, language) == 0)) {
  31. /* if value for the language is already there
  32. replace it with latest one.
  33. */
  34. if (pvalue->language == NULL)
  35. pvalue->language = strdup(language);
  36. if (pvalue->value)
  37. free(pvalue->value);
  38. pvalue->value = strdup(value);
  39. return 0;
  40. }
  41. prev = pvalue;
  42. pvalue = pvalue->next;
  43. }
  44. pvalue = (ValueNode *)malloc(sizeof(ValueNode));
  45. memset(pvalue, 0, sizeof(ValueNode));
  46. prev->next = pvalue;
  47. pvalue->language = strdup(language);
  48. pvalue->value = strdup(value);
  49. return 0;
  50. }
  51. const char *
  52. ValueSearchItem(ValueNode *node, char *language)
  53. {
  54. ValueNode *pvalue;
  55. if (node == NULL)
  56. return NULL;
  57. pvalue = node;
  58. while (pvalue && pvalue->language) {
  59. if (strcmp(pvalue->language, language) == 0) {
  60. return pvalue->value;
  61. }
  62. pvalue = pvalue->next;
  63. }
  64. return NULL;
  65. }
  66. void
  67. ValueDestroy(ValueNode *node)
  68. {
  69. ValueNode *p, *current;
  70. p = node;
  71. /* free itself and go next */
  72. while (p) {
  73. current = p;
  74. p = p->next;
  75. if (current->language)
  76. free(current->language);
  77. if (current->value)
  78. free(current->value);
  79. }
  80. }
  81. /* ======================== End of Value with Language list ==================== */
  82. /* ======================== Tree List Implementation============================ */
  83. const char *
  84. TreeSearchItem(TreeNode *res, char *key, char *language)
  85. {
  86. int k;
  87. const char *result;
  88. if (res == NULL || res->key == NULL)
  89. return NULL;
  90. k = strcmp(key, res->key);
  91. if (k > 0) {
  92. return TreeSearchItem(res->right, key, language);
  93. } else if (k < 0) {
  94. return TreeSearchItem(res->left, key, language);
  95. } else {
  96. /* Add to the current node; */
  97. if (language == NULL || *language == '\0')
  98. return res->value;
  99. result = ValueSearchItem(res->vlist, language);
  100. if (result)
  101. return result;
  102. else /* fallback to default value if there is any */
  103. return res->value;
  104. }
  105. }
  106. /*
  107. TreeAddItem
  108. Add value for specific language to the resource tree
  109. Using binary tree now --> Balanced tree later
  110. */
  111. int
  112. TreeAddItem(TreeNode *res, char *key, char *value, char *language)
  113. {
  114. TreeNode *node;
  115. ValueNode *vnode;
  116. int k;
  117. if (res->key == NULL) {
  118. res->key = strdup(key);
  119. k = 0;
  120. } else {
  121. k = strcmp(key, res->key);
  122. }
  123. if (k > 0) {
  124. if (res->right == NULL) {
  125. /* Create node and it's value sub list
  126. */
  127. node = (TreeNode *)malloc(sizeof(TreeNode));
  128. memset(node, 0, sizeof(TreeNode));
  129. vnode = (ValueNode *)malloc(sizeof(ValueNode));
  130. memset(vnode, 0, sizeof(ValueNode));
  131. node->vlist = vnode;
  132. res->right = node;
  133. /* assign value to node */
  134. node->key = strdup(key);
  135. if (language == NULL)
  136. node->value = strdup(value);
  137. else
  138. ValueAddLanguageItem(node->vlist, value, language);
  139. } else {
  140. return TreeAddItem(res->right, key, value, language);
  141. }
  142. } else if (k < 0) {
  143. if (res->left == NULL) {
  144. node = (TreeNode *)malloc(sizeof(TreeNode));
  145. memset(node, 0, sizeof(TreeNode));
  146. vnode = (ValueNode *)malloc(sizeof(ValueNode));
  147. memset(vnode, 0, sizeof(ValueNode));
  148. node->vlist = vnode;
  149. res->left = node;
  150. /* assign value to node */
  151. node->key = strdup(key);
  152. if (language == NULL)
  153. node->value = strdup(value);
  154. else
  155. return ValueAddLanguageItem(node->vlist, value, language);
  156. } else {
  157. return TreeAddItem(res->left, key, value, language);
  158. }
  159. } else {
  160. /* Add to the current node; */
  161. if (language == NULL)
  162. res->value = strdup(value);
  163. else
  164. return ValueAddLanguageItem(res->vlist, value, language);
  165. }
  166. return 0;
  167. }
  168. void
  169. TreeDestroy(TreeNode *tree)
  170. {
  171. if (tree == NULL)
  172. return;
  173. if (tree->vlist)
  174. ValueDestroy(tree->vlist);
  175. if (tree->key)
  176. free(tree->key);
  177. if (tree->value)
  178. free(tree->value);
  179. if (tree->left)
  180. TreeDestroy(tree->left);
  181. if (tree->right)
  182. TreeDestroy(tree->right);
  183. }
  184. /* ====================== End of Tree implementation ================= */
  185. /* ====================== Tree controller (hash ?) ================ */
  186. ResHash *
  187. ResHashCreate(char *name)
  188. {
  189. ResHash *pResHash;
  190. /* Create hash table */
  191. pResHash = (ResHash *)calloc(1, sizeof(ResHash));
  192. if (pResHash == NULL)
  193. return NULL;
  194. if (name)
  195. pResHash->name = strdup(name);
  196. /* Create initial tree item and it's valuelist to hash table */
  197. pResHash->treelist = (TreeNode *)calloc(1, sizeof(TreeNode));
  198. if (pResHash->treelist == NULL)
  199. goto error;
  200. pResHash->treelist->vlist = (ValueNode *)calloc(1, sizeof(ValueNode));
  201. if (pResHash->treelist->vlist == NULL)
  202. goto error;
  203. goto done;
  204. error:
  205. if (pResHash->treelist) {
  206. free(pResHash->treelist->vlist);
  207. free(pResHash->treelist);
  208. }
  209. free(pResHash->name);
  210. free(pResHash);
  211. return NULL;
  212. done:
  213. return pResHash;
  214. }
  215. int
  216. ResHashAdd(ResHash *res, char *key, char *value, char *language)
  217. {
  218. #if 0
  219. hash = get hash value from key
  220. tree = find the tree associated with hash value
  221. #endif
  222. return TreeAddItem(res->treelist, key, value, language);
  223. }
  224. const char *
  225. ResHashSearch(ResHash *res, char *key, char *language)
  226. {
  227. #if 0
  228. hash = get hash value from key
  229. tree = find the tree associated with hash value
  230. #endif
  231. return TreeSearchItem(res->treelist, key, language);
  232. }
  233. void
  234. ResHashDestroy(ResHash *res)
  235. {
  236. if (res == NULL)
  237. return;
  238. if (res->name)
  239. free(res->name);
  240. if (res->treelist)
  241. TreeDestroy(res->treelist);
  242. }
  243. /* ========================= End of Tree controller ====================== */