CELIX-237: Updated serialized. Added parse tests and conresponding 
implementation and added write functionality


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/24d13f2e
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/24d13f2e
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/24d13f2e

Branch: refs/heads/feature/CELIX-237_rsa-ffi
Commit: 24d13f2ef08de444739e441471e87b349eb6972e
Parents: 9f2ea10
Author: Pepijn Noltes <pepijnnol...@gmail.com>
Authored: Fri Jul 31 12:17:30 2015 +0200
Committer: Pepijn Noltes <pepijnnol...@gmail.com>
Committed: Fri Jul 31 12:17:30 2015 +0200

----------------------------------------------------------------------
 .../dynamic_function_interface/dyn_type.c       | 234 ++++++++---
 .../dynamic_function_interface/dyn_type.h       |  30 +-
 .../json_serializer.c                           | 407 +++++++++++++++----
 .../json_serializer.h                           |   8 +-
 .../tst/json_serializer_tests.cpp               | 265 ++++++++++--
 5 files changed, 765 insertions(+), 179 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/24d13f2e/remote_services/dynamic_function_interface/dyn_type.c
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/dyn_type.c 
b/remote_services/dynamic_function_interface/dyn_type.c
index f90f432..6de9736 100644
--- a/remote_services/dynamic_function_interface/dyn_type.c
+++ b/remote_services/dynamic_function_interface/dyn_type.c
@@ -47,43 +47,45 @@ static void dynType_printTypes(dyn_type *type, FILE 
*stream);
 static void dynType_printComplexType(dyn_type *type, FILE *stream);
 static void dynType_printSimpleType(dyn_type *type, FILE *stream);
 
+static int dynType_parseText(FILE *stream, dyn_type *type);
+
 struct generic_sequence {
     uint32_t cap;
     uint32_t len;
     void *buf;
 };
 
