/[cvs]/eggdrop1.9/testcode/linemode.c
ViewVC logotype

Contents of /eggdrop1.9/testcode/linemode.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.3 - (show annotations) (download) (as text)
Wed Jun 19 04:51:54 2002 UTC (16 years, 9 months ago) by stdarg
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +54 -60 lines
File MIME type: text/x-chdr
* I think the sockbuf api is almost done

1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5
6 #include "sockbuf.h"
7
8 #define LINEMODE_LEVEL SOCKBUF_LEVEL_TEXT_BUFFER
9
10 typedef struct {
11 char *data;
12 int len;
13 } linemode_t;
14
15 static int linemode_on_read(void *client_data, int idx, char *data, int len)
16 {
17 linemode_t *old_data = client_data;
18 char *line, *stop, *save;
19 int linelen, savelen;
20
21 while (1) {
22 /* If there's a cr or lf, we have a line. */
23 stop = memchr(data, '\n', len);
24 if (!stop) {
25 stop = memchr(data, '\r', len);
26 if (!stop) {
27 /* No line, save the whole thing. */
28 save = data;
29 savelen = len;
30 break;
31 }
32 }
33
34 /* Save the cursor position for the next iteration. */
35 save = stop+1;
36 savelen = len - (save - data);
37
38 if (stop > data && *(stop-1) == '\r') stop--;
39 linelen = stop - data;
40 *stop = 0;
41
42 /* If there is buffered data, concat it all. */
43 if (old_data->len) {
44 /* Expand the buffer. */
45 old_data->data = (char *)realloc(old_data->data, old_data->len + linelen + 1);
46 memcpy(old_data->data+old_data->len, data, linelen + 1);
47
48 line = old_data->data;
49 linelen += old_data->len;
50
51 /* All the old data is used. */
52 old_data->len = 0;
53 }
54 else {
55 line = data;
56 }
57
58 sockbuf_on_read(idx, LINEMODE_LEVEL, line, linelen);
59
60 /* If we're out of data, we're done. */
61 if (savelen <= 0) return(0);
62 /* Otherwise, do this again to check for another line. */
63 data = save;
64 len = savelen;
65 }
66
67 /* No cr/lf, so we save the remaining data for next time. */
68 old_data->data = (char *)realloc(old_data->data, savelen + old_data->len + 1);
69 memcpy(old_data->data + old_data->len, save, savelen);
70 old_data->len += savelen;
71 return(0);
72 }
73
74 static int linemode_on_eof(void *client_data, int idx, int err, const char *errmsg)
75 {
76 linemode_t *old_data = client_data;
77 /* If there is any buffered data, do one more on->read callback. */
78 if (old_data->len) {
79 old_data->data[old_data->len] = 0;
80 sockbuf_on_read(idx, LINEMODE_LEVEL, old_data->data, old_data->len);
81 }
82
83 /* And now continue the eof event chain. */
84 return sockbuf_on_eof(idx, LINEMODE_LEVEL, err, errmsg);
85 }
86
87 static int linemode_on_delete(void *client_data, int idx)
88 {
89 linemode_t *old_data = client_data;
90 /* When the sockbuf is deleted, just kill the associated data. */
91 if (old_data->data) free(old_data->data);
92 free(old_data);
93 return(0);
94 }
95
96 static sockbuf_filter_t linemode_filter = {
97 "linemode",
98 LINEMODE_LEVEL,
99 NULL, linemode_on_eof, NULL,
100 linemode_on_read, NULL, NULL,
101 NULL, linemode_on_delete
102 };
103
104 int linemode_on(int idx)
105 {
106 linemode_t *old_data;
107
108 old_data = (linemode_t *)calloc(1, sizeof(*old_data));
109 sockbuf_attach_filter(idx, &linemode_filter, old_data);
110 return(0);
111 }
112
113 int linemode_off(int idx)
114 {
115 linemode_t *old_data;
116
117 sockbuf_detach_filter(idx, &linemode_filter, &old_data);
118 if (old_data) {
119 if (old_data->data) free(old_data->data);
120 free(old_data);
121 }
122 return(0);
123 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23