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)
197 packet_write_int(pkt, 0);
198 else if((unsigned long)data<0x100000)
200 packet_write_int(pkt, ~0);
201 packet_write_pointer(pkt, data);
205 GlOutPacket *out = &pkt->out;
207 packet_write_int(pkt, size);
209 out->vec->iov_base = (void *)data;
210 out->vec->iov_len = size;
213 out->vec->iov_base = out->ptr;
217 void packet_write_string(GlPacket *pkt, const char *s)
219 packet_write_data(pkt, s, strlen(s)+1);
222 void packet_write_string_array(GlPacket *pkt, const char **sa, unsigned size)
225 size /= sizeof(const char *);
226 packet_write_int(pkt, size);
227 for(i=0; i<size; ++i)
228 packet_write_string(pkt, sa[i]);
231 GlPacket *packet_receive_str(const char *data, unsigned *len)
233 const char *end = data+*len;
237 if(*len<sizeof(int)+sizeof(short))
245 packet_read_int(pkt, (int *)&in->chunk);
247 if(in->chunk&0x80000000)
249 in->chunk &= 0x7FFFFFFF;
250 in->length = in->chunk;
254 if(end<in->ptr+in->length+sizeof(int))
258 p.in.ptr = in->ptr+in->length;
259 p.in.chunk = p.in.length = end-p.in.ptr;
262 packet_read_int(&p, (int *)&chunk);
264 in->length += chunk&0x7FFFFFFF;
265 if(!(chunk&0x80000000))
270 in->length = in->chunk;
272 if(end<in->ptr+in->length)
275 *len = in->ptr+in->length-data;
280 GlPacket *packet_receive(int fd)
284 struct timeval tv = { 0, 0 };
288 ret = select(fd+1, &fds, NULL, NULL, &tv);
292 in_buffer = (char *)malloc(1024);
296 memmove(in_buffer, in_buffer+in_offset, in_fill-in_offset);
297 in_fill -= in_offset;
301 ret = read(fd, in_buffer+in_fill, 1024-in_fill);
306 if(ret>0 || in_fill>in_offset)
311 pkt_length = in_fill;
312 pkt = packet_receive_str(in_buffer+in_offset, &pkt_length);
314 in_offset += pkt_length;
322 static void next_chunk(GlPacket *pkt)
324 GlInPacket *in = &pkt->in;
329 in->chunk = in->length;
330 packet_read_int(pkt, (int *)&in->chunk);
331 in->chunk &= 0x7FFFFFFF;
334 static void read_raw(GlPacket *pkt, char *ptr, unsigned size, int byteswap)
336 GlInPacket *in = &pkt->in;
345 #if __BYTE_ORDER == __LITTLE_ENDIAN
349 for(i=0; i<size; ++i)
355 for(i=0; i<size; ++i)
364 memset(ptr, 0, size);
365 in->length -= in->chunk;
370 void packet_read_char(GlPacket *pkt, char *v)
372 read_raw(pkt, v, 1, 0);
375 void packet_read_short(GlPacket *pkt, short *v)
377 read_raw(pkt, (char *)v, sizeof(short), 1);
380 void packet_read_int(GlPacket *pkt, int *v)
382 read_raw(pkt, (char *)v, sizeof(int), 1);
385 void packet_read_long(GlPacket *pkt, long *v)
387 read_raw(pkt, (char *)v, sizeof(long), 1);
390 void packet_read_long_long(GlPacket *pkt, long long *v)
392 read_raw(pkt, (char *)v, sizeof(long long), 1);
395 void packet_read_float(GlPacket *pkt, float *v)
397 read_raw(pkt, (char *)v, sizeof(float), 1);
400 void packet_read_double(GlPacket *pkt, double *v)
402 read_raw(pkt, (char *)v, sizeof(double), 1);
405 void packet_read_pointer(GlPacket *pkt, const void **v)
407 read_raw(pkt, (char *)v, sizeof(const void *), 1);
410 void packet_read_data(GlPacket *pkt, const void **v)
412 GlInPacket *in = &pkt->in;
415 packet_read_int(pkt, &vlen);
417 packet_read_pointer(pkt, v);
429 void packet_read_string(GlPacket *pkt, const char **v)
431 packet_read_data(pkt, (const void **)v);
434 void packet_read_string_array(GlPacket *pkt, const char ***v)
438 packet_read_int(pkt, &count);
439 *v = (const char **)tmpalloc(count*sizeof(const char *));
440 for(i=0; i<count; ++i)
441 packet_read_string(pkt, *v+i);