HTTee.c
上传用户:zlh9724
上传日期:2007-01-04
资源大小:1991k
文件大小:3k
源码类别:

浏览器

开发平台:

Unix_Linux

  1. /*  HTee.c
  2. ** TEE CLASS STREAM DEFINITION
  3. **
  4. ** (c) COPYRIGHT MIT 1995.
  5. ** Please first read the full copyright statement in the file COPYRIGH.
  6. **
  7. ** The Tee class just writes to two streams.  Easy.
  8. ** See also the Black Hole stream which is even easier.
  9. **
  10. ** HISTORY:
  11. **  8 Jul 94  FM Insulate free() from _free structure element.
  12. **
  13. */
  14. /* Library include files */
  15. #include "tcp.h"
  16. #include "HTUtils.h"
  17. #include "HTArray.h"
  18. #include "HTTee.h"
  19. /* Stream Object
  20. ** ------------
  21. */
  22. struct _HTStream {
  23.     CONST HTStreamClass * isa;
  24.     HTStream * s1;
  25.     HTStream * s2;
  26.     HTComparer * resolver;
  27. };
  28. /*
  29. ** Algorithm produced by H&kon
  30. */
  31. PRIVATE int default_resolver (CONST void *a, CONST void *b)
  32. {
  33.     if (*(int *) a < 0)
  34.         return *(int *) a;
  35.     if (*(int *) b < 0)
  36.         return *(int *) b;
  37.     if (*(int *) a == 0)
  38.         return *(int *) b;
  39.     return *(int *) a;
  40. }
  41. PRIVATE int HTTee_put_character (HTStream * me, char c)
  42. {
  43.     int ret1 = (*me->s1->isa->put_character)(me->s1, c);
  44.     int ret2 = (*me->s2->isa->put_character)(me->s2, c);
  45.     return me->resolver(&ret1, &ret2);
  46. }
  47. PRIVATE int HTTee_put_string (HTStream * me, CONST char* s)
  48. {
  49.     int ret1 = (*me->s1->isa->put_string)(me->s1, s);
  50.     int ret2 = (*me->s2->isa->put_string)(me->s2, s);
  51.     return me->resolver(&ret1, &ret2);
  52. }
  53. PRIVATE int HTTee_write (HTStream * me, CONST char* s, int l)
  54. {
  55.     int ret1 = (*me->s1->isa->put_block)(me->s1, s, l);
  56.     int ret2 = (*me->s2->isa->put_block)(me->s2, s, l);
  57.     return me->resolver(&ret1, &ret2);
  58. }
  59. PRIVATE int HTTee_flush (HTStream * me)
  60. {
  61.     int ret1 = (*me->s1->isa->flush)(me->s1);
  62.     int ret2 = (*me->s2->isa->flush)(me->s2);
  63.     return me->resolver(&ret1, &ret2);
  64. }
  65. PRIVATE int HTTee_free (HTStream * me)
  66. {
  67.     int ret1 = (*me->s1->isa->_free)(me->s1);
  68.     int ret2 = (*me->s2->isa->_free)(me->s2);
  69.     return me->resolver(&ret1, &ret2);
  70.     HT_FREE(me);
  71. }
  72. PRIVATE int HTTee_abort (HTStream * me, HTList * e)
  73. {
  74.     (*me->s1->isa->abort)(me->s1, e);
  75.     (*me->s2->isa->abort)(me->s2, e);
  76.     HT_FREE(me);
  77.     return HT_ERROR;
  78. }
  79. /* Tee stream
  80. ** ----------
  81. */
  82. PRIVATE CONST HTStreamClass HTTeeClass =
  83. {
  84. "Tee",
  85. HTTee_flush,
  86. HTTee_free,
  87. HTTee_abort,
  88. HTTee_put_character,  HTTee_put_string,
  89. HTTee_write
  90. }; 
  91. /* Tee Stream creation
  92. ** -------------------
  93. ** You can create a T stream using this method. Each stream returns a
  94. ** return value and in order to resolve conflicts in the return code
  95. ** you can specify a resolver callback function. Each time any of the 
  96. ** data methods are called the resolver function is then called with
  97. ** the return codes from the two streams. The return code of the T stream
  98. ** itself will be the result of the resolver function. If you pass NULL
  99. ** as the resolver routine then a default resolver is used.
  100. */
  101. PUBLIC HTStream * HTTee(HTStream * s1, HTStream * s2, HTComparer * resolver)
  102. {
  103.     HTStream * me;
  104.     if ((me = (HTStream  *) HT_CALLOC(1, sizeof(*me))) == NULL)
  105.         HT_OUTOFMEM("HTTee");
  106.     me->isa = &HTTeeClass;
  107.     me->s1 = s1;
  108.     me->s2 = s2;
  109.     me->resolver = resolver ? resolver : default_resolver;
  110.     return me;
  111. }