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 
26 #include <netcomm/utils/dynamic_buffer.h>
27 #include <netcomm/fawkes/component_ids.h>
28 #include <core/exceptions/software.h>
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 
50 /** Message content constructor.
51  * This constructor is meant to be used with FawkesNetworkMessage::msgc().
52  * @param component_id component ID
53  * @param msg_id message ID
54  * @param payload message payload
55  * @param payload_size total payload size
56  */
57 ConfigListContent::ConfigListContent(unsigned int component_id,
58  unsigned int msg_id,
59  void *payload, size_t payload_size)
60 {
61  if ( component_id != FAWKES_CID_CONFIGMANAGER ) {
62  throw TypeMismatchException("ConfigListContent: invalid component ID");
63  }
64  config_list_msg_t *tmsg = (config_list_msg_t *)payload;
65  void *config_list_payload = (void *)((size_t)payload + sizeof(msg));
66  config_list = new DynamicBuffer(&(tmsg->config_list), config_list_payload,
67  payload_size - sizeof(msg));
68 }
69 
70 
71 /** Destructor. */
73 {
74  delete config_list;
75  if (_payload != NULL) {
76  free(_payload);
77  _payload = NULL;
78  _payload_size = 0;
79  }
80 }
81 
82 /// @cond INTERNAL
83 template <typename T>
84 static inline void
85 copy_data_vector(T *in, T *out, const size_t num_values)
86 {
87  for (unsigned int j = 0; j < num_values; ++j) {
88  out[j] = in[j];
89  }
90 }
91 /// @endcond
92 
93 /** Append from iterator.
94  * Appends the value the iterator points to.
95  * @param i iterator
96  */
97 void
99 {
100  unsigned int num_values = (i->is_list() ? i->get_list_size() : 1);
101  size_t data_size = 0;
102  char *data;
103 
105  memset(&cle, 0, sizeof(cle));
106  strncpy(cle.cp.path, i->path(), CONFIG_MSG_PATH_LENGTH);
107  cle.type = MSG_CONFIG_FLOAT_VALUE;
108  cle.cp.is_default = (i->is_default() ? 1 : 0);
109  cle.cp.num_values = (i->is_list() ? i->get_list_size() : 0);
110 
111  if ( i->is_uint() ) {
112  cle.type = MSG_CONFIG_UINT_VALUE;
113  data_size = num_values * sizeof(uint32_t);
114  } else if ( i->is_int() ) {
115  cle.type = MSG_CONFIG_INT_VALUE;
116  data_size = num_values * sizeof(int32_t);
117  } else if ( i->is_bool() ) {
118  cle.type = MSG_CONFIG_BOOL_VALUE;
119  data_size = num_values * sizeof(int32_t);
120  } else if ( i->is_float() ) {
121  cle.type = MSG_CONFIG_FLOAT_VALUE;
122  data_size = num_values * sizeof(float);
123  } else if ( i->is_string() ) {
124  cle.type = MSG_CONFIG_STRING_VALUE;
125  if (i->is_list()) {
126  std::vector<std::string> values = i->get_strings();
127  for (unsigned int j = 0; j < values.size(); ++j) {
128  data_size += sizeof(config_string_value_t) + values[j].length() + 1;
129  }
130  } else {
131  data_size = sizeof(config_string_value_t) + i->get_string().length() + 1;
132  }
133  } else {
134  throw Exception("Invalid type of config iterator value (%s)", i->path());
135  }
136 
137  data = (char *)malloc(sizeof(config_list_entity_header_t) + data_size);
138  memcpy(data, &cle, sizeof(config_list_entity_header_t));
139 
140  if ( i->is_uint() ) {
141  if (i->is_list()) {
142  copy_data_vector(&i->get_uints()[0], (uint32_t *)(data + sizeof(cle)), num_values);
143  } else {
144  *((uint32_t *)(data + sizeof(cle))) = i->get_uint();
145  }
146  } else if ( i->is_int() ) {
147  if (i->is_list()) {
148  copy_data_vector(&i->get_ints()[0], (int32_t *)(data + sizeof(cle)), num_values);
149  } else {
150  *((int32_t *)(data + sizeof(cle))) = i->get_int();
151  }
152  } else if ( i->is_bool() ) {
153  if (i->is_list()) {
154  std::vector<bool> values = i->get_bools();
155  int32_t *msg_values = (int32_t *)(data + sizeof(cle));
156  for (unsigned int j = 0; j < values.size(); ++j) {
157  msg_values[j] = values[j] ? 1 : 0;
158  }
159 
160  } else {
161  *((int32_t *)(data + sizeof(cle))) = i->get_bool() ? 1 : 0;
162  }
163  } else if ( i->is_float() ) {
164  if (i->is_list()) {
165  copy_data_vector(&i->get_floats()[0], (float *)(data + sizeof(cle)), num_values);
166  } else {
167  *((float *)(data + sizeof(cle))) = i->get_float();
168  }
169  } else if ( i->is_string() ) {
170  if (i->is_list()) {
171  std::vector<std::string> values = i->get_strings();
172  char *tmpdata = (char *)data + sizeof(cle);
173  for (unsigned int j = 0; j < values.size(); ++j) {
175  csv->s_length = values[j].length();
176  char *msg_string = tmpdata + sizeof(config_string_value_t);
177  strcpy(msg_string, values[j].c_str());
178  tmpdata += sizeof(config_string_value_t) + values[j].length() + 1;
179  }
180  } else {
181  config_string_value_t *csv = (config_string_value_t *)((char *)data + sizeof(cle));
182  csv->s_length = i->get_string().length();
183  char *msg_string = data + sizeof(cle) + sizeof(config_string_value_t);
184  strcpy(msg_string, i->get_string().c_str());
185  }
186  }
187 
188  config_list->append(data, sizeof(cle) + data_size);
189 }
190 
191 
192 void
194 {
195  _payload_size = sizeof(msg) + config_list->buffer_size();
196  _payload = calloc(1, _payload_size);
197  copy_payload(0, &msg, sizeof(msg));
198  copy_payload(sizeof(msg), config_list->buffer(), config_list->buffer_size());
199 }
200 
201 
202 /** Reset iterator.
203  * For incoming messages only.
204  */
205 void
207 {
208  config_list->reset_iterator();
209 }
210 
211 
212 /** Check if more list elements are available.
213  * For incoming messages only.
214  * @return true if there are more elements available, false otherwise.
215  */
216 bool
218 {
219  return config_list->has_next();
220 }
221 
222 
223 /** Get next plugin from list.
224  * @param size upon return contains the size of the returned data element.
225  * @return next config entitiy from the list. The value is only of the type of
226  * the header. Check the message type and the size and cast the message to the correct
227  * entity.
228  */
231 {
232  void *tmp = config_list->next(size);
233  return (config_list_entity_header_t *)tmp;
234 }
235 
236 } // end namespace fawkes
void * _payload
Pointer to payload.
virtual std::vector< bool > get_bools() const =0
Get list of values from configuration which is of type bool.
void append(Configuration::ValueIterator *i)
Append from iterator.
virtual std::vector< std::string > get_strings() const =0
Get list of values from configuration which is of type string.
virtual std::vector< float > get_floats() const =0
Get list of values from configuration which is of type float.
virtual ~ConfigListContent()
Destructor.
virtual bool is_bool() const =0
Check if current value is a bool.
Fawkes library namespace.
config_list_entity_header_t * next(size_t *size)
Get next plugin from list.
void * buffer()
Get pointer to buffer.
char path[CONFIG_MSG_PATH_LENGTH]
path to config value.
Definition: net_messages.h:93
virtual std::vector< int > get_ints() const =0
Get list of values from configuration which is of type int.
virtual float get_float() const =0
Get float value.
virtual unsigned int get_uint() const =0
Get unsigned int value.
virtual size_t get_list_size() const =0
Get number of elements in list value.
virtual bool is_float() const =0
Check if current value is a float.
dynamic_list_t config_list
DynamicBuffer for list.
Definition: net_messages.h:143
virtual bool is_int() const =0
Check if current value is a int.
virtual bool get_bool() const =0
Get bool value.
bool has_next()
Check if another element is available.
size_t buffer_size()
Get buffer size.
uint32_t type
type of entity, uses MSG_CONFIG_*_VALUE message IDs
Definition: net_messages.h:149
virtual void serialize()
Serialize message content.
virtual int get_int() const =0
Get int value.
bool has_next()
Check if more list elements are available.
virtual bool is_string() const =0
Check if current value is a string.
virtual std::vector< unsigned int > get_uints() const =0
Get list of values from configuration which is of type unsigned int.
uint16_t is_default
1 if value is a default value, 0 otherwise, only for get response
Definition: net_messages.h:94
Base class for exceptions in Fawkes.
Definition: exception.h:36
String value header indicating the string length.
Definition: net_messages.h:121
virtual bool is_uint() const =0
Check if current value is a unsigned int.
virtual bool is_list() const =0
Check if a value is a list.
virtual std::string get_string() const =0
Get string value.
virtual void * payload()
Return pointer to payload.
uint16_t num_values
Number of valus in list.
Definition: net_messages.h:97
Config list message.
Definition: net_messages.h:142
virtual const char * path() const =0
Path of value.
config_descriptor_t cp
Config descriptor.
Definition: net_messages.h:148
void copy_payload(size_t offset, const void *buf, size_t len)
Copy payload into payload buffer to a specified offset.
Dynamically growing buffer.
virtual size_t payload_size()
Return payload size.
Config list entity header.
Definition: net_messages.h:147
Iterator interface to iterate over config values.
Definition: config.h:72
void reset_iterator()
Reset iterator.
virtual bool is_default() const =0
Check if current value was read from the default config.
uint16_t s_length
Length of following string.
Definition: net_messages.h:122
void append(const void *data, size_t data_size)
Append data.
void * next(size_t *size)
Get next buffer.
void reset_iterator()
Reset iterator.