You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2015/07/31 12:18:36 UTC
[5/5] celix git commit: CELIX-237: Updated serialized. Added parse
tests and conresponding implementation and added write functionality
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 <pe...@gmail.com>
Authored: Fri Jul 31 12:17:30 2015 +0200
Committer: Pepijn Noltes <pe...@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();
}