diff --git a/.bzrignore b/.bzrignore
index 7c11f80132a34152f829ad561b9d32eb49dd872e..4604e2fe800c8bd5d2fb09a69714389895582bb0 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -38,3 +38,4 @@ lib/c/liblabcomm_plain_c.so.1
 lib/c/test/test_signature_plain_c
 test/test_signature_numbers
 lib/c/test/test_signature_numbers
+lib/c/test/test_labcomm
diff --git a/lib/c/Makefile b/lib/c/Makefile
index 5ca4d0cb955921274998b40678c09d89a5d7edcc..113e4acb0b4afafb516114456d6e85a881d4df3e 100644
--- a/lib/c/Makefile
+++ b/lib/c/Makefile
@@ -1,7 +1,6 @@
 ## Macros
 
 CC=gcc
-#CFLAGS=-g -Wall -Werror -O3  -I. -Itest -DLABCOMM_ENCODER_LINEAR_SEARCH
 CFLAGS=-g -Wall -Werror -O3  -I. -Itest 
 LDFLAGS=-L.
 LDLIBS_TEST=-llabcomm -lrt
@@ -23,18 +22,15 @@ LABCOMM_JAR=../../compiler/labComm.jar
 LABCOMM=java -jar $(LABCOMM_JAR) 
 
 TESTS=test_labcomm_basic_type_encoding test_labcomm_generated_encoding \
+      test_signature_numbers \
+      test_labcomm \
       test_labcomm_pthread_scheduler \
-      test_signature_numbers
 #
 #FIXME: test_labcomm test_labcomm_errors
 TEST_DIR=test
-TESTDATA_DIR=$(TEST_DIR)/testdata
-TEST_GEN_DIR=$(TESTDATA_DIR)/gen
 
 VPATH=$(TEST_DIR)
 
-CREATED_DIRS=$(TEST_DIR) $(TESTDATA_DIR) $(TEST_GEN_DIR)
-
 # Enable experimental objects by invoking make like `make LABCOMM_EXPERIMENTAL=true`
 ifeq ($(LABCOMM_EXPERIMENTAL),true)
 	OBJS += experimental/udp_hack.o experimental/ethaddr.o \
@@ -66,10 +62,6 @@ labcomm_fd_reader_writer.o : labcomm_fd_reader_writer.c  labcomm_fd_reader_write
 
 ethaddr.o: ethaddr.c
 
-$(CREATED_DIRS):
-	mkdir -p $@
-
-## NB! the tests need CUnit to be installed
 run-test: $(TESTS:%=run-test-%)
 
 run-test-%: $(TEST_DIR)/% | $(TEST_DIR)
@@ -85,6 +77,8 @@ $(TEST_DIR)/%: $(TEST_DIR)/%.o
 $(TEST_DIR)/gen:
 	mkdir -p $@
 
+.PRECIOUS: $(TEST_DIR)/gen/%.c
+.PRECIOUS: $(TEST_DIR)/gen/%.h
 $(TEST_DIR)/gen/%.c $(TEST_DIR)/gen/%.h: $(TEST_DIR)/%.lc | $(TEST_DIR)/gen
 	$(LABCOMM) \
 		--c=$(TEST_DIR)/gen/$*.c \
@@ -127,7 +121,7 @@ $(TEST_DIR)/test_labcomm_generated_encoding.o: labcomm_private.h
 $(TEST_DIR)/test_labcomm_generated_encoding.o: $(TEST_DIR)/gen/generated_encoding.h
 $(TEST_DIR)/test_labcomm_generated_encoding : $(TEST_DIR)/gen/generated_encoding.o
 
-$(TEST_DIR)/test_labcomm:  $(TEST_GEN_DIR)/test_sample.o
+$(TEST_DIR)/test_labcomm:  $(TEST_DIR)/gen/test_sample.o
 $(TEST_DIR)/test_signature_numbers.c: $(TEST_DIR)/gen/another_encoding.h
 $(TEST_DIR)/test_signature_numbers.c: $(TEST_DIR)/gen/generated_encoding.h
 $(TEST_DIR)/test_signature_numbers: $(TEST_DIR)/gen/another_encoding.o
diff --git a/lib/c/labcomm_decoder.c b/lib/c/labcomm_decoder.c
index 0641e405caf00d6b345bf9deec54cb183521d350..3bbc8e136f61f405bd7e5edeec84bd00cc257bcf 100644
--- a/lib/c/labcomm_decoder.c
+++ b/lib/c/labcomm_decoder.c
@@ -83,11 +83,15 @@ void labcomm_decoder_free(struct labcomm_decoder* d)
   labcomm_memory_free(memory, 0, d);
 }
 
