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