204 lines
5 KiB
C++
204 lines
5 KiB
C++
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1995
|
|
//
|
|
// File: stemcf.cxx
|
|
//
|
|
// Contents: Stemmer class factory
|
|
//
|
|
// History: 01-July-1996 PatHal Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include "pch.cxx"
|
|
#pragma hdrstop
|
|
|
|
#include "stemcf.hxx"
|
|
#include "stemmer.hxx"
|
|
|
|
extern long gulcInstances;
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Method: CStemmerCF::CStemmerCF
|
|
//
|
|
// Synopsis: Stemmer class factory constructor
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
CStemmerCF::CStemmerCF( LCID lcid )
|
|
: _cRefs( 1 ), _lcid( lcid )
|
|
{
|
|
InterlockedIncrement( &gulcInstances );
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Method: CStemmerCF::~CStemmerCF
|
|
//
|
|
// Synopsis: Stemmer class factory destructor
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
CStemmerCF::~CStemmerCF()
|
|
{
|
|
InterlockedDecrement( &gulcInstances );
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Method: CStemmerCF::QueryInterface
|
|
//
|
|
// Synopsis: Rebind to other interface
|
|
//
|
|
// Arguments: [riid] -- IID of new interface
|
|
// [ppvObject] -- New interface * returned here
|
|
//
|
|
// Returns: S_OK if bind succeeded, E_NOINTERFACE if bind failed
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
SCODE STDMETHODCALLTYPE CStemmerCF::QueryInterface( REFIID riid,
|
|
void ** ppvObject )
|
|
{
|
|
//
|
|
// Optimize QueryInterface by only checking minimal number of bytes.
|
|
//
|
|
// IID_IUnknown = 00000000-0000-0000-C000-000000000046
|
|
// IID_IClassFactory = 00000001-0000-0000-C000-000000000046
|
|
// --
|
|
// |
|
|
// +--- Unique!
|
|
//
|
|
|
|
Assert( (IID_IUnknown.Data1 & 0x000000FF) == 0x00 );
|
|
Assert( (IID_IClassFactory.Data1 & 0x000000FF) == 0x01 );
|
|
|
|
IUnknown *pUnkTemp;
|
|
SCODE sc = S_OK;
|
|
|
|
switch( riid.Data1 & 0x000000FF )
|
|
{
|
|
case 0x00:
|
|
if ( riid == IID_IUnknown )
|
|
pUnkTemp = (IUnknown *)this;
|
|
else
|
|
sc = E_NOINTERFACE;
|
|
break;
|
|
|
|
case 0x01:
|
|
if ( riid == IID_IClassFactory )
|
|
pUnkTemp = (IUnknown *)(IClassFactory *)this;
|
|
else
|
|
sc = E_NOINTERFACE;
|
|
break;
|
|
|
|
default:
|
|
pUnkTemp = 0;
|
|
sc = E_NOINTERFACE;
|
|
break;
|
|
}
|
|
|
|
if( 0 != pUnkTemp )
|
|
{
|
|
*ppvObject = (void * )pUnkTemp;
|
|
pUnkTemp->AddRef();
|
|
}
|
|
else
|
|
*ppvObject = 0;
|
|
|
|
return(sc);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Method: CStemmerCF::AddRef
|
|
//
|
|
// Synopsis: Increments refcount
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
ULONG STDMETHODCALLTYPE CStemmerCF::AddRef()
|
|
{
|
|
return InterlockedIncrement( &_cRefs );
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Method: CStemmerCF::Release
|
|
//
|
|
// Synopsis: Decrement refcount. Delete if necessary.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
ULONG STDMETHODCALLTYPE CStemmerCF::Release()
|
|
{
|
|
unsigned long uTmp = InterlockedDecrement( &_cRefs );
|
|
|
|
if ( 0 == uTmp )
|
|
delete this;
|
|
|
|
return(uTmp);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Method: CStemmerCF::CreateInstance
|
|
//
|
|
// Synopsis: Creates new CStemmer object
|
|
//
|
|
// Arguments: [pUnkOuter] -- 'Outer' IUnknown
|
|
// [riid] -- Interface to bind
|
|
// [ppvObject] -- Interface returned here
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
SCODE STDMETHODCALLTYPE CStemmerCF::CreateInstance( IUnknown * pUnkOuter,
|
|
REFIID riid,
|
|
void * * ppvObject )
|
|
{
|
|
CStemmer *pIUnk = 0;
|
|
SCODE sc = S_OK;
|
|
|
|
__try
|
|
{
|
|
pIUnk = new CStemmer( _lcid );
|
|
sc = pIUnk->QueryInterface( riid , ppvObject );
|
|
|
|
pIUnk->Release(); // Release extra refcount from QueryInterface
|
|
}
|
|
__except(1)
|
|
{
|
|
Assert( 0 == pIUnk );
|
|
|
|
sc = E_UNEXPECTED;
|
|
}
|
|
|
|
return (sc);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Method: CStemmerCF::LockServer
|
|
//
|
|
// Synopsis: Force class factory to remain loaded
|
|
//
|
|
// Arguments: [fLock] -- TRUE if locking, FALSE if unlocking
|
|
//
|
|
// Returns: S_OK
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
SCODE STDMETHODCALLTYPE CStemmerCF::LockServer(BOOL fLock)
|
|
{
|
|
if(fLock)
|
|
InterlockedIncrement( &gulcInstances );
|
|
else
|
|
InterlockedDecrement( &gulcInstances );
|
|
|
|
return(S_OK);
|
|
}
|
|
|