reshash.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include "reshash.h"
  42. /* ======================== Value with Language list ==================== */
  43. int ValueAddLanguageItem(ValueNode *node, char *value, char *language)
  44. {
  45. ValueNode *prev, *pvalue;
  46. if (node == NULL)
  47. return 0;
  48. if (language == NULL || *language == '\0') {
  49. /* should be added to default value */
  50. return 0;
  51. }
  52. prev = pvalue = node;
  53. while (pvalue != NULL) {
  54. if ((pvalue->language == NULL) ||
  55. (strcmp(pvalue->language,language) == 0)) {
  56. /* if value for the language is already there
  57. replace it with latest one.
  58. */
  59. if (pvalue->language == NULL)
  60. pvalue->language = strdup(language);
  61. if (pvalue->value)
  62. free(pvalue->value);
  63. pvalue->value = strdup(value);
  64. return 0;
  65. }
  66. prev = pvalue;
  67. pvalue = pvalue->next;
  68. }
  69. pvalue = (ValueNode *) malloc(sizeof(ValueNode));
  70. memset(pvalue, 0, sizeof(ValueNode));
  71. prev->next = pvalue;
  72. pvalue->language = strdup(language);
  73. pvalue->value = strdup(value);
  74. return 0;
  75. }
  76. const char *ValueSearchItem(ValueNode *node, char *language)
  77. {
  78. ValueNode *pvalue;
  79. if (node == NULL)
  80. return NULL;
  81. pvalue = node;
  82. while (pvalue && pvalue->language) {
  83. if (strcmp(pvalue->language,language) == 0) {
  84. return pvalue->value;
  85. }
  86. pvalue = pvalue->next;
  87. }
  88. return NULL;
  89. }
  90. void ValueDestroy(ValueNode *node)
  91. {
  92. ValueNode *p, *current;
  93. p = node;
  94. /* free itself and go next */
  95. while (p) {
  96. current = p;
  97. p = p->next;
  98. if (current->language)
  99. free (current->language);
  100. if (current->value)
  101. free (current->value);
  102. }
  103. }
  104. /* ======================== End of Value with Language list ==================== */
  105. /* ======================== Tree List Implementation============================ */
  106. const char * TreeSearchItem(TreeNode *res, char *key, char *language)
  107. {
  108. int k;
  109. const char *result;
  110. if (res == NULL || res->key == NULL)
  111. return NULL;
  112. k = strcmp(key, res->key);
  113. if (k > 0) {
  114. return TreeSearchItem(res->right, key, language);
  115. }
  116. else if (k < 0) {
  117. return TreeSearchItem(res->left, key, language);
  118. }
  119. else {
  120. /* Add to the current node; */
  121. if (language == NULL || *language == '\0')
  122. return res->value;
  123. result = ValueSearchItem(res->vlist, language);
  124. if (result)
  125. return result;
  126. else /* fallback to default value if there is any */
  127. return res->value;
  128. }
  129. }
  130. /*
  131. TreeAddItem
  132. Add value for specific language to the resource tree
  133. Using binary tree now --> Balanced tree later
  134. */
  135. int TreeAddItem(TreeNode *res, char *key, char *value, char *language)
  136. {
  137. TreeNode *node;
  138. ValueNode *vnode;
  139. int k;
  140. if (res->key == NULL) {
  141. res->key = strdup(key);
  142. k = 0;
  143. }
  144. else {
  145. k = strcmp(key, res->key);
  146. }
  147. if (k > 0) {
  148. if (res->right == NULL) {
  149. /* Create node and it's value sub list
  150. */
  151. node = (TreeNode *) malloc (sizeof(TreeNode));
  152. memset(node, 0, sizeof(TreeNode));
  153. vnode = (ValueNode *) malloc(sizeof(ValueNode));
  154. memset(vnode, 0, sizeof(ValueNode));
  155. node->vlist = vnode;
  156. res->right = node;
  157. /* assign value to node */
  158. node->key = strdup(key);
  159. if (language == NULL)
  160. node->value = strdup(value);
  161. else
  162. ValueAddLanguageItem(node->vlist, value, language);
  163. }
  164. else {
  165. return TreeAddItem(res->right, key, value, language);
  166. }
  167. }
  168. else if (k < 0) {
  169. if (res->left == NULL) {
  170. node = (TreeNode *) malloc (sizeof(TreeNode));
  171. memset(node, 0, sizeof(TreeNode));
  172. vnode = (ValueNode *) malloc(sizeof(ValueNode));
  173. memset(vnode, 0, sizeof(ValueNode));
  174. node->vlist = vnode;
  175. res->left = node;
  176. /* assign value to node */
  177. node->key = strdup(key);
  178. if (language == NULL)
  179. node->value = strdup(value);
  180. else
  181. return ValueAddLanguageItem(node->vlist, value, language);
  182. }
  183. else {
  184. return TreeAddItem(res->left, key, value, language);
  185. }
  186. }
  187. else {
  188. /* Add to the current node; */
  189. if (language == NULL)
  190. res->value = strdup(value);
  191. else
  192. return ValueAddLanguageItem(res->vlist, value, language);
  193. }
  194. return 0;
  195. }
  196. void TreeDestroy(TreeNode *tree)
  197. {
  198. if (tree == NULL)
  199. return;
  200. if (tree->vlist)
  201. ValueDestroy(tree->vlist);
  202. if (tree->key)
  203. free(tree->key);
  204. if (tree->value)
  205. free(tree->value);
  206. if (tree->left)
  207. TreeDestroy(tree->left);
  208. if (tree->right)
  209. TreeDestroy(tree->right);
  210. }
  211. /* ====================== End of Tree implementation ================= */
  212. /* ====================== Tree controller (hash ?) ================ */
  213. ResHash * ResHashCreate(char * name)
  214. {
  215. ResHash *pResHash;
  216. /* Create hash table */
  217. pResHash = (ResHash *) malloc (sizeof(ResHash));
  218. if (pResHash == NULL)
  219. return NULL;
  220. memset(pResHash, 0, sizeof(ResHash));
  221. if (name)
  222. pResHash->name = strdup(name);
  223. /* Create initial tree item and it's valuelist to hash table */
  224. pResHash->treelist = (TreeNode *) malloc(sizeof(TreeNode));
  225. if (pResHash->treelist)
  226. memset(pResHash->treelist, 0, sizeof(TreeNode));
  227. pResHash->treelist->vlist = (ValueNode *) malloc(sizeof(ValueNode));
  228. memset(pResHash->treelist->vlist, 0, sizeof(ValueNode));
  229. return pResHash;
  230. }
  231. int ResHashAdd(ResHash *res, char *key, char *value, char *language)
  232. {
  233. #if 0
  234. hash = get hash value from key
  235. tree = find the tree associated with hash value
  236. #endif
  237. return TreeAddItem(res->treelist, key, value, language);
  238. }
  239. const char *ResHashSearch(ResHash *res, char *key, char *language)
  240. {
  241. #if 0
  242. hash = get hash value from key
  243. tree = find the tree associated with hash value
  244. #endif
  245. return TreeSearchItem(res->treelist, key, language);
  246. }
  247. void ResHashDestroy(ResHash *res)
  248. {
  249. if (res == NULL)
  250. return;
  251. if (res->name)
  252. free(res->name);
  253. if (res->treelist)
  254. TreeDestroy(res->treelist);
  255. }
  256. /* ========================= End of Tree controller ====================== */