Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
472
Src/omBrowser/cacheGroup.cpp
Normal file
472
Src/omBrowser/cacheGroup.cpp
Normal file
|
@ -0,0 +1,472 @@
|
|||
#include "main.h"
|
||||
#include "./cacheGroup.h"
|
||||
#include "./cacheRecord.h"
|
||||
#include "./cacheManager.h"
|
||||
|
||||
#include <wininet.h>
|
||||
#include <shlwapi.h>
|
||||
#include <strsafe.h>
|
||||
#include <algorithm>
|
||||
|
||||
CacheGroup::CacheGroup(LPCWSTR pszName)
|
||||
: ref(1), name(NULL), owner(NULL)
|
||||
{
|
||||
name = Plugin_CopyString(pszName);
|
||||
}
|
||||
|
||||
CacheGroup::~CacheGroup()
|
||||
{
|
||||
Clear();
|
||||
|
||||
Plugin_FreeString(name);
|
||||
}
|
||||
|
||||
HRESULT CacheGroup::CreateInstance(LPCWSTR pszName, CacheGroup **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
*instance = NULL;
|
||||
|
||||
*instance = new CacheGroup(pszName);
|
||||
if (NULL == *instance) return E_OUTOFMEMORY;
|
||||
|
||||
return S_OK;
|
||||
|
||||
}
|
||||
|
||||
size_t CacheGroup::AddRef()
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
size_t CacheGroup::Release()
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int CacheGroup::QueryInterface(GUID interface_guid, void **object)
|
||||
{
|
||||
if (NULL == object) return E_POINTER;
|
||||
|
||||
if (IsEqualIID(interface_guid, IFC_OmCacheGroup))
|
||||
*object = static_cast<ifc_omcachegroup*>(this);
|
||||
else
|
||||
{
|
||||
*object = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
if (NULL == *object)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CacheGroup::SetOwner(CacheManager *group)
|
||||
{
|
||||
owner = group;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CacheGroup::GetName(LPWSTR pszBuffer, UINT cchBufferMax)
|
||||
{
|
||||
if (NULL == pszBuffer || 0 == cchBufferMax)
|
||||
return E_INVALIDARG;
|
||||
|
||||
return StringCchCopyEx(pszBuffer, cchBufferMax, name, NULL, NULL, STRSAFE_IGNORE_NULLS);
|
||||
}
|
||||
|
||||
HRESULT CacheGroup::IsEqualName(LPCWSTR pszGroup)
|
||||
{
|
||||
if (NULL == pszGroup)
|
||||
return (NULL == name) ? S_OK : S_FALSE;
|
||||
|
||||
if (NULL == name) return S_FALSE;
|
||||
|
||||
INT result = CompareString(CSTR_INVARIANT, NORM_IGNORECASE, pszGroup, -1, name, -1);
|
||||
if (0 == result)
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
return HRESULT_FROM_WIN32(error);
|
||||
}
|
||||
return (CSTR_EQUAL == result) ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT CacheGroup::IsEqual(CacheGroup *group)
|
||||
{
|
||||
return (NULL != group) ? IsEqualName(group->name) : E_INVALIDARG;
|
||||
}
|
||||
|
||||
HRESULT CacheGroup::IsEmpty()
|
||||
{
|
||||
return (0 == recordList.size()) ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT CacheGroup::Delete(LPCWSTR pszName)
|
||||
{
|
||||
HRESULT hr = S_FALSE;
|
||||
size_t index = recordList.size();
|
||||
|
||||
while(index--)
|
||||
{
|
||||
CacheRecord *record = recordList[index];
|
||||
if (NULL != record && S_OK == record->IsEqualName(pszName))
|
||||
{
|
||||
recordList.erase(recordList.begin() + index);
|
||||
record->Release();
|
||||
hr = S_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CacheGroup::Clear()
|
||||
{
|
||||
size_t index = recordList.size();
|
||||
|
||||
while(index--)
|
||||
{
|
||||
CacheRecord *record = recordList[index];
|
||||
if (NULL != record) record->Release();
|
||||
}
|
||||
|
||||
recordList.clear();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
__inline static int __cdecl CacheGroup_RecordSearch(const void *elem1, const void *elem2)
|
||||
{
|
||||
int r = ((CacheRecord*)elem2)->CompareTo((LPCWSTR)elem1);
|
||||
return -r;
|
||||
}
|
||||
|
||||
HRESULT CacheGroup::Find(LPCWSTR pszName, BOOL fInsertMissing, CacheRecord **recordOut, BOOL *created)
|
||||
{
|
||||
if (NULL != created)
|
||||
*created = FALSE;
|
||||
|
||||
if (NULL == recordOut)
|
||||
return E_POINTER;
|
||||
|
||||
HRESULT hr = S_FALSE;
|
||||
size_t index = recordList.size();
|
||||
if (0 != index)
|
||||
{
|
||||
//CacheRecord *rec = (CacheRecord*)bsearch(pszName, recordList.at(0), recordList.size(), sizeof(CacheRecord*), CacheGroup_RecordSearch);
|
||||
auto it = std::find_if(recordList.begin(), recordList.end(),
|
||||
[&](CacheRecord* upT) -> bool
|
||||
{
|
||||
return upT->CompareTo(pszName) == 0;
|
||||
}
|
||||
);
|
||||
if (it != recordList.end())
|
||||
{
|
||||
*recordOut = *it;
|
||||
(*recordOut)->AddRef();
|
||||
hr = S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (S_FALSE == hr && FALSE != fInsertMissing)
|
||||
{
|
||||
hr = CacheRecord::CreateInstance(pszName, NULL, 0, recordOut);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
recordList.push_back(*recordOut);
|
||||
Sort();
|
||||
|
||||
(*recordOut)->AddRef();
|
||||
(*recordOut)->SetOwner(this);
|
||||
|
||||
if (NULL != created)
|
||||
*created = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (S_OK != hr)
|
||||
*recordOut = NULL;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CacheGroup::GetPath(LPWSTR pszBuffer, UINT cchBufferMax)
|
||||
{
|
||||
if (NULL == pszBuffer || 0 == cchBufferMax)
|
||||
return E_INVALIDARG;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
if (NULL != owner)
|
||||
{
|
||||
hr = owner->GetPath(pszBuffer, cchBufferMax);
|
||||
if (SUCCEEDED(hr) && NULL != name)
|
||||
{
|
||||
if (FALSE == PathAppend(pszBuffer, name))
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*pszBuffer = L'\0';
|
||||
hr = E_UNEXPECTED;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT CacheGroup_FormatStoreData(LPWSTR pszBuffer, size_t cchBufferMax, LPCWSTR pszPath, UINT *cchLength)
|
||||
{
|
||||
if (NULL == pszBuffer)
|
||||
return E_INVALIDARG;
|
||||
|
||||
size_t remaining = cchBufferMax;
|
||||
HRESULT hr;
|
||||
hr = StringCchCopyEx(pszBuffer, remaining, L"path=", &pszBuffer, &remaining, 0);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
hr = StringCchCopyEx(pszBuffer, remaining, pszPath, &pszBuffer, &remaining, 0);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
if (0 == remaining)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
remaining--;
|
||||
pszBuffer++;
|
||||
*pszBuffer = L'\0';
|
||||
|
||||
if (NULL != cchLength)
|
||||
*cchLength = (UINT)(cchBufferMax - remaining) + 1;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CacheGroup::Store(LPCWSTR pszName, LPCWSTR pszPath)
|
||||
{
|
||||
HRESULT hr;
|
||||
WCHAR szBuffer[2048] = {0};
|
||||
|
||||
hr = GetPath(szBuffer, ARRAYSIZE(szBuffer));
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
Plugin_EnsurePathExist(szBuffer);
|
||||
|
||||
if (FALSE == PathAppend(szBuffer, L"cache.ini"))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
LPSTR pathAnsi = Plugin_WideCharToMultiByte(CP_UTF8, 0, szBuffer, -1, NULL, NULL);
|
||||
if (NULL == pathAnsi) return E_OUTOFMEMORY;
|
||||
|
||||
LPSTR nameAnsi = Plugin_WideCharToMultiByte(CP_UTF8, 0, pszName, -1, NULL, NULL);
|
||||
if (NULL == nameAnsi) return E_OUTOFMEMORY;
|
||||
|
||||
LPSTR dataAnsi = NULL;
|
||||
if (NULL != pszPath)
|
||||
{
|
||||
UINT cchData;
|
||||
hr = CacheGroup_FormatStoreData(szBuffer, ARRAYSIZE(szBuffer), pszPath, &cchData);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
dataAnsi = Plugin_WideCharToMultiByte(CP_UTF8, 0, szBuffer, cchData, NULL, NULL);
|
||||
if (NULL == dataAnsi)
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr) && 0 == WritePrivateProfileSectionA(nameAnsi, dataAnsi, pathAnsi))
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
hr = HRESULT_FROM_WIN32(error);
|
||||
}
|
||||
|
||||
Plugin_FreeAnsiString(dataAnsi);
|
||||
Plugin_FreeAnsiString(nameAnsi);
|
||||
Plugin_FreeAnsiString(pathAnsi);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CacheGroup::Load()
|
||||
{
|
||||
HRESULT hr;
|
||||
WCHAR szBuffer[4096] = {0};
|
||||
|
||||
hr = GetPath(szBuffer, ARRAYSIZE(szBuffer));
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
if (FALSE == PathAppend(szBuffer, L"cache.ini"))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
HANDLE hFile = CreateFile(szBuffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||||
if (INVALID_HANDLE_VALUE == hFile)
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
return HRESULT_FROM_WIN32(error);
|
||||
}
|
||||
|
||||
DWORD read = 0;
|
||||
CHAR szLine[INTERNET_MAX_URL_LENGTH + 3] = {0};
|
||||
WCHAR szUnicode[ARRAYSIZE(szLine)] = {0};
|
||||
UINT lineIndex = 0;
|
||||
CacheRecord *record = NULL;
|
||||
UINT recordSet = 0;
|
||||
size_t inserted = 0;
|
||||
|
||||
RecordList cleanupList;
|
||||
|
||||
while (0 != ReadFile(hFile, szBuffer, sizeof(szBuffer), &read, NULL))
|
||||
{
|
||||
LPCSTR cursor = (LPCSTR)szBuffer;
|
||||
LPCSTR end = cursor + read;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if (cursor >= end)
|
||||
break;
|
||||
|
||||
if (cursor == end || ('\r' == *cursor && '\n' == *(cursor+1)))
|
||||
{
|
||||
szLine[lineIndex] = '\0';
|
||||
|
||||
if (lineIndex > 0)
|
||||
{
|
||||
if ('[' == szLine[0] && ']' == szLine[lineIndex-1])
|
||||
{
|
||||
if (NULL != record)
|
||||
{
|
||||
if (0 != (0x00000001 & recordSet))
|
||||
{
|
||||
recordList.push_back(record);
|
||||
inserted++;
|
||||
}
|
||||
else
|
||||
{
|
||||
cleanupList.push_back(record);
|
||||
}
|
||||
|
||||
record = NULL;
|
||||
}
|
||||
|
||||
szLine[lineIndex-1] = '\0';
|
||||
if (0 != MultiByteToWideChar(CP_UTF8, 0, szLine + 1, -1, szUnicode, ARRAYSIZE(szUnicode)) &&
|
||||
SUCCEEDED(CacheRecord::CreateInstance(szUnicode, NULL, 0, &record)))
|
||||
{
|
||||
record->SetOwner(this);
|
||||
recordSet = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const char kw_path[] = "path=";
|
||||
UINT cchKey = ARRAYSIZE(kw_path) - 1;
|
||||
if (NULL != record &&
|
||||
lineIndex > cchKey &&
|
||||
CSTR_EQUAL == CompareStringA(CSTR_INVARIANT, NORM_IGNORECASE, kw_path, cchKey, szLine, cchKey) &&
|
||||
0 != MultiByteToWideChar(CP_UTF8, 0, szLine + cchKey, -1, szUnicode, ARRAYSIZE(szUnicode)))
|
||||
{
|
||||
if(SUCCEEDED(record->SetPath(szUnicode)) &&
|
||||
SUCCEEDED(record->GetPath(szUnicode, ARRAYSIZE(szUnicode))) &&
|
||||
FALSE != PathFileExists(szUnicode))
|
||||
{
|
||||
recordSet |= 0x00000001;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
lineIndex = 0;
|
||||
cursor += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lineIndex < ARRAYSIZE(szLine) - 2)
|
||||
{
|
||||
szLine[lineIndex++] = *cursor;
|
||||
}
|
||||
|
||||
cursor++;
|
||||
}
|
||||
|
||||
if (0 == read)
|
||||
{
|
||||
if (NULL != record)
|
||||
{
|
||||
if (0 != (0x00000001 & recordSet))
|
||||
{
|
||||
recordList.push_back(record);
|
||||
inserted++;
|
||||
}
|
||||
else
|
||||
record->Release();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
|
||||
if (0 != inserted)
|
||||
{
|
||||
Sort();
|
||||
}
|
||||
|
||||
size_t i = cleanupList.size();
|
||||
if (0 != i)
|
||||
{
|
||||
while (i--)
|
||||
{
|
||||
aTRACE_LINE("ADD CACHE CLEANUP!!!!");
|
||||
cleanupList[i]->Release();
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
__inline static int __cdecl CacheGroup_RecordComparer(const void *elem1, const void *elem2)
|
||||
{
|
||||
return CacheRecord::Compare((CacheRecord*)elem1, (CacheRecord*)elem2);
|
||||
}
|
||||
|
||||
__inline static bool __cdecl CacheGroup_RecordComparer_V2(const void* elem1, const void* elem2)
|
||||
{
|
||||
return CacheGroup_RecordComparer(elem1, elem2) < 0;
|
||||
}
|
||||
|
||||
HRESULT CacheGroup::Sort()
|
||||
{
|
||||
HRESULT hr;
|
||||
if (0 == recordList.size())
|
||||
{
|
||||
hr = S_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
//qsort(recordList.first(), recordList.size(), sizeof(CacheRecord*), CacheGroup_RecordComparer);
|
||||
std::sort(recordList.begin(), recordList.end(), CacheGroup_RecordComparer_V2);
|
||||
hr = S_OK;
|
||||
}
|
||||
|
||||
return hr;
|
||||
|
||||
}
|
||||
|
||||
#define CBCLASS CacheGroup
|
||||
START_DISPATCH;
|
||||
CB(ADDREF, AddRef)
|
||||
CB(RELEASE, Release)
|
||||
CB(QUERYINTERFACE, QueryInterface)
|
||||
CB(API_GETNAME, GetName)
|
||||
CB(API_FIND, Find)
|
||||
CB(API_DELETE, Delete)
|
||||
CB(API_CLEAR, Clear)
|
||||
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
Loading…
Add table
Add a link
Reference in a new issue