Goby Underwater Autonomy Project
Series: 1.1, revision: 163, released on 2013-02-06 14:23:27 -0500
|
00001 // copyright 2008, 2009 t. schneider tes@mit.edu 00002 // 00003 // this file is part of the Dynamic Compact Control Language (DCCL), 00004 // the goby-acomms codec. goby-acomms is a collection of libraries 00005 // for acoustic underwater networking 00006 // 00007 // This program is free software: you can redistribute it and/or modify 00008 // it under the terms of the GNU General Public License as published by 00009 // the Free Software Foundation, either version 3 of the License, or 00010 // (at your option) any later version. 00011 // 00012 // This software is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 // 00017 // You should have received a copy of the GNU General Public License 00018 // along with this software. If not, see <http://www.gnu.org/licenses/>. 00019 00020 #include "message_xml_callbacks.h" 00021 00022 #include "goby/util/string.h" 00023 00024 using namespace xercesc; 00025 using namespace goby::acomms::xml; 00026 00027 // this is called when the parser encounters the start tag, e.g. <message> 00028 void goby::acomms::DCCLMessageContentHandler::startElement( 00029 const XMLCh *const uri, // namespace URI 00030 const XMLCh *const localname, // tagname w/ out NS prefix 00031 const XMLCh *const qname, // tagname + NS pefix 00032 const Attributes &attrs ) // elements's attributes 00033 { 00034 const XMLCh* val; 00035 00036 // tag parameters 00037 static const XMLCh* algorithm = fromNative("algorithm"); 00038 static const XMLCh* mandatory_content = fromNative("mandatory_content"); 00039 static const XMLCh* key = fromNative("key"); 00040 static const XMLCh* stype = fromNative("type"); 00041 00042 Tag current_tag = tags_map_[toNative(localname)]; 00043 parents_.insert(current_tag); 00044 00045 switch(current_tag) 00046 { 00047 default: 00048 break; 00049 00050 case tag_message: 00051 // start new message 00052 messages.push_back(DCCLMessage()); 00053 break; 00054 00055 case tag_layout: 00056 break; 00057 00058 case tag_publish: 00059 messages.back().add_publish(); 00060 break; 00061 00062 case tag_hex: 00063 case tag_int: 00064 case tag_string: 00065 case tag_float: 00066 case tag_bool: 00067 case tag_static: 00068 case tag_enum: 00069 messages.back().add_message_var(toNative(localname)); 00070 if((val = attrs.getValue(algorithm)) != 0) 00071 { 00072 std::vector<std::string> vec; 00073 std::string str = boost::erase_all_copy(toNative(val), " "); 00074 boost::split(vec, 00075 str, 00076 boost::is_any_of(",")); 00077 messages.back().last_message_var().set_algorithms(vec); 00078 } 00079 00080 break; 00081 00082 00083 case tag_trigger_var: 00084 if((val = attrs.getValue(mandatory_content)) != 0) 00085 messages.back().set_trigger_mandatory(toNative(val)); 00086 break; 00087 00088 00089 case tag_repeat: 00090 messages.back().set_repeat_enabled(true); 00091 break; 00092 00093 case tag_all: 00094 messages.back().last_publish().set_use_all_names(true); 00095 break; 00096 00097 00098 case tag_src_var: 00099 case tag_publish_var: 00100 case tag_moos_var: 00101 if(in_message_var() && ((val = attrs.getValue(key)) != 0)) 00102 messages.back().last_message_var().set_source_key(toNative(val)); 00103 else if(in_header_var() && ((val = attrs.getValue(key)) != 0)) 00104 messages.back().header_var(curr_head_piece_).set_source_key(toNative(val)); 00105 else if(in_publish() && ((val = attrs.getValue(stype)) != 0)) 00106 { 00107 if(toNative(val) == "double") 00108 messages.back().last_publish().set_type(cpp_double); 00109 else if(toNative(val) == "string") 00110 messages.back().last_publish().set_type(cpp_string); 00111 else if(toNative(val) == "long") 00112 messages.back().last_publish().set_type(cpp_long); 00113 else if(toNative(val) == "bool") 00114 messages.back().last_publish().set_type(cpp_bool); 00115 } 00116 break; 00117 00118 case tag_message_var: 00119 if(in_publish()) 00120 { 00121 if((val = attrs.getValue(algorithm)) != 0) 00122 { 00123 std::vector<std::string> vec; 00124 std::string str = boost::erase_all_copy(toNative(val), " "); 00125 boost::split(vec, 00126 str, 00127 boost::is_any_of(",")); 00128 messages.back().last_publish().add_algorithms(vec); 00129 } 00130 else 00131 { 00132 messages.back().last_publish().add_algorithms(std::vector<std::string>()); 00133 } 00134 } 00135 break; 00136 00137 case tag_time: 00138 curr_head_piece_ = HEAD_TIME; 00139 if((val = attrs.getValue(algorithm)) != 0) 00140 { 00141 std::vector<std::string> vec; 00142 std::string str = boost::erase_all_copy(toNative(val), " "); 00143 boost::split(vec, 00144 str, 00145 boost::is_any_of(",")); 00146 00147 messages.back().header_var(curr_head_piece_).set_algorithms(vec); 00148 } 00149 break; 00150 00151 case tag_src_id: 00152 curr_head_piece_ = HEAD_SRC_ID; 00153 if((val = attrs.getValue(algorithm)) != 0) 00154 { 00155 std::vector<std::string> vec; 00156 std::string str = boost::erase_all_copy(toNative(val), " "); 00157 boost::split(vec, 00158 str, 00159 boost::is_any_of(",")); 00160 messages.back().header_var(curr_head_piece_).set_algorithms(vec); 00161 } 00162 00163 break; 00164 00165 case tag_dest_id: 00166 curr_head_piece_ = HEAD_DEST_ID; 00167 if((val = attrs.getValue(algorithm)) != 0) 00168 { 00169 std::vector<std::string> vec; 00170 std::string str = boost::erase_all_copy(toNative(val), " "); 00171 boost::split(vec, 00172 str, 00173 boost::is_any_of(",")); 00174 messages.back().header_var(curr_head_piece_).set_algorithms(vec); 00175 } 00176 break; 00177 00178 // legacy 00179 case tag_destination_var: 00180 if((val = attrs.getValue(key)) != 0) 00181 messages.back().header_var(HEAD_DEST_ID).set_name(toNative(val)); 00182 break; 00183 } 00184 00185 current_text.clear(); // starting a new tag, clear any old CDATA 00186 } 00187 00188 void goby::acomms::DCCLMessageContentHandler::endElement( 00189 const XMLCh *const uri, // namespace URI 00190 const XMLCh *const localname, // tagname w/ out NS prefix 00191 const XMLCh *const qname ) // tagname + NS pefix 00192 { 00193 std::string trimmed_data = boost::trim_copy(current_text); 00194 00195 Tag current_tag = tags_map_[toNative(localname)]; 00196 parents_.erase(current_tag); 00197 00198 switch(current_tag) 00199 { 00200 case tag_message: 00201 messages.back().preprocess(); // do any message tasks that require all data 00202 break; 00203 00204 case tag_layout: 00205 break; 00206 00207 case tag_publish: 00208 break; 00209 00210 case tag_hex: 00211 case tag_int: 00212 case tag_bool: 00213 case tag_enum: 00214 case tag_float: 00215 case tag_static: 00216 case tag_string: 00217 break; 00218 00219 case tag_max_delta: 00220 messages.back().last_message_var().set_max_delta(trimmed_data); 00221 break; 00222 00223 case tag_format: 00224 messages.back().last_publish().set_format(trimmed_data); 00225 break; 00226 00227 case tag_id: 00228 messages.back().set_id(trimmed_data); 00229 break; 00230 00231 case tag_incoming_hex_moos_var: 00232 messages.back().set_in_var(trimmed_data); 00233 break; 00234 00235 case tag_max_length: 00236 messages.back().last_message_var().set_max_length(trimmed_data); 00237 break; 00238 00239 case tag_num_bytes: 00240 messages.back().last_message_var().set_num_bytes(trimmed_data); 00241 break; 00242 00243 case tag_max: 00244 messages.back().last_message_var().set_max(trimmed_data); 00245 break; 00246 00247 case tag_message_var: 00248 messages.back().last_publish().add_name(trimmed_data); 00249 break; 00250 00251 case tag_min: 00252 messages.back().last_message_var().set_min(trimmed_data); 00253 break; 00254 00255 case tag_src_var: 00256 case tag_publish_var: 00257 case tag_moos_var: 00258 if(in_message_var()) 00259 messages.back().last_message_var().set_source_var(trimmed_data); 00260 else if(in_header_var()) 00261 messages.back().header_var(curr_head_piece_).set_source_var(trimmed_data); 00262 else if(in_publish()) 00263 messages.back().last_publish().set_var(trimmed_data); 00264 break; 00265 00266 // legacy 00267 case tag_destination_var: 00268 messages.back().header_var(HEAD_DEST_ID).set_source_var(trimmed_data); 00269 break; 00270 00271 00272 case tag_name: 00273 if(!in_message_var() && !in_header_var()) 00274 messages.back().set_name(trimmed_data); 00275 else if(in_message_var()) 00276 messages.back().last_message_var().set_name(trimmed_data); 00277 else if(in_header_var()) 00278 messages.back().header_var(curr_head_piece_).set_name(trimmed_data); 00279 break; 00280 00281 00282 case tag_outgoing_hex_moos_var: 00283 messages.back().set_out_var(trimmed_data); 00284 break; 00285 00286 case tag_precision: 00287 messages.back().last_message_var().set_precision(trimmed_data); 00288 break; 00289 00290 00291 case tag_size: 00292 messages.back().set_size(trimmed_data); 00293 break; 00294 00295 case tag_trigger_var: 00296 messages.back().set_trigger_var(trimmed_data); 00297 break; 00298 00299 case tag_trigger_time: 00300 messages.back().set_trigger_time(trimmed_data); 00301 break; 00302 00303 case tag_trigger: 00304 messages.back().set_trigger(trimmed_data); 00305 break; 00306 00307 case tag_value: 00308 if(parents_.count(tag_static)) 00309 messages.back().last_message_var().set_static_val(trimmed_data); 00310 else if(parents_.count(tag_enum)) 00311 messages.back().last_message_var().add_enum(trimmed_data); 00312 break; 00313 00314 case tag_array_length: 00315 messages.back().last_message_var().set_array_length(trimmed_data); 00316 break; 00317 00318 00319 default: 00320 break; 00321 00322 } 00323 }