-static const int DT_OK = 0;
-static const int DT_ERROR = 1;
-static const int DT_MEM_ERROR = 2;
-static const int DT_PARSE_ERROR = 3;
+static const int OK = 0;
+static const int ERROR = 1;
+static const int MEM_ERROR = 2;
+static const int PARSE_ERROR = 3;
 
 int dynType_parse(FILE *descriptorStream, const char *name, struct 
reference_types_head *refTypes, dyn_type **type) {
     return dynType_parseWithStream(descriptorStream, name, NULL, refTypes, 
type);
 }
 
 int dynType_parseWithStr(const char *descriptor, const char *name, struct 
reference_types_head *refTypes, dyn_type **type) {
-    int status = DT_OK;
+    int status = OK;
     FILE *stream = fmemopen((char *)descriptor, strlen(descriptor), "r");
     if (stream != NULL) {
         status = dynType_parseWithStream(stream, name, NULL, refTypes, type);
-        if (status == DT_OK) {
+        if (status == OK) {
             int c = fgetc(stream);
             if (c != '\0' && c != EOF) {
-                status = DT_PARSE_ERROR;
+                status = PARSE_ERROR;
                 LOG_ERROR("Expected EOF got %c", c);
             }
         } 
         fclose(stream);
     } else {
-        status = DT_ERROR;
+        status = ERROR;
         LOG_ERROR("Error creating mem stream for descriptor string. %s", 
strerror(errno)); 
     }
     return status;
 }
 
 static int dynType_parseWithStream(FILE *stream, const char *name, dyn_type 
*parent, struct reference_types_head *refTypes, dyn_type **result) {
-    int status = DT_OK;
+    int status = OK;
     dyn_type *type = calloc(1, sizeof(*type));
     if (type != NULL) {
         type->parent = parent;
@@ -93,33 +95,33 @@ static int dynType_parseWithStream(FILE *stream, const char 
*name, dyn_type *par
         if (name != NULL) {
             type->name = strdup(name);
             if (type->name == NULL) {
-                status = DT_MEM_ERROR;
+                status = MEM_ERROR;
                 LOG_ERROR("Error strdup'ing name '%s'\n", name);               
        
             } 
         }
-        if (status == DT_OK) {
+        if (status == OK) {
             status = dynType_parseAny(stream, type);        
         }
-        if (status == DT_OK) {
+        if (status == OK) {
             *result = type;
         } else {
             dynType_destroy(type);
         }
     } else {
-        status = DT_MEM_ERROR;
+        status = MEM_ERROR;
         LOG_ERROR("Error allocating memory for type");
     }
     return status;
 }
 
 static int dynType_parseAny(FILE *stream, dyn_type *type) {
-    int status = DT_OK;
+    int status = OK;
 
     int c = fgetc(stream);
     switch(c) {
         case 'T' :
             status = dynType_parseNestedType(stream, type);
-            if (status == DT_OK) {
+            if (status == OK) {
                 status = dynType_parseAny(stream, type);
             } 
             break;
@@ -138,6 +140,9 @@ static int dynType_parseAny(FILE *stream, dyn_type *type) {
         case '*' :
             status = dynType_parseTypedPointer(stream, type);
             break;
+        case 't' :
+            status = dynType_parseText(stream, type);
+            break;
         default :
             status = dynType_parseSimple(c, type);
             break;
@@ -146,8 +151,16 @@ static int dynType_parseAny(FILE *stream, dyn_type *type) {
     return status;
 }
 
+static int dynType_parseText(FILE *stream, dyn_type *type) {
+    int status = OK;
+    type->type = DYN_TYPE_TEXT;
+    type->descriptor = 't';
+    type->ffiType = &ffi_type_pointer;
+    return status;
+}
+
 static int dynType_parseComplex(FILE *stream, dyn_type *type) {
-    int status = DT_OK;
+    int status = OK;
     type->type = DYN_TYPE_COMPLEX;
     type->descriptor = '{';
     type->ffiType = &type->complex.structType;
@@ -165,7 +178,7 @@ static int dynType_parseComplex(FILE *stream, dyn_type 
*type) {
             TAILQ_INSERT_TAIL(&type->complex.entriesHead, entry, entries);
             status = dynType_parseAny(stream, &entry->type);
         } else {
-            status = DT_MEM_ERROR;
+            status = MEM_ERROR;
             LOG_ERROR("Error allocating memory for type");
         }
         c = fgetc(stream);
@@ -175,7 +188,7 @@ static int dynType_parseComplex(FILE *stream, dyn_type 
*type) {
     char *name = NULL;
     while (c == ' ' && entry != NULL) {
         status = dynCommon_parseName(stream, &name);
-        if (status == DT_OK) {
+        if (status == OK) {
             entry->name = name;
             entry = TAILQ_NEXT(entry, entries);
         } else {
@@ -189,7 +202,7 @@ static int dynType_parseComplex(FILE *stream, dyn_type 
*type) {
         count +=1;
     }
 
-    if (status == DT_OK) {
+    if (status == OK) {
         type->complex.structType.type =  FFI_TYPE_STRUCT;
         type->complex.structType.elements = calloc(count + 1, 
sizeof(ffi_type));
         type->complex.structType.elements[count] = NULL;
@@ -199,12 +212,12 @@ static int dynType_parseComplex(FILE *stream, dyn_type 
*type) {
                 type->complex.structType.elements[index++] = 
entry->type.ffiType;
             }
         } else {
-            status = DT_MEM_ERROR;
+            status = MEM_ERROR;
             //T\nODO log: error allocating memory
         }
     }
 
-    if (status == DT_OK) {
+    if (status == OK) {
         type->complex.types = calloc(count, sizeof(dyn_type *));
         if (type != NULL) {
             int index = 0;
@@ -212,12 +225,12 @@ static int dynType_parseComplex(FILE *stream, dyn_type 
*type) {
                 type->complex.types[index++] = &entry->type;
             }
         } else {
-            status = DT_MEM_ERROR;
+            status = MEM_ERROR;
             LOG_ERROR("Error allocating memory for type")
         }
     }
 
-    if (status == DT_OK) {
+    if (status == OK) {
         dynType_prepCif(type->ffiType);
     }
 
@@ -226,7 +239,7 @@ static int dynType_parseComplex(FILE *stream, dyn_type 
*type) {
 }
 
 static int dynType_parseNestedType(FILE *stream, dyn_type *type) {
-    int status = DT_OK;
+    int status = OK;
     char *name = NULL;
     struct nested_entry *entry = NULL; 
 
@@ -239,22 +252,22 @@ static int dynType_parseNestedType(FILE *stream, dyn_type 
*type) {
         status = dynCommon_parseName(stream, &name);
         entry->type.name = name;
     } else {
-        status = DT_MEM_ERROR;  
+        status = MEM_ERROR;
     }     
 
-    if (status == DT_OK) {
+    if (status == OK) {
         int c = fgetc(stream);
         if (c != '=') {
-            status = DT_PARSE_ERROR;
+            status = PARSE_ERROR;
             LOG_ERROR("Error parsing nested type expected '=' got '%c'", c);
         }
     }
 
-    if (status == DT_OK) {
+    if (status == OK) {
         status = dynType_parseAny(stream, &entry->type);
         int c = fgetc(stream);
         if (c != ';') {
-            status = DT_PARSE_ERROR;
+            status = PARSE_ERROR;
             LOG_ERROR("Expected ';' got '%c'\n", c);
         }
     }
@@ -263,7 +276,7 @@ static int dynType_parseNestedType(FILE *stream, dyn_type 
*type) {
 }
 
 static int dynType_parseReference(FILE *stream, dyn_type *type) {
-    int status = DT_OK;
+    int status = OK;
     type->type = DYN_TYPE_TYPED_POINTER;
     type->descriptor = '*';
 
@@ -279,7 +292,7 @@ static int dynType_parseReference(FILE *stream, dyn_type 
*type) {
         TAILQ_INIT(&subType->nestedTypesHead);
         status = dynType_parseRefByValue(stream, subType);
     } else {
-        status = DT_MEM_ERROR;
+        status = MEM_ERROR;
         LOG_ERROR("Error allocating memory for subtype\n");
     }
 
@@ -287,27 +300,27 @@ static int dynType_parseReference(FILE *stream, dyn_type 
*type) {
 }
 
 static int dynType_parseRefByValue(FILE *stream, dyn_type *type) {
-    int status = DT_OK;
+    int status = OK;
     type->type = DYN_TYPE_REF;
     type->descriptor = 'l';
 
     char *name = NULL;
     status = dynCommon_parseName(stream, &name);
-    if (status == DT_OK) {
+    if (status == OK) {
         dyn_type *ref = dynType_findType(type, name);
         if (ref != NULL) {
             type->ref.ref = ref;
         } else {
-            status = DT_PARSE_ERROR;
+            status = PARSE_ERROR;
             LOG_ERROR("Error cannot find type '%s'", name);
         }
         free(name);
     } 
 
-    if (status == DT_OK) {
+    if (status == OK) {
         int c = fgetc(stream);
         if (c != ';') {
-            status = DT_PARSE_ERROR;
+            status = PARSE_ERROR;
             LOG_ERROR("Error expected ';' got '%c'", c);
         } 
     }
@@ -318,14 +331,14 @@ static int dynType_parseRefByValue(FILE *stream, dyn_type 
*type) {
 static ffi_type *seq_types[] = {&ffi_type_uint32, &ffi_type_uint32, 
&ffi_type_pointer, NULL};
 
 static int dynType_parseSequence(FILE *stream, dyn_type *type) {
-    int status = DT_OK;
+    int status = OK;
     type->type = DYN_TYPE_SEQUENCE;
     type->descriptor = '[';
 
     type->sequence.seqType.elements = seq_types;
     status = dynType_parseWithStream(stream, NULL, type, NULL, 
&type->sequence.itemType);
 
-    if (status == DT_OK) {
+    if (status == OK) {
         type->ffiType = &type->sequence.seqType;
         dynType_prepCif(&type->sequence.seqType);
     }
@@ -334,14 +347,14 @@ static int dynType_parseSequence(FILE *stream, dyn_type 
*type) {
 }
 
 static int dynType_parseSimple(int c, dyn_type *type) {
-    int status = DT_OK;
+    int status = OK;
     ffi_type *ffiType = dynType_ffiTypeFor(c);
     if (ffiType != NULL) {
         type->type = DYN_TYPE_SIMPLE;
         type->descriptor = c;
         type->ffiType = ffiType;
     } else {
-        status = DT_PARSE_ERROR;
+        status = PARSE_ERROR;
         LOG_ERROR("Error unsupported type '%c'", c);
     }
 
@@ -349,7 +362,7 @@ static int dynType_parseSimple(int c, dyn_type *type) {
 }
 
 static int dynType_parseTypedPointer(FILE *stream, dyn_type *type) {
-    int status = DT_OK;
+    int status = OK;
     type->type = DYN_TYPE_TYPED_POINTER;
     type->descriptor = '*';
     type->ffiType = &ffi_type_pointer;
@@ -436,14 +449,17 @@ static void dynType_clearTypedPointer(dyn_type *type) {
 }
 
 int dynType_alloc(dyn_type *type, void **bufLoc) {
-    int status = DT_OK;
+    assert(type->type != DYN_TYPE_REF);
+    int status = OK;
+
     void *inst = calloc(1, type->ffiType->size);
     if (inst != NULL) {
         *bufLoc = inst;
     } else {
-        status = DT_MEM_ERROR;
+        status = MEM_ERROR;
         LOG_ERROR("Error allocating memory for type '%c'", type->descriptor);
     }
+
     return status;
 }
 
@@ -471,7 +487,11 @@ char dynType_complex_descriptorTypeAt(dyn_type *type, int 
index) {
 
 int dynType_complex_dynTypeAt(dyn_type *type, int index, dyn_type **result) {
     assert(type->type == DYN_TYPE_COMPLEX);
-    *result = type->complex.types[index];
+    dyn_type *sub = type->complex.types[index];
+    if (sub->type == DYN_TYPE_REF) {
+        sub = sub->ref.ref;
+    }
+    *result = sub;
     return 0;
 }
 
@@ -491,10 +511,17 @@ int dynType_complex_valLocAt(dyn_type *type, int index, 
void *inst, void **resul
     return 0;
 }
 
+int dynType_complex_entries(dyn_type *type, struct complex_type_entries_head 
**entries) {
+    assert(type->type == DYN_TYPE_COMPLEX);
+    int status = OK;
+    *entries = &type->complex.entriesHead;
+    return status;
+}
+
 //sequence
 int dynType_sequence_alloc(dyn_type *type, void *inst, int cap, void **out) {
     assert(type->type == DYN_TYPE_SEQUENCE);
-    int status = DT_OK;
+    int status = OK;
     struct generic_sequence *seq = inst;
     if (seq != NULL) {
         size_t size = dynType_size(type->sequence.itemType);
@@ -505,11 +532,11 @@ int dynType_sequence_alloc(dyn_type *type, void *inst, 
int cap, void **out) {
             *out = seq->buf;
         } else {
             seq->cap = 0;
-            status = DT_MEM_ERROR;
+            status = MEM_ERROR;
             LOG_ERROR("Error allocating memory for buf")
         }
     } else {
-            status = DT_MEM_ERROR;
+            status = MEM_ERROR;
             LOG_ERROR("Error allocating memory for seq")
     }
     return status;
@@ -517,31 +544,73 @@ int dynType_sequence_alloc(dyn_type *type, void *inst, 
int cap, void **out) {
 
 void dynType_free(dyn_type *type, void *loc) {
     //TODO
-    LOG_INFO("TODO");
+    LOG_INFO("TODO dynType_free");
 }
 
-int dynType_sequence_append(dyn_type *type, void *inst, void *in) {
+uint32_t dynType_sequence_length(void *seqLoc) {
+    struct generic_sequence *seq = seqLoc;
+    return seq->len;
+}
+
+int dynType_sequence_locForIndex(dyn_type *type, void *seqLoc, int index, void 
**out) {
     assert(type->type == DYN_TYPE_SEQUENCE);
-    int status = DT_OK;
-    int index = -1;
-    struct generic_sequence *seq = inst;
-    if (seq->len + 1 <= seq->cap) {
-        index = seq->len;
+    int status = OK;
+
+    struct generic_sequence *seq = seqLoc;
+    char *valLoc = seq->buf;
+    size_t itemSize = type->sequence.itemType->ffiType->size;
+
+    if (index >= seq->cap) {
+        status = ERROR;
+        LOG_ERROR("Requested index (%i) is greater than capacity (%u) of 
sequence", index, seq->cap);
+    }
+
+    if (index >= seq->len) {
+        LOG_WARNING("Requesting index (%i) outsize defined length (%u) but 
within capacity", index, seq->len);
+    }
+
+    if (status == OK) { }
+    int i;
+    for (i = 0; i < seq->cap; i += 1) {
+        if (index == i) {
+            break;
+        } else {
+            valLoc += itemSize;
+        }
+    }
+
+    (*out) = valLoc;
+
+    return status;
+}
+
+int dynType_sequence_increaseLengthAndReturnLastLoc(dyn_type *type, void 
*seqLoc, void **valLoc) {
+    assert(type->type == DYN_TYPE_SEQUENCE);
+    int status = OK;
+    struct generic_sequence *seq = seqLoc;
+
+    int lastIndex = seq->len;
+    if (seq->len < seq->cap) {
         seq->len += 1;
-        char *buf = seq->buf;
-        size_t elSize = dynType_size(type->sequence.itemType);
-        size_t offset = (elSize * index);
-        memcpy(buf + offset, in, elSize);
     } else {
-        status = DT_ERROR;
-        LOG_ERROR("Sequence out of capacity")
+        status = ERROR;
+        LOG_ERROR("Cannot increase sequence length beyond capacity (%u)", 
seq->cap);
+    }
+
+    if (status == OK) {
+        status = dynType_sequence_locForIndex(type, seqLoc, lastIndex, valLoc);
     }
+
     return status;
 }
 
 dyn_type * dynType_sequence_itemType(dyn_type *type) {
     assert(type->type == DYN_TYPE_SEQUENCE);
-    return type->sequence.itemType;
+    dyn_type *itemType = type->sequence.itemType;
+    if (itemType->type == DYN_TYPE_REF) {
+        itemType = itemType->ref.ref;
+    }
+    return itemType;
 }
 
 void dynType_simple_setValue(dyn_type *type, void *inst, void *in) {
@@ -658,6 +727,48 @@ int dynType_type(dyn_type *type) {
     return type->type;
 }
 
+
+int dynType_typedPointer_getTypedType(dyn_type *type, dyn_type **out) {
+    assert(type->type == DYN_TYPE_TYPED_POINTER);
+    int status = 0;
+
+    dyn_type *typedType = type->typedPointer.typedType;
+    if (typedType->type == DYN_TYPE_REF) {
+        typedType = typedType->ref.ref;
+    }
+
+    *out = typedType;
+    return status;
+}
+
+
+int dynType_text_allocAndInit(dyn_type *type, void *textLoc, const char 
*value) {
+    int status = 0;
+    const char *str = strdup(value);
+    char const **loc = textLoc;
+    if (str != NULL) {
+        *loc = str;
+    } else {
+        status = ERROR;
+        LOG_ERROR("Cannot allocate memory for string");
+    }
+    return status;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 void dynType_print(dyn_type *type, FILE *stream) {
     if (type != NULL) {
         dynType_printTypes(type, stream);
@@ -814,3 +925,4 @@ static void dynType_printComplexType(dyn_type *type, FILE 
*stream) {
 static void dynType_printSimpleType(dyn_type *type, FILE *stream) {
     fprintf(stream, "\ttype '%s': simple type, size is %zu, alignment is %i, 
descriptor is '%c'\n", type->name, type->ffiType->size, 
type->ffiType->alignment, type->descriptor);
 }
+

http://git-wip-us.apache.org/repos/asf/celix/blob/24d13f2e/remote_services/dynamic_function_interface/dyn_type.h
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/dyn_type.h 
b/remote_services/dynamic_function_interface/dyn_type.h
index a09a9da..bf6dfc8 100644
--- a/remote_services/dynamic_function_interface/dyn_type.h
+++ b/remote_services/dynamic_function_interface/dyn_type.h
@@ -10,6 +10,7 @@
 #include <stdbool.h>
 
 #include <ffi.h>
+#include <stdint.h>
 
 #include "dfi_log_util.h"
 
@@ -40,26 +41,28 @@
  * i uint32_t
  * j uint62_t
  * s uint64_t
- * P pointer
+ * P untyped pointer (void *)
  * t char* string
  * N native int
  *
- *
  * ComplexTypes (Struct)
  * {[Type]+ [(Name)(SPACE)]+}
  *
- * PointerReference
- * L(Name);
- *
  * ReferenceByValue
  * l(name);
  *
+ * PointerReference -> note shortcut for *l(name);
+ * L(Name);
+ *
  * TypeDef 
  * T(Name)=Type;
  *
  * SequenceType
  * [(Type)
  *
+ * TypedPointer
+ * *(Type)
+ *
  * Annotation TODO
  * <(Name)=(Value)>
  *
@@ -75,12 +78,14 @@
 #define DYN_TYPE_COMPLEX 2
 #define DYN_TYPE_SEQUENCE 3
 #define DYN_TYPE_TYPED_POINTER 4
-#define DYN_TYPE_REF 5
+#define DYN_TYPE_TEXT 5
+#define DYN_TYPE_REF 6
 
 typedef struct _dyn_type dyn_type;
 
 TAILQ_HEAD(reference_types_head, type_entry); 
-TAILQ_HEAD(nested_types_head, nested_entry); 
+TAILQ_HEAD(nested_types_head, nested_entry);
+TAILQ_HEAD(complex_type_entries_head, complex_type_entry);
 
 struct _dyn_type {
     char *name;
@@ -92,7 +97,7 @@ struct _dyn_type {
     struct nested_types_head  nestedTypesHead;
     union {
         struct {
-            TAILQ_HEAD(, complex_type_entry) entriesHead;
+            struct complex_type_entries_head entriesHead;
             ffi_type structType; //dyn_type.ffiType points to this
             dyn_type **types; //based on entriesHead for fast access
         } complex;
@@ -147,11 +152,18 @@ char dynType_complex_descriptorTypeAt(dyn_type *type, int 
index);
 int dynType_complex_dynTypeAt(dyn_type *type, int index, dyn_type **subType);
 int dynType_complex_setValueAt(dyn_type *type, int index, void *inst, void 
*in);
 int dynType_complex_valLocAt(dyn_type *type, int index, void *inst, void 
**valLoc);
+int dynType_complex_entries(dyn_type *type, struct complex_type_entries_head 
**entries);
 
 //sequence
 int dynType_sequence_alloc(dyn_type *type, void *inst, int cap, void **buf);
-int dynType_sequence_append(dyn_type *type, void *seq, void *in);
+int dynType_sequence_locForIndex(dyn_type *type, void *seqLoc, int index, void 
**valLoc);
+int dynType_sequence_increaseLengthAndReturnLastLoc(dyn_type *type, void 
*seqLoc, void **valLoc);
 dyn_type * dynType_sequence_itemType(dyn_type *type);
+uint32_t dynType_sequence_length(void *seqLoc);
+
+int dynType_typedPointer_getTypedType(dyn_type *type, dyn_type **typedType);
+
+int dynType_text_allocAndInit(dyn_type *type, void *textLoc, const char 
*value);
 
 //simple
 void dynType_simple_setValue(dyn_type *type, void *inst, void *in);

http://git-wip-us.apache.org/repos/asf/celix/blob/24d13f2e/remote_services/dynamic_function_interface/json_serializer.c
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/json_serializer.c 
b/remote_services/dynamic_function_interface/json_serializer.c
index 628bec9..3fbdda4 100644
--- a/remote_services/dynamic_function_interface/json_serializer.c
+++ b/remote_services/dynamic_function_interface/json_serializer.c
@@ -1,17 +1,32 @@
-/**
+/*
  * Licensed under Apache License v2. See LICENSE for more information.
  */
 #include "json_serializer.h"
+#include "dyn_type.h"
 
 #include <jansson.h>
 #include <assert.h>
+#include <stdint.h>
+#include <string.h>
 
-static int json_serializer_createObject(dyn_type *type, json_t *object, void 
**result);
-static int json_serializer_writeObject(dyn_type *type, json_t *object, void 
*inst);
-static void json_serializer_writeObjectMember(dyn_type *type, const char 
*name, json_t *val, void *inst); 
-static void json_serializer_writeSequence(json_t *array, dyn_type *seq, void 
*seqLoc); 
+static int jsonSerializer_createObject(dyn_type *type, json_t *object, void 
**result);
+static int jsonSerializer_parseObject(dyn_type *type, json_t *object, void 
*inst);
+static int jsonSerializer_parseObjectMember(dyn_type *type, const char *name, 
json_t *val, void *inst);
+static int jsonSerializer_parseSequence(dyn_type *seq, json_t *array, void 
*seqLoc);
+static int jsonSerializer_parseAny(dyn_type *type, void *input, json_t *val);
 
-int json_deserialize(dyn_type *type, const char *input, void **result) {
+static int jsonSerializer_writeAny(dyn_type *type, void *input, json_t **val);
+
+static int jsonSerializer_writeComplex(dyn_type *type, void *input, json_t 
**val);
+
+static int jsonSerializer_writeSequence(dyn_type *type, void *input, json_t 
**out);
+
+static int OK = 0;
+static int ERROR = 1;
+
+DFI_SETUP_LOG(jsonSerializer);
+
+int jsonSerializer_deserialize(dyn_type *type, const char *input, void 
**result) {
     assert(type->type == DYN_TYPE_COMPLEX);
     int status = 0;
 
@@ -19,133 +34,379 @@ int json_deserialize(dyn_type *type, const char *input, 
void **result) {
     json_t *root = json_loads(input, JSON_DECODE_ANY, &error);
 
     if (root != NULL) {
-        status = json_serializer_createObject(type, root, result);
+        if (json_is_object(root)) {
+            status = jsonSerializer_createObject(type, root, result);
+        } else {
+            status = ERROR;
+            LOG_ERROR("Error expected root element to be an object");
+        }
         json_decref(root);
     } else {
-        status = 1;
-        printf("JSON_SERIALIZER: error parsing json input '%s'. Error is 
%s\n", input, error.text);
+        status = ERROR;
+        LOG_ERROR("Error parsing json input '%s'. Error is %s\n", input, 
error.text);
     }
 
     return status;
 }
 
-static int json_serializer_createObject(dyn_type *type, json_t *object, void 
**result) {
+static int jsonSerializer_createObject(dyn_type *type, json_t *object, void 
**result) {
     assert(object != NULL);
-    int status = 0;
+    int status = OK;
 
     void *inst = NULL;
     status = dynType_alloc(type, &inst);
 
-    if (status == 0) {
+    if (status == OK) {
         assert(inst != NULL);
-        status = json_serializer_writeObject(type, object, inst);
-    } else {
-        //TODO destroy
+        status = jsonSerializer_parseObject(type, object, inst);
+
+        if (status != OK) {
+            dynType_free(type, inst);
+        }
     }
 
-    if (status == 0) {
+    if (status == OK) {
         *result = inst;
-    } 
+    }
 
     return status;
 }
-                
-static int json_serializer_writeObject(dyn_type *type, json_t *object, void 
*inst) {
+
+static int jsonSerializer_parseObject(dyn_type *type, json_t *object, void 
*inst) {
     assert(object != NULL);
     int status = 0;
     json_t *value;
     const char *key;
 
-    if (status == 0)  {
-        json_object_foreach(object, key, value) {
-            json_serializer_writeObjectMember(type, key, value, inst);
+    json_object_foreach(object, key, value) {
+        status = jsonSerializer_parseObjectMember(type, key, value, inst);
+        if (status != OK) {
+            break;
         }
-    } else {
-        status = 1;
-        printf("JSON_SERIALIZER: Error allocating memory\n");
     }
 
     return status;
 }
 
-static void json_serializer_writeObjectMember(dyn_type *type, const char 
*name, json_t *val, void *inst) {
-    //TODO rename to complex. write generic write
-    int status = 0;
+static int jsonSerializer_parseObjectMember(dyn_type *type, const char *name, 
json_t *val, void *inst) {
+    int status = OK;
     int index = dynType_complex_indexForName(type, name);
-    char charType = dynType_complex_descriptorTypeAt(type, index); 
     void *valp = NULL;
+    dyn_type *valType = NULL;
+
     status = dynType_complex_valLocAt(type, index, inst, &valp);
 
-    //TODO check status
+    if (status == OK ) {
+        status = dynType_complex_dynTypeAt(type, index, &valType);
+    }
 
-    float *f;
-    double *d;
-    char *c;
-    short *s;
-    int *i;
-    long *l;
-    dyn_type *nested;
+    if (status == OK) {
+        status = jsonSerializer_parseAny(valType, valp, val);
+    }
+
+    return status;
+}
 
-    switch (charType) {
+static int jsonSerializer_parseAny(dyn_type *type, void *loc, json_t *val) {
+    int status = OK;
+
+    dyn_type *subType = NULL;
+
+    float *f;           //F
+    double *d;          //D
+    char *b;            //B
+    int *n;             //N
+    int16_t *s;         //S
+    int32_t *i;         //I
+    int64_t *l;         //J
+    uint16_t  *us;      //s
+    uint32_t  *ui;      //i
+    uint64_t  *ul;      //j
+
+    switch (type->descriptor) {
         case 'F' :
-            f = valp;
-            *f = json_real_value(val);
+            f = loc;
+            *f = (float) json_real_value(val);
             break;
         case 'D' :
-            d = valp;
+            d = loc;
             *d = json_real_value(val);
             break;
+        case 'N' :
+            n = loc;
+            *n = (int) json_real_value(val);
+            break;
         case 'B' :
-            c = valp;
-            *c = json_integer_value(val);
+            b = loc;
+            *b = (char) json_integer_value(val);
             break;
         case 'S' :
-            s = valp;
-            *s = json_integer_value(val);
+            s = loc;
+            *s = (int16_t) json_integer_value(val);
             break;
         case 'I' :
-            i = valp;
-            *i = json_integer_value(val);
+            i = loc;
+            *i = (int32_t) json_integer_value(val);
             break;
         case 'J' :
-            l = valp;
-            *l = json_integer_value(val);
+            l = loc;
+            *l = (int64_t) json_integer_value(val);
+            break;
+        case 's' :
+            us = loc;
+            *us = (uint16_t) json_integer_value(val);
+            break;
+        case 'i' :
+            ui = loc;
+            *ui = (uint32_t) json_integer_value(val);
+            break;
+        case 'j' :
+            ul = loc;
+            *ul = (uint64_t) json_integer_value(val);
+            break;
+        case 't' :
+            if (json_is_string(val)) {
+                dynType_text_allocAndInit(type, loc, json_string_value(val));
+            } else {
+                status = ERROR;
+                LOG_ERROR("Expected json string type got %i", 
json_typeof(val));
+            }
             break;
         case '[' :
-            status = dynType_complex_dynTypeAt(type, index, &nested); 
-            //TODO check status
-            //TODO json_serializer_writeSequence(val, val, valp); 
+            if (json_is_array(val)) {
+                status = jsonSerializer_parseSequence(type, val, loc);
+            } else {
+                status = ERROR;
+                LOG_ERROR("Expected json array type got '%i'", 
json_typeof(val));
+            }
             break;
         case '{' :
-            status = dynType_complex_dynTypeAt(type, index, &nested); 
-            //TODO check status
-            status = json_serializer_writeObject(nested, val, valp); 
-            //TODO check status
+            if (status == OK) {
+                status = jsonSerializer_parseObject(type, val, loc);
+            }
+            break;
+        case '*' :
+            status = dynType_typedPointer_getTypedType(type, &subType);
+            if (status == OK) {
+                status = jsonSerializer_createObject(subType, val, (void 
**)loc);
+            }
+            break;
+        case 'P' :
+            status = ERROR;
+            LOG_WARNING("Untyped pointer are not supported for serialization");
             break;
         default :
-            printf("JSON_SERIALIZER: error provided type '%c' not 
supported\n", charType);
-            printf("Skipping\n");
+            status = ERROR;
+            LOG_ERROR("Error provided type '%c' not supported for JSON\n", 
type->descriptor);
+            break;
     }
-} 
 
-static void json_serializer_writeSequence(json_t *array, dyn_type *seq, void 
*seqLoc) {
+    return status;
+}
+
+static int jsonSerializer_parseSequence(dyn_type *seq, json_t *array, void 
*seqLoc) {
     assert(dynType_type(seq) == DYN_TYPE_SEQUENCE);
-    size_t size = json_array_size(array);
-    //char seqType = dynType_sequence_elementSchemaType(seq);
+    int status = OK;
 
+    size_t size = json_array_size(array);
     void *buf = NULL;
-    dynType_sequence_alloc(seq, seqLoc, size, &buf); //seq is already 
allocated. only need to allocate the buf
-
-    //assuming int
-    int32_t i;
-    int index;
-    json_t *val;
-    json_array_foreach(array, index, val) {
-        i = json_number_value(val);
-        dynType_sequence_append(seq, seqLoc, &i);
+    LOG_DEBUG("Allocating sequence with capacity %zu", size);
+    status = dynType_sequence_alloc(seq, seqLoc, (int) size, &buf);
+
+    if (status == OK) {
+        dyn_type *itemType = dynType_sequence_itemType(seq);
+        size_t index;
+        json_t *val;
+        json_array_foreach(array, index, val) {
+            void *valLoc = NULL;
+            status = dynType_sequence_increaseLengthAndReturnLastLoc(seq, 
seqLoc, &valLoc);
+            LOG_DEBUG("Got sequence loc %p", valLoc);
+
+            if (status == OK) {
+                status = jsonSerializer_parseAny(itemType, valLoc, val);
+                if (status != OK) {
+                    break;
+                }
+            }
+        }
     }
+
+    return status;
 }
 
-int json_serialize(dyn_type *type, void *input, char **output, size_t *size) {
-    return 0;
+int jsonSerializer_serialize(dyn_type *type, void *input, char **output) {
+    int status = OK;
+
+    json_t *root = NULL;
+    status = jsonSerializer_writeAny(type, input, &root);
+
+    if (status == OK) {
+        *output = json_dumps(root, JSON_COMPACT);
+        json_decref(root);
+    }
+
+    return status;
 }
+
+static int jsonSerializer_writeAny(dyn_type *type, void *input, json_t **out) {
+    int status = OK;
+
+    int descriptor = dynType_descriptorType(type);
+    json_t *val = NULL;
+    dyn_type *subType = NULL;
+
+    float *f;           //F
+    double *d;          //D
+    char *b;            //B
+    int *n;             //N
+    int16_t *s;         //S
+    int32_t *i;         //I
+    int64_t *l;         //J
+    uint16_t  *us;      //s
+    uint32_t  *ui;      //i
+    uint64_t  *ul;      //j
+
+    switch (descriptor) {
+        case 'B' :
+            b = input;
+            val = json_integer((json_int_t)*b);
+            break;
+        case 'S' :
+            s = input;
+            val = json_integer((json_int_t)*s);
+            break;
+        case 'I' :
+            i = input;
+            val = json_integer((json_int_t)*i);
+            break;
+        case 'J' :
+            l = input;
+            val = json_integer((json_int_t)*l);
+            break;
+        case 's' :
+            us = input;
+            val = json_integer((json_int_t)*us);
+            break;
+        case 'i' :
+            ui = input;
+            val = json_integer((json_int_t)*ui);
+            break;
+        case 'j' :
+            ul = input;
+            val = json_integer((json_int_t)*ul);
+            break;
+        case 'N' :
+            n = input;
+            val = json_integer((json_int_t)*n);
+            break;
+        case 'F' :
+            f = input;
+            val = json_real((double) *f);
+            break;
+        case 'D' :
+            d = input;
+            val = json_real(*d);
+            break;
+        case 't' :
+            val = json_string(*(const char **) input);
+            break;
+        case '*' :
+            status = dynType_typedPointer_getTypedType(type, &subType);
+            if (status == OK) {
+                status = jsonSerializer_writeAny(subType, *(void **)input, 
&val);
+            }
+            break;
+        case '{' :
+            status = jsonSerializer_writeComplex(type, input, &val);
+            break;
+        case '[' :
+            status = jsonSerializer_writeSequence(type, input, &val);
+            break;
+        case 'P' :
+            LOG_WARNING("Untyped pointer not supported for serialization. 
ignoring");
+            break;
+        default :
+            LOG_ERROR("Unsupported descriptor '%c'", descriptor);
+            status = ERROR;
+            break;
+    }
+
+    if (status == OK && val != NULL) {
+        *out = val;
+    }
+
+    return status;
+}
+
+static int jsonSerializer_writeSequence(dyn_type *type, void *input, json_t 
**out) {
+    assert(type->type = DYN_TYPE_SEQUENCE);
+    int status = OK;
+
+    json_t *array = json_array();
+    dyn_type *itemType = dynType_sequence_itemType(type);
+    uint32_t len = dynType_sequence_length(input);
+
+    int i = 0;
+    void *itemLoc = NULL;
+    json_t *item = NULL;
+    for (i = 0; i < len; i += 1) {
+        item = NULL;
+        status = dynType_sequence_locForIndex(type, input, i, &itemLoc);
+        if (status == OK) {
+            status = jsonSerializer_writeAny(itemType, itemLoc, &item);
+            if (status == OK) {
+                json_array_append_new(array, item);
+            }
+        }
+
+        if (status != OK) {
+            break;
+        }
+    }
+
+    if (status == OK && array != NULL) {
+        *out = array;
+    }
+
+    return status;
+}
+
+static int jsonSerializer_writeComplex(dyn_type *type, void *input, json_t 
**out) {
+    assert(type->type == DYN_TYPE_COMPLEX);
+    int status = OK;
+
+    json_t *val = json_object();
+    struct complex_type_entry *entry = NULL;
+    struct complex_type_entries_head *entries = NULL;
+    int index = -1;
+
+    status = dynType_complex_entries(type, &entries);
+    if (status == OK) {
+        TAILQ_FOREACH(entry, entries, entries) {
+            void *subLoc = NULL;
+            json_t *subVal = NULL;
+            dyn_type *subType = NULL;
+            index = dynType_complex_indexForName(type, entry->name);
+            status = dynType_complex_valLocAt(type, index, input, &subLoc);
+            if (status == OK ) {
+                status = dynType_complex_dynTypeAt(type, index, &subType);
+            }
+            if (status == OK) {
+                status = jsonSerializer_writeAny(subType, subLoc, &subVal);
+            }
+            if (status == OK) {
+                json_object_set(val, entry->name, subVal);
+            }
+
+            if (status != OK) {
+                break;
+            }
+        }
+    }
+
+    if (status == OK && val != NULL) {
+        *out = val;
+    }
+
+    return status;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/24d13f2e/remote_services/dynamic_function_interface/json_serializer.h
----------------------------------------------------------------------
diff --git a/remote_services/dynamic_function_interface/json_serializer.h 
b/remote_services/dynamic_function_interface/json_serializer.h
index 6b42244..eb2e629 100644
--- a/remote_services/dynamic_function_interface/json_serializer.h
+++ b/remote_services/dynamic_function_interface/json_serializer.h
@@ -4,9 +4,13 @@
 #ifndef __JSON_SERIALIZER_H_
 #define __JSON_SERIALIZER_H_
 
+#include "dfi_log_util.h"
 #include "dyn_type.h"
 
-int json_deserialize(dyn_type *type, const char *input, void **result);
-int json_serialize(dyn_type *type, void *input, char **output, size_t *size);
+//logging
+DFI_SETUP_LOG_HEADER(jsonSerializer);
+
+int jsonSerializer_deserialize(dyn_type *type, const char *input, void 
**result);
+int jsonSerializer_serialize(dyn_type *type, void *input, char **output);
 
 #endif

http://git-wip-us.apache.org/repos/asf/celix/blob/24d13f2e/remote_services/dynamic_function_interface/tst/json_serializer_tests.cpp
----------------------------------------------------------------------
diff --git 
a/remote_services/dynamic_function_interface/tst/json_serializer_tests.cpp 
b/remote_services/dynamic_function_interface/tst/json_serializer_tests.cpp
index cd61e6e..d5c76ea 100644
--- a/remote_services/dynamic_function_interface/tst/json_serializer_tests.cpp
+++ b/remote_services/dynamic_function_interface/tst/json_serializer_tests.cpp
@@ -46,9 +46,13 @@ struct example1 {
     float e;    //4
 };
 
-static void print_example1(void *data) {
+static void check_example1(void *data) {
     struct example1 *ex = (struct example1 *)data;
-    printf("example1: a:%f, b:%li, c:%i, d:%i, e:%f\n", ex->a, (long)ex->b, 
ex->c, ex->d, ex->e);
+    CHECK_EQUAL(1.0, ex->a);
+    CHECK_EQUAL(22, ex->b);
+    CHECK_EQUAL(32, ex->c);
+    CHECK_EQUAL(42, ex->d);
+    CHECK_EQUAL(4.4f, ex->e);
 }
 
 /*********** example 2 ************************/
@@ -72,9 +76,14 @@ struct example2 {
     double double2; //5
 };
 
-static void print_example2(void *data) {
+static void check_example2(void *data) {
     struct example2 *ex = (struct example2 *)data;
-    printf("example2: byte:%i, long1:%li, long2:%li, double1:%f, float1:%f, 
double2:%f\n", ex->byte, (long)ex->long1, (long)ex->long2, ex->double1, 
ex->float1, ex->double2);
+    CHECK_EQUAL(42, ex->byte);
+    CHECK_EQUAL(232, ex->long1);
+    CHECK_EQUAL(242, ex->long2);
+    CHECK_EQUAL(4.2, ex->double1);
+    CHECK_EQUAL(3.2f, ex->float1);
+    CHECK_EQUAL(4.4, ex->double2);
 }
 
 
@@ -88,24 +97,22 @@ const char *example3_input = "{ \
 
 struct example3 {
     struct {
-        uint32_t _cap;
-        uint32_t _len;
+        uint32_t cap;
+        uint32_t len;
         int32_t *buf;
     } numbers;
 };
 
-static void print_example3(void *data) {
+static void check_example3(void *data) {
     struct example3 *ex = (struct example3 *)data;
-    printf("example3: numbers length is %u and cap is %u and pointer buf is 
%p\n", ex->numbers._len, ex->numbers._cap, ex->numbers.buf);
-    int i;
-    for (i = 0; i < ex->numbers._len; i += 1) {
-        printf("\telement %i : %i\n", i, ex->numbers.buf[i]);
-    }
+    CHECK_EQUAL(3, ex->numbers.len);
+    CHECK_EQUAL(22, ex->numbers.buf[0]);
+    CHECK_EQUAL(32, ex->numbers.buf[1]);
+    CHECK_EQUAL(42, ex->numbers.buf[2]);
 }
 
 /*********** example 4 ************************/
 /** structs within a struct (by reference)*******/
-//TODO think about references in descriptor e.g "{Lleaf;Lleaf; left 
right}\nleaf{IDD index val1 val2}"
 const char *example4_descriptor = "{{IDD index val1 val2}{IDD index val1 val2} 
left right}";
 
 static const char *example4_input =  "{ \
@@ -113,23 +120,84 @@ static const char *example4_input =  "{ \
     \"right\" : {\"index\":2, \"val1\":5.0, \"val2\":4.0 } \
 }";
 
-struct leaf {
+struct ex4_leaf {
     int32_t index;
     double val1;
     double val2;
 };
 
 struct example4 {
-    struct leaf left;
-    struct leaf right;
+    struct ex4_leaf left;
+    struct ex4_leaf right;
 };
 
-static void print_example4(void *data) {
+static void check_example4(void *data) {
     struct example4 *ex = (struct example4 *)data;
-    printf("example4: left { index:%i, val1:%f, val2:%f }, right { index;%i, 
val1:%f, val2:%f }\n", ex->left.index, ex->left.val1, ex->left.val2, 
ex->right.index, ex->right.val1, ex->right.val2);
+    CHECK_EQUAL(1, ex->left.index);
+    CHECK_EQUAL(1.0, ex->left.val1);
+    CHECK_EQUAL(2.0, ex->left.val2);
+    CHECK_EQUAL(2, ex->right.index);
+    CHECK_EQUAL(5.0, ex->right.val1);
+    CHECK_EQUAL(4.0, ex->right.val2);
+}
+
+
+/*********** example 4 ************************/
+/** structs within a struct (by reference)*******/
+const char *example5_descriptor = "Tleaf={ts name 
age};Tnode={Lnode;Lnode;Lleaf; left right value};{Lnode; head}";
+
+static const char *example5_input =  "{ \
+    \"head\" : {\
+        \"left\" : {\
+            \"value\" : {\
+                \"name\" : \"John\",\
+                \"age\" : 44 \
+            }\
+        },\
+        \"right\" : {\
+            \"value\" : {\
+                \"name\" : \"Peter\", \
+                \"age\" : 55 \
+            }\
+        }\
+    }\
+}";
+
+struct leaf {
+    const char *name;
+    uint16_t age;
+};
+
+struct node {
+    struct node *left;
+    struct node *right;
+    struct leaf *value;
+};
+
+struct example5 {
+    struct node *head;
+};
+
+static void check_example5(void *data) {
+    struct example5 *ex = (struct example5 *)data;
+    CHECK_TRUE(ex->head != NULL);
+
+    CHECK(ex->head->left != NULL);
+    CHECK(ex->head->left->value != NULL);
+    STRCMP_EQUAL("John", ex->head->left->value->name);
+    CHECK_EQUAL(44, ex->head->left->value->age);
+    CHECK(ex->head->left->left == NULL);
+    CHECK(ex->head->left->right == NULL);
+
+    CHECK(ex->head->right != NULL);
+    CHECK(ex->head->right->value != NULL);
+    STRCMP_EQUAL("Peter", ex->head->right->value->name);
+    CHECK_EQUAL(55, ex->head->right->value->age);
+    CHECK(ex->head->right->left == NULL);
+    CHECK(ex->head->right->right == NULL);
 }
 
-static void tests() {
+static void parseTests(void) {
     printf("Starting json serializer tests\n");
     dyn_type *type;
     void *inst;
@@ -139,47 +207,176 @@ static void tests() {
     inst = NULL;
     rc = dynType_parseWithStr(example1_descriptor, NULL, NULL, &type);    
     CHECK_EQUAL(0, rc);
-    rc = json_deserialize(type, example1_input, &inst); 
+    rc = jsonSerializer_deserialize(type, example1_input, &inst);
     CHECK_EQUAL(0, rc);
-    print_example1(inst);
-    printf("--\n\n");
-
+    check_example1(inst);
 
     type = NULL;
     inst = NULL;
     rc = dynType_parseWithStr(example2_descriptor, NULL, NULL, &type);
     CHECK_EQUAL(0, rc);
-    rc = json_deserialize(type, example2_input, &inst); 
+    rc = jsonSerializer_deserialize(type, example2_input, &inst);
     CHECK_EQUAL(0, rc);
-    print_example2(inst);
-    printf("--\n\n");
+    check_example2(inst);
 
     type = NULL;
     inst = NULL;
     rc = dynType_parseWithStr(example3_descriptor, NULL, NULL, &type);
     CHECK_EQUAL(0, rc);
-    rc = json_deserialize(type, example3_input, &inst); 
+    rc = jsonSerializer_deserialize(type, example3_input, &inst);
     CHECK_EQUAL(0, rc);
-    print_example3(inst);
+    check_example3(inst);
 
     type = NULL;
     inst = NULL;
     rc = dynType_parseWithStr(example4_descriptor, NULL, NULL, &type);
     CHECK_EQUAL(0, rc);
-    rc = json_deserialize(type, example4_input, &inst); 
+    rc = jsonSerializer_deserialize(type, example4_input, &inst);
+    CHECK_EQUAL(0, rc);
+    check_example4(inst);
+
+    type = NULL;
+    inst = NULL;
+    rc = dynType_parseWithStr(example5_descriptor, NULL, NULL, &type);
+    CHECK_EQUAL(0, rc);
+    rc = jsonSerializer_deserialize(type, example5_input, &inst);
+    CHECK_EQUAL(0, rc);
+    check_example5(inst);
+}
+
+const char *write_example1_descriptor = "{BSIJsijFDN a b c d e f g h i j}";
+
+struct write_example1 {
+    char a;
+    int16_t b;
+    int32_t c;
+    int64_t d;
+    uint16_t e;
+    uint32_t f;
+    uint64_t g;
+    float h;
+    double i;
+    int j;
+};
+
+void writeTest1(void) {
+    struct write_example1 ex1 = {.a=1, .b=2, .c=3, .d=4, .e=5, .f=6, .g=7, 
.h=8.8f, .i=9.9, .j=10};
+    dyn_type *type = NULL;
+    char *result = NULL;
+    int rc = dynType_parseWithStr(write_example1_descriptor, "ex1", NULL, 
&type);
+    CHECK_EQUAL(0, rc);
+    rc = jsonSerializer_serialize(type, &ex1, &result);
+    CHECK_EQUAL(0, rc);
+    STRCMP_CONTAINS("\"a\":1", result);
+    STRCMP_CONTAINS("\"b\":2", result);
+    STRCMP_CONTAINS("\"c\":3", result);
+    STRCMP_CONTAINS("\"d\":4", result);
+    STRCMP_CONTAINS("\"e\":5", result);
+    STRCMP_CONTAINS("\"f\":6", result);
+    STRCMP_CONTAINS("\"g\":7", result);
+    STRCMP_CONTAINS("\"h\":8.8", result);
+    STRCMP_CONTAINS("\"i\":9.9", result);
+    STRCMP_CONTAINS("\"j\":10", result);
+    //printf("example 1 result: '%s'\n", result);
+}
+
+const char *write_example2_descriptor = "{*{JJ a b}{SS c d} sub1 sub2}";
+
+struct write_example2_sub {
+        int64_t a;
+        int64_t b;
+};
+
+struct write_example2 {
+    struct write_example2_sub *sub1;
+    struct {
+        int16_t c;
+        int16_t d;
+    } sub2;
+};
+
+void writeTest2(void) {
+    struct write_example2_sub sub1 = { .a = 1, .b = 2 };
+    struct write_example2 ex = { .sub1 = &sub1 };
+    ex.sub2.c = 3;
+    ex.sub2.d = 4;
+
+    dyn_type *type = NULL;
+    char *result = NULL;
+    int rc = dynType_parseWithStr(write_example2_descriptor, "ex2", NULL, 
&type);
+    CHECK_EQUAL(0, rc);
+    rc = jsonSerializer_serialize(type, &ex, &result);
+    CHECK_EQUAL(0, rc);
+    STRCMP_CONTAINS("\"a\":1", result);
+    STRCMP_CONTAINS("\"b\":2", result);
+    STRCMP_CONTAINS("\"c\":3", result);
+    STRCMP_CONTAINS("\"d\":4", result);
+    //printf("example 2 result: '%s'\n", result);
+}
+
+const char *write_example3_descriptor = "Tperson={ti name age};[Lperson;";
+
+struct write_example3_person {
+    const char *name;
+    uint32_t age;
+};
+
+struct write_example3 {
+    uint32_t cap;
+    uint32_t len;
+    struct write_example3_person **buf;
+};
+
+void writeTest3(void) {
+    struct write_example3_person p1 = {.name = "John", .age = 33};
+    struct write_example3_person p2 = {.name = "Peter", .age = 44};
+    struct write_example3_person p3 = {.name = "Carol", .age = 55};
+    struct write_example3_person p4 = {.name = "Elton", .age = 66};
+    struct write_example3 seq;
+    seq.buf = (struct write_example3_person **) calloc(4, sizeof(void *));
+    seq.len = seq.cap = 4;
+    seq.buf[0] = &p1;
+    seq.buf[1] = &p2;
+    seq.buf[2] = &p3;
+    seq.buf[3] = &p4;
+
+    dyn_type *type = NULL;
+    char *result = NULL;
+    int rc = dynType_parseWithStr(write_example3_descriptor, "ex3", NULL, 
&type);
+    CHECK_EQUAL(0, rc);
+    rc = jsonSerializer_serialize(type, &seq, &result);
     CHECK_EQUAL(0, rc);
-    print_example4(inst);
+    STRCMP_CONTAINS("\"age\":33", result);
+    STRCMP_CONTAINS("\"age\":44", result);
+    STRCMP_CONTAINS("\"age\":55", result);
+    STRCMP_CONTAINS("\"age\":66", result);
+    //printf("example 3 result: '%s'\n", result);
 }
+
 }
 
 TEST_GROUP(JsonSerializerTests) {
     void setup() {
-        dynType_logSetup(stdLog, NULL, 3);
-        dynCommon_logSetup(stdLog, NULL, 3);
+        int lvl = 3;
+        dynCommon_logSetup(stdLog, NULL, lvl);
+        dynType_logSetup(stdLog, NULL,lvl);
+        jsonSerializer_logSetup(stdLog, NULL, lvl);
     }
 };
 
-TEST(JsonSerializerTests, Test1) {
+TEST(JsonSerializerTests, ParseTests) {
     //TODO split up
-    tests();
+    parseTests();
+}
+
+TEST(JsonSerializerTests, WriteTest1) {
+    writeTest1();
+}
+
+TEST(JsonSerializerTests, WriteTest2) {
+    writeTest2();
+}
+
+TEST(JsonSerializerTests, WriteTest3) {
+    writeTest3();
 }

Reply via email to