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

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

Webmaster