/* $Id$
This file is part of gldbg
-Copyright © 2009 Mikko Rasa, Mikkosoft Productions
+Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions
Distributed under the GPL
*/
#include <string.h>
#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 *);
int gldecoder_decode(GlDecoder *dec, const char *data, unsigned len)
{
+ GlPacket *pkt;
unsigned short func;
- GlPacket packet;
-
- if(len<sizeof(int)+sizeof(short))
- return -1;
-
- packet.ptr = data;
- packet.chunk = len;
- read_int((int *)&packet.chunk, &packet);
-
- if(packet.chunk&0x80000000)
- {
- packet.chunk &= 0x7FFFFFFF;
- packet.total = packet.chunk;
-
- while(1)
- {
- if(len<packet.total+sizeof(int))
- return -1;
-
- GlPacket p = { packet.ptr+packet.total, len-packet.total, 0 };
- unsigned chunk;
- read_int((int *)&chunk, &p);
- packet.total += chunk&0x7FFFFFFF;
- if(!(chunk&0x80000000))
- break;
- }
- }
- else
- packet.total = packet.chunk;
- if(len<packet.total)
+ pkt = packet_receive_str(data, &len);
+ if(!pkt)
return -1;
- read_short((short *)&func, &packet);
-
- if(dec)
- {
- int ret = 0;
-
- if(func&0x8000)
- ret = decode_gldfunc(dec, func, &packet);
- else
- ret = decode_func(dec, func, &packet);
- if(ret<0)
- return -1;
- }
-
- return packet.ptr+packet.total-data;
-}
+ packet_read_short(pkt, (short *)&func);
-static void next_chunk(GlPacket *pkt)
-{
- if(pkt->total==0)
- return;
- pkt->chunk = pkt->total;
- read_int((int *)&pkt->chunk, pkt);
- pkt->chunk &= 0x7FFFFFFF;
-}
+ int ret = 0;
-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;
- }
+ if(func&0x8000)
+ ret = decode_gldfunc(dec, func, pkt);
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);
-}
+ ret = decode_func(dec, func, pkt);
+ if(ret<0)
+ return -1;
-static void read_double(double *v, GlPacket *pkt)
-{
- read_generic(v, sizeof(double), 1, pkt);
+ return len;
}
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; i<count; ++i)
- read_string(*v+i, pkt);
-}
-
#include "gensrc/gldecoder.funcs"
static void decode_gldError(GlDecoder *dec, GlPacket *pkt)
{
GLenum code;
- read_int((int *)&code, pkt);
+ packet_read_int(pkt, (int *)&code);
if(dec->gldError)
dec->gldError(dec->user_data, code);
+ else if(dec->unhandled)
+ dec->unhandled(dec->user_data, FUNC_GLDERROR);
+}
+
+static void decode_gldBreak(GlDecoder *dec, GlPacket *pkt)
+{
+ unsigned short func;
+ packet_read_short(pkt, (short *)&func);
+ if(dec->gldBreak)
+ dec->gldBreak(dec->user_data, func);
+ else if(dec->unhandled)
+ dec->unhandled(dec->user_data, FUNC_GLDBREAK);
}
static int decode_gldfunc(GlDecoder *dec, unsigned short func, GlPacket *pkt)
switch(func)
{
case FUNC_GLDERROR: decode_gldError(dec, pkt); break;
+ case FUNC_GLDBREAK: decode_gldBreak(dec, pkt); break;
default: return -1;
}
return 0;