// // catmgr.h // #ifndef CATMGR_H #define CATMGR_H #include "private.h" #include "strary.h" #include "enumguid.h" ////////////////////////////////////////////////////////////////////////////// // // CCatGUIDTbl // ////////////////////////////////////////////////////////////////////////////// #define CATGUID_HASHSIZE 31 #define ValidGUIDHash(hashid) (hashid < CATGUID_HASHSIZE) #define ValidGUIDARRAYCount(cnt) (cnt < 0x07ffffff) #define MAKEGUIDATOM(cnt, hashid) (cnt * 32 | (hashid + 1)) #define HASHIDFROMGUIDATOM(atom) ((atom & 0x1f) - 1) #define IDFROMGUIDATOM(atom) (atom / 32) typedef enum { CAT_FORWARD = 0x0, CAT_BACKWARD = 0x1 } CATDIRECTION; typedef struct tag_CATGUIDITEM { GUID guid; SHARED_GUID_ARRAY *rgGuidAry[2]; } CATGUIDITEM; class CCatGUIDTbl { public: CCatGUIDTbl() {} ~CCatGUIDTbl() { for (int i = 0; i < CATGUID_HASHSIZE; i++) { if (_prgCatGUID[i]) { int nCnt = _prgCatGUID[i]->Count(); for (int j = 0; j < nCnt; j++) { CATGUIDITEM *pItem = _prgCatGUID[i]->GetPtr(j); SGA_Release(pItem->rgGuidAry[CAT_FORWARD]); SGA_Release(pItem->rgGuidAry[CAT_BACKWARD]); } delete _prgCatGUID[i]; } } } void FreeCatCache() { for (int i = 0; i < CATGUID_HASHSIZE; i++) { if (_prgCatGUID[i]) { int nCnt = _prgCatGUID[i]->Count(); for (int j = 0; j < nCnt; j++) { CATGUIDITEM *pItem = _prgCatGUID[i]->GetPtr(j); SGA_Release(pItem->rgGuidAry[CAT_FORWARD]); SGA_Release(pItem->rgGuidAry[CAT_BACKWARD]); pItem->rgGuidAry[CAT_FORWARD] = NULL; pItem->rgGuidAry[CAT_BACKWARD] = NULL; } } } } TfGuidAtom Add(REFGUID rguid); TfGuidAtom FindGuid(REFGUID rguid); CATGUIDITEM *GetGUID(TfGuidAtom atom); private: UINT _HashFunc(REFGUID rguid) { return (DWORD)rguid.Data1 % CATGUID_HASHSIZE; } CStructArray *_prgCatGUID[CATGUID_HASHSIZE]; }; ////////////////////////////////////////////////////////////////////////////// // // CCategoryMgr // ////////////////////////////////////////////////////////////////////////////// // perf: this class doesn't really need CComObjectRootImmx, it is stateless class CCategoryMgr : public ITfCategoryMgr, public CComObjectRoot_CreateInstance { public: CCategoryMgr(); ~CCategoryMgr(); BEGIN_COM_MAP_IMMX(CCategoryMgr) COM_INTERFACE_ENTRY(ITfCategoryMgr) END_COM_MAP_IMMX() // // ITfCategoryMgr // STDMETHODIMP RegisterCategory(REFCLSID rclsid, REFGUID rcatid, REFGUID rguid); STDMETHODIMP UnregisterCategory(REFCLSID rclsid, REFGUID rcatid, REFGUID rguid); STDMETHODIMP EnumCategoriesInItem(REFGUID rguid, IEnumGUID **ppEnum); STDMETHODIMP EnumItemsInCategory(REFGUID rcatid, IEnumGUID **ppEnum); STDMETHODIMP FindClosestCategory(REFGUID rguid, GUID *pcatid, const GUID **ppcatidList, ULONG ulCount); STDMETHODIMP RegisterGUIDDescription(REFCLSID rclsid, REFGUID rguid, const WCHAR *pchDesc, ULONG cch); STDMETHODIMP UnregisterGUIDDescription(REFCLSID rclsid, REFGUID rguid); STDMETHODIMP GetGUIDDescription(REFGUID rguid, BSTR *pbstrDesc); STDMETHODIMP RegisterGUIDDWORD(REFCLSID rclsid, REFGUID rguid, DWORD dw); STDMETHODIMP UnregisterGUIDDWORD(REFCLSID rclsid, REFGUID rguid); STDMETHODIMP GetGUIDDWORD(REFGUID rguid, DWORD *pdw); STDMETHODIMP RegisterGUID(REFGUID rguid, TfGuidAtom *pguidatom); STDMETHODIMP GetGUID(TfGuidAtom guidatom, GUID *pguid); STDMETHODIMP IsEqualTfGuidAtom(TfGuidAtom guidatom, REFGUID rguid, BOOL *pfEqual); static BOOL InitGlobal(); static BOOL s_IsValidGUIDATOM(TfGuidAtom guidatom) { if (!_pCatGUIDTbl) return FALSE; return _pCatGUIDTbl->GetGUID(guidatom) ? TRUE : FALSE; } static void UninitGlobal() { if (_pCatGUIDTbl) delete _pCatGUIDTbl; _pCatGUIDTbl = NULL; } static void FreeCatCache() { CicEnterCriticalSection(g_cs); if (_pCatGUIDTbl) _pCatGUIDTbl->FreeCatCache(); CicLeaveCriticalSection(g_cs); } static HRESULT s_RegisterCategory(REFCLSID rclsid, REFGUID rcatid, REFGUID rguid); static HRESULT s_UnregisterCategory(REFCLSID rclsid, REFGUID rcatid, REFGUID rguid); static HRESULT s_EnumCategoriesInItem(REFGUID rguid, IEnumGUID **ppEnum); static HRESULT s_EnumItemsInCategory(REFGUID rcatid, IEnumGUID **ppEnum); static HRESULT s_RegisterGUID(REFGUID rguid, TfGuidAtom *pguidatom); static HRESULT s_GetGUID(TfGuidAtom guidatom, GUID *pguid); static HRESULT s_IsEqualTfGuidAtom(TfGuidAtom guidatom, REFGUID rguid, BOOL *pfEqual); static HRESULT s_FindClosestCategory(REFGUID rguid, GUID *pcatid, const GUID **ppcatidList, ULONG ulCount); static HRESULT s_RegisterGUIDDescription(REFCLSID rclsid, REFGUID rguid, WCHAR *pszDesc); static HRESULT s_UnregisterGUIDDescription(REFCLSID rclsid, REFGUID rguid); static HRESULT s_GetGUIDDescription(REFGUID rguid, BSTR *pbstrDesc); static HRESULT s_GetGUIDValue(REFGUID rguid, const WCHAR* pszValue, BSTR *pbstrDesc); static HRESULT s_RegisterGUIDDWORD(REFCLSID rclsid, REFGUID rguid, DWORD dw); static HRESULT s_UnregisterGUIDDWORD(REFCLSID rclsid, REFGUID rguid); static HRESULT s_GetGUIDDWORD(REFGUID rguid, DWORD *pdw); static CCatGUIDTbl *_pCatGUIDTbl; private: static HRESULT _InternalRegisterCategory(REFCLSID rclsid, REFGUID rcatid, REFGUID rguid, CATDIRECTION catdir); static HRESULT _InternalUnregisterCategory(REFCLSID rclsid, REFGUID rcatid, REFGUID rguid, CATDIRECTION catdir); static HRESULT _InternalEnumCategories(REFGUID rguid, IEnumGUID **ppEnum, CATDIRECTION catdir); static HRESULT _InternalFindClosestCategory(REFGUID rguidOrg, REFGUID rguid, GUID *pcatid, const GUID **ppcatidList, ULONG ulCount); static HRESULT _GetFirstCategory(REFGUID rguid, GUID *pcatid); static void _FlushGuidArrayCache(REFGUID rguid, CATDIRECTION catdir); DBG_ID_DECLARE; }; ////////////////////////////////////////////////////////////////////////////// // // CEnumCategories // ////////////////////////////////////////////////////////////////////////////// class CEnumCategories : public CEnumGuid { public: CEnumCategories(); BOOL _Init(REFGUID rcatid, CATDIRECTION catdir); DBG_ID_DECLARE; }; #endif // CATMGR_H