3 This file is part of gldbg
4 Copyright © 2010 Mikko Rasa, Mikkosoft Productions
5 Distributed under the GPL
28 typedef struct GlOutPacket GlOutPacket;
29 typedef struct GlInPacket GlInPacket;
40 // XXX Should make this stuff truly re-entrant
41 static char *out_buffer = 0;
42 static struct iovec *iovecs = 0;
43 static GlPacket packet;
44 /*static char *in_buffer = 0;
45 static unsigned in_length;*/
47 static void next_vec(GlPacket *pkt)
49 GlOutPacket *out = &pkt->out;
51 if(out->ptr!=out->vec->iov_base)
53 out->vec->iov_len = out->ptr-(char *)out->vec->iov_base;
54 out->length += out->vec->iov_len;
56 out->vec->iov_base = out->ptr;
60 static void reset(GlPacket *pkt)
62 GlOutPacket *out = &pkt->out;
64 out->ptr = out_buffer;
66 out->vec->iov_base = out->ptr;
70 GlPacket *packet_begin(unsigned short func)
75 out_buffer = (char *)malloc(1024);
77 iovecs = (struct iovec *)malloc(16*sizeof(struct iovec));
82 packet_write_int(pkt, 0);
83 packet_write_short(pkt, func);
88 void packet_send_partial(GlPacket *pkt, int fd)
90 GlOutPacket *out = &pkt->out;
92 out->length |= 0x80000000;
97 packet_write_int(pkt, 0);
100 void packet_send(GlPacket *pkt, int fd)
102 GlOutPacket *out = &pkt->out;
106 out->ptr = out_buffer;
107 packet_write_int(pkt, out->length);
109 for(v=iovecs; v!=out->vec; )
113 ret = writev(fd, v, out->vec-v);
117 while(v!=out->vec && (unsigned)ret>=v->iov_len)
131 static void write_raw(GlPacket *pkt, const char *ptr, unsigned size, int byteswap)
133 GlOutPacket *out = &pkt->out;
136 #if __BYTE_ORDER == __LITTLE_ENDIAN
140 for(i=0; i<size; ++i)
141 *out->ptr++ = *--ptr;
146 for(i=0; i<size; ++i)
147 *out->ptr++ = *ptr++;
151 void packet_write_char(GlPacket *pkt, char v)
153 GlOutPacket *out = &pkt->out;
157 void packet_write_short(GlPacket *pkt, short v)
159 write_raw(pkt, (char *)&v, sizeof(short), 1);
162 void packet_write_int(GlPacket *pkt, int v)
164 write_raw(pkt, (char *)&v, sizeof(int), 1);
167 void packet_write_long(GlPacket *pkt, long v)
169 write_raw(pkt, (char *)&v, sizeof(long), 1);
172 void packet_write_long_long(GlPacket *pkt, long long v)
174 write_raw(pkt, (char *)&v, sizeof(long long), 1);
177 void packet_write_float(GlPacket *pkt, float v)
179 write_raw(pkt, (char *)&v, sizeof(float), 1);
182 void packet_write_double(GlPacket *pkt, double v)
184 write_raw(pkt, (char *)&v, sizeof(double), 1);
187 void packet_write_pointer(GlPacket *pkt, const void *p)
189 write_raw(pkt, (char *)&p, sizeof(void *), 1);
192 void packet_write_data(GlPacket *pkt, const void *data, unsigned size)
196 GlOutPacket *out = &pkt->out;
198 packet_write_int(pkt, size);
200 out->vec->iov_base = (void *)data;
201 out->vec->iov_len = size;
204 out->vec->iov_base = out->ptr;
207 packet_write_int(pkt, 0);
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 static void next_chunk(GlPacket *pkt)
275 GlInPacket *in = &pkt->in;
280 in->chunk = in->length;
281 packet_read_int(pkt, (int *)&in->chunk);
282 in->chunk &= 0x7FFFFFFF;
285 static void read_raw(GlPacket *pkt, char *ptr, unsigned size, int byteswap)
287 GlInPacket *in = &pkt->in;
296 #if __BYTE_ORDER == __LITTLE_ENDIAN
300 for(i=0; i<size; ++i)
306 for(i=0; i<size; ++i)
315 memset(ptr, 0, size);
316 in->length -= in->chunk;
321 void packet_read_char(GlPacket *pkt, char *v)
323 read_raw(pkt, v, 1, 0);
326 void packet_read_short(GlPacket *pkt, short *v)
328 read_raw(pkt, (char *)v, sizeof(short), 1);
331 void packet_read_int(GlPacket *pkt, int *v)
333 read_raw(pkt, (char *)v, sizeof(int), 1);
336 void packet_read_long(GlPacket *pkt, long *v)
338 read_raw(pkt, (char *)v, sizeof(long), 1);
341 void packet_read_long_long(GlPacket *pkt, long long *v)
343 read_raw(pkt, (char *)v, sizeof(long long), 1);
346 void packet_read_float(GlPacket *pkt, float *v)
348 read_raw(pkt, (char *)v, sizeof(float), 1);
351 void packet_read_double(GlPacket *pkt, double *v)
353 read_raw(pkt, (char *)v, sizeof(double), 1);
356 void packet_read_pointer(GlPacket *pkt, pointer *v)
358 read_raw(pkt, (char *)v, sizeof(pointer), 1);
361 void packet_read_data(GlPacket *pkt, pointer *v)
363 GlInPacket *in = &pkt->in;
366 packet_read_int(pkt, &vlen);
376 void packet_read_string(GlPacket *pkt, string *v)
378 packet_read_data(pkt, (pointer *)v);
381 void packet_read_string_array(GlPacket *pkt, string **v)
385 packet_read_int(pkt, &count);
386 *v = (string *)tmpalloc(count*sizeof(string));
387 for(i=0; i<count; ++i)
388 packet_read_string(pkt, *v+i);