diff --git a/lib/c/Makefile b/lib/c/Makefile
index 1cc9aa02c04db821424f8a5cab51ff2b0ad46d2c..960854837335b0884262cac262715ab4bae7e385 100644
--- a/lib/c/Makefile
+++ b/lib/c/Makefile
@@ -6,13 +6,14 @@ CFLAGS = -g -Wall -Werror -O3  -I. -Itest -DLABCOMM_ENCODER_LINEAR_SEARCH
 LDFLAGS = -L.
 LDLIBS_TEST = -Tlabcomm.linkscript  -lcunit -llabcomm
 
-OBJS= labcomm.o labcomm_dynamic_buffer_writer.o labcomm_fd_reader.o labcomm_fd_writer.o labcomm_mem_reader.o labcomm_mem_writer.o
+OBJS= labcomm.o labcomm_dynamic_buffer_writer.o labcomm_fd_reader.o labcomm_fd_writer.o 
+#FIXME: labcomm_mem_reader.o labcomm_mem_writer.o
 LABCOMM_JAR=../../compiler/labComm.jar
 LABCOMM=java -jar $(LABCOMM_JAR) 
 
 TESTS=test_labcomm_basic_type_encoding test_labcomm_generated_encoding 
-#test_labcomm 
-#FIXME: test_labcomm_errors
+#
+#FIXME: test_labcomm test_labcomm_errors
 TEST_DIR=test
 TESTDATA_DIR=$(TEST_DIR)/testdata
 TEST_GEN_DIR=$(TESTDATA_DIR)/gen
diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c
index 4ebc4f598c0c685a75503946dffea05b5b03c2fa..c717a69606ff14cf82f4ea412c95bcb2ef1ed208 100644
--- a/lib/c/labcomm.c
+++ b/lib/c/labcomm.c
@@ -34,7 +34,7 @@
 #include "labcomm_ioctl.h"
 #include "labcomm_dynamic_buffer_writer.h"
 
