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