3 This file is part of gldbg
4 Copyright © 2010 Mikko Rasa, Mikkosoft Productions
5 Distributed under the GPL
29 typedef struct GlOutPacket GlOutPacket;
30 typedef struct GlInPacket GlInPacket;
41 // XXX Should make this stuff truly re-entrant
42 static char *out_buffer = NULL;
43 static struct iovec *iovecs = NULL;
44 static GlPacket packet;
45 static char *in_buffer = NULL;
46 static unsigned in_fill = 0;
47 static unsigned in_offset = 0;
49 static void next_vec(GlPacket *pkt)
51 GlOutPacket *out = &pkt->out;
53 if(out->ptr!=out->vec->iov_base)
55 out->vec->iov_len = out->ptr-(char *)out->vec->iov_base;
56 out->length += out->vec->iov_len;
58 out->vec->iov_base = out->ptr;
62 static void reset(GlPacket *pkt)
64 GlOutPacket *out = &pkt->out;
66 out->ptr = out_buffer;
68 out->vec->iov_base = out->ptr;
72 GlPacket *packet_begin(unsigned short func)
77 out_buffer = (char *)malloc(1024);
79 iovecs = (struct iovec *)malloc(16*sizeof(struct iovec));
84 packet_write_int(pkt, 0);
85 packet_write_short(pkt, func);
90 void packet_send_partial(GlPacket *pkt, int fd)
92 GlOutPacket *out = &pkt->out;
94 out->length |= 0x80000000;
99 packet_write_int(pkt, 0);
102 void packet_send(GlPacket *pkt, int fd)
104 GlOutPacket *out = &pkt->out;
108 out->ptr = out_buffer;
109 packet_write_int(pkt, out->length);
111 for(v=iovecs; v!=out->vec; )
115 ret = writev(fd, v, out->vec-v);
119 while(v!=out->vec && (unsigned)ret>=v->iov_len)
133 static void write_raw(GlPacket *pkt, const char *ptr, unsigned size, int byteswap)
135 GlOutPacket *out = &pkt->out;
138 #if __BYTE_ORDER == __LITTLE_ENDIAN
142 for(i=0; i<size; ++i)
143 *out->ptr++ = *--ptr;
148 for(i=0; i<size; ++i)
149 *out->ptr++ = *ptr++;
153 void packet_write_char(GlPacket *pkt, char v)
155 GlOutPacket *out = &pkt->out;
159 void packet_write_short(GlPacket *pkt, short v)
161 write_raw(pkt, (char *)&v, sizeof(short), 1);
164 void packet_write_int(GlPacket *pkt, int v)
166 write_raw(pkt, (char *)&v, sizeof(int), 1);
169 void packet_write_long(GlPacket *pkt, long v)
171 write_raw(pkt, (char *)&v, sizeof(long), 1);
174 void packet_write_long_long(GlPacket *pkt, long long v)
176 write_raw(pkt, (char *)&v, sizeof(long long), 1);
179 void packet_write_float(GlPacket *pkt, float v)
181 write_raw(pkt, (char *)&v, sizeof(float), 1);
184 void packet_write_double(GlPacket *pkt, double v)
186 write_raw(pkt, (char *)&v, sizeof(double), 1);
189 void packet_write_pointer(GlPacket *pkt, const void *p)
191 write_raw(pkt, (char *)&p, sizeof(void *), 1);
194 void packet_write_data(GlPacket *pkt, const void *data, unsigned size)
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;
209 packet_write_int(pkt, 0);
212 void packet_write_string(GlPacket *pkt, const char *s)
214 packet_write_data(pkt, s, strlen(s)+1);
217 void packet_write_string_array(GlPacket *pkt, const char **sa, unsigned size)
220 size /= sizeof(const char *);
221 packet_write_int(pkt, size);
222 for(i=0; i<size; ++i)
223 packet_write_string(pkt, sa[i]);
226 GlPacket *packet_receive_str(const char *data, unsigned *len)
228 const char *end = data+*len;
232 if(*len<sizeof(int)+sizeof(short))
240 packet_read_int(pkt, (int *)&in->chunk);
242 if(in->chunk&0x80000000)
244 in->chunk &= 0x7FFFFFFF;
245 in->length = in->chunk;
249 if(end<in->ptr+in->length+sizeof(int))
253 p.in.ptr = in->ptr+in->length;
254 p.in.chunk = p.in.length = end-p.in.ptr;
257 packet_read_int(&p, (int *)&chunk);
259 in->length += chunk&0x7FFFFFFF;
260 if(!(chunk&0x80000000))
265 in->length = in->chunk;
267 if(end<in->ptr+in->length)
270 *len = in->ptr+in->length-data;
275 GlPacket *packet_receive(int fd)
279 struct timeval tv = { 0, 0 };
283 ret = select(fd+1, &fds, NULL, NULL, &tv);
287 in_buffer = (char *)malloc(1024);
291 memmove(in_buffer, in_buffer+in_offset, in_fill-in_offset);
292 in_fill -= in_offset;
296 ret = read(fd, in_buffer+in_fill, 1024-in_fill);
301 if(ret>0 || in_fill>in_offset)
306 pkt_length = in_fill;
307 pkt = packet_receive_str(in_buffer+in_offset, &pkt_length);
309 in_offset += pkt_length;
317 static void next_chunk(GlPacket *pkt)
319 GlInPacket *in = &pkt->in;
324 in->chunk = in->length;
325 packet_read_int(pkt, (int *)&in->chunk);
326 in->chunk &= 0x7FFFFFFF;
329 static void read_raw(GlPacket *pkt, char *ptr, unsigned size, int byteswap)
331 GlInPacket *in = &pkt->in;
340 #if __BYTE_ORDER == __LITTLE_ENDIAN
344 for(i=0; i<size; ++i)
350 for(i=0; i<size; ++i)
359 memset(ptr, 0, size);
360 in->length -= in->chunk;
365 void packet_read_char(GlPacket *pkt, char *v)
367 read_raw(pkt, v, 1, 0);
370 void packet_read_short(GlPacket *pkt, short *v)
372 read_raw(pkt, (char *)v, sizeof(short), 1);
375 void packet_read_int(GlPacket *pkt, int *v)
377 read_raw(pkt, (char *)v, sizeof(int), 1);
380 void packet_read_long(GlPacket *pkt, long *v)
382 read_raw(pkt, (char *)v, sizeof(long), 1);
385 void packet_read_long_long(GlPacket *pkt, long long *v)
387 read_raw(pkt, (char *)v, sizeof(long long), 1);
390 void packet_read_float(GlPacket *pkt, float *v)
392 read_raw(pkt, (char *)v, sizeof(float), 1);
395 void packet_read_double(GlPacket *pkt, double *v)
397 read_raw(pkt, (char *)v, sizeof(double), 1);
400 void packet_read_pointer(GlPacket *pkt, const void **v)
402 read_raw(pkt, (char *)v, sizeof(const void *), 1);
405 void packet_read_data(GlPacket *pkt, const void **v)
407 GlInPacket *in = &pkt->in;
410 packet_read_int(pkt, &vlen);
420 void packet_read_string(GlPacket *pkt, const char **v)
422 packet_read_data(pkt, (const void **)v);
425 void packet_read_string_array(GlPacket *pkt, const char ***v)
429 packet_read_int(pkt, &count);
430 *v = (const char **)tmpalloc(count*sizeof(const char *));
431 for(i=0; i<count; ++i)
432 packet_read_string(pkt, *v+i);