$search
00001 /* 00002 * Copyright (c) 2009, Willow Garage, Inc. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * * Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * * Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * * Neither the name of Willow Garage, Inc. nor the names of its 00014 * contributors may be used to endorse or promote products derived from 00015 * this software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00018 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00021 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00022 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00023 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00024 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00025 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00026 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00027 * POSSIBILITY OF SUCH DAMAGE. 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 // Written by Jack Handy - jakkhandy@hotmail.com 00040 // found at http://www.codeproject.com/KB/string/wildcmp.aspx 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 // setText will call changed(), so we don't do it here explicitly 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 }