factory.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. static const char version[] = "$Id$";
  2. /*
  3. * factory.c
  4. *
  5. * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
  6. * See the COPYING file for the terms of usage and distribution.
  7. */
  8. #include <sd/factory.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <sd/malloc.h>
  12. #include <sd/hash.h>
  13. #include <sd/error.h>
  14. struct __sd_factory
  15. {
  16. char* fac_name;
  17. const sd_factory_ops_t* fac_ops;
  18. sd_hash_t* fac_hash;
  19. };
  20. /* xxx FIXME: unsafe hand made polymorphism ...
  21. * This is used to access the name field of objects created by
  22. * factories. For example instances of appenders, layouts or
  23. * rollingpolicies.
  24. * So there's a supposition that the name field is always first--this is true
  25. * but should enforce that probably by extending a base 'name' struct.
  26. */
  27. typedef struct {
  28. char* pr_name;
  29. } sd_factory_product_t;
  30. /*******************************************************************************/
  31. extern sd_factory_t* sd_factory_new(const char* a_name,
  32. const sd_factory_ops_t* a_ops)
  33. {
  34. sd_factory_t* this;
  35. if (!a_name || !a_ops)
  36. return NULL;
  37. this = sd_calloc(1, sizeof(*this));
  38. this->fac_name = sd_strdup(a_name);
  39. this->fac_ops = a_ops;
  40. this->fac_hash = sd_hash_new(20, NULL);
  41. return this;
  42. }
  43. /*******************************************************************************/
  44. extern void sd_factory_delete(sd_factory_t* this)
  45. {
  46. sd_hash_iter_t* i;
  47. sd_debug("sd_factory_delete['%s',",
  48. (this && (this->fac_name) ? this->fac_name: "(no name)"));
  49. if (!this){
  50. goto sd_factory_delete_exit;
  51. }
  52. if (this->fac_ops->fac_delete){
  53. for (i = sd_hash_begin(this->fac_hash); i != sd_hash_end(this->fac_hash);
  54. i = sd_hash_iter_next(i)) {
  55. this->fac_ops->fac_delete(i->data);
  56. }
  57. }
  58. sd_hash_delete(this->fac_hash);
  59. free(this->fac_name);
  60. free(this);
  61. sd_factory_delete_exit:
  62. sd_debug("]");
  63. }
  64. /*******************************************************************************/
  65. extern void* sd_factory_get(sd_factory_t* this, const char* a_name)
  66. {
  67. sd_hash_iter_t* i;
  68. sd_factory_product_t* pr;
  69. if ( (i = sd_hash_lookup(this->fac_hash, a_name)) != NULL)
  70. return i->data;
  71. if (!this->fac_ops->fac_new)
  72. return NULL;
  73. if ( (pr = this->fac_ops->fac_new(a_name)) == NULL)
  74. return NULL;
  75. sd_hash_add(this->fac_hash, pr->pr_name, pr);
  76. return pr;
  77. }
  78. /*******************************************************************************/
  79. extern void sd_factory_destroy(sd_factory_t* this, void* a_pr)
  80. {
  81. sd_factory_product_t* pr = (sd_factory_product_t*) a_pr;
  82. sd_hash_del(this->fac_hash, pr->pr_name);
  83. if (this->fac_ops->fac_delete)
  84. this->fac_ops->fac_delete(pr);
  85. }
  86. /*******************************************************************************/
  87. extern void sd_factory_print(const sd_factory_t* this, FILE* a_stream)
  88. {
  89. sd_hash_iter_t* i;
  90. if (!this)
  91. return;
  92. if (!this->fac_ops->fac_print)
  93. return;
  94. fprintf(a_stream, "factory[%s]:\n", this->fac_name);
  95. for (i = sd_hash_begin(this->fac_hash); i != sd_hash_end(this->fac_hash);
  96. i = sd_hash_iter_next(i))
  97. {
  98. this->fac_ops->fac_print(i->data, a_stream);
  99. fprintf(a_stream, "\n");
  100. }
  101. }
  102. /******************************************************************************/
  103. extern int sd_factory_list(const sd_factory_t* this, void** a_items,
  104. int a_nitems)
  105. {
  106. sd_hash_iter_t* i;
  107. int j;
  108. if (!this || !a_items || a_nitems <= 0)
  109. return -1;
  110. for (i = sd_hash_begin(this->fac_hash), j = 0;
  111. i != sd_hash_end(this->fac_hash);
  112. i = sd_hash_iter_next(i), j++)
  113. {
  114. if (j < a_nitems)
  115. a_items[j] = i->data;
  116. }
  117. return j;
  118. }