+void writer_resetbits(writer_t*w)
+{
+ if(w->bitpos)
+ w->write(w, &w->mybyte, 1);
+ w->bitpos = 0;
+ w->mybyte = 0;
+}
+
+unsigned int reader_readbit(reader_t*r)
+{
+ if(r->bitpos==8)
+ {
+ r->bitpos=0;
+ r->read(r, &r->mybyte, 1);
+ }
+ return (r->mybyte>>(7-r->bitpos++))&1;
+}
+unsigned int reader_readbits(reader_t*r, int num)
+{
+ int t;
+ int val = 0;
+ for(t=0;t<num;t++)
+ {
+ val<<=1;
+ val|=reader_readbit(r);
+ }
+ return val;
+}
+void reader_resetbits(reader_t*r)
+{
+ r->mybyte = 0;
+ r->bitpos = 8;
+
+}
+
+U8 reader_readU8(reader_t*r)
+{
+ U8 b = 0;
+ if(r->read(r, &b, 1)<1) {
+ fprintf(stderr, "bitio.c:reader_readU8: Read over end of memory region\n");
+ }
+ return b;
+}
+U16 reader_readU16(reader_t*r)
+{
+ U8 b1=0,b2=0;
+ if(r->read(r, &b1, 1)<1) {
+ fprintf(stderr, "bitio.c:reader_readU16: Read over end of memory region\n");
+ }
+ if(r->read(r, &b2, 1)<1) {
+ fprintf(stderr, "bitio.c:reader_readU16: Read over end of memory region\n");
+ }
+ return b1|b2<<8;
+}
+U32 reader_readU32(reader_t*r)
+{
+ U8 b1=0,b2=0,b3=0,b4=0;
+ if(r->read(r, &b1, 1)<1)
+ fprintf(stderr, "bitio.c:reader_readU32: Read over end of memory region\n");
+ if(r->read(r, &b2, 1)<1)
+ fprintf(stderr, "bitio.c:reader_readU32: Read over end of memory region\n");
+ if(r->read(r, &b3, 1)<1)
+ fprintf(stderr, "bitio.c:reader_readU32: Read over end of memory region\n");
+ if(r->read(r, &b4, 1)<1)
+ fprintf(stderr, "bitio.c:reader_readU32: Read over end of memory region\n");
+ return b1|b2<<8|b3<<16|b4<<24;
+}
+float reader_readFloat(reader_t*r)
+{
+ U8 b1=0,b2=0,b3=0,b4=0;
+ r->read(r, &b1, 1);
+ r->read(r, &b2, 1);
+ r->read(r, &b3, 1);
+ r->read(r, &b4, 1);
+ U32 w = (b1|b2<<8|b3<<16|b4<<24);
+ return *(float*)&w;
+}
+double reader_readDouble(reader_t*r)
+{
+ double f;
+ r->read(r, &f, 8);
+ return f;
+
+ U8 b[8];
+ r->read(r, b, 8);
+ U64 w = ((U64)b[0]|(U64)b[1]<<8|(U64)b[2]<<16|(U64)b[3]<<24|(U64)b[4]<<32|(U64)b[5]<<40|(U64)b[6]<<48|(U64)b[7]<<56);
+ return *(double*)&w;
+}
+char*reader_readString(reader_t*r)
+{
+ writer_t g;
+ writer_init_growingmemwriter(&g, 16);
+ while(1) {
+ U8 b = reader_readU8(r);
+ writer_writeU8(&g, b);
+ if(!b)
+ break;
+ }
+ char*string = (char*)writer_growmemwrite_getmem(&g);
+ g.finish(&g);
+ return string;
+}