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