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