Annotation of libwww/Library/src/HTNetTxt.c, revision 2.3
2.1 frystyk 1: /* HTNetTxt.c
2: ** NETWORK TELNET TO INTERNAL CHARACTER TEXT AND VISE VERSA
3: **
2.2 frystyk 4: ** (c) COPYRIGHT MIT 1995.
2.1 frystyk 5: ** Please first read the full copyright statement in the file COPYRIGH.
6: **
2.3 ! frystyk 7: ** This module provides two basic streams that converts from CRLF to
! 8: ** an internal C representation (\n) and from the C representation to
! 9: ** CRLF.
2.1 frystyk 10: **
11: ** HISTORY:
12: ** 27 Mar 95 HFN Spawned off from HTFormat.c
13: */
14:
15: /* Library Include files */
16: #include "tcp.h"
17: #include "HTUtils.h"
18: #include "HTString.h"
19: #include "HTStream.h"
20: #include "HTNetTxt.h" /* Implemented here */
21:
22: /* Typedefs and global variable local to this module */
23: struct _HTStream {
24: CONST HTStreamClass * isa;
25: HTStream * target;
26: CONST char * start;
27: BOOL had_cr;
28: };
29:
30: #define PUTC(c) (*me->target->isa->put_character)(me->target, c)
31: #define PUTBLOCK(b, l) (*me->target->isa->put_block)(me->target, b, l)
32:
33: /* ------------------------------------------------------------------------- */
34:
2.3 ! frystyk 35: /*
! 36: ** Converter from CRLF to \n
! 37: ** -------------------------
! 38: ** The input is assumed to be in local representation with lines
! 39: ** delimited by (CR,LF) pairs in the local representation.
! 40: ** The conversion to local representation is always done in HTSocket.c
! 41: ** The (CR,LF) sequence when found is changed to a '\n' character,
! 42: ** the internal C representation of a new line.
! 43: **
! 44: */
2.1 frystyk 45: PRIVATE int NetToText_put_block ARGS3(HTStream *, me, CONST char*, s, int, l)
46: {
47: int status;
48: if (!me->start)
49: me->start = s;
50: else {
51: l -= (me->start - s);
52: s = me->start;
53: }
54: while (l-- > 0) {
55: if (me->had_cr && *s == LF) {
56: if (s > me->start+1) {
57: if ((status = PUTBLOCK(me->start, s - me->start-1)) != HT_OK)
58: return status;
59: }
60: me->start = s+1;
61: if ((status = PUTC('\n')) != HT_OK)
62: return status;
63: }
64: me->had_cr = (*s++ == CR);
65: }
66: if (me->start < s && (status = PUTBLOCK(me->start, s-me->start)) != HT_OK)
67: return status;
68: me->start = NULL; /* Whole buffer is written :-) */
69: return HT_OK;
70: }
71:
2.3 ! frystyk 72: PRIVATE int NetToText_put_character ARGS2(HTStream *, me, char, c)
! 73: {
! 74: return NetToText_put_block(me, &c, 1);
! 75: }
! 76:
! 77: PRIVATE int NetToText_put_string ARGS2(HTStream *, me, CONST char *, s)
! 78: {
! 79: return NetToText_put_block(me, s, (int) strlen(s));
! 80: }
! 81:
2.1 frystyk 82: PRIVATE int NetToText_flush ARGS1(HTStream *, me)
83: {
84: return me->target->isa->flush(me->target);
85: }
86:
87: PRIVATE int NetToText_free ARGS1(HTStream *, me)
88: {
89: me->target->isa->_free(me->target); /* Close rest of pipe */
90: free(me);
91: return HT_OK;
92: }
93:
94: PRIVATE int NetToText_abort ARGS2(HTStream *, me, HTError, e)
95: {
96: me->target->isa->abort(me->target,e); /* Abort rest of pipe */
97: free(me);
98: return HT_ERROR;
99: }
100:
101: PRIVATE HTStreamClass NetToTextClass = {
102: "NetToText",
103: NetToText_flush,
104: NetToText_free,
105: NetToText_abort,
106: NetToText_put_character,
107: NetToText_put_string,
108: NetToText_put_block
109: };
110:
111: PUBLIC HTStream * HTNetToText ARGS1(HTStream *, target)
112: {
113: HTStream* me = (HTStream *) calloc(1, sizeof(*me));
114: if (me == NULL) outofmem(__FILE__, "NetToText");
115: me->isa = &NetToTextClass;
2.3 ! frystyk 116:
! 117: me->had_cr = NO;
! 118: me->target = target;
! 119: return me;
! 120: }
! 121:
! 122: /*
! 123: ** Converter from \n to CRLF
! 124: ** -------------------------
! 125: ** The input is assumed to be in local representation with lines
! 126: ** delimited by \n. The \n when found is changed to a CRLF sequence,
! 127: ** the network representation of a new line.
! 128: ** Conversion: '\r' is stripped and \n => CRLF
! 129: */
! 130: PRIVATE int TextToNet_put_block ARGS3(HTStream *, me, CONST char*, b, int, len)
! 131: {
! 132: int status;
! 133: CONST char *limit = b+len;
! 134:
! 135: if (!me->start)
! 136: me->start = b;
! 137: else {
! 138: len -= (me->start - b);
! 139: b = me->start;
! 140: }
! 141: while (len-- > 0) {
! 142: if (me->had_cr && *b == LF) {
! 143: if (b > me->start+1) {
! 144: if ((status = PUTBLOCK(me->start, b - me->start-1)) != HT_OK)
! 145: return status;
! 146: }
! 147: me->start = b+1;
! 148: if ((status = PUTC('\n')) != HT_OK)
! 149: return status;
! 150: }
! 151: me->had_cr = (*b++ == CR);
! 152: }
! 153: if (me->start < b && (status = PUTBLOCK(me->start, b-me->start)) != HT_OK)
! 154: return status;
! 155: me->start = NULL; /* Whole buffer is written :-) */
! 156: return HT_OK;
! 157: }
! 158:
! 159: PRIVATE int TextToNet_put_character ARGS2(HTStream *, me, char, c)
! 160: {
! 161: return TextToNet_put_block(me, &c, 1);
! 162: }
! 163:
! 164: PRIVATE int TextToNet_put_string ARGS2(HTStream *, me, CONST char *, s)
! 165: {
! 166: return TextToNet_put_block(me, s, (int) strlen(s));
! 167: }
! 168:
! 169: PRIVATE int TextToNet_flush ARGS1(HTStream *, me)
! 170: {
! 171: return me->target->isa->flush(me->target);
! 172: }
! 173:
! 174: PRIVATE int TextToNet_free ARGS1(HTStream *, me)
! 175: {
! 176: me->target->isa->_free(me->target); /* Close rest of pipe */
! 177: free(me);
! 178: return HT_OK;
! 179: }
! 180:
! 181: PRIVATE int TextToNet_abort ARGS2(HTStream *, me, HTError, e)
! 182: {
! 183: me->target->isa->abort(me->target,e); /* Abort rest of pipe */
! 184: free(me);
! 185: return HT_ERROR;
! 186: }
! 187:
! 188: PRIVATE HTStreamClass TextToNetClass = {
! 189: "TextToNet",
! 190: TextToNet_flush,
! 191: TextToNet_free,
! 192: TextToNet_abort,
! 193: TextToNet_put_character,
! 194: TextToNet_put_string,
! 195: TextToNet_put_block
! 196: };
! 197:
! 198: PUBLIC HTStream * HTTextToNet ARGS1(HTStream *, target)
! 199: {
! 200: HTStream* me = (HTStream *) calloc(1, sizeof(*me));
! 201: if (me == NULL) outofmem(__FILE__, "TextToNet");
! 202: me->isa = &TextToNetClass;
2.1 frystyk 203:
204: me->had_cr = NO;
205: me->target = target;
206: return me;
207: }
208:
Webmaster