time_series.c
Go to the documentation of this file.
1 /*!**********************************************************************
2  *
3  * @copyright Copyright (C) 2016 Siemens Aktiengesellschaft.\n
4  * All rights reserved.
5  *
6  *************************************************************************
7  *
8  * @file time_series.c
9  * @date Jul 11, 2016
10  * @brief Time series module implementation file.
11  *
12  ************************************************************************/
13 
14 #include "time_series.h"
15 #include "definitions.h"
16 #include "memory.h"
17 #include "log_util.h"
18 #include "mcl/mcl_time_series.h"
19 #include "time_util.h"
20 
21 // Private Function Prototypes:
22 static E_MCL_ERROR_CODE _initialize_meta(const char *version, const char *configuration_id, const char *routing, time_series_t *time_series);
24 static void _destroy_value_set(time_series_value_set_t **value_set);
25 
26 E_MCL_ERROR_CODE time_series_initialize(const char *version, const char *configuration_id, const char *routing, time_series_t **time_series)
27 {
28  DEBUG_ENTRY("const char *version = <%s>, const char *configuration_id = <%s>, const char *routing = <%p>, time_series_t **time_series = <%p>", version, configuration_id,
29  routing, time_series)
30 
31  E_MCL_ERROR_CODE code;
32  MCL_NEW(*time_series);
33  ASSERT_CODE_MESSAGE(MCL_NULL != *time_series, MCL_OUT_OF_MEMORY, "Memory couldn't be allocated for time_series.");
34 
35  (*time_series)->meta.content_id = MCL_NULL;
36  (*time_series)->meta.type = MCL_NULL;
37  (*time_series)->meta.version = MCL_NULL;
38  (*time_series)->meta.details.routing = MCL_NULL;
39  (*time_series)->meta.payload.type = MCL_NULL;
40  (*time_series)->meta.payload.version = MCL_NULL;
41  (*time_series)->meta.payload.details.time_series_details.configuration_id = MCL_NULL;
42  (*time_series)->payload.value_sets = MCL_NULL;
43 
44  code = _initialize_meta(version, configuration_id, routing, *time_series);
45  ASSERT_STATEMENT_CODE_MESSAGE(MCL_OK == code, time_series_destroy(time_series), code, "Initializing time series meta fields fails.");
46 
47  // Initialize value_sets.
48  code = list_initialize(&(*time_series)->payload.value_sets);
49  ASSERT_STATEMENT_CODE_MESSAGE(MCL_OK == code, time_series_destroy(time_series), code, "Initialization failed for time_series->time_series_payload.value_sets.");
50 
51  DEBUG_LEAVE("retVal = <%d>", MCL_OK);
52  return MCL_OK;
53 }
54 
56 {
57  DEBUG_ENTRY("mcl_time_series_t *time_series = <%p>, const char *timestamp = <%p>, mcl_time_series_value_set_t **value_set = <%p>", time_series, timestamp, value_set)
58 
59  E_MCL_ERROR_CODE code;
60  ASSERT_NOT_NULL(time_series);
61  ASSERT_NOT_NULL(timestamp);
62  ASSERT_NOT_NULL(value_set);
63 
64  // Validate timestamp.
65  ASSERT_CODE_MESSAGE(time_util_validate_timestamp(timestamp), MCL_INVALID_PARAMETER, "Timestamp validation failed.");
66 
67  MCL_NEW(*value_set);
68  ASSERT_CODE_MESSAGE(MCL_NULL != *value_set, MCL_OUT_OF_MEMORY, "Memory couldn't be allocated for value_set.");
69 
70  // Initialize timestamp.
71  code = string_initialize_new(timestamp, 0, &(*value_set)->timestamp);
72  ASSERT_STATEMENT_CODE_MESSAGE(MCL_OK == code, _destroy_value_set(value_set), code, "String initialize fail for timestamp.");
73 
74  // Initialize values.
75  code = list_initialize(&(*value_set)->values);
76  ASSERT_STATEMENT_CODE_MESSAGE(MCL_OK == code, _destroy_value_set(value_set), code, "List initialize fail for values.");
77 
78  // Link value_set to a parent time_series
79  (*value_set)->parent = time_series;
80 
81  // Add new value_set to value_sets.
82  MCL_DEBUG("New value_set will be added to value_sets.");
83  code = list_add(time_series->payload.value_sets, *value_set);
84  ASSERT_STATEMENT_CODE_MESSAGE(MCL_OK == code, _destroy_value_set(value_set), code, "Adding value_set to the list failed.");
85 
86  DEBUG_LEAVE("retVal = <%d>", MCL_OK);
87  return MCL_OK;
88 }
89 
90 E_MCL_ERROR_CODE mcl_time_series_add_value(mcl_time_series_value_set_t *value_set, const char *data_point_id, const char *value, const char *quality_code)
91 {
92  DEBUG_ENTRY("mcl_time_series_value_set_t *value_set = <%p>, const char *data_point_id = <%p>, const char *value = <%p>, const char *quality_code = <%p>", value_set,
93  data_point_id, value, quality_code)
94 
95  E_MCL_ERROR_CODE code;
96  time_series_value_t *value_local;
97 
98  ASSERT_NOT_NULL(value_set);
99  ASSERT_NOT_NULL(data_point_id);
100  ASSERT_NOT_NULL(value);
101  ASSERT_NOT_NULL(quality_code);
102 
103  MCL_NEW(value_local);
104  ASSERT_CODE_MESSAGE(MCL_NULL != value_local, MCL_OUT_OF_MEMORY, "Not enough memory to allocate new value_local.");
105 
106  code = string_initialize_new(data_point_id, 0, &value_local->data_point_id);
107  ASSERT_STATEMENT_CODE_MESSAGE(MCL_OK == code, _destroy_value_set_value(&value_local), code, "String initialize fail for data_point_id");
108 
109  code = string_initialize_new(value, 0, &value_local->value);
110  ASSERT_STATEMENT_CODE_MESSAGE(MCL_OK == code, _destroy_value_set_value(&value_local), code, "String initialize fail for value");
111 
112  code = string_initialize_new(quality_code, 0, &value_local->quality_code);
113  ASSERT_STATEMENT_CODE_MESSAGE(MCL_OK == code, _destroy_value_set_value(&value_local), code, "String initialize fail for quality_code");
114 
115  code = list_add(value_set->values, value_local);
116  ASSERT_STATEMENT_CODE_MESSAGE(MCL_OK == code, _destroy_value_set_value(&value_local), code, "Adding value to the list failed.");
117 
118  MCL_DEBUG("New value added into values array. Current index = <%d>", value_set->values->count);
119  DEBUG_LEAVE("retVal = <%d>", MCL_OK);
120  return MCL_OK;
121 }
122 
124 {
125  DEBUG_ENTRY("time_series_t **time_series = <%p>", time_series)
126 
127  if (MCL_NULL != *time_series)
128  {
129  string_destroy(&((*time_series)->meta.content_id));
130  string_destroy(&((*time_series)->meta.type));
131  string_destroy(&((*time_series)->meta.version));
132  string_destroy(&((*time_series)->meta.details.routing));
133  string_destroy(&((*time_series)->meta.payload.type));
134  string_destroy(&((*time_series)->meta.payload.version));
135  string_destroy(&((*time_series)->meta.payload.details.time_series_details.configuration_id));
136  list_destroy_with_content(&(*time_series)->payload.value_sets, (list_item_destroy_callback)_destroy_value_set);
137  MCL_FREE(*time_series);
138  }
139 
140  DEBUG_LEAVE("retVal = void");
141 }
142 
143 // Private Functions:
144 static E_MCL_ERROR_CODE _initialize_meta(const char *version, const char *configuration_id, const char *routing, time_series_t *time_series)
145 {
146  DEBUG_ENTRY("const char *version = <%s>, const char *configuration_id = <%s>, const char *routing = <%p>, time_series_t *time_series = <%p>", version, configuration_id,
147  routing, time_series)
148 
149  // Note that null check for version, configuration_id and time_series is already done by the caller of this function.
150 
151  // Set meta.type.
153  ASSERT_CODE_MESSAGE(MCL_OK == code, code, "String initialize fail for meta type.");
154 
155  // Set meta.version.
157  ASSERT_CODE_MESSAGE(MCL_OK == code, code, "String initialize fail for meta version.");
158 
159  // Set meta.details.routing.
160  if (MCL_NULL != routing)
161  {
162  code = string_initialize_new(routing, 0, &time_series->meta.details.routing);
163  ASSERT_CODE_MESSAGE(MCL_OK == code, code, "String initialize fail for routing");
164  }
165 
166  // Set meta.payload.type.
168  &(time_series->meta.payload.type));
169  ASSERT_CODE_MESSAGE(MCL_OK == code, code, "String initialize fail for meta.payload.type.");
170 
171  // Set meta.payload.version.
172  code = string_initialize_new(version, 0, &time_series->meta.payload.version);
173  ASSERT_CODE_MESSAGE(MCL_OK == code, code, "String initialize fail for meta.payload.version.");
174 
175  // Set configuration_id.
176  code = string_initialize_new(configuration_id, 0, &time_series->meta.payload.details.time_series_details.configuration_id);
177  ASSERT_CODE_MESSAGE(MCL_OK == code, code, "String initialize fail for configuration id.");
178 
179  DEBUG_LEAVE("retVal = <%d>", MCL_OK);
180  return MCL_OK;
181 }
182 
184 {
185  DEBUG_ENTRY("time_series_value_t **value = <%p>", value)
186 
187  string_destroy(&(*value)->data_point_id);
188  string_destroy(&(*value)->value);
189  string_destroy(&(*value)->quality_code);
190  MCL_FREE(*value);
191 
192  DEBUG_LEAVE("retVal = void");
193 }
194 
196 {
197  DEBUG_ENTRY("time_series_value_set_t **value_set = <%p>", value_set)
198 
199  string_destroy(&(*value_set)->timestamp);
201  MCL_FREE(*value_set);
202 
203  DEBUG_LEAVE("retVal = void");
204 }
205 
void string_destroy(string_t **string)
Destroys the allocated resources of the string.
Definition: string_type.c:326
string_t * routing
Information helping the server-side routing mechanism.
Definition: data_types.h:32
item_meta_payload_details_union_t details
Type and version specific meta information about the payload.
Definition: data_types.h:78
string_t * version
Version of payload.
Definition: data_types.h:77
string_t * type
Type of payload.
Definition: data_types.h:76
string_t * data_point_id
Id of the datapoint the value is read from.
Definition: data_types.h:101
Memory module header file.
#define DEBUG_LEAVE(...)
Definition: log_util.h:81
#define DEBUG_ENTRY(...)
Definition: log_util.h:80
Time series type of meta field payload.
Definition: data_types.h:286
#define MCL_NEW(p)
Definition: memory.h:121
static void _destroy_value_set(time_series_value_set_t **value_set)
Definition: time_series.c:195
E_MCL_ERROR_CODE string_initialize_new(const char *value, mcl_size_t value_length, string_t **string)
Initializes a new string_t object with the given value and length.
Definition: string_type.c:46
string_t * type
Type of meta.
Definition: data_types.h:87
This struct is used for building the complete message of time series event.
Definition: time_series.h:22
#define MCL_DEBUG(...)
Definition: log_util.h:70
#define ASSERT_NOT_NULL(argument)
Definition: definitions.h:129
string_t * configuration_id
Unique identifier of the configuration.
Definition: data_types.h:40
Log utility module header file.
E_MCL_ERROR_CODE list_initialize(list_t **list)
Initializes the list.
Definition: list.c:139
Current version of meta field.
Definition: data_types.h:284
E_MCL_ERROR_CODE
MCL Error code definitions. Every function returning an error code uses this enum values...
Definition: mcl_common.h:137
E_MCL_ERROR_CODE mcl_time_series_add_value(mcl_time_series_value_set_t *value_set, const char *data_point_id, const char *value, const char *quality_code)
This function adds data_point_id, value and quality_code to mcl_time_series_value_set_t.
Definition: time_series.c:90
This struct is used for building value set of time series.
Definition: data_types.h:109
struct mcl_time_series_t mcl_time_series_t
This struct is used for building the time series type.
#define MCL_FREE(p)
Definition: memory.h:125
void time_series_destroy(time_series_t **time_series)
To destroy the time_series_t data struct.
Definition: time_series.c:123
item_meta_payload_t payload
Information describing the payload part following this meta or a collection of tuples referencing it...
Definition: data_types.h:91
#define ASSERT_STATEMENT_CODE_MESSAGE(condition, statement, return_code,...)
Definition: definitions.h:121
E_MCL_ERROR_CODE mcl_time_series_new_value_set(mcl_time_series_t *time_series, const char *timestamp, mcl_time_series_value_set_t **value_set)
This function creates new value set to be added to mcl_time_series_t.
Definition: time_series.c:55
General invalid parameter fail.
Definition: mcl_common.h:144
item_meta_payload_details_time_series_t time_series_details
Time series details.
Definition: data_types.h:66
#define ASSERT_CODE_MESSAGE(condition, return_code,...)
Definition: definitions.h:105
Definitions module header file.
string_t * version
Version of meta.
Definition: data_types.h:88
Time series module interface header file.
mcl_bool_t time_util_validate_timestamp(const char *timestamp)
Definition: time_util.c:71
Time series module header file.
Item type of meta field.
Definition: data_types.h:283
string_t meta_field_values[META_FIELD_VALUES_END]
Definition: data_types.c:36
Success.
Definition: mcl_common.h:140
string_t * quality_code
The quality of the value provided.
Definition: data_types.h:103
void list_destroy_with_content(list_t **list, list_item_destroy_callback callback)
To destroy the list and its items with a given callback function.
Definition: list.c:373
This struct is used for building time_series.payload.values structure.
Definition: data_types.h:99
E_MCL_ERROR_CODE string_initialize_static(const char *value, mcl_size_t value_length, string_t **string)
Initializes a static string_t object with the given value and length.
Definition: string_type.c:90
static E_MCL_ERROR_CODE _initialize_meta(const char *version, const char *configuration_id, const char *routing, time_series_t *time_series)
Definition: time_series.c:144
item_meta_t meta
Meta of time series.
Definition: time_series.h:24
string_t * value
The value read.
Definition: data_types.h:102
E_MCL_ERROR_CODE list_add(list_t *list, void *data)
Adds a new list item.
Definition: list.c:159
Memory allocation fail.
Definition: mcl_common.h:143
E_MCL_ERROR_CODE time_series_initialize(const char *version, const char *configuration_id, const char *routing, time_series_t **time_series)
This function creates and initializes a data struct of time_series_t.
Definition: time_series.c:26
#define MCL_NULL
Definition: definitions.h:24
mcl_list_item_destroy_callback list_item_destroy_callback
Definition: list.h:24
static void _destroy_value_set_value(time_series_value_t **value)
Definition: time_series.c:183
Time utility module header file.
struct mcl_time_series_value_set_t mcl_time_series_value_set_t
This struct is used for building value set of time series.
item_meta_details_t details
Type and version-specific meta-information.
Definition: data_types.h:90