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 }