Fawkes API Fawkes Development Version
net_list_content.cpp
1
2/***************************************************************************
3 * config_list_content.cpp - Fawkes Config List Message Content
4 *
5 * Created: Sat Dec 08 23:38:10 2007
6 * Copyright 2006-2007 Tim Niemueller [www.niemueller.de]
7 *
8 ****************************************************************************/
9
10/* This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version. A runtime exception applies to
14 * this software (see LICENSE.GPL_WRE file mentioned below for details).
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Library General Public License for more details.
20 *
21 * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22 */
23
24#include <config/net_list_content.h>
25#include <core/exceptions/software.h>
26#include <netcomm/fawkes/component_ids.h>
27#include <netcomm/utils/dynamic_buffer.h>
28
29#include <cstdlib>
30#include <cstring>
31
32namespace fawkes {
33
34/** @class ConfigListContent <config/net_list_content.h>
35 * Config list content.
36 * A complex dynamic message with an arbitrary number of config entities. Uses
37 * DynamicBuffer for the internal list of plugins and thus the buffer is
38 * limited to 4 GB in total.
39 *
40 * @author Tim Niemueller
41 */
42
43/** Constructor. */
45{
46 config_list = new DynamicBuffer(&(msg.config_list));
47}
48
49/** Message content constructor.
50 * This constructor is meant to be used with FawkesNetworkMessage::msgc().
51 * @param component_id component ID
52 * @param msg_id message ID
53 * @param payload message payload
54 * @param payload_size total payload size
55 */
56ConfigListContent::ConfigListContent(unsigned int component_id,
57 unsigned int msg_id,
58 void * payload,
59 size_t payload_size)
60{
61 if (component_id != FAWKES_CID_CONFIGMANAGER) {
62 throw TypeMismatchException("ConfigListContent: invalid component ID");
63 }
65 void * config_list_payload = (void *)((size_t)payload + sizeof(msg));
66 config_list =
67 new DynamicBuffer(&(tmsg->config_list), config_list_payload, payload_size - sizeof(msg));
68}
69
70/** Destructor. */
72{
73 delete config_list;
74 if (_payload != NULL) {
75 free(_payload);
76 _payload = NULL;
77 _payload_size = 0;
78 }
79}
80
81/// @cond INTERNAL
82template <typename T>
83static inline void
84copy_data_vector(T *in, T *out, const size_t num_values)
85{
86 for (unsigned int j = 0; j < num_values; ++j) {
87 out[j] = in[j];
88 }
89}
90/// @endcond
91
92/** Append from iterator.
93 * Appends the value the iterator points to.
94 * @param i iterator
95 */
96void
98{
99 unsigned int num_values = (i->is_list() ? i->get_list_size() : 1);
100 size_t data_size = 0;
101 char * data;
102
104 memset(&cle, 0, sizeof(cle));
105 strncpy(cle.cp.path, i->path(), CONFIG_MSG_PATH_LENGTH - 1);
106 cle.type = MSG_CONFIG_FLOAT_VALUE;
107 cle.cp.is_default = (i->is_default() ? 1 : 0);
108 cle.cp.num_values = (i->is_list() ? i->get_list_size() : 0);
109
110 if (i->is_uint()) {
111 cle.type = MSG_CONFIG_UINT_VALUE;
112 data_size = num_values * sizeof(uint32_t);
113 } else if (i->is_int()) {
114 cle.type = MSG_CONFIG_INT_VALUE;
115 data_size = num_values * sizeof(int32_t);
116 } else if (i->is_bool()) {
117 cle.type = MSG_CONFIG_BOOL_VALUE;
118 data_size = num_values * sizeof(int32_t);
119 } else if (i->is_float()) {
120 cle.type = MSG_CONFIG_FLOAT_VALUE;
121 data_size = num_values * sizeof(float);
122 } else if (i->is_string()) {
123 cle.type = MSG_CONFIG_STRING_VALUE;
124 if (i->is_list()) {
125 std::vector<std::string> values = i->get_strings();
126 for (unsigned int j = 0; j < values.size(); ++j) {
127 data_size += sizeof(config_string_value_t) + values[j].length() + 1;
128 }
129 } else {
130 data_size = sizeof(config_string_value_t) + i->get_string().length() + 1;
131 }
132 } else {
133 throw Exception("Invalid type of config iterator value (%s)", i->path());
134 }
135
136 data = (char *)malloc(sizeof(config_list_entity_header_t) + data_size);
137 memcpy(data, &cle, sizeof(config_list_entity_header_t));
138
139 if (i->is_uint()) {
140 if (i->is_list()) {
141 copy_data_vector(&i->get_uints()[0], (uint32_t *)(data + sizeof(cle)), num_values);
142 } else {
143 *((uint32_t *)(data + sizeof(cle))) = i->get_uint();
144 }
145 } else if (i->is_int()) {
146 if (i->is_list()) {
147 copy_data_vector(&i->get_ints()[0], (int32_t *)(data + sizeof(cle)), num_values);
148 } else {
149 *((int32_t *)(data + sizeof(cle))) = i->get_int();
150 }
151 } else if (i->is_bool()) {
152 if (i->is_list()) {
153 std::vector<bool> values = i->get_bools();
154 int32_t * msg_values = (int32_t *)(data + sizeof(cle));
155 for (unsigned int j = 0; j < values.size(); ++j) {
156 msg_values[j] = values[j] ? 1 : 0;
157 }
158
159 } else {
160 *((int32_t *)(data + sizeof(cle))) = i->get_bool() ? 1 : 0;
161 }
162 } else if (i->is_float()) {
163 if (i->is_list()) {
164 copy_data_vector(&i->get_floats()[0], (float *)(data + sizeof(cle)), num_values);
165 } else {
166 *((float *)(data + sizeof(cle))) = i->get_float();
167 }
168 } else if (i->is_string()) {
169 if (i->is_list()) {
170 std::vector<std::string> values = i->get_strings();
171 char * tmpdata = (char *)data + sizeof(cle);
172 for (unsigned int j = 0; j < values.size(); ++j) {
174 csv->s_length = values[j].length();
175 char *msg_string = tmpdata + sizeof(config_string_value_t);
176 strcpy(msg_string, values[j].c_str());
177 tmpdata += sizeof(config_string_value_t) + values[j].length() + 1;
178 }
179 } else {
180 config_string_value_t *csv = (config_string_value_t *)((char *)data + sizeof(cle));
181 csv->s_length = i->get_string().length();
182 char *msg_string = data + sizeof(cle) + sizeof(config_string_value_t);
183 strcpy(msg_string, i->get_string().c_str());
184 }
185 }
186
187 config_list->append(data, sizeof(cle) + data_size);
188}
189
190void
192{
193 _payload_size = sizeof(msg) + config_list->buffer_size();
194 _payload = calloc(1, _payload_size);
195 copy_payload(0, &msg, sizeof(msg));
196 copy_payload(sizeof(msg), config_list->buffer(), config_list->buffer_size());
197}
198
199/** Reset iterator.
200 * For incoming messages only.
201 */
202void
204{
205 config_list->reset_iterator();
206}
207
208/** Check if more list elements are available.
209 * For incoming messages only.
210 * @return true if there are more elements available, false otherwise.
211 */
212bool
214{
215 return config_list->has_next();
216}
217
218/** Get next plugin from list.
219 * @param size upon return contains the size of the returned data element.
220 * @return next config entitiy from the list. The value is only of the type of
221 * the header. Check the message type and the size and cast the message to the correct
222 * entity.
223 */
226{
227 void *tmp = config_list->next(size);
228 return (config_list_entity_header_t *)tmp;
229}
230
231} // end namespace fawkes
bool has_next()
Check if more list elements are available.
virtual ~ConfigListContent()
Destructor.
void append(Configuration::ValueIterator *i)
Append from iterator.
void reset_iterator()
Reset iterator.
virtual void serialize()
Serialize message content.
config_list_entity_header_t * next(size_t *size)
Get next plugin from list.
Iterator interface to iterate over config values.
Definition: config.h:75
virtual bool is_list() const =0
Check if a value is a list.
virtual bool is_uint() const =0
Check if current value is a unsigned int.
virtual std::vector< unsigned int > get_uints() const =0
Get list of values from configuration which is of type unsigned int.
virtual const char * path() const =0
Path of value.
virtual bool get_bool() const =0
Get bool value.
virtual unsigned int get_uint() const =0
Get unsigned int value.
virtual std::vector< bool > get_bools() const =0
Get list of values from configuration which is of type bool.
virtual float get_float() const =0
Get float value.
virtual bool is_float() const =0
Check if current value is a float.
virtual bool is_int() const =0
Check if current value is a int.
virtual bool is_default() const =0
Check if current value was read from the default config.
virtual bool is_string() const =0
Check if current value is a string.
virtual bool is_bool() const =0
Check if current value is a bool.
virtual int get_int() const =0
Get int value.
virtual std::vector< std::string > get_strings() const =0
Get list of values from configuration which is of type string.
virtual size_t get_list_size() const =0
Get number of elements in list value.
virtual std::string get_string() const =0
Get string value.
virtual std::vector< int > get_ints() const =0
Get list of values from configuration which is of type int.
virtual std::vector< float > get_floats() const =0
Get list of values from configuration which is of type float.
Dynamically growing buffer.
size_t buffer_size()
Get buffer size.
void append(const void *data, size_t data_size)
Append data.
void reset_iterator()
Reset iterator.
bool has_next()
Check if another element is available.
void * next(size_t *size)
Get next buffer.
void * buffer()
Get pointer to buffer.
Base class for exceptions in Fawkes.
Definition: exception.h:36
void copy_payload(size_t offset, const void *buf, size_t len)
Copy payload into payload buffer to a specified offset.
virtual size_t payload_size()
Return payload size.
void * _payload
Pointer to payload.
virtual void * payload()
Return pointer to payload.
Fawkes library namespace.
uint16_t num_values
Number of valus in list.
Definition: net_messages.h:98
uint16_t is_default
1 if value is a default value, 0 otherwise, only for get response
Definition: net_messages.h:95
char path[CONFIG_MSG_PATH_LENGTH]
path to config value.
Definition: net_messages.h:94
Config list entity header.
Definition: net_messages.h:155
uint32_t type
type of entity, uses MSG_CONFIG_*_VALUE message IDs
Definition: net_messages.h:157
config_descriptor_t cp
Config descriptor.
Definition: net_messages.h:156
Config list message.
Definition: net_messages.h:149
dynamic_list_t config_list
DynamicBuffer for list.
Definition: net_messages.h:150
String value header indicating the string length.
Definition: net_messages.h:127
uint16_t s_length
Length of following string.
Definition: net_messages.h:128