Annotation of libwww/Library/src/HTANSI.c, revision 2.5

2.1       frystyk     1: /*                                                                    HTANSI.c
                      2: **     ANSI C FILE DESCRIPTOR TRANSPORT
                      3: **
                      4: **     (c) COPYRIGHT MIT 1995.
                      5: **     Please first read the full copyright statement in the file COPYRIGH.
2.5     ! frystyk     6: **     @(#) $Id: HTANSI.c,v 2.4 1997/01/29 19:22:16 frystyk Exp $
2.1       frystyk     7: **
                      8: **      History:
                      9: **         HFN: writtem
                     10: */
                     11: 
                     12: /* Library include files */
                     13: #include "sysdep.h"
                     14: #include "WWWUtil.h"
2.4       frystyk    15: #include "WWWCore.h"
2.1       frystyk    16: #include "HTNetMan.h"
                     17: #include "HTANSI.h"                                     /* Implemented here */
                     18: 
2.5     ! frystyk    19: #include  "HTHstMan.h"                 /* @@@ FIX ME @@@ */
        !            20: 
2.1       frystyk    21: struct _HTStream {
                     22:     const HTStreamClass *      isa;
                     23:     /* ... */
                     24: };
                     25: 
                     26: struct _HTInputStream {
                     27:     const HTInputStreamClass * isa;    
                     28:     HTChannel *                        ch;
2.3       frystyk    29:     HTHost *                   host;
2.1       frystyk    30:     char *                     write;                  /* Last byte written */
                     31:     char *                     read;                      /* Last byte read */
2.4       frystyk    32:     int                                b_read;
2.1       frystyk    33:     char                       data [FILE_BUFFER_SIZE];
                     34: };
                     35: 
                     36: struct _HTOutputStream {
                     37:     const HTOutputStreamClass *        isa;
                     38:     HTChannel *                        ch;
2.3       frystyk    39:     HTHost *                   host;
2.1       frystyk    40:     FILE *                     fp;
                     41: };
                     42: 
                     43: /* ------------------------------------------------------------------------- */
                     44: /*                              READ STREAM                                 */
                     45: /* ------------------------------------------------------------------------- */
                     46: 
                     47: PRIVATE int HTANSIReader_flush (HTInputStream * me)
                     48: {
2.4       frystyk    49:     HTNet * net = HTHost_getReadNet(me->host);
                     50:     return net && net->readStream ?
                     51:        (*net->readStream->isa->flush)(net->readStream) : HT_OK;
2.1       frystyk    52: }
                     53: 
                     54: PRIVATE int HTANSIReader_free (HTInputStream * me)
                     55: {
2.4       frystyk    56:     HTNet * net = HTHost_getReadNet(me->host);
                     57:     if (net && net->readStream) {
                     58:        int status = (*net->readStream->isa->_free)(net->readStream);
                     59:        if (status == HT_OK) net->readStream = NULL;
2.1       frystyk    60:        return status;
                     61:     }
                     62:     return HT_OK;
                     63: }
                     64: 
                     65: PRIVATE int HTANSIReader_abort (HTInputStream * me, HTList * e)
                     66: {
2.4       frystyk    67:     HTNet * net = HTHost_getReadNet(me->host);
                     68:     if (net && net->readStream) {
                     69:        int status = (*net->readStream->isa->abort)(net->readStream, NULL);
                     70:        if (status != HT_IGNORE) net->readStream = NULL;
2.1       frystyk    71:     }
                     72:     return HT_ERROR;
                     73: }
                     74: 
                     75: PRIVATE int HTANSIReader_read (HTInputStream * me)
                     76: {
2.4       frystyk    77:     FILE * fp = HTChannel_file(me->ch);
                     78:     HTNet * net = HTHost_getReadNet(me->host);
2.1       frystyk    79:     int status;
                     80: 
                     81:     /* Read the file desriptor */
                     82:     while (fp) {
2.4       frystyk    83:        if ((me->b_read = fread(me->data, 1, FILE_BUFFER_SIZE, fp)) == 0){
2.1       frystyk    84:            if (ferror(fp)) {
                     85:                if (PROT_TRACE) HTTrace("ANSI read... READ ERROR\n");
                     86:            } else {
                     87:                HTAlertCallback *cbf = HTAlert_find(HT_PROG_DONE);
2.4       frystyk    88:                if (PROT_TRACE) HTTrace("ANSI read... Finished loading file %p\n", fp);
                     89:                if (cbf) (*cbf)(net->request, HT_PROG_DONE, HT_MSG_NULL,NULL,NULL,NULL);
2.1       frystyk    90:                return HT_CLOSED;
                     91:            }
                     92:        }
                     93: 
                     94:        /* Remember how much we have read from the input socket */
2.4       frystyk    95:        HTTraceData(me->data, me->b_read, "HTANSIReader_read me->data:");
2.1       frystyk    96:        me->write = me->data;
2.4       frystyk    97:        me->read = me->data + me->b_read;
2.1       frystyk    98: 
                     99:        {
                    100:            HTAlertCallback * cbf = HTAlert_find(HT_PROG_READ);
2.4       frystyk   101:            net->bytesRead += me->b_read;
                    102:            if (cbf) (*cbf)(net->request, HT_PROG_READ, HT_MSG_NULL, NULL, NULL, NULL);
2.1       frystyk   103:        }
                    104: 
                    105:        /* Now push the data down the stream */
2.4       frystyk   106:        if ((status = (*net->readStream->isa->put_block)
                    107:             (net->readStream, me->data, me->b_read)) != HT_OK) {
2.1       frystyk   108:            if (status == HT_WOULD_BLOCK) {
                    109:                if (PROT_TRACE) HTTrace("ANSI read... Target WOULD BLOCK\n");
                    110:                return HT_WOULD_BLOCK;
                    111:            } else if (status == HT_PAUSE) {
                    112:                if (PROT_TRACE) HTTrace("ANSI read... Target PAUSED\n");
                    113:                return HT_PAUSE;
                    114:            } else if (status > 0) {          /* Stream specific return code */
                    115:                if (PROT_TRACE)
                    116:                    HTTrace("ANSI read... Target returns %d\n", status);
2.4       frystyk   117:                me->write = me->data + me->b_read;
2.1       frystyk   118:                return status;
                    119:            } else {                                 /* We have a real error */
                    120:                if (PROT_TRACE) HTTrace("ANSI read... Target ERROR\n");
                    121:                return status;
                    122:            }
                    123:        }
2.4       frystyk   124:        me->write = me->data + me->b_read;
2.1       frystyk   125:     }
                    126:     if (PROT_TRACE) HTTrace("ANSI read... File descriptor is NULL...\n");
                    127:     return HT_ERROR;
                    128: }
                    129: 
                    130: /*
                    131: **     The difference between the close and the free method is that we don't
                    132: **     close the connection in the free method - we only call the free method
                    133: **     of the target stream. That way, we can keep the output stream as long 
                    134: **     as the channel itself.
                    135: */
                    136: PRIVATE int HTANSIReader_close (HTInputStream * me)
                    137: {
                    138:     if (PROT_TRACE) HTTrace("ANSI read... FREEING...\n");
                    139:     HT_FREE(me);
                    140:     return HT_OK;
                    141: }
                    142: 
