factory.c 3.5 KB

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