Goby v2
message_xml_callbacks.cpp
1 // Copyright 2009-2018 Toby Schneider (http://gobysoft.org/index.wt/people/toby)
2 // GobySoft, LLC (2013-)
3 // Massachusetts Institute of Technology (2007-2014)
4 // Community contributors (see AUTHORS file)
5 //
6 //
7 // This file is part of the Goby Underwater Autonomy Project Libraries
8 // ("The Goby Libraries").
9 //
10 // The Goby Libraries are free software: you can redistribute them and/or modify
11 // them under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 2.1 of the License, or
13 // (at your option) any later version.
14 //
15 // The Goby Libraries are distributed in the hope that they will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with Goby. If not, see <http://www.gnu.org/licenses/>.
22 
23 #include "message_xml_callbacks.h"
24 
25 #include "goby/util/as.h"
26 
27 using namespace xercesc;
28 using namespace goby::transitional::xml;
29 
30 // this is called when the parser encounters the start tag, e.g. <message>
31 void goby::transitional::DCCLMessageContentHandler::startElement(
32  const XMLCh* const uri, // namespace URI
33  const XMLCh* const localname, // tagname w/ out NS prefix
34  const XMLCh* const qname, // tagname + NS pefix
35  const Attributes& attrs) // elements's attributes
36 {
37  const XMLCh* val;
38 
39  // tag parameters
40  static const XMLCh* algorithm = fromNative("algorithm");
41  static const XMLCh* mandatory_content = fromNative("mandatory_content");
42  static const XMLCh* key = fromNative("key");
43  static const XMLCh* stype = fromNative("type");
44 
45  Tag current_tag = tags_map_[toNative(localname)];
46  parents_.insert(current_tag);
47 
48  switch (current_tag)
49  {
50  default: break;
51 
52  case tag_message:
53  // start new message
54  messages.push_back(DCCLMessage());
55  break;
56 
57  case tag_layout: break;
58 
59  case tag_publish: messages.back().add_publish(); break;
60 
61  case tag_hex:
62  case tag_int:
63  case tag_string:
64  case tag_float:
65  case tag_bool:
66  case tag_static:
67  case tag_enum:
68  messages.back().add_message_var(toNative(localname));
69  if ((val = attrs.getValue(algorithm)) != 0)
70  {
71  std::vector<std::string> vec;
72  std::string str = boost::erase_all_copy(toNative(val), " ");
73  boost::split(vec, str, boost::is_any_of(","));
74  messages.back().last_message_var().set_algorithms(vec);
75  }
76 
77  break;
78 
79  case tag_trigger_var:
80  if ((val = attrs.getValue(mandatory_content)) != 0)
81  messages.back().set_trigger_mandatory(toNative(val));
82  break;
83 
84  case tag_repeat: messages.back().set_repeat_enabled(true); break;
85 
86  case tag_all: messages.back().last_publish().set_use_all_names(true); break;
87 
88  case tag_src_var:
89  case tag_publish_var:
90  case tag_moos_var:
91  if (in_message_var() && ((val = attrs.getValue(key)) != 0))
92  messages.back().last_message_var().set_source_key(toNative(val));
93  else if (in_header_var() && ((val = attrs.getValue(key)) != 0))
94  messages.back().header_var(curr_head_piece_).set_source_key(toNative(val));
95  else if (in_publish() && ((val = attrs.getValue(stype)) != 0))
96  {
97  if (toNative(val) == "double")
98  messages.back().last_publish().set_type(cpp_double);
99  else if (toNative(val) == "string")
100  messages.back().last_publish().set_type(cpp_string);
101  else if (toNative(val) == "long")
102  messages.back().last_publish().set_type(cpp_long);
103  else if (toNative(val) == "bool")
104  messages.back().last_publish().set_type(cpp_bool);
105  }
106  break;
107 
108  case tag_message_var:
109  if (in_publish())
110  {
111  if ((val = attrs.getValue(algorithm)) != 0)
112  {
113  std::vector<std::string> vec;
114  std::string str = boost::erase_all_copy(toNative(val), " ");
115  boost::split(vec, str, boost::is_any_of(","));
116  messages.back().last_publish().add_algorithms(vec);
117  }
118  else
119  {
120  messages.back().last_publish().add_algorithms(std::vector<std::string>());
121  }
122  }
123  break;
124 
125  case tag_time:
126  curr_head_piece_ = HEAD_TIME;
127  if ((val = attrs.getValue(algorithm)) != 0)
128  {
129  std::vector<std::string> vec;
130  std::string str = boost::erase_all_copy(toNative(val), " ");
131  boost::split(vec, str, boost::is_any_of(","));
132 
133  messages.back().header_var(curr_head_piece_).set_algorithms(vec);
134  }
135  break;
136 
137  case tag_src_id:
138  curr_head_piece_ = HEAD_SRC_ID;
139  if ((val = attrs.getValue(algorithm)) != 0)
140  {
141  std::vector<std::string> vec;
142  std::string str = boost::erase_all_copy(toNative(val), " ");
143  boost::split(vec, str, boost::is_any_of(","));
144  messages.back().header_var(curr_head_piece_).set_algorithms(vec);
145  }
146 
147  break;
148 
149  case tag_dest_id:
150  curr_head_piece_ = HEAD_DEST_ID;
151  if ((val = attrs.getValue(algorithm)) != 0)
152  {
153  std::vector<std::string> vec;
154  std::string str = boost::erase_all_copy(toNative(val), " ");
155  boost::split(vec, str, boost::is_any_of(","));
156  messages.back().header_var(curr_head_piece_).set_algorithms(vec);
157  }
158  break;
159 
160  // legacy
161  case tag_destination_var:
162  if ((val = attrs.getValue(key)) != 0)
163  messages.back().header_var(HEAD_DEST_ID).set_name(toNative(val));
164  break;
165  }
166 
167  current_text.clear(); // starting a new tag, clear any old CDATA
168 }
169 
170 void goby::transitional::DCCLMessageContentHandler::endElement(
171  const XMLCh* const uri, // namespace URI
172  const XMLCh* const localname, // tagname w/ out NS prefix
173  const XMLCh* const qname) // tagname + NS pefix
174 {
175  std::string trimmed_data = boost::trim_copy(current_text);
176 
177  Tag current_tag = tags_map_[toNative(localname)];
178  parents_.erase(current_tag);
179 
180  switch (current_tag)
181  {
182  case tag_message:
183  messages.back().preprocess(); // do any message tasks that require all data
184  break;
185 
186  case tag_layout: break;
187 
188  case tag_publish: break;
189 
190  case tag_hex:
191  case tag_int:
192  case tag_bool:
193  case tag_enum:
194  case tag_float:
195  case tag_static:
196  case tag_string: break;
197 
198  case tag_max_delta: messages.back().last_message_var().set_max_delta(trimmed_data); break;
199 
200  case tag_format: messages.back().last_publish().set_format(trimmed_data); break;
201 
202  case tag_id: messages.back().set_id(trimmed_data); break;
203 
204  case tag_incoming_hex_moos_var: messages.back().set_in_var(trimmed_data); break;
205 
206  case tag_max_length: messages.back().last_message_var().set_max_length(trimmed_data); break;
207 
208  case tag_num_bytes: messages.back().last_message_var().set_num_bytes(trimmed_data); break;
209 
210  case tag_max: messages.back().last_message_var().set_max(trimmed_data); break;
211 
212  case tag_message_var: messages.back().last_publish().add_name(trimmed_data); break;
213 
214  case tag_min: messages.back().last_message_var().set_min(trimmed_data); break;
215 
216  case tag_src_var:
217  case tag_publish_var:
218  case tag_moos_var:
219  if (in_message_var())
220  messages.back().last_message_var().set_source_var(trimmed_data);
221  else if (in_header_var())
222  messages.back().header_var(curr_head_piece_).set_source_var(trimmed_data);
223  else if (in_publish())
224  messages.back().last_publish().set_var(trimmed_data);
225  break;
226 
227  // legacy
228  case tag_destination_var:
229  messages.back().header_var(HEAD_DEST_ID).set_source_var(trimmed_data);
230  break;
231 
232  case tag_name:
233  if (!in_message_var() && !in_header_var())
234  messages.back().set_name(trimmed_data);
235  else if (in_message_var())
236  messages.back().last_message_var().set_name(trimmed_data);
237  else if (in_header_var())
238  messages.back().header_var(curr_head_piece_).set_name(trimmed_data);
239  break;
240 
241  case tag_outgoing_hex_moos_var: messages.back().set_out_var(trimmed_data); break;
242 
243  case tag_precision: messages.back().last_message_var().set_precision(trimmed_data); break;
244 
245  case tag_size: messages.back().set_size(trimmed_data); break;
246 
247  case tag_trigger_var: messages.back().set_trigger_var(trimmed_data); break;
248 
249  case tag_trigger_time: messages.back().set_trigger_time(trimmed_data); break;
250 
251  case tag_trigger: messages.back().set_trigger(trimmed_data); break;
252 
253  case tag_value:
254  if (parents_.count(tag_static))
255  messages.back().last_message_var().set_static_val(trimmed_data);
256  else if (parents_.count(tag_enum))
257  messages.back().last_message_var().add_enum(trimmed_data);
258  break;
259 
260  case tag_array_length:
261  messages.back().last_message_var().set_array_length(trimmed_data);
262  break;
263 
264  default: break;
265  }
266 }