-static void collect_flat_signature(
+static int collect_flat_signature(
   struct labcomm_decoder *decoder,
   struct labcomm_writer *writer)
 {
-  int type = labcomm_read_packed32(decoder->reader); 
+  int result, type;
+
+  type = labcomm_read_packed32(decoder->reader); 
+  result = decoder->reader->error;
+  if (result < 0) { goto out; }
   if (type >= LABCOMM_USER) {
     decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 3,
 			"Implement %s ... (1) for type 0x%x\n", __FUNCTION__, type);
@@ -103,7 +107,8 @@ static void collect_flat_signature(
 	  int n = labcomm_read_packed32(decoder->reader);
 	  labcomm_write_packed32(writer, n);
 	}
-	collect_flat_signature(decoder, writer);
+	result = collect_flat_signature(decoder, writer);
+	if (result < 0) { goto out; }
       } break;
       case LABCOMM_STRUCT: {
 	int fields, i;
@@ -114,7 +119,8 @@ static void collect_flat_signature(
 	  char *name = labcomm_read_string(decoder->reader);
 	  labcomm_write_string(writer, name);
 	  labcomm_memory_free(decoder->memory, 1, name);
-	  collect_flat_signature(decoder, writer);
+	  result = collect_flat_signature(decoder, writer);
+	  if (result < 0) { goto out; }
 	}
       } break;
       case LABCOMM_BOOLEAN:
@@ -127,11 +133,14 @@ static void collect_flat_signature(
       case LABCOMM_STRING: {
       } break;
       default: {
+	result = -ENOSYS;
         decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 3,
 				"Implement %s (2) for type 0x%x...\n", __FUNCTION__, type);
       } break;
     }
   }
