]> git.pond.sub.org Git - empserver/blob - src/client/ioqueue.c
COPYING duplicates information from README. Remove. Move GPL from
[empserver] / src / client / ioqueue.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2006, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                           Ken Stevens, Steve McClure
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  ---
21  *
22  *  See files README, COPYING and CREDITS in the root of the source
23  *  tree for related information and legal notices.  It is expected
24  *  that future projects/authors will amend these files as needed.
25  *
26  *  ---
27  *
28  *  ioqueue.c: Manage an i/o queue
29  * 
30  *  Known contributors to this file:
31  *     Steve McClure, 1998
32  */
33
34 #include <config.h>
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sys/types.h>
40 #include "misc.h"
41 #include "queue.h"
42 #include "ioqueue.h"
43
44 static int ioqtobuf(struct ioqueue *ioq, char *buf, int cc);
45 static void enqueuecc(struct ioqueue *ioq, char *buf, int cc);
46 static int dequeuecc(struct ioqueue *ioq, int cc);
47
48
49 void
50 ioq_init(struct ioqueue *ioq, int bsize)
51 {
52     initque(&ioq->queue);
53     ioq->cc = 0;
54     ioq->bsize = bsize;
55     *num_teles = '\0';
56 }
57
58 /*
59  * Copy the specified number of characters into the buffer
60  * provided, without actually dequeueing the data.  Return
61  * number of bytes actually found.
62  */
63 int
64 ioq_peek(struct ioqueue *ioq, char *buf, int cc)
65 {
66     return ioqtobuf(ioq, buf, cc);
67 }
68
69 int
70 ioq_dequeue(struct ioqueue *ioq, int cc)
71 {
72     if (dequeuecc(ioq, cc) != cc)
73         return 0;
74     return cc;
75 }
76
77 int
78 ioq_read(struct ioqueue *ioq, char *buf, int cc)
79 {
80     int n;
81
82     n = ioqtobuf(ioq, buf, cc);
83     if (n > 0)
84         dequeuecc(ioq, n);
85     return n;
86 }
87
88 void
89 ioq_write(struct ioqueue *ioq, char *buf, int cc)
90 {
91     enqueuecc(ioq, buf, cc);
92 }
93
94 int
95 ioq_qsize(struct ioqueue *ioq)
96 {
97     return ioq->cc;
98 }
99
100 void
101 ioq_drain(struct ioqueue *ioq)
102 {
103     struct io *io;
104     struct qelem *qp;
105
106     while ((qp = ioq->queue.q_forw) != &ioq->queue) {
107         io = (struct io *)qp;
108         free(io->data);
109         (void)remque(&io->queue);
110         (void)free(io);
111     }
112     ioq->cc = 0;
113 }
114
115 char *
116 ioq_gets(struct ioqueue *ioq, char *buf, int cc, int *eol)
117 {
118     char *p;
119     char *end;
120     int nbytes;
121
122     *eol = 0;
123
124     cc--;
125
126     nbytes = ioqtobuf(ioq, buf, cc);
127     end = &buf[nbytes];
128     for (p = buf; p < end && *p; p++) {
129         if (*p == '\n') {
130             *++p = '\0';
131             *eol = 1;
132             dequeuecc(ioq, p - buf);
133             return buf;
134         }
135     }
136     if (cc && (p - buf) == cc) {
137         dequeuecc(ioq, cc);
138         buf[cc] = '\0';
139         return buf;
140     }
141     return NULL;
142 }
143
144 /*
145  * all the rest are local to this module
146  */
147
148
149 /*
150  * copy cc bytes from ioq to buf.
151  * this routine doesn't free memory; this is
152  * left for a higher level.
153  */
154 static int
155 ioqtobuf(struct ioqueue *ioq, char *buf, int cc)
156 {
157     struct io *io;
158     struct qelem *qp;
159     char *offset;
160     int nbytes;
161     int nleft;
162
163     nleft = cc;
164     offset = buf;
165     for (qp = ioq->queue.q_forw; qp != &ioq->queue; qp = qp->q_forw) {
166         io = (struct io *)qp;
167         if ((nbytes = io->nbytes - io->offset) < 0) {
168             fprintf(stderr, "ioqtobuf: offset %d nbytes %d\n",
169                     io->offset, io->nbytes);
170             continue;
171         }
172         if (nbytes > 0) {
173             if (nleft < nbytes)
174                 nbytes = nleft;
175             memcpy(offset, io->data + io->offset, nbytes);
176             offset += nbytes;
177             nleft -= nbytes;
178         }
179     }
180     return offset - buf;
181 }
182
183 /*
184  * append a buffer to the end of the ioq.
185  */
186 static void
187 enqueuecc(struct ioqueue *ioq, char *buf, int cc)
188 {
189     struct io *io;
190
191     io = malloc(sizeof(*io));
192     io->nbytes = cc;
193     io->offset = 0;
194     io->data = buf;
195     insque(&io->queue, ioq->queue.q_back);
196     ioq->cc += cc;
197 }
198
199 /*
200  * remove cc bytes from ioqueue ioq
201  * free memory, dequeue io elements
202  * which are no longer used.
203  */
204 static int
205 dequeuecc(struct ioqueue *ioq, int cc)
206 {
207     struct io *io;
208     struct qelem *qp;
209     int nbytes;
210     int there;
211
212     nbytes = 0;
213     while ((qp = ioq->queue.q_forw) != &ioq->queue) {
214         io = (struct io *)qp;
215         there = io->nbytes - io->offset;
216         if (there < 0) {
217             fprintf(stderr, "dequeuecc: nbytes %d, offset %d\n",
218                     io->nbytes, io->offset);
219             continue;
220         }
221         if (cc > there) {
222             cc -= there;
223             nbytes += there;
224             (void)remque(&io->queue);
225             free(io->data);
226         } else {
227             io->offset += cc;
228             nbytes += cc;
229             break;
230         }
231     }
232     ioq->cc -= nbytes;
233     return nbytes;
234 }