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