-#define LABCOMM_VERSION "LabComm2013"
+#define LABCOMM_VERSION "\x0bLabComm2013"
 
 typedef struct labcomm_sample_entry {
   struct labcomm_sample_entry *next;
@@ -227,20 +227,22 @@ static int get_encoder_index(
 void labcomm_encode_signature(struct labcomm_encoder *e,
                               labcomm_signature_t *signature) 
 {
-  int i;
-  e->writer.write(&e->writer, labcomm_writer_start_signature);
+  int i, index;
+
+  index = get_encoder_index(e, signature);
+  e->writer.action.start(&e->writer, e, index, signature, NULL);
   labcomm_encode_packed32(e, signature->type);
-  labcomm_encode_packed32(e, get_encoder_index(e, signature));
+  labcomm_encode_packed32(e, index);
 
   labcomm_encode_string(e, signature->name);
   for (i = 0 ; i < signature->size ; i++) {
     if (e->writer.pos >= e->writer.count) {
-      e->writer.write(&e->writer, labcomm_writer_continue);
+      e->writer.action.flush(&e->writer);
     }
     e->writer.data[e->writer.pos] = signature->signature[i];
     e->writer.pos++;
   }
-  e->writer.write(&e->writer, labcomm_writer_end_signature);
+  e->writer.action.end(&e->writer);
 }
 
 #ifdef LABCOMM_ENCODER_LINEAR_SEARCH
@@ -363,25 +365,23 @@ static int do_encode(
   void *value)
 {
   int result;
-  labcomm_writer_start_t lws;
-  
-  lws.encoder = e;
-  lws.index = get_encoder_index(e, signature);
-  lws.signature = signature;
-  lws.value = value;
-  result = e->writer.write(&e->writer, labcomm_writer_start, &lws);
-  if (result == -EALREADY) { result = 0; goto out; }
+  int index;
+
+  index = get_encoder_index(e, signature);
+  result = e->writer.action.start(&e->writer, e, index, signature, value);
+  if (result == -EALREADY) { result = 0; goto no_end; }
   if (result != 0) { goto out; }
-  result = labcomm_encode_packed32(e, lws.index);
+  result = labcomm_encode_packed32(e, index);
   if (result != 0) { goto out; }
   result = encode(e, value);
 out:
-  e->writer.write(&e->writer, labcomm_writer_end, &lws);
+  e->writer.action.end(&e->writer);
+no_end:
   return result;
 }
 
 labcomm_encoder_t *labcomm_encoder_new(
-  int (*writer)(labcomm_writer_t *, labcomm_writer_action_t, ...),
+  const struct labcomm_writer_action action,
   void *writer_context)
 {
   labcomm_encoder_t *result = malloc(sizeof(labcomm_encoder_t));
@@ -402,13 +402,12 @@ labcomm_encoder_t *labcomm_encoder_new(
     result->writer.count = 0;
     result->writer.pos = 0;
     result->writer.error = 0;
-    result->writer.write = writer;
-    result->writer.ioctl = NULL;
+    result->writer.action = action;
     result->writer.on_error = on_error_fprintf;
     result->do_register = do_encoder_register;
     result->do_encode = do_encode;
     result->on_error = on_error_fprintf;
-    result->writer.write(&result->writer, labcomm_writer_alloc);
+    result->writer.action.alloc(&result->writer, LABCOMM_VERSION);
   }
   return result;
 }
@@ -442,7 +441,7 @@ int labcomm_internal_encode(
 
 void labcomm_encoder_free(labcomm_encoder_t* e)
 {
-  e->writer.write(&e->writer, labcomm_writer_free);
+  e->writer.action.free(&e->writer);
   labcomm_encoder_context_t *context = (labcomm_encoder_context_t *) e->context;
 
 #ifdef LABCOMM_ENCODER_LINEAR_SEARCH
@@ -466,11 +465,11 @@ int labcomm_encoder_ioctl(struct labcomm_encoder *encoder,
 {
   int result = -ENOTSUP;
   
-  if (encoder->writer.ioctl != NULL) {
+  if (encoder->writer.action.ioctl != NULL) {
     va_list va;
     
     va_start(va, action);
-    result = encoder->writer.ioctl(&encoder->writer, action, NULL, va);
+    result = encoder->writer.action.ioctl(&encoder->writer, action, NULL, va);
     va_end(va);
   }
   return result;
@@ -483,8 +482,9 @@ int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder,
 {
   int result = -ENOTSUP;
   
-  if (encoder->writer.ioctl != NULL) {
-    result = encoder->writer.ioctl(&encoder->writer, action, signature, va);
+  if (encoder->writer.action.ioctl != NULL) {
+    result = encoder->writer.action.ioctl(&encoder->writer, action, 
+					  signature, va);
   }
   return result;
 }
@@ -584,7 +584,7 @@ static int do_decode_one(labcomm_decoder_t *d)
 	/* TODO: should the labcomm_dynamic_buffer_writer be 
 	   a permanent part of labcomm_decoder? */
 	labcomm_encoder_t *e = labcomm_encoder_new(
-	  labcomm_dynamic_buffer_writer, 0);
+	  labcomm_dynamic_buffer_writer, NULL);
 	labcomm_signature_t signature;
 	labcomm_sample_entry_t *entry = NULL;
 	int index, err;
@@ -592,11 +592,11 @@ static int do_decode_one(labcomm_decoder_t *d)
 	index = labcomm_decode_packed32(d); //int
 	signature.name = labcomm_decode_string(d);
 	signature.type = result;
-	e->writer.write(&e->writer, labcomm_writer_start);
+	e->writer.action.start(&e->writer, NULL, 0, NULL, NULL);
 	/* printf("do_decode_one: result = %x, index = %x, name=%s\n", 
 	   result, index, signature.name); */
 	collect_flat_signature(d, e);
-	e->writer.write(&e->writer, labcomm_writer_end);
+	e->writer.action.end(&e->writer);
 	err = labcomm_encoder_ioctl(e, LABCOMM_IOCTL_WRITER_GET_BYTES_WRITTEN,
 				    &signature.size);
 	if (err < 0) {
diff --git a/lib/c/labcomm.h b/lib/c/labcomm.h
index 7d38828393389459bffa60cc49874cf9063d5a61..ec4f9f84e3ff79c7eda500f22d9f847b4ba17567 100644
--- a/lib/c/labcomm.h
+++ b/lib/c/labcomm.h
@@ -81,24 +81,14 @@ void labcomm_decoder_register_new_datatype_handler(struct labcomm_decoder *d,
  * Decoder
  */
 
-typedef enum { 
-  labcomm_reader_alloc,     /* (..., char *labcomm_version)
-			       Allocate all neccessary data */
-  labcomm_reader_free,
-  labcomm_reader_start, 
-  labcomm_reader_continue, 
-  labcomm_reader_end,
-  labcomm_reader_ioctl
-} labcomm_reader_action_t;
-
 struct labcomm_reader;
 
 struct labcomm_reader_action {
   int (*alloc)(struct labcomm_reader *, char *labcomm_version);
   int (*free)(struct labcomm_reader *);
   int (*start)(struct labcomm_reader *);
-  int (*fill)(struct labcomm_reader *); 
   int (*end)(struct labcomm_reader *);
+  int (*fill)(struct labcomm_reader *); 
   int (*ioctl)(struct labcomm_reader *, int, labcomm_signature_t *, va_list);
 };
 
@@ -108,6 +98,7 @@ typedef struct labcomm_reader {
   int data_size;
   int count;
   int pos;
+  int error;
   struct labcomm_reader_action action;
   labcomm_error_handler_callback on_error;
 }  labcomm_reader_t;
@@ -130,26 +121,20 @@ int labcomm_decoder_ioctl(struct labcomm_decoder *decoder,
 /*
  * Encoder
  */
-typedef struct {
-  struct labcomm_encoder *encoder;
-  int index;
-  labcomm_signature_t *signature;
-  void *value;
-} labcomm_writer_start_t;
-
-typedef enum { 
-  labcomm_writer_alloc,              /* (..., char *labcomm_version)
-					Allocate all neccessary data */
-  labcomm_writer_free,               /* Free all allocated data */
-  labcomm_writer_start,              /* (..., labcomm_writer_start_t *s)
-					-EALREADY skips further encoding 
-					Start writing an ordinary sample */
-  labcomm_writer_continue,           /* Buffer full during ordinary sample */
-  labcomm_writer_end,                /* End writing ordinary sample */
-  labcomm_writer_start_signature,    /* Start writing signature */
-  labcomm_writer_continue_signature, /* Buffer full during signature */
-  labcomm_writer_end_signature,      /* End writing signature */
-} labcomm_writer_action_t;
+struct labcomm_writer;
+
+struct labcomm_writer_action {
+  int (*alloc)(struct labcomm_writer *w, char *labcomm_version);
+  int (*free)(struct labcomm_writer *w);
+  int (*start)(struct labcomm_writer *w,
+	       struct labcomm_encoder *encoder,
+	       int index,
+	       labcomm_signature_t *signature,
+	       void *value);
+  int (*end)(struct labcomm_writer *w);
+  int (*flush)(struct labcomm_writer *w); 
+  int (*ioctl)(struct labcomm_writer *w, int, labcomm_signature_t *, va_list);
+};
 
 typedef struct labcomm_writer {
   void *context;
@@ -158,13 +143,12 @@ typedef struct labcomm_writer {
   int count;
   int pos;
   int error;
-  int (*write)(struct labcomm_writer *, labcomm_writer_action_t, ...);
-  int (*ioctl)(struct labcomm_writer *, int, labcomm_signature_t *, va_list);
+  struct labcomm_writer_action action;
   labcomm_error_handler_callback on_error;
 } labcomm_writer_t;
 
 struct labcomm_encoder *labcomm_encoder_new(
-  int (*writer)(labcomm_writer_t *, labcomm_writer_action_t, ...),
+  const struct labcomm_writer_action action,
   void *writer_context);
 void labcomm_encoder_free(
   struct labcomm_encoder *encoder);
diff --git a/lib/c/labcomm_dynamic_buffer_writer.c b/lib/c/labcomm_dynamic_buffer_writer.c
index 4197857dc3b6700eb13e09890b581043579368a4..b03fae0906bbcef5a7ea6d30c46d22e96eae6888 100644
--- a/lib/c/labcomm_dynamic_buffer_writer.c
+++ b/lib/c/labcomm_dynamic_buffer_writer.c
@@ -4,11 +4,78 @@
 #include "labcomm_ioctl.h"
 #include "labcomm_dynamic_buffer_writer.h"
 
-static int labcomm_dynamic_buffer_writer_ioctl(
-  struct labcomm_writer *w, 
-  int action, 
-  labcomm_signature_t *signature,
-  va_list arg)
+static int dyn_alloc(struct labcomm_writer *w, char *labcomm_version)
+{
+  w->data_size = 1000;
+  w->count = w->data_size;
+  w->data = malloc(w->data_size);
+  if (w->data == NULL) {
+    w->error = -ENOMEM;
+  }
+  w->pos = 0;
+
+  return w->error;
+}
+
+static int dyn_free(struct labcomm_writer *w)
+{
+  free(w->data);
+  w->data = 0;
+  w->data_size = 0;
+  w->count = 0;
+  w->pos = 0;
+
+  return 0;
+}
+
+static int dyn_start(struct labcomm_writer *w,
+		     struct labcomm_encoder *encoder,
+		     int index,
+		     labcomm_signature_t *signature,
+		     void *value)
+{
+  void *tmp;
+
+  w->data_size = 1000;
+  w->count = w->data_size;
+  tmp = realloc(w->data, w->data_size);
+  if (tmp != NULL) {
+    w->data = tmp;
+    w->error = 0;
+  } else {
+    w->error = -ENOMEM;
+  }
+  w->pos = 0;
+
+  return w->error;
+}
+
+static int dyn_end(struct labcomm_writer *w)
+{
+  return 0;
+}
+
+static int dyn_flush(struct labcomm_writer *w)
+{
+  void *tmp;
+
+  w->data_size += 1000;
+  w->count = w->data_size;
+  tmp = realloc(w->data, w->data_size);
+  if (tmp != NULL) {
+    w->data = tmp;
+    w->error = 0;
+  } else {
+    w->error = -ENOMEM;
+  }
+
+  return w->error; 
+}
+
+static int dyn_ioctl(struct labcomm_writer *w, 
+		     int action, 
+		     labcomm_signature_t *signature,
+		     va_list arg)
 {
   int result = -ENOTSUP;
   switch (action) {
@@ -26,59 +93,11 @@ static int labcomm_dynamic_buffer_writer_ioctl(
   return result;
 }
 
-int labcomm_dynamic_buffer_writer(
-  labcomm_writer_t *w,
-  labcomm_writer_action_t action,
-  ...)
-{
-  switch (action) {
-    case labcomm_writer_alloc: {
-      w->data_size = 1000;
-      w->count = w->data_size;
-      w->data = malloc(w->data_size);
-      if (w->data == NULL) {
-	w->error = -ENOMEM;
-      }
-      w->pos = 0;
-      w->ioctl = labcomm_dynamic_buffer_writer_ioctl;
-    } break;
-    case labcomm_writer_start: 
-    case labcomm_writer_start_signature: {
-      void *tmp;
-      w->data_size = 1000;
-      w->count = w->data_size;
-      tmp = realloc(w->data, w->data_size);
-      if (tmp != NULL) {
-	w->data = tmp;
-	w->error = 0;
-      } else {
-	w->error = -ENOMEM;
-      }
-      w->pos = 0;
-    } break;
-    case labcomm_writer_continue: 
-    case labcomm_writer_continue_signature: {
-      void *tmp;
-      w->data_size += 1000;
-      w->count = w->data_size;
-      tmp = realloc(w->data, w->data_size);
-      if (tmp != NULL) {
-	w->data = tmp;
-      } else {
-	w->error = -ENOMEM;
-      }
-    } break;
-    case labcomm_writer_end: 
-    case labcomm_writer_end_signature: {
-    } break;
-    case labcomm_writer_free: {
-      free(w->data);
-      w->data = 0;
-      w->data_size = 0;
-      w->count = 0;
-      w->pos = 0;
-    } break;
-  }
-  return w->error;
-}
-
+const struct labcomm_writer_action labcomm_dynamic_buffer_writer = {
+  .alloc = dyn_alloc,
+  .free = dyn_free,
+  .start = dyn_start,
+  .end = dyn_end,
+  .flush = dyn_flush,
+  .ioctl = dyn_ioctl
+};
diff --git a/lib/c/labcomm_dynamic_buffer_writer.h b/lib/c/labcomm_dynamic_buffer_writer.h
index c743c02662f2f19bbb52e09917f0f64379108d4a..63099ef1b41b7d25dea3df5b85fc9ec28ff0fa25 100644
--- a/lib/c/labcomm_dynamic_buffer_writer.h
+++ b/lib/c/labcomm_dynamic_buffer_writer.h
@@ -3,9 +3,6 @@
 
 #include "labcomm.h"
 
-extern int labcomm_dynamic_buffer_writer(
-  labcomm_writer_t *writer, 
-  labcomm_writer_action_t action,
-  ...);
+extern const struct labcomm_writer_action labcomm_dynamic_buffer_writer;
 
 #endif
diff --git a/lib/c/labcomm_fd_writer.c b/lib/c/labcomm_fd_writer.c
index 0eecccdf4f9378e59847ae34b531b90f8ad7da5d..57f9248f0205de03b7a5aa44d0c072241899f5af 100644
--- a/lib/c/labcomm_fd_writer.c
+++ b/lib/c/labcomm_fd_writer.c
@@ -7,59 +7,70 @@
 
 #define BUFFER_SIZE 2048
 
-int labcomm_fd_writer(
-  labcomm_writer_t *w, 
-  labcomm_writer_action_t action,
-  ...)
+static int fd_alloc(struct labcomm_writer *w, char *version)
 {
-  int result = 0;
+#ifndef LABCOMM_FD_OMIT_VERSION
   int *fd = w->context;
+  write(*fd, version, strlen(version));
+#endif
+  w->data = malloc(BUFFER_SIZE);
+  if (! w->data) {
+    w->error = -ENOMEM;
+    w->data_size = 0;
+    w->count = 0;
+    w->pos = 0;
+  } else {
+    w->data_size = BUFFER_SIZE;
+    w->count = BUFFER_SIZE;
+    w->pos = 0;
+  }
 
-  switch (action) {
-    case labcomm_writer_alloc: {
-#ifndef LABCOMM_FD_OMIT_VERSION
-      va_list ap;
-      va_start(ap, action);
-      char *version = va_arg(ap, char *);
+  return w->error;
+}
 
-      write(*fd, version, strlen(version));
-#endif
-      w->data = malloc(BUFFER_SIZE);
-      if (! w->data) {
-        result = -ENOMEM;
-        w->data_size = 0;
-        w->count = 0;
-        w->pos = 0;
-      } else {
-        w->data_size = BUFFER_SIZE;
-        w->count = BUFFER_SIZE;
-        w->pos = 0;
-      }
-#ifndef LABCOMM_FD_OMIT_VERSION
-      va_end(ap);
-#endif
-    } break;
-    case labcomm_writer_free: {
-      free(w->data);
-      w->data = 0;
-      w->data_size = 0;
-      w->count = 0;
-      w->pos = 0;
-    } break;
-    case labcomm_writer_start: 
-    case labcomm_writer_start_signature: {
-      w->pos = 0;
-    } break;
-    case labcomm_writer_continue: 
-    case labcomm_writer_continue_signature: {
-      result = write(*fd, w->data, w->pos);
-      w->pos = 0;
-    } break;
-    case labcomm_writer_end: 
-    case labcomm_writer_end_signature: {
-      result = write(*fd, w->data, w->pos);
-      w->pos = 0;
-    } break;
+static int fd_free(struct labcomm_writer *w)
+{
+  free(w->data);
+  w->data = 0;
+  w->data_size = 0;
+  w->count = 0;
+  w->pos = 0;
+
+  return 0;
+}
+
+static int fd_start(struct labcomm_writer *w,
+		    struct labcomm_encoder *encoder,
+		    int index,
+		    labcomm_signature_t *signature,
+		    void *value)
+{
+  w->pos = 0;
+  
+  return w->error;
+}
+
+static int fd_flush(struct labcomm_writer *w)
+{
+  int *fd = w->context;
+  int err;
+
+  err = write(*fd, w->data, w->pos);
+  if (err < 0) {
+    w->error = -errno;
+  } else if (err == 0) {
+    w->error = -EINVAL;
   }
-  return result;
+  w->pos = 0;
+   
+  return w->error;
 }
+
+const struct labcomm_writer_action labcomm_fd_writer = {
+  .alloc = fd_alloc,
+  .free = fd_free,
+  .start = fd_start,
+  .end = fd_flush,
+  .flush = fd_flush,
+  .ioctl = NULL
+};
diff --git a/lib/c/labcomm_fd_writer.h b/lib/c/labcomm_fd_writer.h
index ea89eb29fe38b0147bbff077c627de72e8bef8bb..39d0258955366330a42077223f5595b44539e5d0 100644
--- a/lib/c/labcomm_fd_writer.h
+++ b/lib/c/labcomm_fd_writer.h
@@ -3,10 +3,7 @@
 
 #include "labcomm.h"
 
-extern int labcomm_fd_writer(
-  labcomm_writer_t *writer, 
-  labcomm_writer_action_t action,
-  ...);
+extern const struct labcomm_writer_action labcomm_fd_writer;
 
 #endif
 
diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h
index fd1068c1481b699447b7fb5b74e600747419284e..7d0cda83d3fecbb79356a5c5032a77082fec3c51 100644
--- a/lib/c/labcomm_private.h
+++ b/lib/c/labcomm_private.h
@@ -221,7 +221,7 @@ int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder,
     for (i = sizeof(type) - 1 ; i >= 0 ; i--) {				\
       if (w->pos >= w->count) { /*buffer is full*/			\
         int err;							\
-	err = w->write(w, labcomm_writer_continue);			\
+	err = w->action.flush(w);					\
 	if (err != 0) { return err; }					\
       }									\
       w->data[w->pos] = ((unsigned char*)(&data))[i];			\
@@ -241,7 +241,7 @@ int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder,
     for (i = 0 ; i < sizeof(type) ; i++) {				\
       if (w->pos >= w->count) {						\
         int err;							\
-	err = w->write(w, labcomm_writer_continue);			\
+	err = w->action.flush(w);					\
 	if (err != 0) { return err; }					\
       }									\
       w->data[w->pos] = ((unsigned char*)(&data))[i];			\
@@ -263,95 +263,6 @@ LABCOMM_ENCODE(long, long long)
 LABCOMM_ENCODE(float, float)
 LABCOMM_ENCODE(double, double)
 
-#if 0
-/* 
- * Pack the 32 bit unsigned number data as a sequence bytes, where the 
- * first byte is prefixed with a variable length bit pattern that
- * indicates the number of bytes used for encoding. The encoding
- * is inspired by the UTF-8 encoding.
- *
- * 0b0     - 1 byte  (0x00000000 - 0x0000007f)
- * 0b10    - 2 bytes (0x00000080 - 0x00003fff)
- * 0b110   - 3 bytes (0x00004000 - 0x001fffff)
- * 0b1110  - 4 bytes (0x00200000 - 0x0fffffff)
- * 0b11110 - 5 bytes (0x10000000 - 0xffffffff) [4 bits unused]
- */
-static inline int labcomm_write_packed32(labcomm_writer_t *w, 
-					 unsigned int data)
-{
-  int n;
-  unsigned char tag;
-  unsigned char tmp[4] = { (data >> 24) & 0xff, 
-			   (data >> 16) & 0xff, 
-			   (data >>  8) & 0xff, 
-			   (data      ) & 0xff }; 
-  if (data < 0x80) {
-    n = 1;
-    tag = 0x00;
-  } else if (data < 0x4000) { 
-    n = 2;
-    tag = 0x80;
-  } else if (data < 0x200000) { 
-    n = 3;
-    tag = 0xc0;
-  } else if (data < 0x10000000) { 
-    n = 4;
-    tag = 0xe0;
-  } else  {
-    n = 5;
-    tag = 0xf0;
-  }
-  /* TODO: maybe?
-    if (w->pos + n - 1 >= w->count) {	
-    w->write(w, labcomm_writer_continue, n);
-    }
-  */
-  switch (n) {
-    case 5: { 
-      if (w->pos >= w->count) {	
-	int err;
-	err = w->write(w, labcomm_writer_continue);
-	if (err != 0) { return err; }
-      }
-      w->data[w->pos++] = tag; tag = 0;
-    }
-    case 4: { 
-      if (w->pos >= w->count) {					
-	int err;
-	err = w->write(w, labcomm_writer_continue);
-	if (err != 0) { return err; }
-      }
-      w->data[w->pos++] = tmp[0] | tag; tag = 0;
-    }
-    case 3: { 
-      if (w->pos >= w->count) {					
-	int err;
-	err = w->write(w, labcomm_writer_continue);
-	if (err != 0) { return err; }
-      }
-      w->data[w->pos++] = tmp[1] | tag; tag = 0;
-    }
-    case 2: { 
-      if (w->pos >= w->count) {					
-	int err;
-	err = w->write(w, labcomm_writer_continue);
-	if (err != 0) { return err; }
-      }
-      w->data[w->pos++] = tmp[2] | tag; tag = 0;
-    }
-    case 1: { 
-      if (w->pos >= w->count) {					
-	int err;
-	err = w->write(w, labcomm_writer_continue);
-	if (err != 0) { return err; }
-      }
-      w->data[w->pos++] = tmp[3] | tag;
-    }
-  }
-  return 0;
-}
-#endif
-
 static inline int labcomm_write_packed32(labcomm_writer_t *w, 
 					 unsigned int data)
 {
@@ -364,7 +275,7 @@ static inline int labcomm_write_packed32(labcomm_writer_t *w,
   for (i = i - 1 ; i >= 0 ; i--) {
     if (w->pos >= w->count) {					
       int err;
-      err = w->write(w, labcomm_writer_continue);
+      err = w->action.flush(w);
       if (err != 0) { return err; }
     }
     w->data[w->pos++] = tmp[i] | (i?0x80:0x00);
@@ -390,7 +301,7 @@ static inline int labcomm_write_string(labcomm_writer_t *w, char *s)
   for (i = 0 ; i < length ; i++) {
     if (w->pos >= w->count) {	
       int err;
-      err = w->write(w, labcomm_writer_continue);
+      err = w->action.flush(w);
       if (err != 0) { return err; }
     }
     w->data[w->pos] = s[i];
diff --git a/lib/c/test/test_labcomm_basic_type_encoding.c b/lib/c/test/test_labcomm_basic_type_encoding.c
index 2efad6fd841144735e67633866b458dc2c86af22..dd8d65090e7443310f3ce1f2c624e2a1e55be192 100644
--- a/lib/c/test/test_labcomm_basic_type_encoding.c
+++ b/lib/c/test/test_labcomm_basic_type_encoding.c
@@ -4,18 +4,6 @@
 
 static int line;
 
-int test_write(struct labcomm_writer *w, labcomm_writer_action_t a, ...)
-{
-  fprintf(stderr, "test_write should not be called\n");
-  exit(1);
-}
-
-int test_read(struct labcomm_reader *r, labcomm_reader_action_t a, ...)
-{
-  fprintf(stderr, "test_read should not be called %s:%d\n", __FILE__, line);
-  exit(1);
-}
-
 static unsigned char buffer[128];
 static labcomm_encoder_t encoder = {
   .context = NULL,
@@ -26,8 +14,7 @@ static labcomm_encoder_t encoder = {
     .count = sizeof(buffer),
     .pos = 0,
     .error = 0,
-    .write = test_write,
-    .ioctl = NULL,
+    .action = { NULL, NULL, NULL, NULL, NULL, NULL },
     .on_error = NULL,
   },
   .do_register = NULL,
diff --git a/lib/c/test/test_labcomm_generated_encoding.c b/lib/c/test/test_labcomm_generated_encoding.c
index f539111ce4d5c3f57a4c905a3bfc4c29f776fc5c..615fcea1efbb3040b44effce91a74c580f662b93 100644
--- a/lib/c/test/test_labcomm_generated_encoding.c
+++ b/lib/c/test/test_labcomm_generated_encoding.c
@@ -5,18 +5,49 @@
 #include "labcomm_private.h"
 #include "test/gen/generated_encoding.h"
 
-int test_write(struct labcomm_writer *w, labcomm_writer_action_t a, ...)
-{
-  fprintf(stderr, "test_write should not be called\n");
-  exit(1);
-}
-
 #define IOCTL_WRITER_ASSERT_BYTES 4096
 #define IOCTL_WRITER_RESET 4097
 
 static unsigned char buffer[128];
 
-static int buffer_writer_ioctl(
+static int buf_writer_alloc(struct labcomm_writer *w, char *labcomm_version)
+{
+  w->data_size = sizeof(buffer);
+  w->count = w->data_size;
+  w->data = buffer;
+  w->pos = 0;
+  
+  return 0;
+}
+
+static int buf_writer_free(struct labcomm_writer *w)
+{
+  return 0;
+}
+
+static int buf_writer_start(struct labcomm_writer *w,
+			    struct labcomm_encoder *encoder,
+			    int index,
+			    labcomm_signature_t *signature,
+			    void *value)
+{
+  return 0;
+}
+
+static int buf_writer_end(struct labcomm_writer *w)
+{
+  return 0;
+}
+
+static int buf_writer_flush(struct labcomm_writer *w)
+{
+  fprintf(stderr, "Should not come here %s:%d\n", __FILE__, __LINE__);
+  exit(1);
+  
+  return 0;
+}
+
+static int buf_writer_ioctl(
   struct labcomm_writer *w, 
   int action, 
   labcomm_signature_t *signature,
@@ -68,39 +99,14 @@ static int buffer_writer_ioctl(
   return result;
 }
 
-static int buffer_writer(
-  labcomm_writer_t *w, 
-  labcomm_writer_action_t action,
-  ...)
-{
-  switch (action) {
-    case labcomm_writer_alloc: {
-      w->data_size = sizeof(buffer);
-      w->count = w->data_size;
-      w->data = buffer;
-      w->pos = 0;
-      w->ioctl = buffer_writer_ioctl;
-    } break;
-    case labcomm_writer_start: 
-    case labcomm_writer_start_signature: {
-    } break;
-    case labcomm_writer_continue: 
-    case labcomm_writer_continue_signature: {
-      fprintf(stderr, "Should not come here %s:%d\n", __FILE__, __LINE__);
-      exit(1);
-    } break;
-    case labcomm_writer_end: 
-    case labcomm_writer_end_signature: {
-    } break;
-    case labcomm_writer_free: {
-      w->data = 0;
-      w->data_size = 0;
-      w->count = 0;
-      w->pos = 0;
-    } break;
-  }
-  return w->error;
-}
+const struct labcomm_writer_action buffer_writer = {
+  .alloc = buf_writer_alloc,
+  .free = buf_writer_free,
+  .start = buf_writer_start,
+  .end = buf_writer_end,
+  .flush = buf_writer_flush,
+  .ioctl = buf_writer_ioctl
+};
 
 void dump_encoder(labcomm_encoder_t *encoder)
 {