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