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

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.2 ! frystyk     6: **     @(#) $Id: HTDemux.c,v 1.1.2.1 1996/10/30 23:21:53 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 "HTSession.h"
                     24: #include "HTDemux.h"                                    /* Implemented here */
                     25: 
                     26: struct _HTStream {
                     27:     const HTStreamClass *      isa;
1.1.2.2 ! frystyk    28:     HTChannel *                        ch;
1.1.2.1   frystyk    29:     HTMuxChannel *             muxch;
                     30:     HTHost *                   host;
1.1.2.2 ! frystyk    31:     HTSession *                        session;
1.1.2.1   frystyk    32:     int                                next;                         /* Next header */
                     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:            HTSessionId sid = INVSID;
        !            53:            HTMuxHeader header[2];
        !            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.2 ! 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:            }
                     68:            length = HTMIN(len, me->next);
1.1.2.2 ! frystyk    69:            sid = MUX_GET_SID(header[0]);
1.1.2.1   frystyk    70: 
                     71:            /*
1.1.2.2 ! frystyk    72:            **  If this is a control message then handle it here
        !            73:            */
        !            74:            if (header[0] & MUX_CONTROL) {
        !            75:                if (header[0] & MUX_STRING) {
        !            76: 
        !            77:                    ; /* Define the string */
        !            78:                    
        !            79:                } else if (header[0] & MUX_STACK) {
        !            80:                
        !            81:                    ; /* Define the stack */
        !            82: 
        !            83:                } else if (header[0] & MUX_FRAGMENT) {
        !            84:                    HTSession * ses = HTMuxChannel_findSessionFromId(muxch, sid);
        !            85: 
        !            86:                    ; /* Assign the fragment size */
        !            87: 
        !            88:                } else if (header[0] & MUX_CREDIT) {
        !            89:                    HTSession * ses = HTMuxChannel_findSessionFromId(muxch, sid);
        !            90: 
        !            91:                    ; /* Assign the fragment size */
        !            92: 
        !            93:                }
        !            94:            } else if (header[0] & MUX_SYN) {
        !            95: 
        !            96:                ; /* Register new session */
        !            97: 
        !            98:            } else {
        !            99: 
        !           100:                /*
        !           101:                **  Remember any data flags in this session so we know how and
        !           102:                **  when to terminate the session.
        !           103:                */
        !           104:                if ((me->session = HTMuxChannel_findSessionFromId(muxch, sid)))
        !           105:                    HTSession_setState(me->session, header[0]);
        !           106:            }
        !           107:        }
        !           108: 
        !           109:        /*
        !           110:        **  If there is data on this session then handle it here.
        !           111:        */
        !           112:        if (me->next && me->session) {
        !           113:            HTNet * net = HTSession_net(me->session);
        !           114:            HTStream * sink = HTNet_readStream(net);
        !           115:            int status = sink ? (*sink->isa->put_block)(sink, buf, length) : HT_ERROR;
        !           116: 
        !           117:            /*
        !           118:            **  Now see what the stream responded and pass this information
        !           119:            **  back to the sender.
        !           120:            */
        !           121:            if (status == HT_OK) {
        !           122: 
        !           123:                /* Generate a credit message */
        !           124: 
        !           125:            } else {
        !           126:                if (status == HT_WOULD_BLOCK || status == HT_PAUSE) {
        !           127:                    if (PROT_TRACE) HTTrace("Demux....... Target PAUSING\n");
        !           128:                    
        !           129:                    /* Save data in extra buffer */
        !           130: 
        !           131:                } else {
        !           132:                    if (PROT_TRACE) HTTrace("Demux....... Target ERROR\n");
        !           133:                        
        !           134:                    /* Send a RST on this session */
        !           135: 
1.1.2.1   frystyk   136:                }
                    137:            }
1.1.2.2 ! frystyk   138:            me->next -= length;
1.1.2.1   frystyk   139:        }
1.1.2.2 ! frystyk   140:        buf += length, len -= length;
1.1.2.1   frystyk   141:     }
                    142:     return HT_OK;
                    143: }
                    144: 
                    145: PRIVATE int HTDemux_put_character (HTStream * me, char c)
                    146: {
                    147:     return HTDemux_write(me, &c, 1);
                    148: }
                    149: 
                    150: PRIVATE int HTDemux_put_string (HTStream * me, const char * s)
                    151: {
                    152:     return HTDemux_write(me, s, (int) strlen(s));
                    153: }
                    154: 
                    155: PRIVATE int HTDemux_flush (HTStream * me)
                    156: {
                    157:     return HT_OK;
                    158: }
                    159: 
                    160: PRIVATE int HTDemux_free (HTStream * me)
                    161: {
                    162:     return HTDemux_flush(me);
                    163: }
                    164: 
                    165: PRIVATE int HTDemux_abort (HTStream * me, HTList * e)
                    166: {
                    167:     if (PROT_TRACE) HTTrace("MUX Tx...... ABORTING...\n");
                    168:     return HT_ERROR;
                    169: }
                    170: 
                    171: PRIVATE const HTStreamClass HTDemux =
                    172: {              
                    173:     "Demux",
                    174:     HTDemux_flush,
                    175:     HTDemux_free,
                    176:     HTDemux_abort,
                    177:     HTDemux_put_character,
                    178:     HTDemux_put_string,
                    179:     HTDemux_write
                    180: }; 
                    181: 
1.1.2.2 ! frystyk   182: PUBLIC HTStream * HTDemux_new (HTHost * host, HTChannel * ch, HTMuxChannel * muxch)
1.1.2.1   frystyk   183: {
                    184:     HTStream * me = NULL;
                    185:     if (muxch) {
                    186:        if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL)
                    187:            HT_OUTOFMEM("HTDemux_new");
                    188:        me->isa = &HTDemux;
1.1.2.2 ! frystyk   189:        me->muxch = muxch;
1.1.2.1   frystyk   190:     }
                    191:     return me;
                    192: }

Webmaster