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 
32 namespace 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  */
56 ConfigListContent::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
82 template <typename T>
83 static inline void
84 copy_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  */
96 void
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 
190 void
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  */
202 void
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  */
212 bool
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