From: Mikko Rasa Date: Thu, 18 Nov 2010 13:39:42 +0000 (+0000) Subject: Use a centralized packet framework X-Git-Url: http://git.tdb.fi/?p=gldbg.git;a=commitdiff_plain;h=fab9ed5163a8f4ef5314bc67e48d1690d1126649 Use a centralized packet framework Use a linker script to hide all unnecessary symbols from glwrap.so --- diff --git a/Makefile b/Makefile index af82389..3679ee7 100644 --- a/Makefile +++ b/Makefile @@ -17,10 +17,13 @@ SOURCES_libgldbg := source/gldecoder.c \ source/glprint.c \ source/enums.c \ source/arraysize.c \ - source/tmpalloc.c + source/tmpalloc.c \ + source/packet.c SOURCES_glwrap := source/glwrap.c \ source/glwrap_funcs.c \ - source/arraysize.c + source/arraysize.c \ + source/packet.c \ + source/tmpalloc.c SOURCES_gldump := source/gldump.c SOURCES_gldbg := source/gldbg.cpp \ source/commandinterpreter.cpp \ @@ -65,8 +68,9 @@ DEPS_all := $(call deps,$(SOURCES_all) $(TEMPLATES)) $(OBJECTS_gldbg): CXXFLAGS += $(shell pkg-config --cflags $(PACKAGES_gldbg)) gldbg: LIBS += $(shell pkg-config --libs $(PACKAGES_gldbg)) -lreadline gldump gldbg: LIBS += ./libgldbg.a +glwrap.so: LDFLAGS += -s -glwrap.so: $(OBJECTS_glwrap) +glwrap.so: $(OBJECTS_glwrap) glwrap.ld $(CC) -shared -o $@ $^ $(LIBS) $(LDFLAGS) gldump: $(OBJECTS_gldump) libgldbg.a diff --git a/flavors/gl/source/glwrap_funcs.c b/flavors/gl/source/glwrap_funcs.c index 7fc5adf..38621f3 100644 --- a/flavors/gl/source/glwrap_funcs.c +++ b/flavors/gl/source/glwrap_funcs.c @@ -10,13 +10,14 @@ Distributed under the GPL #include "functions.h" #include "glwrap.h" #include "opengl.h" +#include "packet.h" -int in_begin_block = 0; -GLenum cur_error = GL_NO_ERROR; +static int in_begin_block = 0; +static GLenum cur_error = GL_NO_ERROR; static void check_error() { - GLenum (*orig_glGetError)() = 0; + static GLenum (*orig_glGetError)() = NULL; GLenum code; if(in_begin_block) @@ -28,9 +29,11 @@ static void check_error() code = orig_glGetError(); if(code!=GL_NO_ERROR) { - begin_packet(FUNC_GLDERROR); - write_int(code); - send_packet(); + GlPacket *pkt; + + pkt = packet_begin(FUNC_GLDERROR); + packet_write_int(pkt, code); + packet_send(pkt, get_out_fd()); if(cur_error==GL_NO_ERROR) cur_error = code; @@ -39,27 +42,31 @@ static void check_error() void APIENTRY glBegin(GLenum mode) { - static void (*orig)(GLenum); + static void (*orig)(GLenum) = NULL; + GlPacket *pkt; + if(!orig) orig = glsym("glBegin"); orig(mode); - begin_packet(FUNC_GLBEGIN); - write_int(mode); - send_packet(); + pkt = packet_begin(FUNC_GLBEGIN); + packet_write_int(pkt, mode); + packet_send(pkt, get_out_fd()); in_begin_block = 1; } void APIENTRY glEnd() { - static void (*orig)(); + static void (*orig)() = NULL; + GlPacket *pkt; + if(!orig) orig = glsym("glEnd"); orig(); - begin_packet(FUNC_GLEND); - send_packet(); + pkt = packet_begin(FUNC_GLEND); + packet_send(pkt, get_out_fd()); in_begin_block = 0; check_error(); @@ -68,6 +75,7 @@ void APIENTRY glEnd() GLenum APIENTRY glGetError() { GLenum ret = GL_NO_ERROR; + GlPacket *pkt; if(in_begin_block) { @@ -80,9 +88,9 @@ GLenum APIENTRY glGetError() cur_error = GL_NO_ERROR; } - begin_packet(FUNC_GLGETERROR); - write_int(ret); - send_packet(); + pkt = packet_begin(FUNC_GLGETERROR); + packet_write_int(pkt, ret); + packet_send(pkt, get_out_fd()); return ret; } @@ -91,6 +99,7 @@ void (*glXGetProcAddress(const GLubyte *procname))(void) { void *handle = 0; void (*ret)() = 0; + GlPacket *pkt; if(glsym((const char *)procname)) { @@ -98,10 +107,10 @@ void (*glXGetProcAddress(const GLubyte *procname))(void) ret = dlsym(handle, (const char *)procname); } - begin_packet(FUNC_GLXGETPROCADDRESS); - write_string((const char *)procname); - write_pointer(ret); - send_packet(); + pkt = packet_begin(FUNC_GLXGETPROCADDRESS); + packet_write_string(pkt, (const char *)procname); + packet_write_pointer(pkt, ret); + packet_send(pkt, get_out_fd()); return ret; } diff --git a/flavors/gles2/source/glwrap_funcs.c b/flavors/gles2/source/glwrap_funcs.c index c647753..e4f457a 100644 --- a/flavors/gles2/source/glwrap_funcs.c +++ b/flavors/gles2/source/glwrap_funcs.c @@ -10,12 +10,13 @@ Distributed under the GPL #include "functions.h" #include "glwrap.h" #include "opengl.h" +#include "packet.h" GLenum cur_error = GL_NO_ERROR; static void check_error() { - GLenum (*orig_glGetError)() = 0; + GLenum (*orig_glGetError)() = NULL; GLenum code; if(!orig_glGetError) @@ -24,9 +25,11 @@ static void check_error() code = orig_glGetError(); if(code!=GL_NO_ERROR) { - begin_packet(FUNC_GLDERROR); - write_int(code); - send_packet(); + GlPacket *pkt; + + pkt = packet_begin(FUNC_GLDERROR); + packet_write_int(pkt, code); + packet_send(pkt, get_out_fd()); if(cur_error==GL_NO_ERROR) cur_error = code; @@ -37,18 +40,20 @@ GLenum APIENTRY glGetError() { GLenum ret = cur_error; cur_error = GL_NO_ERROR; + GlPacket *pkt; - begin_packet(FUNC_GLGETERROR); - write_int(ret); - send_packet(); + pkt = packet_begin(FUNC_GLGETERROR); + packet_write_int(pkt, ret); + packet_send(pkt, get_out_fd()); return ret; } void (*eglGetProcAddress(const char *procname))(void) { - void *handle = 0; - void (*ret)() = 0; + void *handle = NULL; + void (*ret)() = NULL; + GlPacket *pkt; if(glsym((const char *)procname)) { @@ -56,10 +61,10 @@ void (*eglGetProcAddress(const char *procname))(void) ret = dlsym(handle, (const char *)procname); } - begin_packet(FUNC_EGLGETPROCADDRESS); - write_pointer(ret); - write_string((const char *)procname); - send_packet(); + pkt = packet_begin(FUNC_EGLGETPROCADDRESS); + packet_write_pointer(pkt, ret); + packet_write_string(pkt, (const char *)procname); + packet_send(pkt, get_out_fd()); return ret; } diff --git a/glwrap.ld b/glwrap.ld new file mode 100644 index 0000000..15afadc --- /dev/null +++ b/glwrap.ld @@ -0,0 +1,11 @@ +/* $Id$ */ + +VERSION +{ + { + global: + gl*; + local: + *; + }; +} diff --git a/source/gldecoder.c b/source/gldecoder.c index 6444fca..999accc 100644 --- a/source/gldecoder.c +++ b/source/gldecoder.c @@ -1,7 +1,7 @@ /* $Id$ This file is part of gldbg -Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions Distributed under the GPL */ @@ -9,17 +9,8 @@ Distributed under the GPL #include #include "functions.h" #include "gldecoder.h" -#include "tmpalloc.h" +#include "packet.h" -typedef struct sGlPacket -{ - const char *ptr; - unsigned chunk; - unsigned total; -} GlPacket; - -static void read_short(short *, GlPacket *); -static void read_int(int *, GlPacket *); static int decode_func(GlDecoder *, unsigned short, GlPacket *); static int decode_gldfunc(GlDecoder *, unsigned short, GlPacket *); @@ -44,158 +35,28 @@ void gldecoder_delete(GlDecoder *dec) int gldecoder_decode(GlDecoder *dec, const char *data, unsigned len) { + GlPacket *pkt; unsigned short func; - GlPacket packet; - - if(lentotal==0) - return; - pkt->chunk = pkt->total; - read_int((int *)&pkt->chunk, pkt); - pkt->chunk &= 0x7FFFFFFF; -} - -static void read_generic(void *v, unsigned size, int byteswap, GlPacket *pkt) -{ - if(pkt->chunk==0) - next_chunk(pkt); - - if(pkt->chunk>=size) - { - // TODO: Actually implement byteswap if needed - (void)byteswap; - memcpy(v, pkt->ptr, size); - pkt->ptr += size; - pkt->chunk -= size; - pkt->total -= size; - } - else - { - memset(v, 0, size); - pkt->total -= pkt->chunk; - pkt->chunk = 0; - } -} - -static void read_char(char *v, GlPacket *pkt) -{ - read_generic(v, 1, 0, pkt); -} - -static void read_short(short *v, GlPacket *pkt) -{ - read_generic(v, sizeof(short), 1, pkt); -} - -static void read_int(int *v, GlPacket *pkt) -{ - read_generic(v, sizeof(int), 1, pkt); -} - -static void read_long(long *v, GlPacket *pkt) -{ - read_generic(v, sizeof(long), 1, pkt); -} - -static void read_long_long(long long *v, GlPacket *pkt) -{ - read_generic(v, sizeof(long long), 1, pkt); -} - -static void read_float(float *v, GlPacket *pkt) -{ - read_generic(v, sizeof(float), 1, pkt); -} - -static void read_double(double *v, GlPacket *pkt) -{ - read_generic(v, sizeof(double), 1, pkt); -} - -typedef const void *pointer; - -static void read_pointer(pointer *v, GlPacket *pkt) -{ - read_generic(v, sizeof(pointer), 1, pkt); -} - -static void read_data(pointer *v, GlPacket *pkt) -{ - int vlen; - read_int(&vlen, pkt); - if(vlen) - *v = pkt->ptr; - else - *v = NULL; - pkt->ptr += vlen; - pkt->chunk -= vlen; - pkt->total -= vlen; -} - -typedef const char *string; - -static void read_string(string *v, GlPacket *pkt) -{ - read_data((pointer *)v, pkt); -} - -static void read_string_array(string **v, GlPacket *pkt) -{ - int count; - int i; - read_int(&count, pkt); - *v = (string *)tmpalloc(count*sizeof(string)); - for(i=0; igldError) dec->gldError(dec->user_data, code); } diff --git a/source/gldecoder.funcs.t b/source/gldecoder.funcs.t index 545f8b4..d4433aa 100644 --- a/source/gldecoder.funcs.t +++ b/source/gldecoder.funcs.t @@ -8,15 +8,15 @@ for p in params: wl(' %s p_%s;', p.ctype, p.name) for p in params: if p.kind=="value": - wl(' read_%s((%s *)&p_%s, pkt);', p.io[0].replace(' ', '_'), p.io[0], p.name) + wl(' packet_read_%s(pkt, (%s *)&p_%s);', p.io[0].replace(' ', '_'), p.io[0], p.name) elif p.kind=="array" and p.io and p.io[0]=="string": - wl(' read_string_array(&p_%s, pkt);', p.name) + wl(' packet_read_string_array(pkt, &p_%s);', p.name) elif p.csize: - wl(' read_data((pointer *)&p_%s, pkt);', p.name) + wl(' packet_read_data(pkt, (pointer *)&p_%s);', p.name) else: - wl(' read_pointer((pointer *)&p_%s, pkt);', p.name) + wl(' packet_read_pointer(pkt, (pointer *)&p_%s);', p.name) if ret.ctype!="void": - wl(' read_%s((%s *)&ret, pkt);', ret.io[0].replace(' ', '_'), ret.io[0]) + wl(' packet_read_%s(pkt, (%s *)&ret);', ret.io[0].replace(' ', '_'), ret.io[0]) wl(' if(dec->%s)', func.name) w(' dec->%s(dec->user_data', func.name) if ret.ctype!="void": diff --git a/source/glwrap.c b/source/glwrap.c index f801a20..10bfc77 100644 --- a/source/glwrap.c +++ b/source/glwrap.c @@ -11,19 +11,16 @@ Distributed under the GPL #include #include #include -#include -#define INTERNAL __attribute__((visibility("internal"))) - -INTERNAL inline const char *get_lib_names(void) +static const char *get_lib_names(void) { const char *env = getenv("GLWRAP_LIBS"); if(env) return env; - return "libGL.so"; + return "libGL.so.1"; } -INTERNAL inline void *glsym(const char *name) +void *glsym(const char *name) { static void **gl_libs = NULL; unsigned i; @@ -77,117 +74,7 @@ INTERNAL inline void *glsym(const char *name) return NULL; } -INTERNAL char *buffer = 0; -INTERNAL char *write_pos; -INTERNAL struct iovec *iovecs = 0; -INTERNAL struct iovec *cur_vec; -INTERNAL unsigned length; - -INTERNAL inline void next_vec(void) -{ - if(write_pos!=cur_vec->iov_base) - { - cur_vec->iov_len = write_pos-(char *)cur_vec->iov_base; - length += cur_vec->iov_len; - ++cur_vec; - cur_vec->iov_base = write_pos; - } -} - -INTERNAL inline void write_bytes(const char *ptr, unsigned size) -{ - unsigned i; - for(i=0; iiov_base = (void *)data; - cur_vec->iov_len = size; - length += size; - ++cur_vec; - cur_vec->iov_base = write_pos; - } - else - write_int(0); -} - -INTERNAL inline void write_string(const char *s) -{ - write_data(s, strlen(s)+1); -} - -INTERNAL inline void write_string_array(const char **sa, unsigned size) -{ - unsigned i; - size /= sizeof(const char *); - write_int(size); - for(i=0; iiov_base = write_pos; - length = 0; - - write_int(0); - write_short(func); -} - -INTERNAL inline int get_out_fd(void) +int get_out_fd(void) { static int fd = -1; @@ -201,7 +88,7 @@ INTERNAL inline int get_out_fd(void) var = getenv("GLWRAP_FILE"); if(var) { - fd = open(var, O_WRONLY|O_CREAT, 0644); + fd = open(var, O_WRONLY|O_CREAT|O_TRUNC, 0644); if(fd==-1) { fprintf(stderr, "Couldn't open dumpfile %s for output: %s", var, strerror(errno)); @@ -215,26 +102,3 @@ INTERNAL inline int get_out_fd(void) return fd; } - -INTERNAL inline void send_partial_packet(void) -{ - next_vec(); - write_pos = buffer; - write_int(length|0x80000000); - writev(get_out_fd(), iovecs, cur_vec-iovecs); - - write_pos = buffer; - cur_vec = iovecs; - cur_vec->iov_base = write_pos; - length = 0; - - write_int(0); -} - -INTERNAL inline void send_packet(void) -{ - next_vec(); - write_pos = buffer; - write_int(length); - writev(get_out_fd(), iovecs, cur_vec-iovecs); -} diff --git a/source/glwrap.funcs.t b/source/glwrap.funcs.t index 6770ec7..bcee771 100644 --- a/source/glwrap.funcs.t +++ b/source/glwrap.funcs.t @@ -7,40 +7,42 @@ !handcode eglGetProcAddress wl('%s APIENTRY %s(%s)', ret.ctype, func.name, ", ".join([p.ctype+" "+p.name for p in params])) wl('{') -wl(' static %s (*orig)(%s);', ret.ctype, ", ".join([p.ctype for p in params])) +wl(' static %s (*orig)(%s) = NULL;', ret.ctype, ", ".join([p.ctype for p in params])) +wl(' GlPacket *pkt;') if ret.ctype!='void': wl(' %s ret;', ret.ctype) wl(' if(!orig)') wl(' orig = glsym("%s");', func.name) -wl(' begin_packet(FUNC_%s);', func.name.upper()) +wl(' pkt = packet_begin(FUNC_%s);', func.name.upper()) head_sent = False for p in params: if p.direction=="out" and not head_sent: - wl(' send_partial_packet();') + wl(' packet_send_partial(pkt, get_out_fd());') w(' ') if ret.ctype!='void': w('ret = ') wl('orig(%s);', ", ".join([q.name for q in params])) head_sent = True if p.kind=="value": - wl(' write_%s(%s);', p.io[0].replace(' ', '_'), p.name) + wl(' packet_write_%s(pkt, %s);', p.io[0].replace(' ', '_'), p.name) elif p.kind=="array" and p.io and p.io[0]=="string": - wl(' write_string_array(%s, %s);', p.name, p.csize) + wl(' packet_write_string_array(pkt, %s, %s);', p.name, p.csize) elif p.csize: - wl(' write_data(%s, %s);', p.name, p.csize) + wl(' packet_write_data(pkt, %s, %s);', p.name, p.csize) else: - wl(' write_pointer(%s);', p.name) + wl(' packet_write_pointer(pkt, %s);', p.name) if ret.ctype!='void': if not head_sent: - wl(' send_partial_packet();') + wl(' packet_send_partial(pkt, get_out_fd());') wl(' ret = orig(%s);', ", ".join([p.name for p in params])) head_sent = True - wl(' write_%s(ret);', ret.io[0].replace(' ', '_')) -wl(' send_packet();') + wl(' packet_write_%s(pkt, ret);', ret.io[0].replace(' ', '_')) +wl(' packet_send(pkt, get_out_fd());') if not head_sent: wl(' orig(%s);', ", ".join([p.name for p in params])) if not func.name.startswith("glX"): wl(' check_error();') +#wl(' receive_packet();') if ret.ctype!='void': wl(' return ret;') wl('}') diff --git a/source/glwrap.h b/source/glwrap.h index 04d8f37..f8422a5 100644 --- a/source/glwrap.h +++ b/source/glwrap.h @@ -9,19 +9,6 @@ Distributed under the GPL #define GLWRAP_H_ void *glsym(const char *); -void write_char(char); -void write_short(short); -void write_int(int); -void write_long(long); -void write_long_long(long long); -void write_float(float); -void write_double(double); -void write_pointer(const void *); -void write_data(const void *, unsigned); -void write_string(const char *); -void write_string_array(const char **, unsigned); -void begin_packet(int); -void send_partial_packet(void); -void send_packet(void); +int get_out_fd(void); #endif diff --git a/source/packet.c b/source/packet.c new file mode 100644 index 0000000..465f118 --- /dev/null +++ b/source/packet.c @@ -0,0 +1,389 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2010 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + +#include +#include +#include +#include "packet.h" +#include "tmpalloc.h" + +struct GlOutPacket +{ + char *ptr; + unsigned length; + struct iovec *vec; +}; + +struct GlInPacket +{ + const char *ptr; + unsigned length; + unsigned chunk; +}; + +typedef struct GlOutPacket GlOutPacket; +typedef struct GlInPacket GlInPacket; + +struct GlPacket +{ + union + { + GlOutPacket out; + GlInPacket in; + }; +}; + +// XXX Should make this stuff truly re-entrant +static char *out_buffer = 0; +static struct iovec *iovecs = 0; +static GlPacket packet; +/*static char *in_buffer = 0; +static unsigned in_length;*/ + +static void next_vec(GlPacket *pkt) +{ + GlOutPacket *out = &pkt->out; + + if(out->ptr!=out->vec->iov_base) + { + out->vec->iov_len = out->ptr-(char *)out->vec->iov_base; + out->length += out->vec->iov_len; + ++out->vec; + out->vec->iov_base = out->ptr; + } +} + +static void reset(GlPacket *pkt) +{ + GlOutPacket *out = &pkt->out; + + out->ptr = out_buffer; + out->vec = iovecs; + out->vec->iov_base = out->ptr; + out->length = 0; +} + +GlPacket *packet_begin(unsigned short func) +{ + GlPacket *pkt; + + if(!out_buffer) + out_buffer = (char *)malloc(1024); + if(!iovecs) + iovecs = (struct iovec *)malloc(16*sizeof(struct iovec)); + + pkt = &packet; + reset(pkt); + + packet_write_int(pkt, 0); + packet_write_short(pkt, func); + + return pkt; +} + +void packet_send_partial(GlPacket *pkt, int fd) +{ + GlOutPacket *out = &pkt->out; + + out->length |= 0x80000000; + packet_send(pkt, fd); + + reset(pkt); + + packet_write_int(pkt, 0); +} + +void packet_send(GlPacket *pkt, int fd) +{ + GlOutPacket *out = &pkt->out; + struct iovec *v; + + next_vec(pkt); + out->ptr = out_buffer; + packet_write_int(pkt, out->length); + + for(v=iovecs; v!=out->vec; ) + { + int ret; + + ret = writev(fd, v, out->vec-v); + if(ret<0) + return; + + while(v!=out->vec && (unsigned)ret>=v->iov_len) + { + ret -= v->iov_len; + ++v; + } + + if(v!=out->vec) + { + v->iov_base += ret; + v->iov_len -= ret; + } + } +} + +static void write_raw(GlPacket *pkt, const char *ptr, unsigned size, int byteswap) +{ + GlOutPacket *out = &pkt->out; + unsigned i; + +#if __BYTE_ORDER == __LITTLE_ENDIAN + if(byteswap) + { + ptr += size; + for(i=0; iptr++ = *--ptr; + } + else +#endif + { + for(i=0; iptr++ = *ptr++; + } +} + +void packet_write_char(GlPacket *pkt, char v) +{ + GlOutPacket *out = &pkt->out; + *out->ptr++ = v; +} + +void packet_write_short(GlPacket *pkt, short v) +{ + write_raw(pkt, (char *)&v, sizeof(short), 1); +} + +void packet_write_int(GlPacket *pkt, int v) +{ + write_raw(pkt, (char *)&v, sizeof(int), 1); +} + +void packet_write_long(GlPacket *pkt, long v) +{ + write_raw(pkt, (char *)&v, sizeof(long), 1); +} + +void packet_write_long_long(GlPacket *pkt, long long v) +{ + write_raw(pkt, (char *)&v, sizeof(long long), 1); +} + +void packet_write_float(GlPacket *pkt, float v) +{ + write_raw(pkt, (char *)&v, sizeof(float), 1); +} + +void packet_write_double(GlPacket *pkt, double v) +{ + write_raw(pkt, (char *)&v, sizeof(double), 1); +} + +void packet_write_pointer(GlPacket *pkt, const void *p) +{ + write_raw(pkt, (char *)&p, sizeof(void *), 1); +} + +void packet_write_data(GlPacket *pkt, const void *data, unsigned size) +{ + if(data) + { + GlOutPacket *out = &pkt->out; + + packet_write_int(pkt, size); + next_vec(pkt); + out->vec->iov_base = (void *)data; + out->vec->iov_len = size; + out->length += size; + ++out->vec; + out->vec->iov_base = out->ptr; + } + else + packet_write_int(pkt, 0); +} + +void packet_write_string(GlPacket *pkt, const char *s) +{ + packet_write_data(pkt, s, strlen(s)+1); +} + +void packet_write_string_array(GlPacket *pkt, const char **sa, unsigned size) +{ + unsigned i; + size /= sizeof(const char *); + packet_write_int(pkt, size); + for(i=0; iin; + in->ptr = data; + in->chunk = *len; + + packet_read_int(pkt, (int *)&in->chunk); + + if(in->chunk&0x80000000) + { + in->chunk &= 0x7FFFFFFF; + in->length = in->chunk; + + while(1) + { + if(endptr+in->length+sizeof(int)) + return NULL; + + GlPacket p; + p.in.ptr = in->ptr+in->length; + p.in.chunk = p.in.length = end-p.in.ptr; + + unsigned chunk; + packet_read_int(&p, (int *)&chunk); + + in->length += chunk&0x7FFFFFFF; + if(!(chunk&0x80000000)) + break; + } + } + else + in->length = in->chunk; + + if(endptr+in->length) + return NULL; + + *len = in->ptr+in->length-data; + + return pkt; +} + +static void next_chunk(GlPacket *pkt) +{ + GlInPacket *in = &pkt->in; + + if(in->length==0) + return; + + in->chunk = in->length; + packet_read_int(pkt, (int *)&in->chunk); + in->chunk &= 0x7FFFFFFF; +} + +static void read_raw(GlPacket *pkt, char *ptr, unsigned size, int byteswap) +{ + GlInPacket *in = &pkt->in; + + if(in->chunk==0) + next_chunk(pkt); + + if(in->chunk>=size) + { + unsigned i; + +#if __BYTE_ORDER == __LITTLE_ENDIAN + if(byteswap) + { + ptr += size; + for(i=0; iptr++; + } + else +#endif + { + for(i=0; iptr++; + } + + in->length -= size; + in->chunk -= size; + } + else + { + memset(ptr, 0, size); + in->length -= in->chunk; + in->chunk = 0; + } +} + +void packet_read_char(GlPacket *pkt, char *v) +{ + read_raw(pkt, v, 1, 0); +} + +void packet_read_short(GlPacket *pkt, short *v) +{ + read_raw(pkt, (char *)v, sizeof(short), 1); +} + +void packet_read_int(GlPacket *pkt, int *v) +{ + read_raw(pkt, (char *)v, sizeof(int), 1); +} + +void packet_read_long(GlPacket *pkt, long *v) +{ + read_raw(pkt, (char *)v, sizeof(long), 1); +} + +void packet_read_long_long(GlPacket *pkt, long long *v) +{ + read_raw(pkt, (char *)v, sizeof(long long), 1); +} + +void packet_read_float(GlPacket *pkt, float *v) +{ + read_raw(pkt, (char *)v, sizeof(float), 1); +} + +void packet_read_double(GlPacket *pkt, double *v) +{ + read_raw(pkt, (char *)v, sizeof(double), 1); +} + +void packet_read_pointer(GlPacket *pkt, pointer *v) +{ + read_raw(pkt, (char *)v, sizeof(pointer), 1); +} + +void packet_read_data(GlPacket *pkt, pointer *v) +{ + GlInPacket *in = &pkt->in; + int vlen; + + packet_read_int(pkt, &vlen); + if(vlen) + *v = in->ptr; + else + *v = NULL; + in->ptr += vlen; + in->chunk -= vlen; + in->length -= vlen; +} + +void packet_read_string(GlPacket *pkt, string *v) +{ + packet_read_data(pkt, (pointer *)v); +} + +void packet_read_string_array(GlPacket *pkt, string **v) +{ + int count; + int i; + packet_read_int(pkt, &count); + *v = (string *)tmpalloc(count*sizeof(string)); + for(i=0; i