+out:
+  return result;
 }
 
 static int writer_ioctl(struct labcomm_writer *writer,
@@ -181,7 +190,7 @@ static int decode_typedef_or_sample(struct labcomm_decoder *d, int kind)
   local_index = 0;
   labcomm_writer_alloc(&writer, writer.action_context, "");
   labcomm_writer_start(&writer, writer.action_context, 0, NULL, NULL);
-  remote_index = labcomm_read_packed32(d->reader); //int
+  remote_index = labcomm_read_packed32(d->reader);
   signature.name = labcomm_read_string(d->reader);
   signature.type = kind;
   collect_flat_signature(d, &writer);
diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h
index 8e2f0595c23910cc60689022999dfb3aa989cc3d..455e88d3a6fe3796f15608c1ca671500c9e9f999 100644
--- a/lib/c/labcomm_private.h
+++ b/lib/c/labcomm_private.h
@@ -201,6 +201,9 @@ int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder,
     for (i = sizeof(type) - 1 ; i >= 0 ; i--) {				\
       if (r->pos >= r->count) {						\
 	labcomm_reader_fill(r, r->action_context);			\
+	if (r->error < 0) {						\
+	  return 0;							\
+	}								\
       }									\
       ((unsigned char*)(&result))[i] = r->data[r->pos];			\
       r->pos++;								\
@@ -216,6 +219,9 @@ int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder,
     for (i = 0 ; i < sizeof(type) ; i++) {				\
       if (r->pos >= r->count) {						\
 	labcomm_reader_fille(r, r->action_context);			\
+	if (r->error < 0) {						\
+	  return 0;							\
+	}								\
       }									\
       ((unsigned char*)(&result))[i] = r->data[r->pos];			\
       r->pos++;								\
@@ -259,19 +265,23 @@ out:
  
 static inline char *labcomm_read_string(struct labcomm_reader *r)
 {
-  char *result;
-  int length, i; 
+  char *result = NULL;
+  int length, pos; 
   
   length = labcomm_read_packed32(r);
   result = labcomm_memory_alloc(r->memory, 1, length + 1);
-  for (i = 0 ; i < length ; i++) {
+  for (pos = 0 ; pos < length ; pos++) {
     if (r->pos >= r->count) {	
       labcomm_reader_fill(r, r->action_context);
+      if (r->error < 0) {
+	goto out;
+      }
     }
-    result[i] = r->data[r->pos];
+    result[pos] = r->data[r->pos];
     r->pos++;
   }
-  result[length] = 0;
+out:
+  result[pos] = 0;
   return result;
 }
 
diff --git a/lib/c/test/test_labcomm.c b/lib/c/test/test_labcomm.c
index 1c5020f7e8f5ee9b622351097fd44e496f330887..3addcf2297484923f77266f9557cc8c72b66abd3 100644
--- a/lib/c/test/test_labcomm.c
+++ b/lib/c/test/test_labcomm.c
@@ -1,6 +1,173 @@
+/*
+  test_labcomm.c -- Various labcomm tests
 
-#include "CUnit/Basic.h"
-#include "CUnit/Console.h"
+  Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
+
+  This file is part of LabComm.
+
+  LabComm is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LabComm is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdint.h>
+#include <inttypes.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "labcomm_private.h"
+#include "labcomm_default_error_handler.h"
+#include "labcomm_default_memory.h"
+#include "labcomm_default_scheduler.h"
+#include "test/gen/test_sample.h"
+
+static unsigned char buffer[512];
+
+static int writer_alloc(struct labcomm_writer *w, 
+			struct labcomm_writer_action_context *action_context, 
+			char *labcomm_version)
+{
+  w->data = buffer;
+  w->data_size = sizeof(buffer);
+  w->count = sizeof(buffer);
+  
+  return 0;
+}
+static int writer_start(struct labcomm_writer *w, 
+			 struct labcomm_writer_action_context *action_context,
+			 int index, struct labcomm_signature *signature,
+			 void *value)
+{
+  return 0;
+}
+const struct labcomm_writer_action writer_action = {
+  .alloc = writer_alloc,
+  .start = writer_start,
+};
+static struct labcomm_writer_action_context writer_action_context = {
+  .next = NULL,
+  .action = &writer_action,
+  .context = NULL
+}; 
+static struct labcomm_writer writer =  {
+  .action_context = &writer_action_context,
+  .data = buffer,
+  .data_size = sizeof(buffer),
+  .count = sizeof(buffer),
+  .pos = 0,
+  .error = 0,
+};
+
+static int reader_alloc(struct labcomm_reader *r, 
+			struct labcomm_reader_action_context *action_context, 
+			char *labcomm_version)
+{
+  r->data = buffer;
+  r->data_size = sizeof(buffer);
+  r->count = 0;
+  r->memory = labcomm_default_memory;
+  
+  return 0;
+}
+static int reader_fill(struct labcomm_reader *r, 
+		       struct labcomm_reader_action_context *action_context)
+{
+  r->error = -ENOMEM;
+  return r->error;
+}
+const struct labcomm_reader_action reader_action = {
+  .alloc = reader_alloc,
+  .fill = reader_fill,
+};
+static struct labcomm_reader_action_context reader_action_context = {
+  .next = NULL,
+  .action = &reader_action,
+  .context = NULL
+}; 
+static struct labcomm_reader reader =  {
+  .action_context = &reader_action_context,
+  .data = buffer,
+  .data_size = sizeof(buffer),
+  .count = 0,
+  .pos = 0,
+  .error = 0,
+};
+
+test_sample_test_var encoder_var, decoder_var;
+
+void handle_test_var(test_sample_test_var *v, void *ctx)
+{
+  decoder_var = *v;  
+}
+
+int test_decode_one(struct labcomm_decoder *decoder)
+{
+  int result;
+
+  for (reader.count = 0 ; reader.count < writer.pos ; reader.count++) {
+    reader.error = 0;
+    reader.pos = 0;
+    result = labcomm_decoder_decode_one(decoder);
+    if (result >= 0) {
+      fprintf(stderr, "Got result from buffer with bogus length (%d)\n",
+	      result);
+      exit(1);
+    }
+  }
+  reader.error = 0;
+  reader.pos = 0;
+  reader.count = writer.pos;
+  result = labcomm_decoder_decode_one(decoder);
+  if (result < 0) {
+    fprintf(stderr, "Got result from buffer with correct length (%d)\n",
+	    result);
+    exit(1);
+  }
+  return result;
+}
+
+int main(void)
+{
+  int err;
+  struct labcomm_encoder *encoder = labcomm_encoder_new(
+    &writer, 
+    labcomm_default_error_handler,
+    labcomm_default_memory,
+    labcomm_default_scheduler);
+  struct labcomm_decoder *decoder = labcomm_decoder_new(
+    &reader,
+    labcomm_default_error_handler,
+    labcomm_default_memory,
+    labcomm_default_scheduler);
+  labcomm_decoder_register_test_sample_test_var(decoder,
+						handle_test_var, 
+						NULL);
+  labcomm_encoder_register_test_sample_test_var(encoder);
+  err = test_decode_one(decoder);
+  fprintf(stderr, "decode of register %d\n", err);
+  writer.pos = 0;
+  encoder_var = 314;
+  labcomm_encode_test_sample_test_var(encoder, &encoder_var);
+  err = test_decode_one(decoder);
+  fprintf(stderr, "decode of sample %d -> %d\n", err, decoder_var);
+  if (decoder_var != encoder_var) {
+    fprintf(stderr, "Failed to decode correct value %d != %d\n", 
+	    encoder_var, decoder_var);
+    exit(1);
+  }
+  return 0;
+}
+
+#if 0
 #include <stdbool.h>
 #include <stdlib.h>
 
@@ -186,3 +353,4 @@ int main()
 
 	return CU_get_error();
 }
+#endif
diff --git a/lib/c/test/testdata/test_sample.lc b/lib/c/test/test_sample.lc
similarity index 100%
rename from lib/c/test/testdata/test_sample.lc
rename to lib/c/test/test_sample.lc