diff --git a/dse/modelc/examples/doc/apis/signalvector_annotation.c b/dse/modelc/examples/doc/apis/signalvector_annotation.c index 79d6072..d28d0a2 100644 --- a/dse/modelc/examples/doc/apis/signalvector_annotation.c +++ b/dse/modelc/examples/doc/apis/signalvector_annotation.c @@ -7,7 +7,7 @@ ModelDesc* model_create(ModelDesc* m) if (idx.scalar) { /* Set initial value. */ - const char* v = signal_annotation(idx.sv, idx.signal, "initial_value"); + const char* v = signal_annotation(idx.sv, idx.signal, "initial_value", NULL); if (v) *(idx.scalar) = atoi(v); } diff --git a/dse/modelc/examples/doc/apis/signalvector_interface.c b/dse/modelc/examples/doc/apis/signalvector_interface.c index 16a0066..3ed74b0 100644 --- a/dse/modelc/examples/doc/apis/signalvector_interface.c +++ b/dse/modelc/examples/doc/apis/signalvector_interface.c @@ -23,7 +23,7 @@ int model_step(ModelDesc* m, double* model_time, double stop_time) signal_append(sv, i, data, strlen("foo")); free(data); signal_release(sv, i); - const char* mime_type = signal_annotation(sv, i, "mime_type"); + const char* mime_type = signal_annotation(sv, i, "mime_type", NULL); if (mime_type) log_debug(" annotation : %s", mime_type); } else { log_debug(" scalar : %s", sv->scalar[i]); diff --git a/dse/modelc/model.h b/dse/modelc/model.h index 0a9a415..0906833 100644 --- a/dse/modelc/model.h +++ b/dse/modelc/model.h @@ -195,9 +195,9 @@ typedef int (*BinarySignalResetFunc)(SignalVector* sv, uint32_t index); typedef int (*BinarySignalReleaseFunc)(SignalVector* sv, uint32_t index); typedef void* (*BinarySignalCodecFunc)(SignalVector* sv, uint32_t index); typedef const char* (*SignalAnnotationGetFunc)( - SignalVector* sv, uint32_t index, const char* name); + SignalVector* sv, uint32_t index, const char* name, void** node); typedef const char* (*SignalGroupAnnotationGetFunc)( - SignalVector* sv, const char* name); + SignalVector* sv, const char* name, void** node); typedef struct SignalVectorVTable { @@ -220,7 +220,8 @@ typedef struct SignalVector { /* Reference data. */ const char* function_name; ModelInstanceSpec* mi; - void* index; /* Hashmap object, index on `signal`. */ + void* index; /* Hashmap object, index on `signal`. */ + void* index_uid; /* Hashmap object, index on `uid`. */ /* Vector representation of Signals (each with _count_ elements). */ uint32_t count; @@ -244,7 +245,7 @@ typedef struct SignalVector { SignalVectorVTable vtable; /* Reserved. */ - uint64_t __reserved__[9]; + uint64_t __reserved__[8]; } SignalVector; @@ -261,8 +262,8 @@ DLL_PUBLIC int signal_reset_called( DLL_PUBLIC int signal_release(SignalVector* sv, uint32_t index); DLL_PUBLIC void* signal_codec(SignalVector* sv, uint32_t index); DLL_PUBLIC const char* signal_annotation( - SignalVector* sv, uint32_t index, const char* name); + SignalVector* sv, uint32_t index, const char* name, void** node); DLL_PUBLIC const char* signal_group_annotation( - SignalVector* sv, const char* name); + SignalVector* sv, const char* name, void** node); #endif // DSE_MODELC_MODEL_H_ diff --git a/dse/modelc/model/signal.c b/dse/modelc/model/signal.c index 6a8edc3..f94a798 100644 --- a/dse/modelc/model/signal.c +++ b/dse/modelc/model/signal.c @@ -58,9 +58,10 @@ static int _signal_group_match_handler( } static const char* _signal_annotation(ModelInstanceSpec* mi, SignalVector* sv, - const char* signal, const char* name) + const char* signal, const char* name, void** node) { const char* value = NULL; + if (node) *node = NULL; /* Set the search vars. */ __signal_match = NULL; @@ -80,6 +81,9 @@ static const char* _signal_annotation(ModelInstanceSpec* mi, SignalVector* sv, if (__signal_match) { YamlNode* n = dse_yaml_find_node(__signal_match->data, "annotations"); value = dse_yaml_get_scalar(n, name); + if (node && value) { + *node = dse_yaml_find_node(n, name); + } free(__signal_match); __signal_match = NULL; } @@ -90,28 +94,32 @@ static const char* _signal_annotation(ModelInstanceSpec* mi, SignalVector* sv, static const char* __signal_group_annotation_name; static const char* __signal_group_annotation_value; +static YamlNode* __signal_group_annotation_node; static int _sg_annotation_search_match_handler( ModelInstanceSpec* model_instance, SchemaObject* object) { UNUSED(model_instance); + const char* name = __signal_group_annotation_name; YamlNode* n = dse_yaml_find_node(object->doc, "metadata/annotations"); - const char* value = dse_yaml_get_scalar(n, __signal_group_annotation_name); + const char* value = dse_yaml_get_scalar(n, name); if (value) { /* Match found, return +ve to stop search. */ __signal_group_annotation_value = value; + __signal_group_annotation_node = dse_yaml_find_node(n, name); return 1; } return 0; /* Continue search. */ } static const char* _signal_group_annotation( - ModelInstanceSpec* mi, SignalVector* sv, const char* name) + ModelInstanceSpec* mi, SignalVector* sv, const char* name, void** node) { /* Set the search vars. */ __signal_group_annotation_name = name; __signal_group_annotation_value = NULL; + __signal_group_annotation_node = NULL; /* Search over the schema objects. */ ChannelSpec* cs = model_build_channel_spec(mi, sv->name); @@ -125,6 +133,7 @@ static const char* _signal_group_annotation( /* If the search was successful (first match wins), the value will be set. */ + if (node) *node = (void*)__signal_group_annotation_node; return __signal_group_annotation_value; } @@ -203,20 +212,21 @@ static int __binary_release(SignalVector* sv, uint32_t index) } static const char* __annotation_get( - SignalVector* sv, uint32_t index, const char* name) + SignalVector* sv, uint32_t index, const char* name, void** node) { assert(sv); assert(sv->mi); - return _signal_annotation(sv->mi, sv, sv->signal[index], name); + return _signal_annotation(sv->mi, sv, sv->signal[index], name, node); } -static const char* __group_annotation_get(SignalVector* sv, const char* name) +static const char* __group_annotation_get( + SignalVector* sv, const char* name, void** node) { assert(sv); assert(sv->mi); - return _signal_group_annotation(sv->mi, sv, name); + return _signal_group_annotation(sv->mi, sv, name, node); } static void* __binary_codec(SignalVector* sv, uint32_t index) @@ -274,7 +284,8 @@ static int _add_sv(void* _mfc, void* _sv_data) for (uint32_t i = 0; i < current_sv->count; i++) { current_sv->mime_type[i] = DEFAULT_BINARY_MIME_TYPE; const char* mt; - mt = current_sv->vtable.annotation(current_sv, i, "mime_type"); + mt = + current_sv->vtable.annotation(current_sv, i, "mime_type", NULL); if (mt) current_sv->mime_type[i] = mt; } /* NCodec. */ @@ -641,7 +652,8 @@ Returns <>0 : Indicates an error condition. Inspect `errno` for additional information. */ -inline int signal_reset_called(SignalVector* sv, uint32_t index, bool* reset_called) +inline int signal_reset_called( + SignalVector* sv, uint32_t index, bool* reset_called) { if (reset_called == NULL) return -EINVAL; @@ -811,11 +823,11 @@ Example (Code Usage) >}} */ inline const char* signal_annotation( - SignalVector* sv, uint32_t index, const char* name) + SignalVector* sv, uint32_t index, const char* name, void** node) { if (sv && index < sv->count) { if (sv->vtable.annotation) { - return sv->vtable.annotation(sv, index, name); + return sv->vtable.annotation(sv, index, name, node); } else { errno = ENOSYS; return NULL; @@ -850,11 +862,12 @@ NULL : The requested annotation was not found, inspect `errno` for additional information.. */ -inline const char* signal_group_annotation(SignalVector* sv, const char* name) +inline const char* signal_group_annotation( + SignalVector* sv, const char* name, void** node) { if (sv) { if (sv->vtable.group_annotation) { - return sv->vtable.group_annotation(sv, name); + return sv->vtable.group_annotation(sv, name, node); } else { errno = ENOSYS; return NULL; diff --git a/tests/cmocka/model/test_signal.c b/tests/cmocka/model/test_signal.c index ccbdb4e..64fd2e7 100644 --- a/tests/cmocka/model/test_signal.c +++ b/tests/cmocka/model/test_signal.c @@ -331,19 +331,28 @@ void test_signal__annotations(void** state) /* Check annotations. */ const char* value; + YamlNode* node = NULL; - value = signal_annotation(sv, 0, "name"); + value = signal_annotation(sv, 0, "name", NULL); assert_non_null(value); assert_string_equal(value, "binary_foo"); - value = signal_annotation(sv, 0, "mime_type"); + value = signal_annotation(sv, 0, "mime_type", NULL); assert_null(value); + value = signal_annotation(sv, 0, "mime_type", (void**)&node); + assert_null(value); + assert_null(node); - value = signal_annotation(sv, 1, "name"); + value = signal_annotation(sv, 1, "name", NULL); assert_non_null(value); assert_string_equal(value, "binary_bar"); - value = signal_annotation(sv, 1, "mime_type"); + value = signal_annotation(sv, 1, "mime_type", NULL); + assert_non_null(value); + assert_string_equal(value, "application/custom-stream"); + value = signal_annotation(sv, 1, "mime_type", (void**)&node); assert_non_null(value); + assert_non_null(node); assert_string_equal(value, "application/custom-stream"); + assert_string_equal(node->scalar, "application/custom-stream"); } @@ -364,12 +373,20 @@ void test_signal__group_annotations(void** state) /* Check annotations. */ const char* value; + YamlNode* node = NULL; - value = signal_group_annotation(sv, "vector_name"); + value = signal_group_annotation(sv, "vector_name", NULL); assert_non_null(value); + value = signal_group_annotation(sv, "vector_name", (void**)&node); + assert_non_null(value); + assert_non_null(node); + assert_string_equal(value, "network_vector"); - value = signal_group_annotation(sv, "missing"); + value = signal_group_annotation(sv, "missing", NULL); + assert_null(value); + value = signal_group_annotation(sv, "missing", (void**)&node); assert_null(value); + assert_null(node); }