Note: Goby version 1 (shown here) is now considered obsolete. Please use version 2 for new projects, and consider upgrading old projects.

Goby Underwater Autonomy Project  Series: 1.1, revision: 163, released on 2013-02-06 14:23:27 -0500
acomms/libdccl/message_algorithms.cpp
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 <boost/foreach.hpp>
00021 
00022 #include "message_algorithms.h"
00023 #include "message_val.h"
00024 #include "message.h"
00025 #include "dccl_exception.h"
00026 
00027 #include "goby/util/string.h"
00028 
00029 goby::acomms::DCCLAlgorithmPerformer* goby::acomms::DCCLAlgorithmPerformer::inst_ = 0;
00030 
00031 // singleton class, use this to get pointer
00032 goby::acomms::DCCLAlgorithmPerformer* goby::acomms::DCCLAlgorithmPerformer::getInstance()
00033 {
00034     if(!inst_) inst_ = new DCCLAlgorithmPerformer();
00035 
00036     return(inst_);
00037 }
00038 
00039 void goby::acomms::DCCLAlgorithmPerformer::algorithm(DCCLMessageVal& in, unsigned array_index, const std::string& algorithm, const std::map<std::string,std::vector<DCCLMessageVal> >& vals)
00040 {
00041     if(in.empty()) return;
00042 
00043 // algo_name:ref_variable_name1:ref_variable_name2...
00044     
00045     std::vector<std::string>ref_vars;
00046     std::string algorithm_deblanked = boost::erase_all_copy(algorithm, " ");
00047     boost::split(ref_vars, algorithm_deblanked, boost::is_any_of(":"));
00048 
00049     std::string alg;
00050     std::vector<DCCLMessageVal> tied_vals;
00051 
00052     for(std::vector<std::string>::size_type i = 1, n = ref_vars.size();
00053         i < n;
00054         ++i)
00055     {
00056         std::map<std::string, std::vector<DCCLMessageVal> >::const_iterator it = vals.find(ref_vars[i]);
00057         if(it != vals.end())
00058         {
00059             if(array_index < it->second.size())
00060                 tied_vals.push_back(it->second[array_index]);
00061             else
00062                 tied_vals.push_back(it->second[0]);
00063         }
00064     }
00065     
00066     if(ref_vars.size() > 0)
00067         alg = ref_vars[0];
00068     
00069     // short form for simple algorithms
00070     if (adv_map1_.count(alg))
00071     { adv_map1_.find(alg)->second(in); }
00072     // longer form for more demanding algorithms
00073     else if (adv_map2_.count(alg))
00074     { adv_map2_.find(alg)->second(in, tied_vals); }
00075 
00076 }
00077 
00078 // check validity of algorithm name and references
00079 void goby::acomms::DCCLAlgorithmPerformer::check_algorithm(const std::string& alg, const DCCLMessage& msg)
00080 {
00081     if(alg.empty()) return;
00082     
00083     std::vector<std::string>ref_vars;
00084     std::string algorithm_deblanked = boost::erase_all_copy(alg, " ");
00085     boost::split(ref_vars, algorithm_deblanked, boost::is_any_of(":"));
00086 
00087     // check if the algorithm exists
00088     // but ignore if no algorithms loaded (to use for testing tools)
00089     if ((adv_map1_.size() || adv_map2_.size()) && !adv_map1_.count(ref_vars.at(0)) && !adv_map2_.count(ref_vars.at(0)))
00090         throw(DCCLException(std::string(msg.get_display() + "unknown algorithm defined: " + ref_vars.at(0))));
00091 
00092     
00093     for(std::vector<std::string>::size_type i = 1, n = ref_vars.size();
00094         i < n;
00095         ++i)
00096     {
00097         bool ref_found = false;
00098         BOOST_FOREACH(const boost::shared_ptr<DCCLMessageVar> mv, msg.header_const())
00099         {
00100             if(ref_vars[i] == mv->name())
00101             {
00102                 ref_found =true;
00103                 break;
00104             }
00105         }
00106         
00107         BOOST_FOREACH(const boost::shared_ptr<DCCLMessageVar> mv, msg.layout_const())
00108         {
00109             if(ref_vars[i] == mv->name())
00110             {
00111                 ref_found =true;
00112                 break;
00113             }
00114         }
00115 
00116         if(!ref_found)
00117             throw(DCCLException(std::string(msg.get_display() + "no such reference message variable " + ref_vars.at(i) + " used in algorithm: " + ref_vars.at(0))));
00118     }
00119 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends