Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "rosout_text_filter.h"
00031
00032 #include <boost/algorithm/string/case_conv.hpp>
00033
00034 namespace rxtools
00035 {
00036
00037 int wildcmp(const char* wild, const char* string)
00038 {
00039
00040
00041
00042 const char *cp = NULL, *mp = NULL;
00043
00044 while ((*string) && (*wild != '*'))
00045 {
00046 if ((*wild != *string) && (*wild != '?'))
00047 {
00048 return 0;
00049 }
00050 wild++;
00051 string++;
00052 }
00053
00054 while (*string)
00055 {
00056 if (*wild == '*')
00057 {
00058 if (!*++wild)
00059 {
00060 return 1;
00061 }
00062 mp = wild;
00063 cp = string+1;
00064 }
00065 else if ((*wild == *string) || (*wild == '?'))
00066 {
00067 wild++;
00068 string++;
00069 }
00070 else
00071 {
00072 wild = mp;
00073 string = cp++;
00074 }
00075 }
00076
00077 while (*wild == '*')
00078 {
00079 wild++;
00080 }
00081 return !*wild;
00082 }
00083
00084 RosoutTextFilter::RosoutTextFilter()
00085 : field_mask_(Default)
00086 , use_regex_(false)
00087 , type_(Include)
00088 , regex_valid_(true)
00089 {
00090
00091 }
00092
00093 void RosoutTextFilter::setFieldMask(uint32_t field_mask)
00094 {
00095 field_mask_ = field_mask;
00096
00097 changed();
00098 }
00099
00100 void RosoutTextFilter::setText(const std::string& text)
00101 {
00102 text_ = text;
00103
00104 if (use_regex_)
00105 {
00106 regex_valid_ = true;
00107 if (!text_.empty())
00108 {
00109 try
00110 {
00111 regex_ = boost::regex(text_, boost::regbase::normal | boost::regbase::icase);
00112 }
00113 catch (std::runtime_error&)
00114 {
00115 regex_valid_ = false;
00116 }
00117 }
00118 }
00119
00120 changed();
00121 }
00122
00123 void RosoutTextFilter::setUseRegex(bool use)
00124 {
00125 use_regex_ = use;
00126
00127
00128 setText(text_);
00129 }
00130
00131 void RosoutTextFilter::setFilterType(FilterType type)
00132 {
00133 type_ = type;
00134
00135 changed();
00136 }
00137
00138 bool RosoutTextFilter::filterString(const std::string& str) const
00139 {
00140 bool match = false;
00141 if (use_regex_)
00142 {
00143 if (regex_valid_)
00144 {
00145 match = boost::regex_match(str, regex_);
00146 }
00147 }
00148 else
00149 {
00150 std::string lower_str = boost::algorithm::to_lower_copy(str);
00151 std::string lower_text = "*" + boost::algorithm::to_lower_copy(text_) + "*";
00152 match = wildcmp(lower_text.c_str(), lower_str.c_str());
00153 }
00154
00155 return match;
00156 }
00157
00158 bool RosoutTextFilter::filterVector(const std::vector<std::string>& strs) const
00159 {
00160 std::vector<std::string>::const_iterator it = strs.begin();
00161 std::vector<std::string>::const_iterator end = strs.end();
00162 for (; it != end; ++it)
00163 {
00164 if (filterString(*it))
00165 {
00166 return true;
00167 }
00168 }
00169
00170 return false;
00171 }
00172
00173 bool RosoutTextFilter::doFilter(const rosgraph_msgs::LogConstPtr& msg) const
00174 {
00175 if (text_.empty())
00176 {
00177 return true;
00178 }
00179
00180 bool match = false;
00181
00182 if (field_mask_ & Message)
00183 {
00184 match = match || filterString(msg->msg);
00185 }
00186
00187 if (field_mask_ & Node)
00188 {
00189 match = match || filterString(msg->name);
00190 }
00191
00192 if (field_mask_ & Location)
00193 {
00194 if (!match)
00195 {
00196 std::stringstream ss;
00197 ss << msg->file << ":" << msg->function << ":" << msg->line;
00198 match = match || filterString(ss.str());
00199 }
00200 }
00201
00202 if (field_mask_ & Topics)
00203 {
00204 match = match || filterVector(msg->topics);
00205 }
00206
00207 return type_ == Include ? match : !match;
00208 }
00209
00210 bool RosoutTextFilter::doIsValid() const
00211 {
00212 return !use_regex_ || regex_valid_;
00213 }
00214
00215 }