00001
00002
00003 #ifndef BASE_WILDCARD_H
00004 #define BASE_WILDCARD_H
00005
00006 #include "String.h"
00007
00008 namespace base {
00015 template<class charT, class traits = CharTraits<charT> > class WildcardT {
00016 public:
00018 WildcardT() {}
00019
00025 WildcardT(const StringT<charT, traits> &wildcard) {
00026 set(wildcard);
00027 }
00028
00034 const StringT<charT, traits> &get() const {
00035 return _wildcard;
00036 }
00037
00038 #ifdef _WIN32
00039 #define BASE_ICASE true
00040 #else
00041 #define BASE_ICASE false
00042 #endif
00043
00050 static bool match(const charT *wildcard, const charT *filename, bool icase = BASE_ICASE);
00051
00058 bool match(const StringT<charT, traits> &filename, bool icase = BASE_ICASE) const;
00059 #undef BASE_ICASE
00060
00066 void set(const StringT<charT, traits> &wildcard) {
00067 _wildcard = wildcard;
00068 }
00069
00070 private:
00071 StringT<charT, traits> _wildcard;
00072 };
00073
00074 typedef WildcardT<char> Wildcard;
00075 typedef WildcardT<wchar_t> WWildcard;
00076
00077 template<class charT, class traits> bool WildcardT<charT, traits>::match(const charT *wildcard, const charT *filename, bool icase) {
00078 bool ret = false;
00079
00080 if (wildcard == NULL)
00081 throw std::invalid_argument("wildcard == NULL");
00082 if (filename == NULL)
00083 throw std::invalid_argument("filename == NULL");
00084
00085 for (;;) {
00086 if (*wildcard == traits::nul) {
00087 if (*filename == traits::nul)
00088 ret = true;
00089 break;
00090 }
00091
00092 if (*wildcard == traits::ch_ast) {
00093 for (;;) {
00094 if (match(wildcard + 1, filename, icase)) {
00095 ret = true;
00096 break;
00097 }
00098 if (*filename == traits::nul)
00099 break;
00100 filename++;
00101 }
00102 break;
00103 } else if (*wildcard == traits::ch_qm) {
00104 if (*filename == traits::nul)
00105 break;
00106 wildcard++;
00107 filename++;
00108 } else {
00109 if (icase) {
00110 if (traits::tolower(*wildcard) != traits::tolower(*filename))
00111 break;
00112 } else {
00113 if (*wildcard != *filename)
00114 break;
00115 }
00116 wildcard++;
00117 filename++;
00118 }
00119 }
00120
00121 return ret;
00122 }
00123
00124 template<class charT, class traits> bool WildcardT<charT, traits>::match(const StringT<charT, traits> &filename, bool icase) const {
00125 return match(_wildcard.c_str(), filename.c_str(), icase);
00126 }
00127
00128 }
00129
00130 #endif