Diff for /libwww/Library/src/HTBound.c between versions 2.10 and 2.11

version 2.10, 1998/05/04 19:36:19 version 2.11, 1998/11/30 03:52:36
Line 1 Line 1
 /*                                                                   HTBound.c  /*                                                                   HTBound.c
 **      MIME MULTIPART PARSER STREAM  **      MIME MULTIPART PARSER STREAM
 **  **
 **      (c) COPYRIGHT MIT 1995.  **      (c) COPYRIGHT MIT 1995.
 **      Please first read the full copyright statement in the file COPYRIGH.  **      Please first read the full copyright statement in the file COPYRIGH.
 **      @(#) $Id$  **      @(#) $Id$
 **  **
 **      This stream parses a MIME multipart stream and builds a set of new  **      This stream parses a MIME multipart stream and builds a set of new
 **      streams via the stream stack each time we encounter a boundary start.  **      streams via the stream stack each time we encounter a boundary start.
 **      We get the boundary from the normal MIME parser via the Request object  **      We get the boundary from the normal MIME parser via the Request object
 **  **
 ** Authors  ** Authors
 **      HF      Henrik Frystyk <frystyk@w3.org>  **      HF      Henrik Frystyk <frystyk@w3.org>
 **  **
 ** History:  ** History:
 **      Nov 95  Written from scratch  **      Nov 95  Written from scratch
 **  **
 */  */
   
 /* Library include files */  /* Library include files */
 #include "wwwsys.h"  #include "wwwsys.h"
 #include "WWWUtil.h"  #include "WWWUtil.h"
 #include "WWWCore.h"  #include "WWWCore.h"
 #include "HTReqMan.h"  #include "WWWStream.h"
 #include "HTBound.h"                                     /* Implemented here */  #include "HTReqMan.h"
   #include "HTBound.h"                                     /* Implemented here */
 #define PUTBLOCK(b, l)  (*me->target->isa->put_block)(me->target, b, l)  
 #define PUTDEBUG(b, l)  (*me->debug->isa->put_block)(me->debug, b, l)  #define PUTBLOCK(b, l)  (*me->target->isa->put_block)(me->target, b, l)
 #define FREE_TARGET     (*me->target->isa->_free)(me->target)  #define PUTDEBUG(b, l)  (*me->debug->isa->put_block)(me->debug, b, l)
   #define FREE_TARGET     (*me->target->isa->_free)(me->target)
 struct _HTStream {  
     const HTStreamClass *       isa;  struct _HTStream {
     HTStream *                  target;      const HTStreamClass *       isa;
     HTStream *                  orig_target;      HTStream *                  target;
     HTFormat                    format;      HTStream *                  orig_target;
     HTStream *                  debug;            /* For preamble and epilog */      HTFormat                    format;
     HTRequest *                 request;      HTStream *                  debug;            /* For preamble and epilog */
     BOOL                        body;             /* Body or preamble|epilog */      HTRequest *                 request;
     HTEOLState                  state;      BOOL                        body;             /* Body or preamble|epilog */
     int                         dash;                    /* Number of dashes */      HTEOLState                  state;
     char *                      boundary;      int                         dash;                    /* Number of dashes */
     char *                      bpos;      char *                      boundary;
 };      char *                      bpos;
   };
 /* ------------------------------------------------------------------------- */  
   /* ------------------------------------------------------------------------- */
 /*  
 **      Searches for FTP line until buffer fills up or a CRLF or LF is found  /*
 */  **      Searches for FTP line until buffer fills up or a CRLF or LF is found
 PRIVATE int HTBoundary_put_block (HTStream * me, const char * b, int l)  */
 {  PRIVATE int HTBoundary_put_block (HTStream * me, const char * b, int l)
     const char *start = b;  {
     const char *end = b;      const char *start = b;
     while (l-- > 0) {      const char *end = b;
         if (me->state == EOL_FCR) {      while (l-- > 0) {
             me->state = (*b == LF) ? EOL_FLF : EOL_BEGIN;          if (me->state == EOL_FCR) {
         } else if (me->state == EOL_FLF) {              me->state = (*b == LF) ? EOL_FLF : EOL_BEGIN;
             if (me->dash == 2) {          } else if (me->state == EOL_FLF) {
                 while (l>0 && *me->bpos && *me->bpos==*b) l--, me->bpos++, b++;              if (me->dash == 2) {
                 if (!*me->bpos) {                  while (l>0 && *me->bpos && *me->bpos==*b) l--, me->bpos++, b++;
                     if (STREAM_TRACE && !*me->bpos)                  if (!*me->bpos) {
                         HTTrace("Boundary.... `%s\' found\n", me->boundary);                      if (STREAM_TRACE && !*me->bpos)
                     me->bpos = me->boundary;                          HTTrace("Boundary.... `%s\' found\n", me->boundary);
                     me->body = YES;                      me->bpos = me->boundary;
                     me->state = EOL_DOT;                      me->body = YES;
                 } else if (l>0) {                      me->state = EOL_DOT;
                     me->dash = 0;                  } else if (l>0) {
                     me->bpos = me->boundary;                      me->dash = 0;
                     me->state = EOL_BEGIN;                      me->bpos = me->boundary;
                 }                      me->state = EOL_BEGIN;
             }                  }
             if (*b == '-') {              }
                 me->dash++;              if (*b == '-') {
             } else if (*b != LF) {                  me->dash++;
                 me->dash = 0;              } else if (*b != CR && *b != LF) {
                 me->state = EOL_BEGIN;                  me->dash = 0;
             }                  me->state = EOL_BEGIN;
         } else if (me->state == EOL_SLF) {          /* Look for closing '--' */              }
             if (me->dash == 4) {          } else if (me->state == EOL_SLF) {          /* Look for closing '--' */
                 if (end > start) {              if (me->dash == 4) {
                     int status = PUTBLOCK(start, end-start);                  if (end > start) {
                     if (status != HT_OK) return status;                      int status = PUTBLOCK(start, end-start);
                 }                      if (status != HT_OK) return status;
                 if (STREAM_TRACE) HTTrace("Boundary.... Ending\n");                  }
                 start = b;                  if (STREAM_TRACE) HTTrace("Boundary.... Ending\n");
                 me->dash = 0;                  start = b;
                 me->state = EOL_BEGIN;                  me->dash = 0;
             }                  me->state = EOL_BEGIN;
             if (*b == '-') {              }
                 me->dash++;              if (*b == '-') {
             } else if (*b != LF) {                  me->dash++;
                 me->dash = 0;              } else if (*b != CR && *b != LF) {
                 me->state = EOL_BEGIN;                  me->dash = 0;
             }                  me->state = EOL_BEGIN;
             me->body = NO;              }
         } else if (me->state == EOL_DOT) {              me->body = NO;
             int status;          } else if (me->state == EOL_DOT) {
             if (me->body) {              int status;
                 if (me->target) FREE_TARGET;              if (me->body) {
                 me->target = HTStreamStack(WWW_MIME,me->format,me->orig_target,                  if (me->target) FREE_TARGET;
                                            me->request, YES);                  me->target = HTStreamStack(WWW_MIME,me->format,
                 if (end > start) {                                             HTMerge(me->orig_target, 2),
                     if ((status = PUTBLOCK(start, end-start)) != HT_OK)                                             me->request, YES);
                         return status;                  if (end > start) {
                 }                      if ((status = PUTBLOCK(start, end-start)) != HT_OK)
             } else {                          return status;
                 if (me->debug)                  }
                     if ((status = PUTDEBUG(start, end-start)) != HT_OK)              } else {
                         return status;                  if (me->debug)
             }                      if ((status = PUTDEBUG(start, end-start)) != HT_OK)
             start = b;                          return status;
             if (*b == '-') me->dash++;              }
             me->state = EOL_SLF;              start = b;
         } else if (*b == CR) {              if (*b == '-') me->dash++;
             me->state = EOL_FCR;              me->state = EOL_SLF;
             end = b;          } else if (*b == CR) {
         } else if (*b == LF) {              me->state = EOL_FCR;
             if (me->state != EOL_FCR) end = b;              end = b;
             me->state = EOL_FLF;          } else if (*b == LF) {
         }              if (me->state != EOL_FCR) end = b;
         b++;              me->state = EOL_FLF;
     }          }
     return (start<b && me->body) ? PUTBLOCK(start, b-start) : HT_OK;          b++;
 }      }
       return (start<b && me->body) ? PUTBLOCK(start, b-start) : HT_OK;
 PRIVATE int HTBoundary_put_string (HTStream * me, const char * s)  }
 {  
     return HTBoundary_put_block(me, s, (int) strlen(s));  PRIVATE int HTBoundary_put_string (HTStream * me, const char * s)
 }  {
       return HTBoundary_put_block(me, s, (int) strlen(s));
 PRIVATE int HTBoundary_put_character (HTStream * me, char c)  }
 {  
     return HTBoundary_put_block(me, &c, 1);  PRIVATE int HTBoundary_put_character (HTStream * me, char c)
 }  {
       return HTBoundary_put_block(me, &c, 1);
 PRIVATE int HTBoundary_flush (HTStream * me)  }
 {  
     return (*me->target->isa->flush)(me->target);  PRIVATE int HTBoundary_flush (HTStream * me)
 }  {
       return (*me->target->isa->flush)(me->target);
 PRIVATE int HTBoundary_free (HTStream * me)  }
 {  
     int status = HT_OK;  PRIVATE int HTBoundary_free (HTStream * me)
     if (me->target) {  {
         if ((status = (*me->target->isa->_free)(me->target)) == HT_WOULD_BLOCK)      int status = HT_OK;
             return HT_WOULD_BLOCK;      if (me->target) {
     }          if ((status = (*me->target->isa->_free)(me->target)) == HT_WOULD_BLOCK)
     if (PROT_TRACE) HTTrace("Boundary.... FREEING....\n");              return HT_WOULD_BLOCK;
     HT_FREE(me->boundary);      }
     HT_FREE(me);      if (PROT_TRACE) HTTrace("Boundary.... FREEING....\n");
     return status;      HT_FREE(me->boundary);
 }      HT_FREE(me);
       return status;
 PRIVATE int HTBoundary_abort (HTStream * me, HTList * e)  }
 {  
     int status = HT_ERROR;  PRIVATE int HTBoundary_abort (HTStream * me, HTList * e)
     if (me->target) status = (*me->target->isa->abort)(me->target, e);  {
     if (PROT_TRACE) HTTrace("Boundary.... ABORTING...\n");      int status = HT_ERROR;
     HT_FREE(me->boundary);      if (me->target) status = (*me->target->isa->abort)(me->target, e);
     HT_FREE(me);      if (PROT_TRACE) HTTrace("Boundary.... ABORTING...\n");
     return status;      HT_FREE(me->boundary);
 }      HT_FREE(me);
       return status;
 PRIVATE const HTStreamClass HTBoundaryClass =  }
 {                 
     "HTBoundary",  PRIVATE const HTStreamClass HTBoundaryClass =
     HTBoundary_flush,  {              
     HTBoundary_free,      "HTBoundary",
     HTBoundary_abort,      HTBoundary_flush,
     HTBoundary_put_character,      HTBoundary_free,
     HTBoundary_put_string,      HTBoundary_abort,
     HTBoundary_put_block      HTBoundary_put_character,
 };      HTBoundary_put_string,
       HTBoundary_put_block
 PUBLIC HTStream * HTBoundary   (HTRequest *     request,  };
                                 void *          param,  
                                 HTFormat        input_format,  PUBLIC HTStream * HTBoundary   (HTRequest *     request,
                                 HTFormat        output_format,                                  void *          param,
                                 HTStream *      output_stream)                                  HTFormat        input_format,
 {                                  HTFormat        output_format,
     HTParentAnchor * anchor = HTRequest_anchor(request);                                  HTStream *      output_stream)
     HTAssocList * type_param = HTAnchor_formatParam(anchor);  {
     char * boundary = HTAssocList_findObject(type_param, "boundary");      HTResponse * response = HTRequest_response(request);
     if (boundary) {      HTParentAnchor * anchor = HTRequest_anchor(request);
         HTStream * me;      HTAssocList * type_param = response ?
         if ((me = (HTStream  *) HT_CALLOC(1, sizeof(HTStream))) == NULL)          HTResponse_formatParam(response) :
             HT_OUTOFMEM("HTBoundary");          HTAnchor_formatParam(anchor);
         me->isa = &HTBoundaryClass;      char * boundary = HTAssocList_findObject(type_param, "boundary");
         me->request = request;      if (boundary) {
         me->format = output_format;          HTStream * me;
         me->orig_target = output_stream;          if ((me = (HTStream  *) HT_CALLOC(1, sizeof(HTStream))) == NULL)
         me->debug = HTRequest_debugStream(request);              HT_OUTOFMEM("HTBoundary");
         me->state = EOL_FLF;          me->isa = &HTBoundaryClass;
         StrAllocCopy(me->boundary, boundary);                  /* Local copy */          me->request = request;
         me->bpos = me->boundary;          me->format = output_format;
         if (STREAM_TRACE)          me->orig_target = output_stream;
             HTTrace("Boundary.... Stream created with boundary '%s\'\n", me->boundary);          me->debug = HTRequest_debugStream(request);
         return me;          me->state = EOL_FLF;
     } else {          StrAllocCopy(me->boundary, boundary);                  /* Local copy */
         if (STREAM_TRACE) HTTrace("Boundary.... UNKNOWN boundary!\n");          me->bpos = me->boundary;
         return HTErrorStream();          if (STREAM_TRACE)
     }              HTTrace("Boundary.... Stream created with boundary '%s\'\n", me->boundary);
 }          return me;
       } else {
           if (STREAM_TRACE) HTTrace("Boundary.... UNKNOWN boundary!\n");
           return HTErrorStream();
       }
   }

Removed from v.2.10  
changed lines
  Added in v.2.11


Webmaster