FilterText.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:4k
源码类别:

模拟服务器

开发平台:

C/C++

  1. // FilterText.cpp : Defines the entry point for the DLL application.
  2. //
  3. #include "stdafx.h"
  4. #include "FilterText.h"
  5. #include "Regexp.h"
  6. ////////////////////////////////////////////////////////////////////////////////////
  7. ////////////////////////////////////////////////////////////////////////////////////
  8. //class ...
  9. class CTextFilter : public ITextFilter
  10. {
  11. protected:
  12. CTextFilter() : m_ref(1), m_cntCommon(0) {}
  13. ~CTextFilter() {}
  14. STDMETHOD_(ULONG, AddRef)() {ASSERT(m_ref>0); return ++m_ref;}
  15. STDMETHOD_(ULONG, Release)() {ASSERT(m_ref>0); if (--m_ref) return m_ref; delete this; return 0;}
  16. STDMETHOD(QueryInterface)(REFIID, void**) {return E_NOTIMPL;}
  17. virtual BOOL AddExpression(LPCTSTR szExp);
  18. virtual BOOL Clearup();
  19. virtual BOOL IsTextPass(LPCTSTR text);
  20. private:
  21. ULONG m_ref;
  22. private:
  23. typedef std::vector<Regexp> CExpArray;
  24. enum {HASHSIZE = 0x01 << (sizeof(_TUCHAR) * 8)};
  25. typedef _TUCHAR HASHINDEXTYPE;
  26. HASHINDEXTYPE Char2HashIdx(TCHAR ch) {return HASHINDEXTYPE(ch);}
  27. CExpArray m_HashEntry[HASHSIZE];
  28. CExpArray m_AdvExps;
  29. size_t m_cntCommon;
  30. private:
  31. static const TCHAR* NextChar(const TCHAR* p)
  32. {
  33. ASSERT(p && p[0]);
  34. #ifdef _UNICODE
  35. return p + 1;
  36. #else
  37. return p + (p[0] < 0 && p[1] < 0 ? 2 : 1);
  38. #endif
  39. }
  40. public:
  41. static CTextFilter* CreateInstance() {return new CTextFilter;}
  42. };
  43. BOOL CTextFilter::AddExpression(LPCTSTR szExp)
  44. {
  45. try
  46. {
  47. static const TCHAR CH_ESC = '\';
  48. if (szExp == NULL || szExp[0] == 0)
  49. return TRUE;
  50. if (szExp[0] == leadchar_ignore)
  51. return TRUE;
  52. BOOL bInsensitive = szExp[0] == leadchar_insensitive;
  53. if (bInsensitive)
  54. szExp ++;
  55. if (szExp[0] != leadchar_common
  56. && szExp[0] != leadchar_advance)
  57. return FALSE;
  58. BOOL bCommon = szExp[0] == leadchar_common;
  59. LPCTSTR szRegExp = szExp + 1;
  60. if (szRegExp[0] == 0)
  61. return TRUE;
  62. TCHAR chLead = szRegExp[0];
  63. if (chLead == CH_ESC)
  64. {
  65. bCommon = TRUE;
  66. chLead = szExp[2];
  67. if (chLead == 0)
  68. return FALSE;
  69. if (_istalpha(chLead))
  70. szRegExp ++;
  71. }
  72. if (bCommon && bInsensitive && _istalpha(chLead))
  73. bCommon = FALSE;
  74. Regexp expr(szRegExp, bInsensitive);
  75. if (!expr.CompiledOK())
  76. return FALSE;
  77. if (bCommon)
  78. {
  79. const HASHINDEXTYPE hashkey = Char2HashIdx(chLead);
  80. m_HashEntry[hashkey].push_back(expr);
  81. m_cntCommon ++;
  82. }
  83. else
  84. {
  85. m_AdvExps.push_back(expr);
  86. }
  87. return TRUE;
  88. }
  89. catch (...)
  90. {
  91. ASSERT(FALSE);
  92. }
  93. return FALSE;
  94. }
  95. BOOL CTextFilter::Clearup()
  96. {
  97. try
  98. {
  99. for (int i = 0; i < HASHSIZE; i++)
  100. m_HashEntry[i].clear();
  101. m_cntCommon = 0;
  102. m_AdvExps.clear();
  103. return TRUE;
  104. }
  105. catch (...)
  106. {
  107. ASSERT(FALSE);
  108. }
  109. return FALSE;
  110. }
  111. BOOL CTextFilter::IsTextPass(LPCTSTR text)
  112. {
  113. try
  114. {
  115. if (text == NULL || text[0] == 0)
  116. return TRUE;
  117. const size_t cntAdvance = m_AdvExps.size();
  118. const BOOL bAdvPrior = cntAdvance < m_cntCommon;
  119. for (int loop = 0; loop < 2; loop++)
  120. {
  121. if ((loop == 0 && bAdvPrior)
  122. || (loop != 0 && !bAdvPrior))
  123. {//advance
  124. for (size_t i = 0; i < cntAdvance; i++)
  125. {
  126. if (m_AdvExps[i].Match(text))
  127. return FALSE;
  128. }
  129. }
  130. else
  131. {//common
  132. ASSERT(HASHSIZE % sizeof(BYTE) == 0);
  133. BYTE occur[HASHSIZE / sizeof(BYTE)] = {0};
  134. for (const TCHAR* pos = text; *pos != 0; pos = NextChar(pos))
  135. {
  136. const HASHINDEXTYPE hashkey = Char2HashIdx(*pos);
  137. BYTE& rByte = occur[hashkey / sizeof(BYTE)];
  138. const BYTE bitmask = 0x01 << (hashkey % sizeof(BYTE));
  139. if (!(rByte & bitmask))
  140. {
  141. CExpArray& rExpVec = m_HashEntry[hashkey];
  142. const size_t expcount = rExpVec.size();
  143. for (size_t k = 0; k < expcount; k++)
  144. {
  145. if (rExpVec[k].Match(pos))
  146. return FALSE;
  147. }
  148. rByte |= bitmask;
  149. }
  150. }
  151. }
  152. }
  153. return TRUE;
  154. }
  155. catch (...)
  156. {
  157. ASSERT(FALSE);
  158. }
  159. return FALSE;
  160. }
  161. //function ...
  162. FILTERTEXT_API HRESULT CreateTextFilter(ITextFilter** ppTextFilter)
  163. {
  164. if (ppTextFilter == NULL)
  165. return E_INVALIDARG;
  166. CTextFilter* pInst = CTextFilter::CreateInstance();
  167. if (pInst == NULL)
  168. return E_FAIL;
  169. *ppTextFilter = pInst;
  170. return S_OK;
  171. }