22 typedef struct GlOutPacket GlOutPacket;
23 typedef struct GlInPacket GlInPacket;
34 // XXX Should make this stuff truly re-entrant
35 static char *out_buffer = NULL;
36 static struct iovec *iovecs = NULL;
37 static GlPacket packet;
38 static char *in_buffer = NULL;
39 static unsigned in_fill = 0;
40 static unsigned in_offset = 0;
42 static void next_vec(GlPacket *pkt)
44 GlOutPacket *out = &pkt->out;
46 if(out->ptr!=out->vec->iov_base)
48 out->vec->iov_len = out->ptr-(char *)out->vec->iov_base;
49 out->length += out->vec->iov_len;
51 out->vec->iov_base = out->ptr;
55 static void reset(GlPacket *pkt)
57 GlOutPacket *out = &pkt->out;
59 out->ptr = out_buffer;
61 out->vec->iov_base = out->ptr;
65 GlPacket *packet_begin(unsigned short func)
70 out_buffer = (char *)malloc(1024);
72 iovecs = (struct iovec *)malloc(16*sizeof(struct iovec));
77 packet_write_int(pkt, 0);
78 packet_write_short(pkt, func);
83 void packet_send_partial(GlPacket *pkt, int fd)
85 GlOutPacket *out = &pkt->out;
87 out->length |= 0x80000000;
92 packet_write_int(pkt, 0);
95 void packet_send(GlPacket *pkt, int fd)
97 GlOutPacket *out = &pkt->out;
101 out->ptr = out_buffer;
102 packet_write_int(pkt, out->length);
104 for(v=iovecs; v!=out->vec; )
108 ret = writev(fd, v, out->vec-v);
112 while(v!=out->vec && (unsigned)ret>=v->iov_len)
126 static void write_raw(GlPacket *pkt, const char *ptr, unsigned size, int byteswap)
128 GlOutPacket *out = &pkt->out;
131 #if __BYTE_ORDER == __LITTLE_ENDIAN
135 for(i=0; i<size; ++i)
136 *out->ptr++ = *--ptr;
141 for(i=0; i<size; ++i)
142 *out->ptr++ = *ptr++;
146 void packet_write_char(GlPacket *pkt, char v)
148 GlOutPacket *out = &pkt->out;
152 void packet_write_short(GlPacket *pkt, short v)
154 write_raw(pkt, (char *)&v, sizeof(short), 1);
157 void packet_write_int(GlPacket *pkt, int v)
159 write_raw(pkt, (char *)&v, sizeof(int), 1);
162 void packet_write_long(GlPacket *pkt, long v)
164 write_raw(pkt, (char *)&v, sizeof(long), 1);
167 void packet_write_long_long(GlPacket *pkt, long long v)
169 write_raw(pkt, (char *)&v, sizeof(long long), 1);
172 void packet_write_float(GlPacket *pkt, float v)
174 write_raw(pkt, (char *)&v, sizeof(float), 1);
177 void packet_write_double(GlPacket *pkt, double v)
179 write_raw(pkt, (char *)&v, sizeof(double), 1);
182 void packet_write_pointer(GlPacket *pkt, const void *p)
184 write_raw(pkt, (char *)&p, sizeof(void *), 1);
187 void packet_write_data(GlPacket *pkt, const void *data, unsigned size)
190 packet_write_int(pkt, 0);
191 else if((unsigned long)data<0x100000)
193 packet_write_int(pkt, ~0);
194 packet_write_pointer(pkt, data);
198 GlOutPacket *out = &pkt->out;
200 packet_write_int(pkt, size);
202 out->vec->iov_base = (void *)data;
203 out->vec->iov_len = size;
206 out->vec->iov_base = out->ptr;
210 void packet_write_string(GlPacket *pkt, const char *s)
212 packet_write_data(pkt, s, strlen(s)+1);
215 void packet_write_string_array(GlPacket *pkt, const char **sa, unsigned size)
218 size /= sizeof(const char *);
219 packet_write_int(pkt, size);
220 for(i=0; i<size; ++i)
221 packet_write_string(pkt, sa[i]);
224 GlPacket *packet_receive_str(const char *data, unsigned *len)
226 const char *end = data+*len;
230 if(*len<sizeof(int)+sizeof(short))
238 packet_read_int(pkt, (int *)&in->chunk);
240 if(in->chunk&0x80000000)
242 in->chunk &= 0x7FFFFFFF;
243 in->length = in->chunk;
247 if(end<in->ptr+in->length+sizeof(int))
251 p.in.ptr = in->ptr+in->length;
252 p.in.chunk = p.in.length = end-p.in.ptr;
255 packet_read_int(&p, (int *)&chunk);
257 in->length += chunk&0x7FFFFFFF;
258 if(!(chunk&0x80000000))
263 in->length = in->chunk;
265 if(end<in->ptr+in->length)
268 *len = in->ptr+in->length-data;
273 GlPacket *packet_receive(int fd)
277 struct timeval tv = { 0, 0 };
281 ret = select(fd+1, &fds, NULL, NULL, &tv);
285 in_buffer = (char *)malloc(1024);
289 memmove(in_buffer, in_buffer+in_offset, in_fill-in_offset);
290 in_fill -= in_offset;
294 ret = read(fd, in_buffer+in_fill, 1024-in_fill);
299 if(ret>0 || in_fill>in_offset)
304 pkt_length = in_fill;
305 pkt = packet_receive_str(in_buffer+in_offset, &pkt_length);
307 in_offset += pkt_length;
315 static void next_chunk(GlPacket *pkt)
317 GlInPacket *in = &pkt->in;
322 in->chunk = in->length;
323 packet_read_int(pkt, (int *)&in->chunk);
324 in->chunk &= 0x7FFFFFFF;
327 static void read_raw(GlPacket *pkt, char *ptr, unsigned size, int byteswap)
329 GlInPacket *in = &pkt->in;
338 #if __BYTE_ORDER == __LITTLE_ENDIAN
342 for(i=0; i<size; ++i)
348 for(i=0; i<size; ++i)
357 memset(ptr, 0, size);
358 in->length -= in->chunk;
363 void packet_read_char(GlPacket *pkt, char *v)
365 read_raw(pkt, v, 1, 0);
368 void packet_read_short(GlPacket *pkt, short *v)
370 read_raw(pkt, (char *)v, sizeof(short), 1);
373 void packet_read_int(GlPacket *pkt, int *v)
375 read_raw(pkt, (char *)v, sizeof(int), 1);
378 void packet_read_long(GlPacket *pkt, long *v)
380 read_raw(pkt, (char *)v, sizeof(long), 1);
383 void packet_read_long_long(GlPacket *pkt, long long *v)
385 read_raw(pkt, (char *)v, sizeof(long long), 1);
388 void packet_read_float(GlPacket *pkt, float *v)
390 read_raw(pkt, (char *)v, sizeof(float), 1);
393 void packet_read_double(GlPacket *pkt, double *v)
395 read_raw(pkt, (char *)v, sizeof(double), 1);
398 void packet_read_pointer(GlPacket *pkt, const void **v)
400 read_raw(pkt, (char *)v, sizeof(const void *), 1);
403 void packet_read_data(GlPacket *pkt, const void **v)
405 GlInPacket *in = &pkt->in;
408 packet_read_int(pkt, &vlen);
410 packet_read_pointer(pkt, v);
422 void packet_read_string(GlPacket *pkt, const char **v)
424 packet_read_data(pkt, (const void **)v);
427 void packet_read_string_array(GlPacket *pkt, const char ***v)
431 packet_read_int(pkt, &count);
432 *v = (const char **)tmpalloc(count*sizeof(const char *));
433 for(i=0; i<count; ++i)
434 packet_read_string(pkt, *v+i);