You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
357 lines
11 KiB
357 lines
11 KiB
/*-----------------------------------------------------------------------------
|
|
*
|
|
* File: wiacache.cpp
|
|
* Author: Samuel Clement (samclem)
|
|
* Date: Thu Sep 09 16:15:11 1999
|
|
*
|
|
* Copyright (c) 1999 Microsoft Corporation
|
|
*
|
|
* Description:
|
|
*
|
|
* This contains the implementation of the CWiaCacheManager. Which handles
|
|
* managing items/data that we want to cache for performance reasons
|
|
*
|
|
* History:
|
|
* 09 Sep 1999: Created.
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
#include "stdafx.h"
|
|
|
|
DeclareTag( tagWiaCache, "!WiaCache", "Wia cache debug information" );
|
|
|
|
CWiaCacheManager* CWiaCacheManager::sm_pManagerInstance = NULL;
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* CWiaCacheManager
|
|
*
|
|
* This creates a new CWiaCacheManager object. This simply initalizes all
|
|
* the variables to a known state. Initialize handles actually creating
|
|
* the objects that we need.
|
|
*--(samclem)-----------------------------------------------------------------*/
|
|
CWiaCacheManager::CWiaCacheManager() : m_hThumbHeap( 0 )
|
|
{
|
|
TraceTag((0,"** Creating WiaCache" ));
|
|
TRACK_OBJECT( "CWiaCacheManager - SINGLETON" );
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* ~CWiaCacheManager
|
|
*
|
|
* This destroyes the CWiaCacheManager object. This will handle taking all
|
|
* the memory it has away with it. including any thumbnail memory we might be
|
|
* carrying around.
|
|
*--(samclem)-----------------------------------------------------------------*/
|
|
CWiaCacheManager::~CWiaCacheManager()
|
|
{
|
|
TraceTag((0, "** Destroying WiaCache" ));
|
|
|
|
// Destroying the heap will free any memory
|
|
// allocated by the heap, so this will keep us
|
|
// from leaking
|
|
if ( m_hThumbHeap )
|
|
{
|
|
HeapDestroy( m_hThumbHeap );
|
|
m_hThumbHeap = 0;
|
|
}
|
|
|
|
// destroy our critical section
|
|
DeleteCriticalSection( &m_cs );
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* CWiaCacheManager::Initialize
|
|
*
|
|
* This is called following a call to new in order to get this object ready
|
|
* to use. Without calling this the cache manager will be unusable.
|
|
*--(samclem)-----------------------------------------------------------------*/
|
|
bool CWiaCacheManager::Initialize()
|
|
{
|
|
SYSTEM_INFO si;
|
|
|
|
// initialize our critical section
|
|
__try {
|
|
if(!InitializeCriticalSectionAndSpinCount( &m_cs, MINLONG )) {
|
|
return false;
|
|
}
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
return false;
|
|
}
|
|
|
|
// we need to create the heap we are going to allocate
|
|
// out thumbnail memory from
|
|
GetSystemInfo( &si );
|
|
m_hThumbHeap = TW32( HeapCreate( HEAP_NO_SERIALIZE, si.dwPageSize, 0 ), HANDLE(0) );
|
|
|
|
return ( m_hThumbHeap != 0 );
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* CWiaCacheManager::GetDevice
|
|
*
|
|
* This returns a cached pointer to the device. This returns true if the
|
|
* device was found, (and the out param is valid) or false if we didn't
|
|
* find it. Example:
|
|
*
|
|
* CWiaCacheManager* pCache = CWiaCacheManager::GetInstance();
|
|
* IWiaItem* pItem = NULL;
|
|
*
|
|
* if ( pCache->GetDevice( bstrId, &pItem ) )
|
|
* {
|
|
* // use pItem
|
|
* .
|
|
* .
|
|
* pItem->Release();
|
|
* }
|
|
* else
|
|
* {
|
|
* // create pItem and use
|
|
* .
|
|
* .
|
|
* pCache->AddDevice( bstrId, pItem );
|
|
* pItem->Release();
|
|
* }
|
|
*
|
|
* bstrId: the id of the device that we want.
|
|
* ppDevice: Out, recieves the cached device pointer.
|
|
*--(samclem)-----------------------------------------------------------------*/
|
|
bool CWiaCacheManager::GetDevice( CComBSTR bstrId, IWiaItem** ppDevice )
|
|
{
|
|
return FALSE;
|
|
|
|
//
|
|
// NOTE: We've effectively disabled the device cache by always returning
|
|
// FALSE here and not calling AddDevice anywhere else.
|
|
//
|
|
/*
|
|
bool fRet = true;
|
|
Assert( ppDevice );
|
|
|
|
// our member class does most of the work for us, however we need
|
|
// to ensure that we are thread safe
|
|
Lock();
|
|
*ppDevice = m_icItemCache.GetFromCache( bstrId );
|
|
Unlock();
|
|
if ( !(*ppDevice) )
|
|
fRet = false;
|
|
else
|
|
(*ppDevice)->AddRef();
|
|
|
|
return fRet;
|
|
*/
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* CWiaCacheManager::AddDevice
|
|
*
|
|
* This adds a device item pointer to the cache. See GetDevice() for an
|
|
* complete example. Returns true if we successfully added the device
|
|
*
|
|
* bstrId: the ID of the new device to add
|
|
* pDevice: The pointer to add to the cache
|
|
*--(samclem)-----------------------------------------------------------------*/
|
|
bool CWiaCacheManager::AddDevice( CComBSTR bstrId, IWiaItem* pDevice )
|
|
{
|
|
bool fRet = true;
|
|
|
|
Assert( pDevice );
|
|
|
|
// again our member class does a majority of the work so all we
|
|
// need to do is to call through. However, we make sure that
|
|
// we are thread safe when we do that
|
|
Lock();
|
|
fRet = m_icItemCache.AddToCache( bstrId, pDevice );
|
|
Unlock();
|
|
|
|
return fRet;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* CWiaCacheManager::RemoveDevice
|
|
*
|
|
* This removes a device from the cache. This returns true of the item
|
|
* was found in the cache, or false if it was not.
|
|
*
|
|
* bstrId: the ID of the device to remove from the cache
|
|
*--(samclem)-----------------------------------------------------------------*/
|
|
bool CWiaCacheManager::RemoveDevice( CComBSTR bstrId )
|
|
{
|
|
bool fRet = false;
|
|
|
|
Lock();
|
|
// remove the item from the cache
|
|
fRet = m_icItemCache.RemoveFromCache( bstrId );
|
|
Unlock();
|
|
|
|
return fRet;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* CWiaCacheManager::GetThumbnail
|
|
*
|
|
* This attempts to get a thumbnail from the cache. There might not
|
|
* be one there, in which case this simply returns 'false'
|
|
*
|
|
* bstrFullItemName: the name of the item we want the thumb for
|
|
* ppbThumb: Out, pointer to the thumbnail bites
|
|
* pcbThumb: Out, recieves the size of the thumbnail
|
|
*--(samclem)-----------------------------------------------------------------*/
|
|
bool CWiaCacheManager::GetThumbnail( CComBSTR bstrFullItemName, BYTE** ppbThumb, DWORD* pcbThumb )
|
|
{
|
|
bool fRet = false;
|
|
THUMBNAILCACHEITEM* ptci = 0;
|
|
|
|
Assert( ppbThumb && pcbThumb );
|
|
|
|
*ppbThumb = 0;
|
|
*pcbThumb = 0;
|
|
|
|
Lock();
|
|
ptci = m_tcThumbnails[bstrFullItemName];
|
|
if ( ptci )
|
|
{
|
|
*ppbThumb = ptci->pbThumb;
|
|
*pcbThumb = ptci->cbThumb;
|
|
fRet = true;
|
|
}
|
|
Unlock();
|
|
|
|
return fRet;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* CWiaCacheManager::AddThumbnail
|
|
*
|
|
* This attempts to add a thumbnail to the cache. this will return true
|
|
* if the item was successfully added or false if it failed.
|
|
*
|
|
* bstrFullItemName: the name of the item to cache the thumb for
|
|
* pbThumb: Pointer to the thumbnail memory
|
|
* cbThumb: the number of bytes in the thumbnail.
|
|
*--(samclem)-----------------------------------------------------------------*/
|
|
bool CWiaCacheManager::AddThumbnail( CComBSTR bstrFullItemName, BYTE* pbThumb, DWORD cbThumb )
|
|
{
|
|
bool fRet = false;
|
|
THUMBNAILCACHEITEM* ptci = 0;
|
|
|
|
Assert( pbThumb && cbThumb );
|
|
Assert( m_hThumbHeap && "Need a valid thumbnail heap" );
|
|
RemoveThumbnail( bstrFullItemName );
|
|
|
|
Lock();
|
|
ptci = reinterpret_cast<THUMBNAILCACHEITEM*>(TW32(HeapAlloc( m_hThumbHeap,
|
|
HEAP_NO_SERIALIZE, sizeof( THUMBNAILCACHEITEM ) ), LPVOID(0) ) );
|
|
if ( ptci )
|
|
{
|
|
ptci->pbThumb = pbThumb;
|
|
ptci->cbThumb = cbThumb;
|
|
m_tcThumbnails[bstrFullItemName] = ptci;
|
|
fRet = true;
|
|
}
|
|
Unlock();
|
|
|
|
return fRet;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* CWiaCacheManager::RemoveThumbnail
|
|
*
|
|
* THis removes a thumbnail from the cache. This will return true if found
|
|
* an item to remove, or false if it removed nothing.
|
|
*
|
|
* bstrFullItemName: the name of the item to remove from the cache.
|
|
*--(samclem)-----------------------------------------------------------------*/
|
|
bool CWiaCacheManager::RemoveThumbnail( CComBSTR bstrFullItemName )
|
|
{
|
|
bool fRet = false;
|
|
THUMBNAILCACHEITEM* ptci = 0;
|
|
|
|
Lock();
|
|
ptci = m_tcThumbnails[bstrFullItemName];
|
|
if ( ptci )
|
|
{
|
|
m_tcThumbnails.erase( bstrFullItemName );
|
|
TW32( HeapFree( m_hThumbHeap, HEAP_NO_SERIALIZE, ptci ), FALSE );
|
|
fRet = true;
|
|
}
|
|
Unlock();
|
|
|
|
return fRet;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* CWiaCacheManager::AllocThumbnail
|
|
*
|
|
* This allocates memory for a thumbnail from our thumbnail heap.
|
|
*
|
|
* cbThumb: the size of the thumbnail to allocate
|
|
* ppbThumb: Out, recieves the pointer to the memory
|
|
*--(samclem)-----------------------------------------------------------------*/
|
|
bool CWiaCacheManager::AllocThumbnail( DWORD cbThumb, BYTE** ppbThumb )
|
|
{
|
|
Assert( m_hThumbHeap && "Error: NULL thumbnail heap" );
|
|
Assert( ppbThumb && cbThumb != 0 );
|
|
|
|
Lock();
|
|
*ppbThumb = reinterpret_cast<BYTE*>(TW32( HeapAlloc( m_hThumbHeap,
|
|
HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY, cbThumb ), LPVOID(0) ));
|
|
Unlock();
|
|
|
|
return ( *ppbThumb != NULL );
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* CWiaCacheManager::FreeThumbnail
|
|
*
|
|
* This frees the thumbnail memory. This _SHOULD_NOT_ be called if the
|
|
* thumbnail is cached. This should only be called to cleanup after an error
|
|
* generating the thumbnail.
|
|
*
|
|
* pbThumb: the memory to free
|
|
*--(samclem)-----------------------------------------------------------------*/
|
|
void CWiaCacheManager::FreeThumbnail( BYTE* pbThumb )
|
|
{
|
|
Assert( m_hThumbHeap && "Error: NULL thumbnail heap" );
|
|
Assert( pbThumb );
|
|
|
|
Lock();
|
|
TW32( HeapFree( m_hThumbHeap, HEAP_NO_SERIALIZE, pbThumb ), FALSE );
|
|
Unlock();
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* CWiaCacheManager::Init [static]
|
|
*
|
|
* This is called to initalize the cache manager. This simply creates and
|
|
* instance of the cache manager and then initalizes it.
|
|
*
|
|
* Notes: This can only be called once
|
|
*--(samclem)-----------------------------------------------------------------*/
|
|
bool CWiaCacheManager::Init()
|
|
{
|
|
Assert( !sm_pManagerInstance &&
|
|
"\nInit() can only be called once. Expected NULL instance" );
|
|
|
|
sm_pManagerInstance = new CWiaCacheManager();
|
|
if ( !sm_pManagerInstance )
|
|
return false;
|
|
|
|
return sm_pManagerInstance->Initialize();
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* CWiaCacheManager::Uninit [static]
|
|
*
|
|
* This is called to uninitialize the cache manager. basically this is called
|
|
* to destroy the instance we have. If we have one.
|
|
*
|
|
* Notes: This should only be called once
|
|
*--(samclem)-----------------------------------------------------------------*/
|
|
bool CWiaCacheManager::Uninit()
|
|
{
|
|
if ( sm_pManagerInstance )
|
|
delete sm_pManagerInstance;
|
|
|
|
sm_pManagerInstance = 0;
|
|
return true;
|
|
}
|