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_length;
48 static void next_vec(GlPacket *pkt)
50 GlOutPacket *out = &pkt->out;
52 if(out->ptr!=out->vec->iov_base)
54 out->vec->iov_len = out->ptr-(char *)out->vec->iov_base;
55 out->length += out->vec->iov_len;
57 out->vec->iov_base = out->ptr;
61 static void reset(GlPacket *pkt)
63 GlOutPacket *out = &pkt->out;
65 out->ptr = out_buffer;
67 out->vec->iov_base = out->ptr;
71 GlPacket *packet_begin(unsigned short func)
76 out_buffer = (char *)malloc(1024);
78 iovecs = (struct iovec *)malloc(16*sizeof(struct iovec));
83 packet_write_int(pkt, 0);
84 packet_write_short(pkt, func);
89 void packet_send_partial(GlPacket *pkt, int fd)
91 GlOutPacket *out = &pkt->out;
93 out->length |= 0x80000000;
98 packet_write_int(pkt, 0);
101 void packet_send(GlPacket *pkt, int fd)
103 GlOutPacket *out = &pkt->out;
107 out->ptr = out_buffer;
108 packet_write_int(pkt, out->length);
110 for(v=iovecs; v!=out->vec; )
114 ret = writev(fd, v, out->vec-v);
118 while(v!=out->vec && (unsigned)ret>=v->iov_len)
132 static void write_raw(GlPacket *pkt, const char *ptr, unsigned size, int byteswap)
134 GlOutPacket *out = &pkt->out;
137 #if __BYTE_ORDER == __LITTLE_ENDIAN
141 for(i=0; i<size; ++i)
142 *out->ptr++ = *--ptr;
147 for(i=0; i<size; ++i)
148 *out->ptr++ = *ptr++;
152 void packet_write_char(GlPacket *pkt, char v)
154 GlOutPacket *out = &pkt->out;
158 void packet_write_short(GlPacket *pkt, short v)
160 write_raw(pkt, (char *)&v, sizeof(short), 1);
163 void packet_write_int(GlPacket *pkt, int v)
165 write_raw(pkt, (char *)&v, sizeof(int), 1);
168 void packet_write_long(GlPacket *pkt, long v)
170 write_raw(pkt, (char *)&v, sizeof(long), 1);
173 void packet_write_long_long(GlPacket *pkt, long long v)
175 write_raw(pkt, (char *)&v, sizeof(long long), 1);
178 void packet_write_float(GlPacket *pkt, float v)
180 write_raw(pkt, (char *)&v, sizeof(float), 1);
183 void packet_write_double(GlPacket *pkt, double v)
185 write_raw(pkt, (char *)&v, sizeof(double), 1);
188 void packet_write_pointer(GlPacket *pkt, const void *p)
190 write_raw(pkt, (char *)&p, sizeof(void *), 1);
193 void packet_write_data(GlPacket *pkt, const void *data, unsigned size)
197 GlOutPacket *out = &pkt->out;
199 packet_write_int(pkt, size);
201 out->vec->iov_base = (void *)data;
202 out->vec->iov_len = size;
205 out->vec->iov_base = out->ptr;
208 packet_write_int(pkt, 0);
211 void packet_write_string(GlPacket *pkt, const char *s)
213 packet_write_data(pkt, s, strlen(s)+1);
216 void packet_write_string_array(GlPacket *pkt, const char **sa, unsigned size)
219 size /= sizeof(const char *);
220 packet_write_int(pkt, size);
221 for(i=0; i<size; ++i)
222 packet_write_string(pkt, sa[i]);
225 GlPacket *packet_receive_str(const char *data, unsigned *len)
227 const char *end = data+*len;
231 if(*len<sizeof(int)+sizeof(short))
239 packet_read_int(pkt, (int *)&in->chunk);
241 if(in->chunk&0x80000000)
243 in->chunk &= 0x7FFFFFFF;
244 in->length = in->chunk;
248 if(end<in->ptr+in->length+sizeof(int))
252 p.in.ptr = in->ptr+in->length;
253 p.in.chunk = p.in.length = end-p.in.ptr;
256 packet_read_int(&p, (int *)&chunk);
258 in->length += chunk&0x7FFFFFFF;
259 if(!(chunk&0x80000000))
264 in->length = in->chunk;
266 if(end<in->ptr+in->length)
269 *len = in->ptr+in->length-data;
274 GlPacket *packet_receive(int fd)
278 struct timeval tv = { 0, 0 };
282 ret = select(fd+1, &fds, NULL, NULL, &tv);
286 in_buffer = (char *)malloc(1024);
288 ret = read(fd, in_buffer+in_length, 1024-in_length);
296 pkt_length = in_length;
297 pkt = packet_receive_str(in_buffer, &pkt_length);
300 in_length -= pkt_length;
301 memmove(in_buffer, in_buffer+pkt_length, in_length);
311 static void next_chunk(GlPacket *pkt)
313 GlInPacket *in = &pkt->in;
318 in->chunk = in->length;
319 packet_read_int(pkt, (int *)&in->chunk);
320 in->chunk &= 0x7FFFFFFF;
323 static void read_raw(GlPacket *pkt, char *ptr, unsigned size, int byteswap)
325 GlInPacket *in = &pkt->in;
334 #if __BYTE_ORDER == __LITTLE_ENDIAN
338 for(i=0; i<size; ++i)
344 for(i=0; i<size; ++i)
353 memset(ptr, 0, size);
354 in->length -= in->chunk;
359 void packet_read_char(GlPacket *pkt, char *v)
361 read_raw(pkt, v, 1, 0);
364 void packet_read_short(GlPacket *pkt, short *v)
366 read_raw(pkt, (char *)v, sizeof(short), 1);
369 void packet_read_int(GlPacket *pkt, int *v)
371 read_raw(pkt, (char *)v, sizeof(int), 1);
374 void packet_read_long(GlPacket *pkt, long *v)
376 read_raw(pkt, (char *)v, sizeof(long), 1);
379 void packet_read_long_long(GlPacket *pkt, long long *v)
381 read_raw(pkt, (char *)v, sizeof(long long), 1);
384 void packet_read_float(GlPacket *pkt, float *v)
386 read_raw(pkt, (char *)v, sizeof(float), 1);
389 void packet_read_double(GlPacket *pkt, double *v)
391 read_raw(pkt, (char *)v, sizeof(double), 1);
394 void packet_read_pointer(GlPacket *pkt, const void **v)
396 read_raw(pkt, (char *)v, sizeof(const void *), 1);
399 void packet_read_data(GlPacket *pkt, const void **v)
401 GlInPacket *in = &pkt->in;
404 packet_read_int(pkt, &vlen);
414 void packet_read_string(GlPacket *pkt, const char **v)
416 packet_read_data(pkt, (const void **)v);
419 void packet_read_string_array(GlPacket *pkt, const char ***v)
423 packet_read_int(pkt, &count);
424 *v = (const char **)tmpalloc(count*sizeof(const char *));
425 for(i=0; i<count; ++i)
426 packet_read_string(pkt, *v+i);