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

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

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


Revision 1.3 - (hide annotations) (download) (as text)
Wed Jun 19 04:51:54 2002 UTC (17 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 stdarg 1.1 #include <stdio.h>
2     #include <stdlib.h>
3     #include <string.h>
4     #include <unistd.h>
5    
6     #include "sockbuf.h"
7    
8 stdarg 1.3 #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 stdarg 1.1 {
17 stdarg 1.3 linemode_t *old_data = client_data;
18     char *line, *stop, *save;
19     int linelen, savelen;
20 stdarg 1.1
21     while (1) {
22     /* If there's a cr or lf, we have a line. */
23 stdarg 1.3 stop = memchr(data, '\n', len);
24 stdarg 1.1 if (!stop) {
25 stdarg 1.3 stop = memchr(data, '\r', len);
26 stdarg 1.1 if (!stop) {
27     /* No line, save the whole thing. */
28     save = data;
29 stdarg 1.3 savelen = len;
30 stdarg 1.1 break;
31     }
32     }
33    
34 stdarg 1.3 /* Save the cursor position for the next iteration. */
35 stdarg 1.1 save = stop+1;
36 stdarg 1.3 savelen = len - (save - data);
37 stdarg 1.1
38 stdarg 1.3 if (stop > data && *(stop-1) == '\r') stop--;
39     linelen = stop - data;
40     *stop = 0;
41 stdarg 1.1
42     /* If there is buffered data, concat it all. */
43     if (old_data->len) {
44 stdarg 1.3 /* 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 stdarg 1.1
48     line = old_data->data;
49     linelen += old_data->len;
50    
51 stdarg 1.3 /* All the old data is used. */
52 stdarg 1.1 old_data->len = 0;
53     }
54     else {
55     line = data;
56     }
57    
58 stdarg 1.3 sockbuf_on_read(idx, LINEMODE_LEVEL, line, linelen);
59 stdarg 1.1
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 stdarg 1.3 len = savelen;
65 stdarg 1.1 }
66    
67     /* No cr/lf, so we save the remaining data for next time. */
68 stdarg 1.3 old_data->data = (char *)realloc(old_data->data, savelen + old_data->len + 1);
69     memcpy(old_data->data + old_data->len, save, savelen);
70 stdarg 1.1 old_data->len += savelen;
71     return(0);
72     }
73    
74 stdarg 1.3 static int linemode_on_eof(void *client_data, int idx, int err, const char *errmsg)
75 stdarg 1.1 {
76 stdarg 1.3 linemode_t *old_data = client_data;
77 stdarg 1.1 /* 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 stdarg 1.3 sockbuf_on_read(idx, LINEMODE_LEVEL, old_data->data, old_data->len);
81 stdarg 1.1 }
82    
83 stdarg 1.3 /* 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 stdarg 1.1 return(0);
94     }
95    
96 stdarg 1.3 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 stdarg 1.1 };
103    
104     int linemode_on(int idx)
105     {
106 stdarg 1.3 linemode_t *old_data;
107 stdarg 1.1
108 stdarg 1.3 old_data = (linemode_t *)calloc(1, sizeof(*old_data));
109     sockbuf_attach_filter(idx, &linemode_filter, old_data);
110 stdarg 1.1 return(0);
111     }
112    
113     int linemode_off(int idx)
114     {
115 stdarg 1.3 linemode_t *old_data;
116 stdarg 1.1
117 stdarg 1.3 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 stdarg 1.1 }
122     return(0);
123     }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23