+
+/* ---------------------------- mem reader ------------------------------- */
+
+struct memread_t
+{
+ unsigned char*data;
+ int length;
+};
+static int reader_memread(reader_t*reader, void* data, int len)
+{
+ struct memread_t*mr = (struct memread_t*)reader->internal;
+
+ if(mr->length - reader->pos > len) {
+ memcpy(data, &mr->data[reader->pos], len);
+ reader->pos += len;
+ return len;
+ } else {
+ memcpy(data, &mr->data[reader->pos], mr->length - reader->pos);
+ reader->pos += mr->length;
+ return mr->length - reader->pos;
+ }
+}
+static void reader_memread_dealloc(reader_t*reader)
+{
+ if(reader->internal)
+ free(reader->internal);
+ memset(reader, 0, sizeof(reader_t));
+}
+void reader_init_memreader(reader_t*r, void*newdata, int newlength)
+{
+ struct memread_t*mr = malloc(sizeof(struct memread_t));
+ mr->data = newdata;
+ mr->length = newlength;
+ r->read = reader_memread;
+ r->dealloc = reader_memread_dealloc;
+ r->internal = (void*)mr;
+ r->type = READER_TYPE_MEM;
+ r->mybyte = 0;
+ r->bitpos = 8;
+ r->pos = 0;
+}
+
+/* ---------------------------- mem writer ------------------------------- */
+
+struct memwrite_t
+{
+ unsigned char*data;
+ int length;
+};
+
+static int writer_memwrite_write(writer_t*w, void* data, int len)
+{
+ struct memwrite_t*mw = (struct memwrite_t*)w->internal;
+ if(mw->length - w->pos > len) {
+ memcpy(&mw->data[w->pos], data, len);
+ w->pos += len;
+ return len;
+ } else {
+ memcpy(&mw->data[w->pos], data, mw->length - w->pos);
+ w->pos = mw->length;
+ return mw->length - w->pos;
+ }
+}
+static void writer_memwrite_finish(writer_t*w)
+{
+ if(w->internal)
+ free(w->internal);
+ w->internal = 0;
+}
+void writer_init_memwriter(writer_t*w, void*data, int len)
+{
+ struct memwrite_t *mr;
+ mr = malloc(sizeof(struct memwrite_t));
+ mr->data = data;
+ mr->length = len;
+ memset(w, 0, sizeof(writer_t));
+ w->write = writer_memwrite_write;
+ w->finish = writer_memwrite_finish;
+ w->internal = (void*)mr;
+ w->type = WRITER_TYPE_MEM;
+ w->bitpos = 0;
+ w->mybyte = 0;
+ w->pos = 0;
+}
+
+/* ------------------------- growing mem writer ------------------------------- */
+
+struct growmemwrite_t
+{
+ unsigned char*data;
+ int length;
+ U32 grow;
+};
+static int writer_growmemwrite_write(writer_t*w, void* data, int len)
+{
+ struct growmemwrite_t*mw = (struct growmemwrite_t*)w->internal;
+ if(!mw->data) {
+ fprintf(stderr, "Illegal write operation: data already given away");
+ exit(1);
+ }
+ if(mw->length - w->pos < len) {
+ unsigned char*newmem;
+ int newlength = mw->length;
+ while(newlength - w->pos < len) {
+ newlength += mw->grow;
+ }
+#ifdef NO_REALLOC
+ newmem = malloc(newlength);
+ memcpy(newmem, mw->data, mw->length);
+ free(mw->data);
+ mw->data = newmem;
+#else
+ mw->data = realloc(mw->data, newlength);
+#endif
+ mw->length = newlength;
+ }
+ memcpy(&mw->data[w->pos], data, len);
+ w->pos += len;
+ return len;
+}
+static void writer_growmemwrite_finish(writer_t*w)
+{
+ struct growmemwrite_t*mw = (struct growmemwrite_t*)w->internal;
+ if(mw->data)
+ free(mw->data);
+ mw->data = 0;
+ mw->length = 0;
+ free(w->internal);mw=0;
+ memset(w, 0, sizeof(writer_t));
+}
+void* writer_growmemwrite_getmem(writer_t*w)
+{
+ struct growmemwrite_t*mw = (struct growmemwrite_t*)w->internal;
+ void*ret = mw->data;
+ /* remove own reference so that neither write() nor finish() can free it.
+ It's property of the caller now.
+ */
+ mw->data = 0;
+ return ret;
+}
+void writer_init_growingmemwriter(writer_t*w, U32 grow)
+{
+ struct growmemwrite_t *mr;
+ mr = malloc(sizeof(struct growmemwrite_t));
+ mr->length = 4096;
+ mr->data = malloc(mr->length);
+ mr->grow = grow;
+ memset(w, 0, sizeof(writer_t));
+ w->write = writer_growmemwrite_write;
+ w->finish = writer_growmemwrite_finish;
+ w->internal = (void*)mr;
+ w->type = WRITER_TYPE_GROWING_MEM;
+ w->bitpos = 0;
+ w->mybyte = 0;
+ w->pos = 0;
+}
+
+/* ---------------------------- file writer ------------------------------- */
+
+struct filewrite_t
+{
+ int handle;
+ char free_handle;
+};
+
+static int writer_filewrite_write(writer_t*w, void* data, int len)
+{
+ struct filewrite_t * fw= (struct filewrite_t*)w->internal;
+ return write(fw->handle, data, len);
+}
+static void writer_filewrite_finish(writer_t*w)
+{
+ struct filewrite_t *mr = (struct filewrite_t*)w->internal;
+ if(mr->free_handle)
+ close(mr->handle);
+ free(w->internal);
+ memset(w, 0, sizeof(writer_t));
+}
+void writer_init_filewriter(writer_t*w, int handle)
+{
+ struct filewrite_t *mr = malloc(sizeof(struct filewrite_t));
+ mr->handle = handle;
+ mr->free_handle = 0;
+ memset(w, 0, sizeof(writer_t));
+ w->write = writer_filewrite_write;
+ w->finish = writer_filewrite_finish;
+ w->internal = mr;
+ w->type = WRITER_TYPE_FILE;
+ w->bitpos = 0;
+ w->mybyte = 0;
+ w->pos = 0;
+}
+void writer_init_filewriter2(writer_t*w, char*filename)
+{
+ int fi = open("movie.swf",
+#ifdef O_BINARY
+ O_BINARY|
+#endif
+ O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ writer_init_filewriter(w, fi);
+ ((struct filewrite_t*)w->internal)->free_handle = 1;
+}
+
+/* ---------------------------- null writer ------------------------------- */
+
+static int writer_nullwrite_write(writer_t*w, void* data, int len)
+{
+ w->pos += len;
+ return len;
+}
+static void writer_nullwrite_finish(writer_t*w)
+{
+ memset(w, 0, sizeof(writer_t));
+}
+void writer_init_nullwriter(writer_t*w)
+{
+ memset(w, 0, sizeof(writer_t));
+ w->write = writer_nullwrite_write;
+ w->finish = writer_nullwrite_finish;
+ w->internal = 0;
+ w->type = WRITER_TYPE_NULL;
+ w->bitpos = 0;
+ w->mybyte = 0;
+ w->pos = 0;
+}
+/* ---------------------------- zlibinflate reader -------------------------- */
+