Windows2003-3790/inetsrv/query/h/nullstem.hxx

228 lines
5.3 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1991 - 2001.
//
// File: nullstem.hxx
//
// Contents: Null stemmer. MSSearch in SQL and Exchange has a bug where
// if a wordbreaker is defined and no stemmer is defined it
// trashes memory and AVs. This is a workaround since CH
// languages resources out of the box no longer define stemmers.
//
// Classes: CNullStemmer
//
// History: 7-Jun-01 dlee Created
//
//----------------------------------------------------------------------------
#pragma once
extern long gulcInstances;
//+---------------------------------------------------------------------------
//
// Class: CNullStemmer
//
// Purpose: Returns the word passed in. Needed for backward
// compatibility with SQL Server and Exchange 2000.
//
// History: 7-Jun-01 dlee Created
//
//----------------------------------------------------------------------------
class CNullStemmer : public IStemmer
{
public:
SCODE STDMETHODCALLTYPE QueryInterface( REFIID riid,
void **ppvObject )
{
if ( 0 == ppvObject )
return E_INVALIDARG;
if ( IID_IStemmer == riid )
*ppvObject = (IUnknown *)(IStemmer *) this;
else if ( IID_IUnknown == riid )
*ppvObject = (IUnknown *) this;
else
{
*ppvObject = 0;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE AddRef()
{
return InterlockedIncrement( &_cRefs );
}
ULONG STDMETHODCALLTYPE Release()
{
unsigned long c = InterlockedDecrement( &_cRefs );
if ( 0 == c )
delete this;
return c;
}
SCODE STDMETHODCALLTYPE Init( ULONG ulMaxTokenSize, BOOL *pfLicense )
{
if ( 0 == pfLicense )
return E_INVALIDARG;
*pfLicense = TRUE;
return S_OK;
}
SCODE STDMETHODCALLTYPE GetLicenseToUse( const WCHAR **ppwcsLicense )
{
if ( 0 == ppwcsLicense )
return E_INVALIDARG;
*ppwcsLicense = L"Copyright Microsoft, 1991-2001";
return S_OK;
}
SCODE STDMETHODCALLTYPE GenerateWordForms(
WCHAR const *pwcInBuf,
ULONG cwc,
IWordFormSink *pStemSink )
{
if ( 0 == pwcInBuf || 0 == pStemSink )
return E_INVALIDARG;
return pStemSink->PutWord( pwcInBuf, cwc );
}
CNullStemmer() : _cRefs( 1 )
{
InterlockedIncrement( &gulcInstances );
}
~CNullStemmer()
{
InterlockedDecrement( &gulcInstances );
}
private:
long _cRefs;
};
//+---------------------------------------------------------------------------
//
// Class: CDefWordBreakerCF
//
// Purpose: Class factory for default word breaker
//
// History: 07-Feb-95 SitaramR Created
//
//----------------------------------------------------------------------------
class CNullStemmerCF : public IClassFactory
{
public:
CNullStemmerCF() : _cRefs( 1 )
{
InterlockedIncrement( &gulcInstances );
}
//
// From IUnknown
//
SCODE STDMETHODCALLTYPE QueryInterface( REFIID riid,
void ** ppvObject )
{
if ( 0 == ppvObject )
return E_INVALIDARG;
if ( IID_IClassFactory == riid )
*ppvObject = (IUnknown *)(IClassFactory *)this;
else if ( IID_IUnknown == riid )
*ppvObject = (IUnknown *)this;
else
{
*ppvObject = 0;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE AddRef()
{
return InterlockedIncrement( &_cRefs );
}
ULONG STDMETHODCALLTYPE Release()
{
unsigned long uTmp = InterlockedDecrement( &_cRefs );
if ( 0 == uTmp )
delete this;
return uTmp;
}
//
// From IClassFactory
//
SCODE STDMETHODCALLTYPE CreateInstance( IUnknown * pUnkOuter,
REFIID riid,
void ** ppvObject )
{
if ( 0 == ppvObject )
return E_INVALIDARG;
CNullStemmer *pIUnk = 0;
SCODE sc = S_OK;
TRY
{
pIUnk = new CNullStemmer();
sc = pIUnk->QueryInterface( riid , ppvObject );
pIUnk->Release(); // Release extra refcount from QueryInterface
}
CATCH(CException, e)
{
Win4Assert( 0 == pIUnk );
sc = e.GetErrorCode();
}
END_CATCH;
return sc;
}
SCODE STDMETHODCALLTYPE LockServer( BOOL fLock )
{
if ( fLock )
InterlockedIncrement( &gulcInstances );
else
InterlockedDecrement( &gulcInstances );
return S_OK;
}
private:
virtual ~CNullStemmerCF()
{
InterlockedDecrement( &gulcInstances );
}
long _cRefs;
};