Annotation of libwww/Library/src/HTTee.c, revision 2.15
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 */
2.15 ! frystyk 16: #include "sysdep.h"
2.7 frystyk 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.15 ! frystyk 26: const HTStreamClass * isa;
2.13 frystyk 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: */
2.15 ! frystyk 35: PRIVATE int default_resolver (const void *a, const void *b)
2.13 frystyk 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.15 ! 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.15 ! 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.14 frystyk 79: HT_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.14 frystyk 86: HT_FREE(me);
2.8 frystyk 87: return HT_ERROR;
2.1 timbl 88: }
89:
90:
91: /* Tee stream
92: ** ----------
93: */
2.15 ! frystyk 94: PRIVATE const HTStreamClass HTTeeClass =
2.1 timbl 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.14 frystyk 117: HTStream * me;
118: if ((me = (HTStream *) HT_CALLOC(1, sizeof(*me))) == NULL)
119: HT_OUTOFMEM("HTTee");
2.1 timbl 120: me->isa = &HTTeeClass;
121: me->s1 = s1;
122: me->s2 = s2;
2.13 frystyk 123: me->resolver = resolver ? resolver : default_resolver;
2.1 timbl 124: return me;
125: }
126:
127:
Webmaster