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