Wildcard.h

00001 // $Id: Wildcard.h 21 2010-09-05 04:18:17Z cschwarz1 $
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