100 lines
3.6 KiB
C++
100 lines
3.6 KiB
C++
/**********************************************************************
|
|
Cache Search Stuff (simple, fast strstr)
|
|
|
|
Marc Miller (t-marcmi) - 1998
|
|
**********************************************************************/
|
|
|
|
#include "priv.h"
|
|
|
|
#ifndef __HISTORY_CACHE_SEARCH__
|
|
#define __HISTORY_CACHE_SEARCH__
|
|
|
|
#define UNICODE_SIGNATURE 0xFFFE
|
|
#define UNICODE_SIGNATURE_BACKWARDS 0xFEFF
|
|
|
|
namespace CacheSearchEngine {
|
|
|
|
class IWideSequentialReadStream {
|
|
public:
|
|
virtual BOOL GetNextChar(WCHAR &wc) = 0;
|
|
};
|
|
|
|
class StreamSearcher {
|
|
protected:
|
|
LPWSTR _pwszPreparedSearchTarget;
|
|
static inline BOOL s_IsWhiteSpace(const WCHAR &wc) {
|
|
return ((wc == L' ') || (wc == L'\t') || (wc == L'\n') || (wc == L'\r'));
|
|
}
|
|
static inline LPCWSTR s_SkipWhiteSpace(LPCWSTR pwszStr) {
|
|
LPCWSTR pwszTemp = pwszStr;
|
|
while(s_IsWhiteSpace(*pwszTemp))
|
|
++pwszTemp;
|
|
return pwszTemp;
|
|
}
|
|
void _PrepareSearchTarget(LPCWSTR pwszSearchTarget);
|
|
public:
|
|
StreamSearcher(LPCWSTR pwszSearchTarget) { _PrepareSearchTarget(pwszSearchTarget); }
|
|
~StreamSearcher() { if ( _pwszPreparedSearchTarget ) { LocalFree(_pwszPreparedSearchTarget); _pwszPreparedSearchTarget = NULL; } }
|
|
BOOL SearchCharStream(IWideSequentialReadStream &wsrs, BOOL fIsHTML = FALSE);
|
|
};
|
|
|
|
class StringStream : public IWideSequentialReadStream {
|
|
BOOL fCleanup; // the string we hold needs to be deallocated by us
|
|
LPCWSTR pwszStr;
|
|
UINT uCurrentPos;
|
|
public:
|
|
StringStream(LPCWSTR pwszStr, BOOL fDuplicate = FALSE) : uCurrentPos(0), fCleanup(fDuplicate) {
|
|
if (fDuplicate)
|
|
SHStrDupW(pwszStr, const_cast<LPWSTR *>(&(this->pwszStr)));
|
|
else
|
|
this->pwszStr = pwszStr;
|
|
}
|
|
StringStream(LPCSTR pszStr, BOOL fDuplicate = FALSE) : uCurrentPos(0), fCleanup(TRUE) {
|
|
SHStrDupA(pszStr, const_cast<LPWSTR *>(&(pwszStr)));
|
|
}
|
|
~StringStream() {
|
|
if (fCleanup)
|
|
CoTaskMemFree(const_cast<LPWSTR>(pwszStr));
|
|
}
|
|
BOOL GetNextChar(WCHAR &wc) {
|
|
wc = pwszStr[uCurrentPos];
|
|
if (wc)
|
|
++uCurrentPos;
|
|
return wc;
|
|
}
|
|
};
|
|
|
|
class CacheStreamWrapper : public IWideSequentialReadStream {
|
|
protected:
|
|
HANDLE _hCacheStream;
|
|
DWORD _dwCacheStreamLoc; // our offset into the actual cache file
|
|
BOOL _fEndOfFile;
|
|
|
|
// I can never remember which one is little endian and which is big endian
|
|
enum DATATYPEENUM { UNICODE_DATA = 0, UNICODE_BACKWARDS_DATA, ASCII_DATA } _dataType;
|
|
static inline BOOL s_IsUnicode(DATATYPEENUM dte) { return dte < ASCII_DATA; }
|
|
static inline UINT s_Charsize (DATATYPEENUM dte) { return s_IsUnicode(dte) ? sizeof(USHORT) : sizeof(CHAR); }
|
|
|
|
static DWORD s_dwPageSize;
|
|
|
|
LPBYTE _pbBuff; /* buffer of bytes which are type-neutral
|
|
_pbBuff is allocated with VirtualAlloc */
|
|
LPBYTE _pbBuffPos; // current position in buffer
|
|
LPBYTE _pbBuffLast; // last byte in buffer
|
|
DWORD _dwBuffSize; // current valid buffer size (not allocated size)
|
|
|
|
BOOL _ReadNextBlock();
|
|
BOOL _GetNextByte(BYTE &b);
|
|
|
|
public:
|
|
CacheStreamWrapper(HANDLE hCacheStream);
|
|
~CacheStreamWrapper();
|
|
BOOL GetNextChar(WCHAR &wc);
|
|
};
|
|
|
|
|
|
BOOL SearchCacheStream(StreamSearcher &cse, HANDLE hCacheStream, BOOL fIsHTML = FALSE);
|
|
}
|
|
|
|
#endif
|