| 1 |
#include <windows.h> |
| 2 |
#include <stdlib.h> |
| 3 |
#include <tchar.h> |
| 4 |
#include <string.h> |
| 5 |
|
| 6 |
#include "Tombo.h" |
| 7 |
#include "SearchEngine.h" |
| 8 |
#include "TString.h" |
| 9 |
#include "UniConv.h" |
| 10 |
#include "Property.h" |
| 11 |
#include "TomboURI.h" |
| 12 |
#include "Repository.h" |
| 13 |
|
| 14 |
#include "AutoPtr.h" |
| 15 |
|
| 16 |
#include "RegexUtil.h" |
| 17 |
|
| 18 |
//////////////////////////////////////////////////////// |
| 19 |
//////////////////////////////////////////////////////// |
| 20 |
// regex search (MBCS version) |
| 21 |
//////////////////////////////////////////////////////// |
| 22 |
//////////////////////////////////////////////////////// |
| 23 |
|
| 24 |
//////////////////////////////////////////////////////// |
| 25 |
// ctor & dtor |
| 26 |
//////////////////////////////////////////////////////// |
| 27 |
|
| 28 |
SearchEngineA::SearchEngineA() : pCompiledPattern(NULL), pPattern(NULL) |
| 29 |
{ |
| 30 |
} |
| 31 |
|
| 32 |
SearchEngineA::~SearchEngineA() |
| 33 |
{ |
| 34 |
delete [] pPattern; |
| 35 |
if (pCompiledPattern) { |
| 36 |
Regex_Free(pCompiledPattern); |
| 37 |
} |
| 38 |
} |
| 39 |
|
| 40 |
BOOL SearchEngineA::Init(DWORD nCP, BOOL bSE, BOOL bFo, PasswordManager *pPMgr) |
| 41 |
{ |
| 42 |
nCodePage = nCP; |
| 43 |
bSearchEncrypt = bSE; |
| 44 |
bFileNameOnly = bFo; |
| 45 |
pPassMgr = pPMgr; |
| 46 |
return TRUE; |
| 47 |
} |
| 48 |
|
| 49 |
//////////////////////////////////////////////////////// |
| 50 |
// prepare regex pattern |
| 51 |
//////////////////////////////////////////////////////// |
| 52 |
|
| 53 |
BOOL SearchEngineA::Prepare(LPCTSTR pPat, BOOL bCS, const char **ppReason) |
| 54 |
{ |
| 55 |
delete[] pPattern; // release previous Prepare data |
| 56 |
pPattern = ConvTCharToFileEncoding(pPat, &nPatLen); |
| 57 |
|
| 58 |
if (pPattern == NULL) { |
| 59 |
SetLastError(ERROR_NOT_ENOUGH_MEMORY); |
| 60 |
*ppReason = "Not enough memory"; |
| 61 |
return FALSE; |
| 62 |
} |
| 63 |
|
| 64 |
if (pCompiledPattern) { |
| 65 |
Regex_Free(pCompiledPattern); |
| 66 |
} |
| 67 |
|
| 68 |
pCompiledPattern = Regex_Compile(pPattern, !bCS, ppReason, nCodePage); |
| 69 |
if (!pCompiledPattern) { |
| 70 |
return FALSE; |
| 71 |
} |
| 72 |
|
| 73 |
bCaseSensitive = bCS; |
| 74 |
return TRUE; |
| 75 |
} |
| 76 |
|
| 77 |
//////////////////////////////////////////////////////// |
| 78 |
// search from text |
| 79 |
//////////////////////////////////////////////////////// |
| 80 |
|
| 81 |
BOOL SearchEngineA::SearchTextA(const LPBYTE pText, DWORD nStartPos, BOOL bForward, BOOL bShift) |
| 82 |
{ |
| 83 |
LPBYTE p = pText + nStartPos; |
| 84 |
|
| 85 |
if (!pCompiledPattern) return TRUE; |
| 86 |
|
| 87 |
// if bShift is TRUE, shift start position 1 letter |
| 88 |
if (bShift) { |
| 89 |
if (bForward) { |
| 90 |
p = ShiftRight(pText, p, nCodePage); |
| 91 |
} else { |
| 92 |
p = ShiftLeft(pText, p, nCodePage); |
| 93 |
} |
| 94 |
} |
| 95 |
|
| 96 |
// execute searching |
| 97 |
int s, e; |
| 98 |
int res = Regex_Search(pCompiledPattern, (p - pText), pText, bForward, &s, &e, nCodePage); |
| 99 |
if (res >= 0) { |
| 100 |
nMatchStart = s; |
| 101 |
nMatchEnd = e; |
| 102 |
return TRUE; |
| 103 |
} else { |
| 104 |
return FALSE; |
| 105 |
} |
| 106 |
} |
| 107 |
|
| 108 |
BOOL SearchEngineA::SearchTextT(LPCTSTR pText, DWORD nStartPos, BOOL bForward, BOOL bShift) |
| 109 |
{ |
| 110 |
DWORD nTextLen; |
| 111 |
LPBYTE pData = ConvTCharToFileEncoding(pText, &nTextLen); |
| 112 |
SecureBufferAutoPointerByte ap(pData, nTextLen); |
| 113 |
|
| 114 |
#if defined(PLATFORM_WIN32) |
| 115 |
DWORD nSystemCodePage = 0; |
| 116 |
#else |
| 117 |
DWORD nSystemCodePage = TOMBO_CP_UTF16LE; |
| 118 |
#endif |
| 119 |
|
| 120 |
// convert unicode pos to MBCS pos |
| 121 |
DWORD nStartPosA = ConvertPos((LPBYTE)pText, nStartPos * sizeof(TCHAR), nSystemCodePage, pData, nCodePage); |
| 122 |
|
| 123 |
// exec searching |
| 124 |
BOOL bResult = SearchTextA(pData, nStartPosA, bForward, bShift); |
| 125 |
|
| 126 |
// if matched, convert MBCS pos to unicode pos |
| 127 |
if (bResult) { |
| 128 |
DWORD nMatchStartA = nMatchStart; |
| 129 |
DWORD nMatchEndA = nMatchEnd; |
| 130 |
|
| 131 |
nMatchStart = ConvertPos(pData, nMatchStartA, nCodePage, (LPBYTE)pText, nSystemCodePage) / sizeof(TCHAR); |
| 132 |
nMatchEnd = ConvertPos(pData, nMatchEndA, nCodePage, (LPBYTE)pText, nSystemCodePage) / sizeof(TCHAR); |
| 133 |
} |
| 134 |
return bResult; |
| 135 |
} |
| 136 |
|
| 137 |
//////////////////////////////////////////////////////// |
| 138 |
// Matching |
| 139 |
//////////////////////////////////////////////////////// |
| 140 |
|
| 141 |
SearchResult SearchEngineA::SearchFromURI(const TomboURI *pURI) |
| 142 |
{ |
| 143 |
if (bFileNameOnly) { |
| 144 |
TString sPartName; |
| 145 |
if (!g_Repository.GetFileName(pURI, &sPartName)) return SR_FAILED; |
| 146 |
|
| 147 |
BOOL bMatch; |
| 148 |
|
| 149 |
DWORD nSize; |
| 150 |
LPBYTE pText = ConvTCharToFileEncoding(sPartName.Get(), &nSize); |
| 151 |
SecureBufferAutoPointerByte ap(pText, nSize); |
| 152 |
|
| 153 |
bMatch = (Regex_Search(pCompiledPattern, 0, pText, TRUE, NULL, NULL, nCodePage) >= 0); |
| 154 |
|
| 155 |
return bMatch ? SR_FOUND : SR_NOTFOUND; |
| 156 |
} else { |
| 157 |
URIOption opt(NOTE_OPTIONMASK_ENCRYPTED); |
| 158 |
if (!g_Repository.GetOption(pURI, &opt)) return SR_FAILED; |
| 159 |
|
| 160 |
// skip crypted note if it is not search target. |
| 161 |
if (!IsSearchEncryptMemo() && opt.bEncrypt) return SR_NOTFOUND; |
| 162 |
|
| 163 |
DWORD nSize; |
| 164 |
LPBYTE pMemo = g_Repository.GetNoteDataNative(pURI, &nSize); |
| 165 |
if (pMemo == NULL) return SR_FAILED; |
| 166 |
SecureBufferAutoPointerByte ap(pMemo, nSize); |
| 167 |
|
| 168 |
BOOL bMatch = (Regex_Search(pCompiledPattern, 0, pMemo, TRUE, NULL, NULL, nCodePage) >= 0); |
| 169 |
return bMatch ? SR_FOUND : SR_NOTFOUND; |
| 170 |
} |
| 171 |
} |
| 172 |
|
| 173 |
//////////////////////////////////////////////////////// |
| 174 |
// Duplicate object |
| 175 |
//////////////////////////////////////////////////////// |
| 176 |
|
| 177 |
SearchEngineA *SearchEngineA::Clone() |
| 178 |
{ |
| 179 |
const char *pReason; |
| 180 |
SearchEngineA *p = new SearchEngineA(); |
| 181 |
if (!p) return NULL; |
| 182 |
|
| 183 |
LPTSTR pPat = ConvFileEncodingToTChar(pPattern); |
| 184 |
ArrayAutoPointer<TCHAR> ap(pPat); |
| 185 |
|
| 186 |
if (!p->Init(nCodePage, bSearchEncrypt, bFileNameOnly, pPassMgr) || |
| 187 |
!p->Prepare(pPat, bCaseSensitive, &pReason)) { |
| 188 |
delete p; |
| 189 |
return NULL; |
| 190 |
} |
| 191 |
return p; |
| 192 |
} |
| 193 |
|
| 194 |
|