+int gldecoder_decode(GlDecoder *dec, const char *data, unsigned len)
+{
+ 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)
+ 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;
+}
+
+static void next_chunk(GlPacket *pkt)