+ 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;
+};
+static int writer_growmemwrite_write(struct 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 += 4096;
+ }
+ newmem = malloc(newlength);
+ memcpy(newmem, mw->data, mw->length);
+ free(mw->data);
+ mw->data = newmem;
+ mw->length = newlength;
+ }
+ memcpy(&mw->data[w->pos], data, len);
+ w->pos += len;
+ return len;
+}
+static void writer_growmemwrite_finish(struct 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(struct writer_t));
+}
+void* writer_growmemwrite_getmem(struct 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(struct writer_t*w)
+{
+ struct memwrite_t *mr;
+ mr = malloc(sizeof(struct memwrite_t));
+ mr->length = 4096;
+ mr->data = malloc(mr->length);
+ memset(w, 0, sizeof(struct writer_t));
+ w->write = writer_growmemwrite_write;
+ w->finish = writer_growmemwrite_finish;
+ w->internal = (void*)mr;
+ w->type = WRITER_TYPE_GROWING_MEM;