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