Annotation of libwww/Library/src/HTTChunk.c, revision 2.1

2.1     ! frystyk     1: /*
        !             2: **     CHUNKED TRANSFER CODING
        !             3: **
        !             4: **     (c) COPYRIGHT MIT 1995.
        !             5: **     Please first read the full copyright statement in the file COPYRIGH.
        !             6: **     @(#) $Id: Date Author State $
        !             7: **
        !             8: **     This stream parses a chunked transfer encoding using multiple chunks.
        !             9: **
        !            10: ** Authors
        !            11: **     HF      Henrik Frystyk <frystyk@w3.org>
        !            12: **
        !            13: ** History:
        !            14: **     Apr 96  Written from scratch
        !            15: **
        !            16: */
        !            17: 
        !            18: /* Library include files */
        !            19: #include "sysdep.h"
        !            20: #include "WWWUtil.h"
        !            21: #include "WWWCore.h"
        !            22: #include "HTTChunk.h"                                   /* Implemented here */
        !            23: 
        !            24: #define PUTBLOCK(b, l) (*me->target->isa->put_block)(me->target, b, l)
        !            25: #define PUTDEBUG(b, l) (*me->debug->isa->put_block)(me->debug, b, l)
        !            26: #define FREE_TARGET    (*me->target->isa->_free)(me->target)
        !            27: 
        !            28: struct _HTStream {
        !            29:     const HTStreamClass *      isa;
        !            30:     HTEncoding                 coding;
        !            31:     HTStream *                 target;
        !            32:     HTRequest *                        request;
        !            33:     long                       left;       /* Remaining bytes in this chunk */
        !            34:     long                       total;                        /* Full length */
        !            35:     HTEOLState                 state;    
        !            36:     HTChunk *                  buf;
        !            37: };
        !            38: 
        !            39: /* ------------------------------------------------------------------------- */
        !            40: 
        !            41: /*
        !            42: **
        !            43: */
        !            44: PRIVATE BOOL HTTChunk_header (HTStream * me) 
        !            45: {
        !            46:     me->left = strtol(HTChunk_data(me->buf), (char **) NULL, 16);    /* hex! */
        !            47:     if (STREAM_TRACE) HTTrace("Chunked..... chunk size: %X\n", me->left);
        !            48:     if (me->left) {
        !            49:        me->total += me->left;
        !            50: 
        !            51:        /* Look for arguments */
        !            52:        
        !            53:        HTChunk_clear(me->buf);
        !            54:     } else {                                                  /* Last chunk */
        !            55:        HTRequest * request = me->request;
        !            56:        me->target = HTStreamStack(WWW_MIME_FOOT, WWW_SOURCE,
        !            57:                                   me->target, request, NO);
        !            58:     }
        !            59:     return YES;
        !            60: }
        !            61: 
        !            62: PRIVATE int HTTChunk_put_block (HTStream * me, const char * b, int l)
        !            63: {
        !            64:     while (l > 0) {
        !            65:        if (me->left <= 0) {
        !            66:            while (l > 0) {
        !            67:                if (me->state == EOL_FLF) {
        !            68:                    HTTChunk_header(me);
        !            69:                    me->state = EOL_DOT;
        !            70:                    break;
        !            71:                } else if (*b == CR) {
        !            72:                    me->state = me->state == EOL_DOT ? EOL_SCR : EOL_FCR;
        !            73:                } else if (*b == LF) {
        !            74:                    me->state = me->state == EOL_SCR ? EOL_BEGIN : EOL_FLF;
        !            75:                } else
        !            76:                    HTChunk_putc(me->buf, *b);
        !            77:                b++, l--;
        !            78:            }
        !            79:        }
        !            80:        if (l > 0) {
        !            81:            int bytes = me->left ? HTMIN(l, me->left) : l;
        !            82:            int status = (*me->target->isa->put_block)(me->target, b, bytes);
        !            83:            if (status == HT_OK) {
        !            84:                me->left -= bytes;
        !            85:                l -= bytes, b+= bytes;
        !            86:            } else
        !            87:                return status;
        !            88:        }
        !            89:     }
        !            90:     return HT_OK;
        !            91: }
        !            92: 
        !            93: PRIVATE int HTTChunk_put_string (HTStream * me, const char * s)
        !            94: {
        !            95:     return HTTChunk_put_block(me, s, (int) strlen(s));
        !            96: }
        !            97: 
        !            98: PRIVATE int HTTChunk_put_character (HTStream * me, char c)
        !            99: {
        !           100:     return HTTChunk_put_block(me, &c, 1);
        !           101: }
        !           102: 
        !           103: PRIVATE int HTTChunk_flush (HTStream * me)
        !           104: {
        !           105:     return (*me->target->isa->flush)(me->target);
        !           106: }
        !           107: 
        !           108: PRIVATE int HTTChunk_free (HTStream * me)
        !           109: {
        !           110:     int status = HT_OK;
        !           111:     HTParentAnchor * anchor = HTRequest_anchor(me->request);
        !           112:     HTAnchor_setLength(anchor, me->total);
        !           113:     if (me->target) {
        !           114:        if ((status = (*me->target->isa->_free)(me->target)) == HT_WOULD_BLOCK)
        !           115:            return HT_WOULD_BLOCK;
        !           116:     }
        !           117:     if (PROT_TRACE) HTTrace("Chunked..... FREEING....\n");
        !           118:     HTChunk_delete(me->buf);
        !           119:     HT_FREE(me);
        !           120:     return status;
        !           121: }
        !           122: 
        !           123: PRIVATE int HTTChunk_abort (HTStream * me, HTList * e)
        !           124: {
        !           125:     int status = HT_ERROR;
        !           126:     if (me->target) status = (*me->target->isa->abort)(me->target, e);
        !           127:     if (PROT_TRACE) HTTrace("Chunked..... ABORTING...\n");
        !           128:     HT_FREE(me);
        !           129:     return status;
        !           130: }
        !           131: 
        !           132: PRIVATE const HTStreamClass HTChunkedClass =
        !           133: {
        !           134:     "HTChunked",
        !           135:     HTTChunk_flush,
        !           136:     HTTChunk_free,
        !           137:     HTTChunk_abort,
        !           138:     HTTChunk_put_character,
        !           139:     HTTChunk_put_string,
        !           140:     HTTChunk_put_block
        !           141: };
        !           142: 
        !           143: PUBLIC HTStream * HTChunkedDecoder   (HTRequest *      request,
        !           144:                                      void *            param,
        !           145:                                      HTEncoding        coding,
        !           146:                                      HTStream *        target)
        !           147: {
        !           148:     HTStream * me;
        !           149:     HTParentAnchor * anchor = HTRequest_anchor(request);
        !           150:     if ((me = (HTStream  *) HT_CALLOC(1, sizeof(HTStream))) == NULL)
        !           151:         HT_OUTOFMEM("HTTChunk");
        !           152:     me->isa = &HTChunkedClass;
        !           153:     me->coding = coding;
        !           154:     me->target = target;
        !           155:     me->request = request;
        !           156:     me->state = EOL_BEGIN;
        !           157:     me->buf = HTChunk_new(64);
        !           158:     
        !           159:     /* Adjust information in anchor */
        !           160:     HTAnchor_setTransfer(anchor, NULL);
        !           161: 
        !           162:     if (STREAM_TRACE) HTTrace("Chunked..... Decoder stream created\n");
        !           163:     return me;
        !           164: }

Webmaster