#pragma once #include "../../../../Common/ShareMemArray.h" // Идентификаторы хранилищ #define ISID_DEFAULT 0x0000 // По умолчанию #define ISID_WIN_FONT_STATUS_STORAGE 0x0001 // Таблица для статуса #define ISID_WIN_FONT_INFO_STORAGE 0x0002 // Таблица для Информации // Макс. длина имени таблицы #define STORAGE_TABLE_NAME_LEN 1024 #define STATUS_STORAGE_NAME CString( _T("AVS_LOADED_WIN_FONTS") ) namespace NSStrings { static CString ConvertCStringWToCString(CStringW& strW) { BSTR bstr = strW.AllocSysString(); CString str(bstr); SysFreeString(bstr); return str; } static CStringW GetCStringWFromUTF8( BYTE* pBuffer, LONG64 lCount ) { LONG64 lLenght = 0; CStringW strRes = L""; for (LONG lIndex = 0; lIndex < lCount; ++lIndex) { if (0x00 == (0x80 & pBuffer[lIndex])) { strRes += (WCHAR)pBuffer[lIndex]; continue; } else if (0x00 == (0x20 & pBuffer[lIndex])) { WCHAR mem = (WCHAR)(((pBuffer[lIndex] & 0x1F) << 6) + (pBuffer[lIndex + 1] & 0x3F)); strRes += mem; lIndex += 1; } else if (0x00 == (0x10 & pBuffer[lIndex])) { WCHAR mem = (WCHAR)(((pBuffer[lIndex] & 0x0F) << 12) + ((pBuffer[lIndex + 1] & 0x3F) << 6) + (pBuffer[lIndex + 2] & 0x3F)); strRes += mem; lIndex += 2; } } return strRes; } static CString GetCStringFromUTF8( BYTE* pBuffer, LONG64 lCount ) { CStringW strRes = GetCStringWFromUTF8(pBuffer, lCount); return ConvertCStringWToCString(strRes); } }; // статус таблицы установленных шрифтов enum WinFontsTableStatus {STIF_ERROR, STIF_AVAILABLE, STIF_CREATING, STIF_BROKEN}; enum StringCoding { scASCII = 0, scUNICODE = 1, scUTF8 = 2 }; // Структура для определения статуса таблицы хранилища struct WinFontsStatusStorage { // Общие данные WinFontsTableStatus m_sStatus; // Статус LONG64 m_lLength; // Размер таблицы WinFontsStatusStorage() { Reset(); } void Reset() { // Общие данные m_sStatus = STIF_ERROR; // Статус m_lLength = 0; } }; // Структура для определения информации struct WinFontsInfoStorage { LONG m_lCount; CStringA m_strXml; BYTE* m_pBuffer; LONG m_lCountData; WinFontsInfoStorage() { Reset(); } ~WinFontsInfoStorage() { } void Reset() { m_lCount = 0; m_strXml = ""; m_pBuffer = NULL; } void GenerateInfo(BSTR bstrXML) { m_strXml = CStringA(bstrXML); m_pBuffer = NULL; m_lCountData = 0; } void GenerateInfo(BYTE* pBuffer, LONG lCountData) { m_pBuffer = pBuffer; m_lCountData = lCountData; } void Save(BYTE* pBuffer) { if (NULL == pBuffer) return; if (0 == m_lCountData) { memcpy(pBuffer, (BYTE*)m_strXml.GetBuffer(), m_strXml.GetLength()); } else { memcpy(pBuffer, m_pBuffer, m_lCountData); } } LONG64 GetLength() { if (0 == m_lCountData) { return m_strXml.GetLength(); } return m_lCountData; } void Load(BYTE* pBuffer, LONG64 lLength) { //m_pBuffer = pBuffer; m_lCountData = (LONG)lLength; m_pBuffer = new BYTE[m_lCountData]; memcpy(m_pBuffer, pBuffer, m_lCountData); } }; // Класс хранилища таблицы статуса class CWinFontsStatusStorage: public CShareMemArray { protected: bool ReadStruct_unsync(WinFontsStatusStorage *aData) // Прочитать структуру unsync { __try { WinFontsStatusStorage *pTable = (WinFontsStatusStorage *) ( (BYTE *)m_pArray + sizeof(LONG64)); // sizeof(LONG64) - размер таблицы memcpy(aData, pTable, sizeof(WinFontsStatusStorage)); } __except(EXCEPTION_IN_PAGE_ERROR == GetExceptionCode() ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { // Failed to read from the view. //ATLTRACE2("CStatusStorage::ReadStruct_unsync() fails!\n"); return false; } return true; } bool WriteStruct_unsync(WinFontsStatusStorage *aData) // Записать структуру unsync { __try { WinFontsStatusStorage *pTable = (WinFontsStatusStorage *) ( (BYTE *)m_pArray + sizeof(LONG64)); // sizeof(LONG64) - размер таблицы memcpy(pTable, aData, sizeof(WinFontsStatusStorage)); } __except(EXCEPTION_IN_PAGE_ERROR == GetExceptionCode() ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { // Failed to read from the view. //ATLTRACE2("CStatusStorage::ReadStruct_unsync() fails!\n"); return false; } return true; } public: bool ReadStruct(WinFontsStatusStorage *aData) { CSynchAccess oAccess = m_hAccessMutex; return ReadStruct_unsync(aData); } bool WriteStruct(WinFontsStatusStorage *aData) { CSynchAccess oAccess = m_hAccessMutex; return WriteStruct_unsync(aData); } public: // Получить статус индексатора (bForceControl - Попытаться стать мастером, если получится) // возвращаем *bForceControl == true - вызывающий объект стал мастером bool GetStatus(bool *bForceControl, WinFontsStatusStorage* aIS) { bool bTryToForceControl = bForceControl && (*bForceControl); if (NULL == aIS) return false; if (bForceControl) *bForceControl = false; // Пока мы не можем стать мастером // Делаем все под мутексом :) CSynchAccess oAccess = m_hAccessMutex; if (!ReadStruct_unsync(aIS)) return false; // Не получилось прочитать статус if ((STIF_BROKEN == aIS->m_sStatus) || (STIF_ERROR == aIS->m_sStatus)) { // Таблица нарушена - говорим, что можно стать мастером (если нужно было) if (bTryToForceControl) { // Сбрасываем таблицу aIS->Reset(); aIS->m_sStatus = STIF_CREATING; *bForceControl = WriteStruct_unsync(aIS); // пишем в память и говорим, что стали мастером } } return true; } // Установить статус, как нарушенное хранилище. Мастерство может перехватываться другими объектами bool SetBroken() { CSynchAccess oAccess = m_hAccessMutex; WinFontsStatusStorage sStor; sStor.m_sStatus = STIF_BROKEN; // Пишем в ш-память return WriteStruct_unsync(&sStor); } private: // Скрываем методы работы с массивами bool Save(CAtlArray &aTable) { return false; } bool Load(CAtlArray &aTable) { return false; } public: CWinFontsStatusStorage(CString &aName): CShareMemArray(aName, sizeof(WinFontsStatusStorage), ISID_WIN_FONT_STATUS_STORAGE) { // Параметр aName должен быть AVS_LOAD_WIN_FONTS //ATLTRACE2("CStatusStorage created;\n"); }; ~CWinFontsStatusStorage() { //ATLTRACE2("CStatusStorage destroyed;\n"); }; }; // Класс хранилища таблицы информации class CWinFontsInfoStorage: public CShareMemArray { protected: bool ReadStruct_unsync(WinFontsInfoStorage *aData) // Прочитать структуру unsync { __try { LONG64 lLength = Size(); aData->Load((BYTE*)m_pArray + sizeof(LONG64), lLength); // sizeof(LONG64) - размер таблицы } __except(EXCEPTION_IN_PAGE_ERROR == GetExceptionCode() ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { // Failed to read from the view. //ATLTRACE2("CStatusStorage::ReadStruct_unsync() fails!\n"); return false; } return true; } bool WriteStruct_unsync(WinFontsInfoStorage *aData) // Записать структуру unsync { __try { LONG64 *pSize = (LONG64*)m_pArray; *pSize = m_nSize; aData->Save((BYTE*)m_pArray + sizeof(LONG64)); // sizeof(LONG64) - размер таблицы } __except(EXCEPTION_IN_PAGE_ERROR == GetExceptionCode() ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { // Failed to read from the view. //ATLTRACE2("CStatusStorage::ReadStruct_unsync() fails!\n"); return false; } return true; } public: bool ReadStruct(WinFontsInfoStorage *aData) { //CSynchAccess oAccess = m_hAccessMutex; return ReadStruct_unsync(aData); } bool WriteStruct(WinFontsInfoStorage *aData) { CSynchAccess oAccess = m_hAccessMutex; return WriteStruct_unsync(aData); } bool WriteCount(WinFontsInfoStorage *aData) { __try { BYTE* pData = (BYTE*)m_pArray + sizeof(LONG64); *((LONG*)pData) = aData->m_lCount; } __except(EXCEPTION_IN_PAGE_ERROR == GetExceptionCode() ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { // Failed to read from the view. //ATLTRACE2("CWinFontsInfoStorage::ReadStruct_unsync() fails!\n"); return false; } return true; } private: // Скрываем методы работы с массивами bool Save(CAtlArray &aTable) { return false; } bool Load(CAtlArray &aTable) { return false; } public: CWinFontsInfoStorage(CString &aFileName, LONG64 lSize): CShareMemArray(aFileName, lSize, ISID_WIN_FONT_INFO_STORAGE) { //ATLTRACE2("CWinFontsInfoStorage created;\n"); }; ~CWinFontsInfoStorage() { //ATLTRACE2("CWinFontsInfoStorage destroyed;\n"); }; };