reshash.c 9.0 KB

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