From 07189291dda371e871ec914f8697f10242293335 Mon Sep 17 00:00:00 2001
From: Anders Blomdell <anders.blomdell@control.lth.se>
Date: Wed, 20 May 2015 15:48:51 +0200
Subject: [PATCH] Refactoring to enable implementation of renaming
 encoders/decoders.

---
 compiler/2014/C_CodeGen.jrag      |  18 +--
 lib/c/2014/labcomm2014_decoder.c  | 180 +++++++++++++++--------------
 lib/c/2014/labcomm2014_encoder.c  | 181 ++++++++++++++++--------------
 lib/c/2014/labcomm2014_private.h  |  95 +++++++++-------
 lib/python/labcomm2014/LabComm.py |   4 +
 packaging/.gitignore              |   2 +-
 6 files changed, 259 insertions(+), 221 deletions(-)

diff --git a/compiler/2014/C_CodeGen.jrag b/compiler/2014/C_CodeGen.jrag
index afa7f04..d7da9c0 100644
--- a/compiler/2014/C_CodeGen.jrag
+++ b/compiler/2014/C_CodeGen.jrag
@@ -528,7 +528,7 @@ aspect C_Decoder {
     env.print(env.qualid + " = ");
     switch (getToken()) {
       case LABCOMM_SAMPLE: { 
-        env.println("labcomm2014_internal_decoder_index_to_signature(" +
+        env.println("r->decoder->index_to_signature(" +
                     "r->decoder, labcomm2014_read_int(r));");
       } break;
       default: {
@@ -691,7 +691,7 @@ aspect C_Decoder {
     env.println(")");
     env.println("{");
     env.indent();
-    env.println("return labcomm2014_internal_decoder_register(");
+    env.println("return d->register_sample(");
     env.indent();
     env.println("d,");
     env.println("&signature_" + env.prefix + getName() + ",");
@@ -985,7 +985,7 @@ aspect C_DecoderIoctl {
     env.println("int result;");
     env.println("va_list va;");
     env.println("va_start(va, ioctl_action);");
-    env.println("result = labcomm2014_internal_decoder_ioctl(");
+    env.println("result = d->ioctl(");
     env.indent();
     env.println("d, &signature_" + env.prefix + getName() + ", ");
     env.println("ioctl_action, va);");
@@ -1038,7 +1038,7 @@ aspect C_Encoder {
     env.println(")");
     env.println("{");
     env.indent();
-    env.println("return labcomm2014_internal_encode(e, &signature_" + 
+    env.println("return e->encode(e, &signature_" + 
 		env.prefix + getName() + 
 		", (labcomm2014_encoder_function)encode_" + 
                 env.prefix + getName() +
@@ -1062,7 +1062,7 @@ aspect C_Encoder {
     switch (getToken()) {
       case LABCOMM_SAMPLE: { 
         env.println("labcomm2014_write_int(w, " + 
-                    "labcomm2014_internal_encoder_signature_to_index(w->encoder, " +
+                    "w->encoder->signature_to_index(w->encoder, " +
                     env.qualid + "));");
       } break;
       default: {
@@ -1144,7 +1144,7 @@ aspect C_Encoder {
     C_emitUserTypeDeps(env, null, true); 
 
     if(!isSampleDecl() || hasDependencies()) {
-      env.println("return labcomm2014_internal_encoder_type_register(");
+      env.println("return e->type_register(");
       env.indent();
       env.println("e,");
       env.println("&signature_" + env.prefix + getName() + "");
@@ -1174,7 +1174,7 @@ aspect C_Encoder {
     C_emitUserTypeDeps(env, null, false); //XXX HERE BE DRAGONS
                                           //currently set to false to turn off
                                           //outputting of code
-    env.println("int result = labcomm2014_internal_encoder_register(");
+    env.println("int result = e->sample_register(");
     env.indent();
     env.println("e,");
     env.println("&signature_" + env.prefix + getName() + ",");
@@ -1184,7 +1184,7 @@ aspect C_Encoder {
     env.println("if(result >= 0) {\n");
     env.indent();
     env.println("labcomm2014_encoder_type_register_" + env.prefix + getName()+"(e);");
-    env.println("labcomm2014_internal_encoder_type_bind(");
+    env.println("e->type_bind(");
     env.indent();
     env.println("e,");
     env.println("&signature_" + env.prefix + getName() + ",");
@@ -1222,7 +1222,7 @@ aspect C_EncoderIoctl {
     env.println("int result;");
     env.println("va_list va;");
     env.println("va_start(va, ioctl_action);");
-    env.println("result = labcomm2014_internal_encoder_ioctl(");
+    env.println("result = e->ioctl(");
     env.indent();
     env.println("e, &signature_" + env.prefix + getName() + ", ");
     env.println("ioctl_action, va);");
diff --git a/lib/c/2014/labcomm2014_decoder.c b/lib/c/2014/labcomm2014_decoder.c
index 8d3f79b..4aafbaf 100644
--- a/lib/c/2014/labcomm2014_decoder.c
+++ b/lib/c/2014/labcomm2014_decoder.c
@@ -46,82 +46,31 @@ struct sample_entry {
   void *context;
 };
 
-struct labcomm2014_decoder {
-  struct labcomm2014_reader *reader;
-  int reader_allocated;
-  int version_ok;
-  struct labcomm2014_error_handler *error;
-  struct labcomm2014_memory *memory;
-  struct labcomm2014_scheduler *scheduler;
-  labcomm2014_error_handler_callback on_error;
-  labcomm2014_handle_new_datatype_callback on_new_datatype;
+struct decoder {
+  struct labcomm2014_decoder decoder;
   LABCOMM_SIGNATURE_ARRAY_DEF(local, struct sample_entry);
   LABCOMM_SIGNATURE_ARRAY_DEF(remote_to_local, int);
   LABCOMM_SIGNATURE_ARRAY_DEF(local_ref, const struct labcomm2014_signature *);
   LABCOMM_SIGNATURE_ARRAY_DEF(remote_to_local_ref, int);
 };
 
-struct labcomm2014_decoder *labcomm2014_decoder_new(
-  struct labcomm2014_reader *reader,
-  struct labcomm2014_error_handler *error,
-  struct labcomm2014_memory *memory,
-  struct labcomm2014_scheduler *scheduler)
-{
-  struct labcomm2014_decoder *result;
-
-  result = labcomm2014_memory_alloc(memory, 0, sizeof(*result));
-  if (result) {
-    result->reader = reader;
-    result->reader->decoder = result;
-    result->reader->data = 0;
-    result->reader->data_size = 0;
-    result->reader->count = 0;
-    result->reader->pos = 0;
-    result->reader->error = 0;
-    result->reader_allocated = 0;
-    result->version_ok = 0;
-    result->error = error;
-    result->memory = memory;
-    result->scheduler = scheduler;
-    result->on_error = labcomm20142014_on_error_fprintf;
-    LABCOMM_SIGNATURE_ARRAY_INIT(result->local, struct sample_entry);
-    LABCOMM_SIGNATURE_ARRAY_INIT(result->remote_to_local, int);
-    LABCOMM_SIGNATURE_ARRAY_INIT(result->local_ref, 
-                                 const struct labcomm2014_signature*);
-    LABCOMM_SIGNATURE_ARRAY_INIT(result->remote_to_local_ref, int);
-  }
-  return result;
-}
-
-void labcomm2014_decoder_free(struct labcomm2014_decoder* d)
-{
-  struct labcomm2014_memory *memory = d->memory;
-
-  labcomm2014_reader_free(d->reader, d->reader->action_context);
-  LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->local, struct sample_entry);
-  LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->remote_to_local, int);
-  LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->local_ref, 
-                               const struct labcomm2014_signature*);
-  LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->remote_to_local_ref, int);
-  labcomm2014_memory_free(memory, 0, d);
-}
-
 static int handle_sample_def(struct labcomm2014_decoder *d, int remote_index,
                              const struct labcomm2014_signature *signature)
 {
+  struct decoder *id = d->context;
   int result;
   int i;
   const struct labcomm2014_signature *local_signature = NULL;
   int local_index = 0;
 
   labcomm2014_scheduler_data_lock(d->scheduler);
-  LABCOMM_SIGNATURE_ARRAY_FOREACH(d->local, struct sample_entry, i) {
+  LABCOMM_SIGNATURE_ARRAY_FOREACH(id->local, struct sample_entry, i) {
     struct sample_entry *s;
     int *remote_to_local;
 
     result = -ENOENT;
     s = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, 
-                                    d->local, struct sample_entry, i);
+                                    id->local, struct sample_entry, i);
     if (s->signature &&
         s->signature->size == signature->size &&
         strcmp(s->signature->name, signature->name) == 0 &&
@@ -131,7 +80,7 @@ static int handle_sample_def(struct labcomm2014_decoder *d, int remote_index,
       local_signature = s->signature;
       local_index = i;
       remote_to_local = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
-                                                    d->remote_to_local, int,
+                                                    id->remote_to_local, int,
                                                     remote_index);
       *remote_to_local = i;
       result = remote_index;
@@ -151,23 +100,26 @@ static int handle_sample_def(struct labcomm2014_decoder *d, int remote_index,
 static int handle_sample_ref(struct labcomm2014_decoder *d, int remote_index,
                              const struct labcomm2014_signature *signature)
 {
+  struct decoder *id = d->context;
   int result;
   int i;
 
   labcomm2014_scheduler_data_lock(d->scheduler);
-  LABCOMM_SIGNATURE_ARRAY_FOREACH(d->local_ref, const struct labcomm2014_signature *, i) {
+  LABCOMM_SIGNATURE_ARRAY_FOREACH(id->local_ref,
+                                  const struct labcomm2014_signature *, i) {
     const struct labcomm2014_signature *s;
     int *remote_to_local_ref;
 
     result = -ENOENT;
-    s = LABCOMM_SIGNATURE_ARRAY_GET(d->local_ref, const struct labcomm2014_signature *, i, 0);
+    s = LABCOMM_SIGNATURE_ARRAY_GET(id->local_ref, const struct labcomm2014_signature *, i, 0);
     if (s &&
         s->signature &&
         s->size == signature->size &&
         strcmp(s->name, signature->name) == 0 &&
         memcmp((void*)s->signature, (void*)signature->signature, signature->size) == 0) {
       remote_to_local_ref = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
-                                                        d->remote_to_local_ref, int,
+                                                        id->remote_to_local_ref,
+                                                        int,
                                                         remote_index);
       *remote_to_local_ref = i;
       result = remote_index;
@@ -309,17 +261,18 @@ static labcomm2014_decoder_function lookup_h(struct labcomm2014_decoder *d,
 		                         int remote_index,
 					 int **local_index)
 {
+  struct decoder *id = d->context;
   labcomm2014_decoder_function do_decode = NULL;
   labcomm2014_scheduler_data_lock(d->scheduler);
   *local_index = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
-      				      d->remote_to_local, int,
-      				      remote_index);
+                                             id->remote_to_local, int,
+                                             remote_index);
   if (**local_index != 0) {
     struct sample_entry *entry;
 
     entry = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
-      				  d->local, struct sample_entry,
-      				  **local_index);
+                                        id->local, struct sample_entry,
+                                        **local_index);
     wrap->local_index = **local_index;
     wrap->signature = entry->signature;
     wrap->handler = entry->handler;
@@ -425,16 +378,16 @@ void labcomm2014_decoder_run(struct labcomm2014_decoder *d)
 }
 
 int labcomm2014_decoder_ioctl(struct labcomm2014_decoder *d, 
-			  uint32_t action,
-			  ...)
+                              uint32_t action,
+                              ...)
 {
   int result;  
   va_list va;
     
   va_start(va, action);
   result = labcomm2014_reader_ioctl(d->reader, 
-				d->reader->action_context,
-				0, 0, NULL, action, va);
+                                    d->reader->action_context,
+                                    0, 0, NULL, action, va);
   va_end(va);
   return result;
 }
@@ -443,6 +396,7 @@ int labcomm2014_decoder_sample_ref_register(
   struct labcomm2014_decoder *d,
   const struct labcomm2014_signature *signature)
 {
+  struct decoder *id = d->context;
   int local_index, *remote_to_local_ref;
   const struct labcomm2014_signature **s;
 
@@ -450,13 +404,13 @@ int labcomm2014_decoder_sample_ref_register(
   if (local_index <= 0) { goto out; }
   labcomm2014_scheduler_data_lock(d->scheduler);
   s = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, 
-                                  d->local_ref, 
+                                  id->local_ref, 
                                   const struct labcomm2014_signature*, local_index);
   if (s == NULL) { local_index = -ENOMEM; goto unlock; };
   if (*s) { goto unlock; }
   *s = signature;	
   remote_to_local_ref = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, 
-                                                    d->remote_to_local_ref, 
+                                                    id->remote_to_local_ref, 
                                                     int, local_index);
   *remote_to_local_ref = 0;
 unlock:
@@ -465,17 +419,18 @@ out:
   return local_index;
 }
 
-int labcomm2014_internal_decoder_ioctl(struct labcomm2014_decoder *d, 
-				   const struct labcomm2014_signature *signature,
-				   uint32_t action, va_list va)
+static int do_ioctl(struct labcomm2014_decoder *d, 
+                    const struct labcomm2014_signature *signature,
+                    uint32_t action, va_list va)
 {
+  struct decoder *id = d->context;
   int result;
   int local_index, remote_index;
 
   local_index = labcomm2014_get_local_index(signature);
   labcomm2014_scheduler_data_lock(d->scheduler);
   remote_index = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
-					     d->local,
+					     id->local,
 					     struct sample_entry,
 					     local_index)->remote_index;
   labcomm2014_scheduler_data_unlock(d->scheduler);
@@ -530,13 +485,14 @@ int labcomm2014_decoder_register_labcomm2014_type_def(
   void *context
 )
 {
+  struct decoder *id = d->context;
   int tag = LABCOMM_TYPE_DEF;
   struct sample_entry *entry;
   int *remote_to_local;
  
   labcomm2014_scheduler_data_lock(d->scheduler);
   entry = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
-				      d->local, struct sample_entry,
+				      id->local, struct sample_entry,
 				      tag);
   if (entry == NULL) { tag = -ENOMEM; goto unlock; }
   entry->remote_index = tag;
@@ -546,8 +502,8 @@ int labcomm2014_decoder_register_labcomm2014_type_def(
   entry->context = context;
 
   remote_to_local = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
-                                                    d->remote_to_local, int,
-                                                    tag);
+                                                id->remote_to_local, int,
+                                                tag);
   *remote_to_local = tag;
 unlock:
   labcomm2014_scheduler_data_unlock(d->scheduler);
@@ -584,13 +540,14 @@ int labcomm2014_decoder_register_labcomm2014_type_binding(
   void *context
 )
 {
+  struct decoder *id = d->context;
   int tag = LABCOMM_TYPE_BINDING;
   struct sample_entry *entry;
   int *remote_to_local;
  
   labcomm2014_scheduler_data_lock(d->scheduler);
   entry = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
-				      d->local, struct sample_entry,
+				      id->local, struct sample_entry,
 				      tag);
   if (entry == NULL) { tag = -ENOMEM; goto unlock; }
   entry->remote_index = tag;
@@ -600,8 +557,8 @@ int labcomm2014_decoder_register_labcomm2014_type_binding(
   entry->context = context;
 
   remote_to_local = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
-                                                    d->remote_to_local, int,
-                                                    tag);
+                                                id->remote_to_local, int,
+                                                tag);
   *remote_to_local = tag;
 unlock:
   labcomm2014_scheduler_data_unlock(d->scheduler);
@@ -612,13 +569,14 @@ unlock:
 //// End type_def handling
 #endif
 
-int labcomm2014_internal_decoder_register(
+static int do_register_sample(
   struct labcomm2014_decoder *d,
   const struct labcomm2014_signature *signature,
   labcomm2014_decoder_function decode, 
   labcomm2014_handler_function handler,
   void *context)
 {
+  struct decoder *id = d->context;
   int local_index;
   struct sample_entry *entry;
  
@@ -632,7 +590,7 @@ int labcomm2014_internal_decoder_register(
 
   labcomm2014_scheduler_data_lock(d->scheduler);
   entry = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
-				      d->local, struct sample_entry,
+				      id->local, struct sample_entry,
 				      local_index);
   if (entry == NULL) { local_index = -ENOMEM; goto unlock; }
   entry->remote_index = 0;
@@ -646,20 +604,72 @@ out:
   return local_index;
 }
 
-const struct labcomm2014_signature *labcomm2014_internal_decoder_index_to_signature(
+static const struct labcomm2014_signature *do_index_to_signature(
   struct labcomm2014_decoder *d, int index)
 {
   const struct labcomm2014_signature *result = 0;
+  struct decoder *id = d->context;
   int local_index;
 
   labcomm2014_scheduler_data_lock(d->scheduler);
-  local_index = LABCOMM_SIGNATURE_ARRAY_GET(d->remote_to_local_ref, 
+  local_index = LABCOMM_SIGNATURE_ARRAY_GET(id->remote_to_local_ref, 
                                             int, index, 0);
   if (local_index) {
-    result = LABCOMM_SIGNATURE_ARRAY_GET(d->local_ref, 
+    result = LABCOMM_SIGNATURE_ARRAY_GET(id->local_ref, 
                                          const struct labcomm2014_signature*, 
                                          local_index, 0);
   }
   labcomm2014_scheduler_data_unlock(d->scheduler);
   return result;
 }
+
+struct labcomm2014_decoder *labcomm2014_decoder_new(
+  struct labcomm2014_reader *reader,
+  struct labcomm2014_error_handler *error,
+  struct labcomm2014_memory *memory,
+  struct labcomm2014_scheduler *scheduler)
+{
+  struct decoder *result;
+
+  result = labcomm2014_memory_alloc(memory, 0, sizeof(*result));
+  if (result) {
+    result->decoder.context = result;
+    result->decoder.reader = reader;
+    result->decoder.reader->decoder = &result->decoder;
+    result->decoder.reader->data = 0;
+    result->decoder.reader->data_size = 0;
+    result->decoder.reader->count = 0;
+    result->decoder.reader->pos = 0;
+    result->decoder.reader->error = 0;
+    result->decoder.reader_allocated = 0;
+    result->decoder.version_ok = 0;
+    result->decoder.error = error;
+    result->decoder.memory = memory;
+    result->decoder.scheduler = scheduler;
+    result->decoder.on_error = labcomm20142014_on_error_fprintf;
+    result->decoder.register_sample = do_register_sample;
+    result->decoder.ioctl = do_ioctl;
+    result->decoder.index_to_signature = do_index_to_signature;
+    LABCOMM_SIGNATURE_ARRAY_INIT(result->local, struct sample_entry);
+    LABCOMM_SIGNATURE_ARRAY_INIT(result->remote_to_local, int);
+    LABCOMM_SIGNATURE_ARRAY_INIT(result->local_ref, 
+                                 const struct labcomm2014_signature*);
+    LABCOMM_SIGNATURE_ARRAY_INIT(result->remote_to_local_ref, int);
+  }
+  return &(result->decoder);
+}
+
+void labcomm2014_decoder_free(struct labcomm2014_decoder* d)
+{
+  struct decoder *id = d->context;
+  struct labcomm2014_memory *memory = d->memory;
+
+  labcomm2014_reader_free(d->reader, d->reader->action_context);
+  LABCOMM_SIGNATURE_ARRAY_FREE(memory, id->local, struct sample_entry);
+  LABCOMM_SIGNATURE_ARRAY_FREE(memory, id->remote_to_local, int);
+  LABCOMM_SIGNATURE_ARRAY_FREE(memory, id->local_ref, 
+                               const struct labcomm2014_signature*);
+  LABCOMM_SIGNATURE_ARRAY_FREE(memory, id->remote_to_local_ref, int);
+  labcomm2014_memory_free(memory, 0, id);
+}
+
diff --git a/lib/c/2014/labcomm2014_encoder.c b/lib/c/2014/labcomm2014_encoder.c
index cbd38c8..d603e5f 100644
--- a/lib/c/2014/labcomm2014_encoder.c
+++ b/lib/c/2014/labcomm2014_encoder.c
@@ -29,89 +29,26 @@
 //define the following to disable encoding of typedefs
 #undef LABCOMM_WITHOUT_TYPE_DEFS
 
-struct labcomm2014_encoder {
-  struct labcomm2014_writer *writer;
-  struct labcomm2014_error_handler *error;
-  struct labcomm2014_memory *memory;
-  struct labcomm2014_scheduler *scheduler;
+struct encoder {
+  struct labcomm2014_encoder encoder;
   LABCOMM_SIGNATURE_ARRAY_DEF(registered, int);
   LABCOMM_SIGNATURE_ARRAY_DEF(sample_ref, int);
   LABCOMM_SIGNATURE_ARRAY_DEF(typedefs, int);
 };
 
-static struct labcomm2014_encoder *internal_encoder_new(
-  struct labcomm2014_writer *writer,
-  struct labcomm2014_error_handler *error,
-  struct labcomm2014_memory *memory,
-  struct labcomm2014_scheduler *scheduler,
-  labcomm2014_bool outputVer)
-{
-  struct labcomm2014_encoder *result;
-
-  result = labcomm2014_memory_alloc(memory, 0, sizeof(*result));
-  if (result) {
-    int length;
-
-    result->writer = writer;
-    result->writer->encoder = result;
-    result->writer->data = NULL;
-    result->writer->data_size = 0;
-    result->writer->count = 0;
-    result->writer->pos = 0;
-    result->writer->error = 0;
-    result->error = error;
-    result->memory = memory;
-    result->scheduler = scheduler;
-    LABCOMM_SIGNATURE_ARRAY_INIT(result->registered, int);
-    LABCOMM_SIGNATURE_ARRAY_INIT(result->sample_ref, int);
-    LABCOMM_SIGNATURE_ARRAY_INIT(result->typedefs, int);
-    labcomm2014_writer_alloc(result->writer,
-			 result->writer->action_context);
-    if(outputVer) {
-        labcomm2014_writer_start(result->writer,
-                            result->writer->action_context,
-                            LABCOMM_VERSION, NULL, CURRENT_VERSION);
-        labcomm2014_write_packed32(result->writer, LABCOMM_VERSION);
-        length = labcomm2014_size_string(CURRENT_VERSION);
-        labcomm2014_write_packed32(result->writer, length);
-        labcomm2014_write_string(result->writer, CURRENT_VERSION);
-        labcomm2014_writer_end(result->writer, result->writer->action_context);
-    }
-  }
-  return result;
-}
-
-struct labcomm2014_encoder *labcomm2014_encoder_new(
-  struct labcomm2014_writer *writer,
-  struct labcomm2014_error_handler *error,
-  struct labcomm2014_memory *memory,
-  struct labcomm2014_scheduler *scheduler)
-{
-    return internal_encoder_new(writer,error,memory,scheduler,LABCOMM2014_TRUE);
-}
-void labcomm2014_encoder_free(struct labcomm2014_encoder* e)
-{
-  struct labcomm2014_memory *memory = e->memory;
-
-  labcomm2014_writer_free(e->writer, e->writer->action_context);
-  LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, e->registered, int);
-  LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, e->sample_ref, int);
-  LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, e->typedefs, int);
-  labcomm2014_memory_free(memory, 0, e);
-}
-
-int labcomm2014_internal_encoder_register(
+static int do_sample_register(
   struct labcomm2014_encoder *e,
   const struct labcomm2014_signature *signature,
   labcomm2014_encoder_function encode)
 {
   int result = -EINVAL;
+  struct encoder *ie = e->context;
   int index, *done, err, i, length;
 
   index = labcomm2014_get_local_index(signature);
   labcomm2014_scheduler_writer_lock(e->scheduler);
   if (index <= 0) { goto out; }
-  done = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, e->registered, int, index);
+  done = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, ie->registered, int, index);
   if (*done) {
       goto out; }
   *done = 1;
@@ -142,23 +79,24 @@ out:
   return result;
 }
 
-int labcomm2014_internal_encode(
+static int do_encode(
   struct labcomm2014_encoder *e,
   const struct labcomm2014_signature *signature,
   labcomm2014_encoder_function encode,
   void *value)
 {
   int result, index, length;
-
+  struct encoder *ie = e->context;
+  
   index = labcomm2014_get_local_index(signature);
   length = (signature->encoded_size(value));
   labcomm2014_scheduler_writer_lock(e->scheduler);
-  if (! LABCOMM_SIGNATURE_ARRAY_GET(e->registered, int, index, 0)) {
+  if (! LABCOMM_SIGNATURE_ARRAY_GET(ie->registered, int, index, 0)) {
     result = -EINVAL;
     goto no_end;
   }
   result = labcomm2014_writer_start(e->writer, e->writer->action_context,
-				index, signature, value);
+                                    index, signature, value);
   if (result == -EALREADY) { result = 0; goto no_end; }
   if (result != 0) { goto out; }
   result = labcomm2014_write_packed32(e->writer, index);
@@ -177,13 +115,14 @@ int labcomm2014_encoder_sample_ref_register(
   const struct labcomm2014_signature *signature)
 {
   int result = -EINVAL;
+  struct encoder *ie = e->context;
   int index, *done, err, i, length;
 
   index = labcomm2014_get_local_index(signature);
   labcomm2014_scheduler_writer_lock(e->scheduler);
   if (index <= 0) { goto out; }
 
-  done = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, e->sample_ref, int, index);
+  done = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, ie->sample_ref, int, index);
   if (*done) { goto out; }
   *done = 1;
   err = labcomm2014_writer_start(e->writer, e->writer->action_context,
@@ -235,9 +174,10 @@ out:
   return result;
 }
 
-int labcomm2014_internal_encoder_ioctl(struct labcomm2014_encoder *encoder,
-				   const struct labcomm2014_signature *signature,
-				   uint32_t action, va_list va)
+static int do_ioctl(
+  struct labcomm2014_encoder *encoder,
+  const struct labcomm2014_signature *signature,
+  uint32_t action, va_list va)
 {
   int result = -ENOTSUP;
   int index;
@@ -249,14 +189,15 @@ int labcomm2014_internal_encoder_ioctl(struct labcomm2014_encoder *encoder,
   return result;
 }
 
-int labcomm2014_internal_encoder_signature_to_index(
+static int do_signature_to_index(
   struct labcomm2014_encoder *e, const struct labcomm2014_signature *signature)
 {
   /* writer_lock should be held at this point */
+  struct encoder *ie = e->context;
   int index = 0;
   if (signature != NULL) {
     index = labcomm2014_get_local_index(signature);
-    if (! LABCOMM_SIGNATURE_ARRAY_GET(e->sample_ref, int, index, 0)) {
+    if (! LABCOMM_SIGNATURE_ARRAY_GET(ie->sample_ref, int, index, 0)) {
       index = 0;
     }
   }
@@ -321,15 +262,16 @@ static int internal_reg_type(
 {
   int result = -EINVAL;
   int index, *done, err;
-
+  struct encoder *ie = e->context;
+  
   index = labcomm2014_get_local_index(signature);
   labcomm2014_scheduler_writer_lock(e->scheduler);
   if (index <= 0) { goto out; }
-  done = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, e->typedefs, int, index);
+  done = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, ie->typedefs, int, index);
   if (*done) { goto out; }
   *done = 1;
   err = labcomm2014_writer_start(e->writer, e->writer->action_context,
-                 index, signature, NULL);
+                                 index, signature, NULL);
   if (err == -EALREADY) { result = 0; goto out; }
   if (err != 0) { result = err; goto out; }
 
@@ -354,7 +296,7 @@ out:
 }
 #endif
 
-int labcomm2014_internal_encoder_type_register(
+static int do_type_register(
   struct labcomm2014_encoder *e,
   const struct labcomm2014_signature *signature)
 {
@@ -364,7 +306,8 @@ int labcomm2014_internal_encoder_type_register(
   return 0;
 #endif
 }
-int labcomm2014_internal_encoder_type_bind(
+
+static int do_type_bind(
   struct labcomm2014_encoder *e,
   const struct labcomm2014_signature *signature,
   char has_deps)
@@ -396,3 +339,75 @@ out:
   return 0;
 #endif
 }
+
+static struct labcomm2014_encoder *internal_encoder_new(
+  struct labcomm2014_writer *writer,
+  struct labcomm2014_error_handler *error,
+  struct labcomm2014_memory *memory,
+  struct labcomm2014_scheduler *scheduler,
+  labcomm2014_bool outputVer)
+{
+  struct encoder *result;
+
+  result = labcomm2014_memory_alloc(memory, 0, sizeof(*result));
+  if (result) {
+    int length;
+
+    result->encoder.context = result;
+    result->encoder.writer = writer;
+    result->encoder.writer->encoder = &result->encoder;
+    result->encoder.writer->data = NULL;
+    result->encoder.writer->data_size = 0;
+    result->encoder.writer->count = 0;
+    result->encoder.writer->pos = 0;
+    result->encoder.writer->error = 0;
+    result->encoder.error = error;
+    result->encoder.memory = memory;
+    result->encoder.scheduler = scheduler;
+    result->encoder.type_register = do_type_register;
+    result->encoder.type_bind = do_type_bind;
+    result->encoder.sample_register = do_sample_register;
+    result->encoder.encode = do_encode;
+    result->encoder.ioctl = do_ioctl;
+    result->encoder.signature_to_index = do_signature_to_index;
+    LABCOMM_SIGNATURE_ARRAY_INIT(result->registered, int);
+    LABCOMM_SIGNATURE_ARRAY_INIT(result->sample_ref, int);
+    LABCOMM_SIGNATURE_ARRAY_INIT(result->typedefs, int);
+    labcomm2014_writer_alloc(result->encoder.writer,
+                             result->encoder.writer->action_context);
+    if(outputVer) {
+        labcomm2014_writer_start(result->encoder.writer,
+                                 result->encoder.writer->action_context,
+                                 LABCOMM_VERSION, NULL, CURRENT_VERSION);
+        labcomm2014_write_packed32(result->encoder.writer, LABCOMM_VERSION);
+        length = labcomm2014_size_string(CURRENT_VERSION);
+        labcomm2014_write_packed32(result->encoder.writer, length);
+        labcomm2014_write_string(result->encoder.writer, CURRENT_VERSION);
+        labcomm2014_writer_end(result->encoder.writer,
+                               result->encoder.writer->action_context);
+    }
+  }
+  return &(result->encoder);
+}
+
+struct labcomm2014_encoder *labcomm2014_encoder_new(
+  struct labcomm2014_writer *writer,
+  struct labcomm2014_error_handler *error,
+  struct labcomm2014_memory *memory,
+  struct labcomm2014_scheduler *scheduler)
+{
+    return internal_encoder_new(writer,error,memory,scheduler,LABCOMM2014_TRUE);
+}
+
+void labcomm2014_encoder_free(struct labcomm2014_encoder* e)
+{
+  struct encoder *ie = e->context;
+  struct labcomm2014_memory *memory = e->memory;
+
+  labcomm2014_writer_free(e->writer, e->writer->action_context);
+  LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, ie->registered, int);
+  LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, ie->sample_ref, int);
+  LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, ie->typedefs, int);
+  labcomm2014_memory_free(memory, 0, ie);
+}
+
diff --git a/lib/c/2014/labcomm2014_private.h b/lib/c/2014/labcomm2014_private.h
index 0306072..b67f748 100644
--- a/lib/c/2014/labcomm2014_private.h
+++ b/lib/c/2014/labcomm2014_private.h
@@ -185,23 +185,33 @@ int labcomm2014_reader_ioctl(struct labcomm2014_reader *r,
 			 const struct labcomm2014_signature *signature, 
 			 uint32_t ioctl_action, va_list args);
 
-/*
- * Non typesafe registration function to be called from
- * generated labcomm2014_decoder_register_* functions.
- */
-int labcomm2014_internal_decoder_register(
-  struct labcomm2014_decoder *d, 
-  const struct labcomm2014_signature *s, 
-  labcomm2014_decoder_function decoder,
-  labcomm2014_handler_function handler,
-  void *context);
-
-int labcomm2014_internal_decoder_ioctl(struct labcomm2014_decoder *decoder, 
-				   const struct labcomm2014_signature *signature,
-				   uint32_t ioctl_action, va_list args);
+struct labcomm2014_decoder {
+  void *context;
+  struct labcomm2014_reader *reader;
+  struct labcomm2014_error_handler *error;
+  struct labcomm2014_memory *memory;
+  struct labcomm2014_scheduler *scheduler;
+  int reader_allocated;
+  int version_ok;
+  labcomm2014_error_handler_callback on_error;
+  labcomm2014_handle_new_datatype_callback on_new_datatype;
+  /*
+   * Non typesafe registration function to be called from
+   * generated labcomm2014_decoder_register_* functions.
+   */
+  int (*register_sample)(struct labcomm2014_decoder *d, 
+                         const struct labcomm2014_signature *s, 
+                         labcomm2014_decoder_function decoder,
+                         labcomm2014_handler_function handler,
+                         void *context);
+  int (*ioctl)(struct labcomm2014_decoder *d, 
+               const struct labcomm2014_signature *s,
+               uint32_t ioctl_action, va_list args);
+
+  const struct labcomm2014_signature *(*index_to_signature)(
+    struct labcomm2014_decoder *decoder, int index);
 
-const struct labcomm2014_signature *labcomm2014_internal_decoder_index_to_signature(
-  struct labcomm2014_decoder *decoder, int index);
+};
 
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 
@@ -353,6 +363,32 @@ struct labcomm2014_writer {
   int error;
 };
 
+struct labcomm2014_encoder {
+  void *context;
+  struct labcomm2014_writer *writer;
+  struct labcomm2014_error_handler *error;
+  struct labcomm2014_memory *memory;
+  struct labcomm2014_scheduler *scheduler;
+  int (*type_register)(struct labcomm2014_encoder *e,
+                       const struct labcomm2014_signature *signature);
+  int (*type_bind)(struct labcomm2014_encoder *e,
+                   const struct labcomm2014_signature *signature,
+                   char has_deps);
+  int (*sample_register)(struct labcomm2014_encoder *encoder, 
+                         const struct labcomm2014_signature *signature, 
+                         labcomm2014_encoder_function encode);
+  int (*encode)(struct labcomm2014_encoder *encoder, 
+                const struct labcomm2014_signature *signature, 
+                labcomm2014_encoder_function encode,
+                void *value);
+  int (*ioctl)(struct labcomm2014_encoder *encoder, 
+             const struct labcomm2014_signature *signature,
+             uint32_t ioctl_action, va_list args);
+  int (*signature_to_index)(struct labcomm2014_encoder *encoder,
+                            const struct labcomm2014_signature *signature);
+};
+
+
 int labcomm2014_writer_alloc(struct labcomm2014_writer *w, 
 			 struct labcomm2014_writer_action_context *action_context);
 int labcomm2014_writer_free(struct labcomm2014_writer *w, 
@@ -370,33 +406,6 @@ int labcomm2014_writer_ioctl(struct labcomm2014_writer *w,
 			 int index, const struct labcomm2014_signature *signature, 
 			 uint32_t ioctl_action, va_list args);
 
-int labcomm2014_internal_encoder_type_register(
-  struct labcomm2014_encoder *e,
-  const struct labcomm2014_signature *signature);
-
-int labcomm2014_internal_encoder_type_bind(
-  struct labcomm2014_encoder *e,
-  const struct labcomm2014_signature *signature,
-  char has_deps);
-
-int labcomm2014_internal_encoder_register(
-  struct labcomm2014_encoder *encoder, 
-  const struct labcomm2014_signature *signature, 
-  labcomm2014_encoder_function encode);
-
-int labcomm2014_internal_encode(
-  struct labcomm2014_encoder *encoder, 
-  const struct labcomm2014_signature *signature, 
-  labcomm2014_encoder_function encode,
-  void *value);
-
-int labcomm2014_internal_encoder_ioctl(struct labcomm2014_encoder *encoder, 
-				   const struct labcomm2014_signature *signature,
-				   uint32_t ioctl_action, va_list args);
-
-int labcomm2014_internal_encoder_signature_to_index(
-  struct labcomm2014_encoder *encoder, const struct labcomm2014_signature *signature);
-
 int labcomm2014_internal_sizeof(const struct labcomm2014_signature *signature,
                             void *v);
 
diff --git a/lib/python/labcomm2014/LabComm.py b/lib/python/labcomm2014/LabComm.py
index bff63de..abf071b 100644
--- a/lib/python/labcomm2014/LabComm.py
+++ b/lib/python/labcomm2014/LabComm.py
@@ -450,6 +450,10 @@ class sample_def(sampledef_or_sampleref_or_typedef):
 
     def add_index(self, decoder, index, decl):
         decoder.add_decl(decl, index)
+
+    def rename(self, name):
+        return sample_def(name=name, decl=self.decl)
+        
     
 class sample_ref(sampledef_or_sampleref_or_typedef):
     type_index = i_SAMPLE_REF
diff --git a/packaging/.gitignore b/packaging/.gitignore
index 9f87b19..f73a06a 100644
--- a/packaging/.gitignore
+++ b/packaging/.gitignore
@@ -1,2 +1,2 @@
-labcomm-*.src.rpm
+labcomm2014-*.src.rpm
 rpmbuild
-- 
GitLab