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
97 ConfigListContent::append(Configuration::ValueIterator *i)
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) {
173  config_string_value_t *csv = (config_string_value_t *)tmpdata;
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  */
225 ConfigListContent::next(size_t *size)
226 {
227  void *tmp = config_list->next(size);
228  return (config_list_entity_header_t *)tmp;
229 }
230 
231 } // end namespace fawkes
fawkes::DynamicBuffer::append
void append(const void *data, size_t data_size)
Append data.
Definition: dynamic_buffer.cpp:125
fawkes::config_list_msg_t
Config list message.
Definition: net_messages.h:152
fawkes::DynamicBuffer::has_next
bool has_next()
Check if another element is available.
Definition: dynamic_buffer.cpp:240
fawkes::DynamicBuffer
Definition: dynamic_buffer.h:53
fawkes::config_descriptor_t::is_default
uint16_t is_default
1 if value is a default value, 0 otherwise, only for get response
Definition: net_messages.h:99
fawkes::ConfigListContent::next
config_list_entity_header_t * next(size_t *size)
Get next plugin from list.
Definition: net_list_content.cpp:229
fawkes::config_descriptor_t::num_values
uint16_t num_values
Number of valus in list.
Definition: net_messages.h:102
fawkes::FawkesNetworkMessageContent::payload
virtual void * payload()
Return pointer to payload.
Definition: message_content.cpp:74
fawkes::FawkesNetworkMessageContent::_payload_size
size_t _payload_size
Payloda size.
Definition: message_content.h:59
fawkes::ConfigListContent::has_next
bool has_next()
Check if more list elements are available.
Definition: net_list_content.cpp:217
fawkes::ConfigListContent::ConfigListContent
ConfigListContent()
Constructor.
Definition: net_list_content.cpp:48
fawkes::DynamicBuffer::buffer
void * buffer()
Get pointer to buffer.
Definition: dynamic_buffer.cpp:160
fawkes::DynamicBuffer::buffer_size
size_t buffer_size()
Get buffer size.
Definition: dynamic_buffer.cpp:200
fawkes::FawkesNetworkMessageContent::copy_payload
void copy_payload(size_t offset, const void *buf, size_t len)
Copy payload into payload buffer to a specified offset.
Definition: message_content.cpp:103
fawkes::TypeMismatchException
Definition: software.h:47
fawkes::config_list_msg_t::config_list
dynamic_list_t config_list
DynamicBuffer for list.
Definition: net_messages.h:154
fawkes::ConfigListContent::~ConfigListContent
virtual ~ConfigListContent()
Destructor.
Definition: net_list_content.cpp:75
fawkes::ConfigListContent::reset_iterator
void reset_iterator()
Reset iterator.
Definition: net_list_content.cpp:207
fawkes::ConfigListContent::serialize
virtual void serialize()
Definition: net_list_content.cpp:195
fawkes::config_list_entity_header_t
Config list entity header.
Definition: net_messages.h:158
fawkes
fawkes::FawkesNetworkMessageContent::_payload
void * _payload
Pointer to payload.
Definition: message_content.h:57
fawkes::config_descriptor_t::path
char path[CONFIG_MSG_PATH_LENGTH]
path to config value.
Definition: net_messages.h:98
fawkes::ConfigListContent::append
void append(Configuration::ValueIterator *i)
Append from iterator.
Definition: net_list_content.cpp:101
fawkes::config_list_entity_header_t::cp
config_descriptor_t cp
Config descriptor.
Definition: net_messages.h:160
fawkes::DynamicBuffer::reset_iterator
void reset_iterator()
Reset iterator.
Definition: dynamic_buffer.cpp:228
fawkes::FawkesNetworkMessageContent::payload_size
virtual size_t payload_size()
Return payload size.
Definition: message_content.cpp:88
fawkes::DynamicBuffer::next
void * next(size_t *size)
Get next buffer.
Definition: dynamic_buffer.cpp:252
fawkes::config_list_entity_header_t::type
uint32_t type
type of entity, uses MSG_CONFIG_*_VALUE message IDs
Definition: net_messages.h:161