domnode.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. static const char version[] = "$Id$";
  2. /*
  3. * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
  4. *
  5. * See the COPYING file for the terms of usage and distribution.
  6. */
  7. #ifdef HAVE_CONFIG_H
  8. #include "config.h"
  9. #endif
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <ctype.h>
  13. #include "malloc.h"
  14. #include "error.h"
  15. #include "domnode.h"
  16. /* TODO: generic format support */
  17. #include "domnode-xml.h"
  18. /******************************************************************************/
  19. extern sd_domnode_t* __sd_domnode_new(const char* a_name, const char* a_value,
  20. int is_elem)
  21. {
  22. sd_domnode_t* ptrThis;
  23. ptrThis = (sd_domnode_t*)sd_calloc(1, sizeof(*ptrThis));
  24. ptrThis->name = a_name ? sd_strdup(a_name) : 0;
  25. ptrThis->value = a_value ? sd_strdup(a_value): 0;
  26. ptrThis->children = is_elem ? sd_list_new(10) : 0;
  27. ptrThis->attrs = is_elem ? sd_list_new(10) : 0;
  28. return ptrThis;
  29. }
  30. /******************************************************************************/
  31. extern sd_domnode_t* sd_domnode_new(const char* a_name, const char* a_value)
  32. {
  33. return __sd_domnode_new(a_name, a_value, 1);
  34. }
  35. /******************************************************************************/
  36. static int foreach_delete(sd_domnode_t* a_node, void* unused)
  37. {
  38. sd_domnode_delete(a_node);
  39. return 0;
  40. }
  41. /******************************************************************************/
  42. static void domnode_clear(sd_domnode_t* ptrThis)
  43. {
  44. free((void*) ptrThis->name);
  45. free((void*) ptrThis->value);
  46. sd_list_foreach(ptrThis->children, (sd_list_func_t) foreach_delete, 0);
  47. sd_list_delete(ptrThis->children);
  48. sd_list_foreach(ptrThis->attrs, (sd_list_func_t) foreach_delete, 0);
  49. sd_list_delete(ptrThis->attrs);
  50. }
  51. /******************************************************************************/
  52. extern void sd_domnode_delete(sd_domnode_t* ptrThis)
  53. {
  54. if (!ptrThis)
  55. return;
  56. domnode_clear(ptrThis);
  57. free(ptrThis);
  58. }
  59. /******************************************************************************/
  60. static void domnode_update(sd_domnode_t* ptrThis, sd_domnode_t* a_node)
  61. {
  62. domnode_clear(ptrThis);
  63. ptrThis->name = a_node->name;
  64. ptrThis->value = a_node->value;
  65. ptrThis->children = a_node->children;
  66. ptrThis->attrs = a_node->attrs;
  67. /* Destroy ptrThis now empty node ! */
  68. free(a_node);
  69. }
  70. /******************************************************************************/
  71. extern int sd_domnode_fread(sd_domnode_t* ptrThis, FILE* a_stream)
  72. {
  73. int ret;
  74. sd_domnode_t* node;
  75. /* TODO: generic format support */
  76. if (! (ret = __sd_domnode_xml_fread(&node, a_stream)))
  77. domnode_update(ptrThis, node);
  78. return ret ? -1 : 0;
  79. }
  80. /******************************************************************************/
  81. extern int sd_domnode_read(sd_domnode_t* ptrThis, const char* a_buffer,
  82. size_t a_size)
  83. {
  84. int ret;
  85. sd_domnode_t* node;
  86. /* TODO: generic format support */
  87. if (! (ret = __sd_domnode_xml_read(&node, a_buffer, a_size)))
  88. domnode_update(ptrThis, node);
  89. return ret ? -1 : 0;
  90. }
  91. /******************************************************************************/
  92. extern int sd_domnode_write(sd_domnode_t* ptrThis, char** a_buffer,
  93. size_t* a_size)
  94. {
  95. /* TODO: generic format support */
  96. return __sd_domnode_xml_write(ptrThis, a_buffer, a_size);
  97. }
  98. /******************************************************************************/
  99. extern int sd_domnode_fwrite(const sd_domnode_t* ptrThis, FILE* a_stream)
  100. {
  101. /* TODO: generic format support */
  102. return __sd_domnode_xml_fwrite(ptrThis, a_stream);
  103. }
  104. /******************************************************************************/
  105. extern int sd_domnode_load(sd_domnode_t* ptrThis, const char* a_filename)
  106. {
  107. FILE* fp;
  108. int ret = 0;
  109. if ( (fp = fopen(a_filename, "r")) == 0)
  110. return -1;
  111. ret = sd_domnode_fread(ptrThis, fp);
  112. fclose(fp);
  113. return ret;
  114. }
  115. /******************************************************************************/
  116. extern int sd_domnode_store(const sd_domnode_t* ptrThis, const char* afilename)
  117. {
  118. FILE* fp;
  119. int ret = 0;
  120. if ( (fp = fopen(afilename, "w")) == 0)
  121. return -1;
  122. ret = sd_domnode_fwrite(ptrThis, fp);
  123. fclose(fp);
  124. return ret;
  125. }
  126. /******************************************************************************/
  127. extern sd_domnode_t* sd_domnode_search(const sd_domnode_t* ptrThis,
  128. const char* a_name)
  129. {
  130. sd_list_iter_t* i;
  131. for (i = sd_list_begin(ptrThis->children); i != sd_list_end(ptrThis->children);
  132. i = sd_list_iter_next(i)) {
  133. sd_domnode_t* node = (sd_domnode_t*)i->data;
  134. if (strcmp(node->name, a_name) == 0)
  135. return node;
  136. }
  137. for (i = sd_list_begin(ptrThis->attrs); i != sd_list_end(ptrThis->attrs);
  138. i = sd_list_iter_next(i)) {
  139. sd_domnode_t* node = (sd_domnode_t*)i->data;
  140. if (strcmp(node->name, a_name) == 0)
  141. return node;
  142. }
  143. for (i = sd_list_begin(ptrThis->children); i != sd_list_end(ptrThis->children);
  144. i = sd_list_iter_next(i)) {
  145. sd_domnode_t* node = (sd_domnode_t*)i->data;
  146. if ((node = sd_domnode_search(node, a_name)) != 0)
  147. return node;
  148. }
  149. return 0;
  150. }
  151. /******************************************************************************/
  152. extern sd_domnode_t* sd_domnode_attrs_put(sd_domnode_t* ptrThis,
  153. sd_domnode_t* a_attr)
  154. {
  155. sd_list_iter_t* i;
  156. if (!ptrThis || !ptrThis->attrs || !a_attr || !a_attr->value)
  157. return 0;
  158. if ((i = sd_list_lookadd(ptrThis->attrs, a_attr)) == sd_list_end(ptrThis->attrs))
  159. return 0;
  160. return (sd_domnode_t*)i->data;
  161. }
  162. /******************************************************************************/
  163. extern sd_domnode_t*
  164. sd_domnode_attrs_get(const sd_domnode_t* ptrThis, const char* a_name)
  165. {
  166. sd_list_iter_t* i;
  167. if (!ptrThis || !ptrThis->attrs || !a_name || !*a_name)
  168. return 0;
  169. for (i = sd_list_begin(ptrThis->attrs); i != sd_list_end(ptrThis->attrs);
  170. i = sd_list_iter_next(i)) {
  171. sd_domnode_t* node = (sd_domnode_t*)i->data;
  172. if (strcmp(node->name, a_name) == 0)
  173. return node;
  174. }
  175. return 0;
  176. }
  177. /******************************************************************************/
  178. extern sd_domnode_t*
  179. sd_domnode_attrs_remove(sd_domnode_t* ptrThis, const char* a_name)
  180. {
  181. sd_list_iter_t* i;
  182. if (!ptrThis || !ptrThis->attrs || !a_name || !*a_name)
  183. return 0;
  184. for (i = sd_list_begin(ptrThis->attrs); i != sd_list_end(ptrThis->attrs);
  185. i = sd_list_iter_next(i)) {
  186. sd_domnode_t* node = (sd_domnode_t*)i->data;
  187. if (strcmp(node->name, a_name) == 0) {
  188. sd_list_iter_del(i);
  189. return node;
  190. }
  191. }
  192. return 0;
  193. }