Annotation of libwww/Library/src/HTDemux.c, revision 1.1.2.3

1.1.2.1   frystyk     1: /*
                      2: **     MUX HEADER PARSER STREAM
                      3: **
                      4: **     (c) COPYRIGHT MIT 1995.
                      5: **     Please first read the full copyright statement in the file COPYRIGH.
1.1.2.3 ! frystyk     6: **     @(#) $Id: HTDemux.c,v 1.1.2.2 1996/11/02 20:10:19 frystyk Exp $
1.1.2.1   frystyk     7: **
                      8: **     This stream parses MUX headers.
                      9: **
                     10: ** Authors
                     11: **     HFN     Henrik Frystyk Nielsen <frystyk@w3.org>
                     12: **
                     13: ** History:
                     14: **     Oct 96  Written
                     15: */
                     16: 
                     17: /* Library include files */
                     18: #include "sysdep.h"
                     19: #include "WWWUtil.h"
                     20: #include "WWWCore.h"
                     21: #include "HTMuxHeader.h"
                     22: #include "HTMuxCh.h"
                     23: #include "HTDemux.h"                                    /* Implemented here */
                     24: 
                     25: struct _HTStream {
                     26:     const HTStreamClass *      isa;
1.1.2.2   frystyk    27:     HTChannel *                        ch;
1.1.2.1   frystyk    28:     HTHost *                   host;
1.1.2.3 ! frystyk    29:     HTMuxChannel *             muxch;
        !            30:     HTMuxSession *             session;
1.1.2.1   frystyk    31:     int                                next;                         /* Next header */
1.1.2.3 ! frystyk    32:     HTMuxHeader                        flags;
1.1.2.1   frystyk    33: };
                     34: 
                     35: /* ------------------------------------------------------------------------- */
                     36: 
                     37: /*
                     38: **  Parse through the buffer, identify the headers, and distribute the
                     39: **  data on the virtual session input streams
                     40: */
                     41: PRIVATE int HTDemux_write (HTStream * me, const char * buf, int len)
                     42: {
                     43:     HTMuxChannel * muxch = me->muxch;
1.1.2.2   frystyk    44:     int length = 0;
1.1.2.1   frystyk    45:     while (len > 0) {
                     46: 
                     47:        /*
                     48:        **  Look for the next header. If this is the first time through then
                     49:        **  we expect the stream of data to start with a header.
                     50:        */
                     51:        if (!me->next) {
1.1.2.2   frystyk    52:            HTMuxHeader header[2];
1.1.2.3 ! frystyk    53:            HTMuxSessionId sid = INVSID;
1.1.2.2   frystyk    54:            header[0] = HT_WORDSWAP(*(HTMuxHeader *) buf);
1.1.2.1   frystyk    55: 
                     56:            /*
                     57:            **  If the long bit is set then we expect another 32 bits as the
                     58:            **  length of the payload
                     59:            */
                     60:            if (MUX_IS_LONG(header[0])) {
1.1.2.3 ! frystyk    61:                header[1] = HT_WORDSWAP(*(HTMuxHeader *) (buf+1));
1.1.2.1   frystyk    62:                me->next = MUX_LONG_ALIGN(header[1]);
                     63:                buf += 8, len -= 8;
                     64:            } else {
                     65:                me->next = MUX_ALIGN(MUX_GET_LEN(header[0]));
                     66:                buf += 4, len -= 4;
                     67:            }
1.1.2.3 ! frystyk    68:            if (MUX_TRACE) HTTrace("Mux Channel. header: %x\n", header[0]);
1.1.2.1   frystyk    69:            length = HTMIN(len, me->next);
1.1.2.2   frystyk    70:            sid = MUX_GET_SID(header[0]);
1.1.2.1   frystyk    71: 
                     72:            /*
1.1.2.2   frystyk    73:            **  If this is a control message then handle it here
                     74:            */
                     75:            if (header[0] & MUX_CONTROL) {
                     76:                if (header[0] & MUX_STRING) {
                     77: 
                     78:                    ; /* Define the string */
                     79:                    
                     80:                } else if (header[0] & MUX_STACK) {
                     81:                
                     82:                    ; /* Define the stack */
                     83: 
                     84:                } else if (header[0] & MUX_FRAGMENT) {
1.1.2.3 ! frystyk    85:                    HTMuxSession_setFragment(muxch, sid, MUX_GET_LEN(header[0]));
1.1.2.2   frystyk    86:                } else if (header[0] & MUX_CREDIT) {
1.1.2.3 ! frystyk    87:                    HTMuxSession_setCredit(muxch, sid, header[1]);
1.1.2.2   frystyk    88:                }
1.1.2.3 ! frystyk    89:            } else if (header[0] & MUX_SYN)
        !            90:                me->session = HTMuxSession_register(muxch, sid, MUX_GET_PID(header[0]));
        !            91:            else {
        !            92:                me->session = HTMuxChannel_findSessionFromId(muxch, sid);
        !            93:                me->flags = header[0] & MUX_FLAGS;
1.1.2.2   frystyk    94:            }
                     95:        }
                     96: 
                     97:        /*
                     98:        **  If there is data on this session then handle it here.
                     99:        */
                    100:        if (me->next && me->session) {
1.1.2.3 ! frystyk   101:            if (HTMuxSession_disposeData(me->session, buf, length) == 1) {
        !           102:                HTMuxChannel_sendControl(muxch, HTMuxSession_id(me->session),
        !           103:                                         MUX_CREDIT, DEFAULT_CREDIT, NULL, 0);
        !           104:            }
        !           105:        }
1.1.2.2   frystyk   106: 
1.1.2.3 ! frystyk   107:        /*
        !           108:        **  If we have a data flag pending for this segment.
        !           109:        **  We currently don't do anthing with PUSH.
        !           110:        */
        !           111:        if (!me->next && (me->flags & (MUX_FIN | MUX_RST))) {
1.1.2.2   frystyk   112: 
1.1.2.3 ! frystyk   113:            /* Mark as closed */
1.1.2.2   frystyk   114: 
1.1.2.1   frystyk   115:        }
1.1.2.3 ! frystyk   116:        buf += length, len -= length, me->next -= length;
1.1.2.1   frystyk   117:     }
                    118:     return HT_OK;
                    119: }
                    120: 
                    121: PRIVATE int HTDemux_put_character (HTStream * me, char c)
                    122: {
                    123:     return HTDemux_write(me, &c, 1);
                    124: }
                    125: 
                    126: PRIVATE int HTDemux_put_string (HTStream * me, const char * s)
                    127: {
                    128:     return HTDemux_write(me, s, (int) strlen(s));
                    129: }
                    130: 
                    131: PRIVATE int HTDemux_flush (HTStream * me)
                    132: {
                    133:     return HT_OK;
                    134: }
                    135: 
                    136: PRIVATE int HTDemux_free (HTStream * me)
                    137: {
                    138:     return HTDemux_flush(me);
                    139: }
                    140: 
                    141: PRIVATE int HTDemux_abort (HTStream * me, HTList * e)
                    142: {
                    143:     if (PROT_TRACE) HTTrace("MUX Tx...... ABORTING...\n");
                    144:     return HT_ERROR;
                    145: }
                    146: 
                    147: PRIVATE const HTStreamClass HTDemux =
                    148: {              
                    149:     "Demux",
                    150:     HTDemux_flush,
                    151:     HTDemux_free,
                    152:     HTDemux_abort,
                    153:     HTDemux_put_character,
                    154:     HTDemux_put_string,
                    155:     HTDemux_write
                    156: }; 
                    157: 
1.1.2.2   frystyk   158: PUBLIC HTStream * HTDemux_new (HTHost * host, HTChannel * ch, HTMuxChannel * muxch)
1.1.2.1   frystyk   159: {
                    160:     HTStream * me = NULL;
                    161:     if (muxch) {
                    162:        if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL)
                    163:            HT_OUTOFMEM("HTDemux_new");
                    164:        me->isa = &HTDemux;
1.1.2.3 ! frystyk   165:        me->muxch = muxch;      
1.1.2.1   frystyk   166:     }
                    167:     return me;
                    168: }

Webmaster