2.3       frystyk   143: PRIVATE int HTANSIReader_consumed (HTInputStream * me, size_t bytes)
                    144: {
                    145:     if (PROT_TRACE) HTTrace("ANSI read... consumed %d bytes\n", bytes);
                    146:     return HT_OK;
                    147: }
                    148: 
2.1       frystyk   149: PRIVATE const HTInputStreamClass HTANSIReader =
                    150: {              
                    151:     "ANSIReader",
                    152:     HTANSIReader_flush,
                    153:     HTANSIReader_free,
                    154:     HTANSIReader_abort,
                    155:     HTANSIReader_read,
2.3       frystyk   156:     HTANSIReader_close,
                    157:     HTANSIReader_consumed
2.1       frystyk   158: };
                    159: 
2.3       frystyk   160: PUBLIC HTInputStream * HTANSIReader_new (HTHost * host, HTChannel * ch,
                    161:                                         void * param,
2.1       frystyk   162:                                         int mode)
                    163: {
2.3       frystyk   164:     if (host && ch) {
2.1       frystyk   165:        HTInputStream * me = HTChannel_input(ch);
                    166:        if (me == NULL) {
                    167:            if ((me=(HTInputStream *) HT_CALLOC(1, sizeof(HTInputStream))) == NULL)
                    168:            HT_OUTOFMEM("HTANSIReader_new");
                    169:            me->isa = &HTANSIReader;
                    170:            me->ch = ch;
                    171:        }
2.3       frystyk   172:        me->host = host;
2.1       frystyk   173:        return me;
                    174:     }
                    175:     return NULL;
                    176: }
                    177: 
                    178: /* ------------------------------------------------------------------------- */
                    179: /*                             WRITE STREAM                                 */
                    180: /* ------------------------------------------------------------------------- */
                    181: 
                    182: PRIVATE int HTANSIWriter_flush (HTOutputStream * me)
                    183: {
                    184:     return (fflush(me->fp) == EOF) ? HT_ERROR : HT_OK;
                    185: }
                    186: 
                    187: PRIVATE int HTANSIWriter_free (HTOutputStream * me)
                    188: {
                    189:     return HT_OK;
                    190: }
                    191: 
                    192: PRIVATE int HTANSIWriter_abort (HTOutputStream * me, HTList * e)
                    193: {
                    194:     if (PROT_TRACE) HTTrace("ANSI write.. ABORTING...\n");
                    195:     return HT_ERROR;
                    196: }
                    197: 
                    198: PRIVATE int HTANSIWriter_character (HTOutputStream * me, char c)
                    199: {
                    200:     return (fputc(c, me->fp) == EOF) ? HT_ERROR : HT_OK;
                    201: }
                    202: 
                    203: PRIVATE int HTANSIWriter_string (HTOutputStream * me, const char* s)
                    204: {
                    205:     if (*s)                                         /* For vms :-( 10/04-94 */
                    206:        return (fputs(s, me->fp) == EOF) ? HT_ERROR : HT_OK;
                    207:     return HT_OK;
                    208: }
                    209: 
                    210: PRIVATE int HTANSIWriter_block (HTOutputStream * me, const char* s, int l)
                    211: {
                    212:     int status ;
                    213:     status = (fwrite(s, 1, l, me->fp) != l) ? HT_ERROR : HT_OK ;
                    214:     if (l > 1 && status == HT_OK) (void) HTANSIWriter_flush(me);
                    215:     return status;
                    216: }
                    217: 
                    218: /*
                    219: **     The difference between the close and the free method is that we don't
                    220: **     close the connection in the free method - we only call the free method
                    221: **     of the target stream. That way, we can keep the output stream as long 
                    222: **     as the channel itself.
                    223: */
                    224: PRIVATE int HTANSIWriter_close (HTOutputStream * me)
                    225: {
                    226:     if (PROT_TRACE) HTTrace("ANSI write.. FREEING...\n");
                    227:     HT_FREE(me);
                    228:     return HT_OK;
                    229: }
                    230: 
                    231: PRIVATE const HTOutputStreamClass HTANSIWriter =
                    232: {              
                    233:     "ANSIWriter",
                    234:     HTANSIWriter_flush,
                    235:     HTANSIWriter_free,
                    236:     HTANSIWriter_abort,
                    237:     HTANSIWriter_character,
                    238:     HTANSIWriter_string,
                    239:     HTANSIWriter_block,
2.3       frystyk   240:     HTANSIWriter_close,
2.1       frystyk   241: };
                    242: 
2.3       frystyk   243: PUBLIC HTOutputStream * HTANSIWriter_new (HTHost * host, HTChannel * ch,
2.1       frystyk   244:                                          void * param, int mode)
                    245: {
2.3       frystyk   246:     if (host && ch) {
2.1       frystyk   247:        HTOutputStream * me = HTChannel_output(ch);
                    248:        if (me == NULL) {
                    249:            if ((me=(HTOutputStream *) HT_CALLOC(1, sizeof(HTOutputStream)))==NULL)
                    250:                HT_OUTOFMEM("HTANSIWriter_new");
                    251:            me->isa = &HTANSIWriter;
                    252:            me->ch = ch;
2.3       frystyk   253:            me->host = host;
2.5     ! frystyk   254:            me->fp = HTChannel_file(ch);
2.1       frystyk   255:        }
                    256:        return me;
                    257:     }
                    258:     return NULL;
                    259: }

Webmaster