Index: src/libchcore/TStringPattern.cpp =================================================================== diff -u -N --- src/libchcore/TStringPattern.cpp (revision 0) +++ src/libchcore/TStringPattern.cpp (revision 5ccf162f73d05a43bbe5cb7c01d16d07b6b0d4d9) @@ -0,0 +1,133 @@ +#include "stdafx.h" +#include "TStringPattern.h" +#include "TCoreException.h" +#include "ErrorCodes.h" +#include + +BEGIN_CHCORE_NAMESPACE + +namespace +{ + bool _tcicmp(TCHAR c1, TCHAR c2) + { + TCHAR ch1[2] = { c1, 0 }, ch2[2] = { c2, 0 }; + return (_tcsicmp(ch1, ch2) == 0); + } +} + +TStringPattern::TStringPattern(EPatternType ePatternType) : + m_ePatternType(ePatternType) +{ +} + +TStringPattern::TStringPattern(const TString& strPattern, EPatternType ePatternType) : + m_ePatternType(ePatternType), + m_strPattern(strPattern) +{ +} + +TString TStringPattern::ToSerializedString() const +{ + TString strPrefix; + switch (m_ePatternType) + { + case EPatternType::eType_Wildcard: + strPrefix = L"WC;"; + break; + + default: + THROW_CORE_EXCEPTION(eErr_UnhandledCase); + } + + return TString(strPrefix + m_strPattern); +} + +void TStringPattern::FromSerializedString(const TString& strSerializedPattern) +{ + if (strSerializedPattern.StartsWith(L"WC;")) + { + m_ePatternType = EPatternType::eType_Wildcard; + m_strPattern = strSerializedPattern.Mid(3); + } + else + THROW_CORE_EXCEPTION(eErr_UnhandledCase); +} + +TStringPattern TStringPattern::CreateFromSerializedString(const TString& strSerializedPattern) +{ + TStringPattern pattern; + pattern.FromSerializedString(strSerializedPattern); + return pattern; +} + +bool TStringPattern::MatchMask(LPCTSTR lpszMask, LPCTSTR lpszString) const +{ + bool bMatch = 1; + + //iterate and delete '?' and '*' one by one + while (*lpszMask != _T('\0') && bMatch && *lpszString != _T('\0')) + { + if (*lpszMask == _T('?')) lpszString++; + else if (*lpszMask == _T('*')) + { + bMatch = Scan(lpszMask, lpszString); + lpszMask--; + } + else + { + bMatch = _tcicmp(*lpszMask, *lpszString); + lpszString++; + } + lpszMask++; + } + while (*lpszMask == _T('*') && bMatch) lpszMask++; + + return bMatch && *lpszString == _T('\0') && *lpszMask == _T('\0'); +} + +// scan '?' and '*' +bool TStringPattern::Scan(LPCTSTR& lpszMask, LPCTSTR& lpszString) const +{ + // remove the '?' and '*' + for (lpszMask++; *lpszString != _T('\0') && (*lpszMask == _T('?') || *lpszMask == _T('*')); lpszMask++) + if (*lpszMask == _T('?')) lpszString++; + while (*lpszMask == _T('*')) lpszMask++; + + // if lpszString is empty and lpszMask has more characters or, + // lpszMask is empty, return + if (*lpszString == _T('\0') && *lpszMask != _T('\0')) return false; + if (*lpszString == _T('\0') && *lpszMask == _T('\0')) return true; + // else search substring + else + { + LPCTSTR wdsCopy = lpszMask; + LPCTSTR lpszStringCopy = lpszString; + bool bMatch = true; + do + { + if (!MatchMask(lpszMask, lpszString)) lpszStringCopy++; + lpszMask = wdsCopy; + lpszString = lpszStringCopy; + while (!(_tcicmp(*lpszMask, *lpszString)) && (*lpszString != '\0')) lpszString++; + wdsCopy = lpszMask; + lpszStringCopy = lpszString; + } while ((*lpszString != _T('\0')) ? !MatchMask(lpszMask, lpszString) : (bMatch = false) != false); + + if (*lpszString == _T('\0') && *lpszMask == _T('\0')) return true; + + return bMatch; + } +} + +bool TStringPattern::Matches(const TString& strTextToMatch) const +{ + return MatchMask(m_strPattern.c_str(), strTextToMatch.c_str()); +} + +void TStringPattern::SetPattern(const TString& strPattern, EPatternType ePatternType) +{ + m_ePatternType = ePatternType; + m_strPattern = strPattern; +} + +END_CHCORE_NAMESPACE Index: src/libchcore/TStringPattern.h =================================================================== diff -u -N --- src/libchcore/TStringPattern.h (revision 0) +++ src/libchcore/TStringPattern.h (revision 5ccf162f73d05a43bbe5cb7c01d16d07b6b0d4d9) @@ -0,0 +1,62 @@ +// ============================================================================ +// Copyright (C) 2001-2015 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#ifndef __TSTRINGPATTERN_H__ +#define __TSTRINGPATTERN_H__ + +#include "libchcore.h" +#include "TString.h" + +BEGIN_CHCORE_NAMESPACE + +class LIBCHCORE_API TStringPattern +{ +public: + enum class EPatternType + { + eType_Wildcard + }; + +public: + explicit TStringPattern(EPatternType ePatternType = EPatternType::eType_Wildcard); + TStringPattern(const TString& strPattern, EPatternType ePatternType = EPatternType::eType_Wildcard); + + void SetPattern(const TString& strPattern, EPatternType ePatternType = EPatternType::eType_Wildcard); + bool Matches(const TString& strTextToMatch) const; + + EPatternType GetPatternType() const { return m_ePatternType; } + TString GetPattern() const { return m_strPattern; } + + // serialization + static TStringPattern CreateFromSerializedString(const TString& strSerializedPattern); + + void FromSerializedString(const TString& strSerializedPattern); + TString ToSerializedString() const; + +private: + bool MatchMask(LPCTSTR lpszMask, LPCTSTR lpszString) const; + bool Scan(LPCTSTR& lpszMask, LPCTSTR& lpszString) const; + +private: + TString m_strPattern; + EPatternType m_ePatternType; +}; + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/TStringPatternArray.cpp =================================================================== diff -u -N --- src/libchcore/TStringPatternArray.cpp (revision 0) +++ src/libchcore/TStringPatternArray.cpp (revision 5ccf162f73d05a43bbe5cb7c01d16d07b6b0d4d9) @@ -0,0 +1,125 @@ +// ============================================================================ +// Copyright (C) 2001-2015 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#include "stdafx.h" +#include "TStringPatternArray.h" +#include "TCoreException.h" +#include "ErrorCodes.h" +#include "TStringArray.h" + +BEGIN_CHCORE_NAMESPACE + +TStringPatternArray::TStringPatternArray() +{ +} + +TStringPatternArray::~TStringPatternArray() +{ +} + +void TStringPatternArray::Add(const TStringPattern& strPattern) +{ + m_vPatterns.push_back(strPattern); +} + +void TStringPatternArray::InsertAt(size_t stIndex, const TStringPattern& strPattern) +{ + if (stIndex > m_vPatterns.size()) + THROW_CORE_EXCEPTION(eErr_BoundsExceeded); + + m_vPatterns.insert(m_vPatterns.begin() + stIndex, strPattern); +} + +void TStringPatternArray::SetAt(size_t stIndex, const TStringPattern& strPattern) +{ + if (stIndex >= m_vPatterns.size()) + THROW_CORE_EXCEPTION(eErr_BoundsExceeded); + + m_vPatterns[stIndex] = strPattern; +} + +void TStringPatternArray::RemoveAt(size_t stIndex) +{ + if (stIndex >= m_vPatterns.size()) + THROW_CORE_EXCEPTION(eErr_BoundsExceeded); + + m_vPatterns.erase(m_vPatterns.begin() + stIndex); +} + +void TStringPatternArray::Clear() +{ + m_vPatterns.clear(); +} + +const TStringPattern& TStringPatternArray::GetAt(size_t stIndex) const +{ + if (stIndex >= m_vPatterns.size()) + THROW_CORE_EXCEPTION(eErr_BoundsExceeded); + + return m_vPatterns[stIndex]; +} + +size_t TStringPatternArray::GetCount() const +{ + return m_vPatterns.size(); +} + +bool TStringPatternArray::MatchesAny(const TString& strTextToMatch) const +{ + for (const TStringPattern& pattern : m_vPatterns) + { + if (pattern.Matches(strTextToMatch)) + return true; + } + + return false; +} + +bool TStringPatternArray::MatchesAll(const TString& strTextToMatch) const +{ + for (const TStringPattern& pattern : m_vPatterns) + { + if (!pattern.Matches(strTextToMatch)) + return false; + } + + return true; +} + +void TStringPatternArray::FromStringArray(const TStringArray& arrSerializedPatterns) +{ + m_vPatterns.clear(); + + for (size_t stIndex = 0; stIndex < arrSerializedPatterns.GetCount(); ++stIndex) + { + m_vPatterns.push_back(TStringPattern::CreateFromSerializedString(arrSerializedPatterns.GetAt(stIndex))); + } +} + +TStringArray TStringPatternArray::ToStringArray() const +{ + TStringArray arrSerialized; + for (const TStringPattern& pattern : m_vPatterns) + { + arrSerialized.Add(pattern.ToSerializedString()); + } + + return arrSerialized; +} + +END_CHCORE_NAMESPACE Index: src/libchcore/TStringPatternArray.h =================================================================== diff -u -N --- src/libchcore/TStringPatternArray.h (revision 0) +++ src/libchcore/TStringPatternArray.h (revision 5ccf162f73d05a43bbe5cb7c01d16d07b6b0d4d9) @@ -0,0 +1,60 @@ +// ============================================================================ +// Copyright (C) 2001-2015 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#ifndef __TSTRINGPATTERNARRAY_H__ +#define __TSTRINGPATTERNARRAY_H__ + +#include "libchcore.h" +#include "TStringPattern.h" + +BEGIN_CHCORE_NAMESPACE + +class LIBCHCORE_API TStringPatternArray +{ +public: + TStringPatternArray(); + ~TStringPatternArray(); + + // general api + void Add(const TStringPattern& strPattern); + void InsertAt(size_t stIndex, const TStringPattern& strPattern); + void SetAt(size_t stIndex, const TStringPattern& strPattern); + void RemoveAt(size_t stIndex); + void Clear(); + + const TStringPattern& GetAt(size_t stIndex) const; + size_t GetCount() const; + + // pattern api + bool MatchesAny(const TString& strTextToMatch) const; + bool MatchesAll(const TString& strTextToMatch) const; + + // serialization + void FromStringArray(const TStringArray& arrSerializedPatterns); + TStringArray ToStringArray() const; + +private: +#pragma warning(push) +#pragma warning(disable: 4251) + std::vector m_vPatterns; +#pragma warning(pop) +}; + +END_CHCORE_NAMESPACE + +#endif