windows-nt/Source/XPSP1/NT/inetsrv/query/cifrmcom/enumstr.cxx
2020-09-26 16:20:57 +08:00

395 lines
9.8 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1997.
//
// File: enumstr.cxx
//
// Contents:
//
// Classes:
//
// Functions:
//
// History: 3-19-97 srikants Created
//
//----------------------------------------------------------------------------
#include <pch.cxx>
#pragma hdrstop
#include <enumstr.hxx>
//+---------------------------------------------------------------------------
//
// Member: CEnumString::QueryInterface
//
// Synopsis:
//
// Arguments: [riid] -
// [ppvObject] -
//
// Returns:
//
// History: 11-27-96 srikants Created
//
//----------------------------------------------------------------------------
STDMETHODIMP CEnumString::QueryInterface(
REFIID riid,
void **ppvObject)
{
Win4Assert( 0 != ppvObject );
if ( IID_IEnumString == riid )
*ppvObject = (void *)((IEnumString *)this);
else if ( IID_IUnknown == riid )
*ppvObject = (void *)((IUnknown *)this);
else
{
*ppvObject = 0;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
} //QueryInterface
//+---------------------------------------------------------------------------
//
// Member: CEnumString::AddRef
//
// History: 11-22-96 srikants Created
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CEnumString::AddRef()
{
return InterlockedIncrement(&_refCount);
} //AddRef
//+---------------------------------------------------------------------------
//
// Member: CEnumString::Release
//
// History: 11-22-96 srikants Created
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CEnumString::Release()
{
Win4Assert( _refCount > 0 );
LONG refCount = InterlockedDecrement(&_refCount);
if ( refCount <= 0 )
delete this;
return (ULONG) refCount;
} //Release
//+---------------------------------------------------------------------------
//
// Member: CEnumString::Clone
//
// Synopsis: Makes a copy of this object.
//
// Arguments: [ppEnumStr] - If successful, will have the refcounted pointer
// to IEnumString interface.
//
// Returns: S_OK if successful; Failure code otherwise.
//
// History: 3-21-97 srikants Created
//
//----------------------------------------------------------------------------
STDMETHODIMP CEnumString::Clone( IEnumString ** ppEnumStr )
{
SCODE sc = S_OK;
TRY
{
CEnumString * pCopy = new CEnumString( _aStr.Size() );
for ( unsigned i = 0; i < _cValid; i++ )
pCopy->Append( _aStr[i] );
*ppEnumStr = pCopy;
}
CATCH( CException, e )
{
sc = e.GetErrorCode();
ciDebugOut(( DEB_ERROR, "CEnumString::Clone failed. Error (0x%X)\n", sc ));
}
END_CATCH
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CEnumString::Next
//
// Synopsis: Retrieves the specified number of strings. If there are
// fewer strings than requested, then the returned number is
// indicated in the pceltFetched parameter.
//
// Arguments: [celt] -
// [rgelt] -
// [pceltFetched] -
//
// Returns: S_OK if fetched celt.
// S_FALSE otherwise.
//
// History: 3-19-97 srikants Created
//
// Notes: No copies are being made, but pointers to internal data.
// Also, this is not OLE memory but if it is read-only memory,
// it doesn't matter.
//
//----------------------------------------------------------------------------
STDMETHODIMP CEnumString::Next( ULONG celt,
LPOLESTR * rgelt,
ULONG * pceltFetched )
{
Win4Assert( _iCurrEnum <= _cValid );
*pceltFetched = 0;
while ( (_iCurrEnum < _cValid) && ( (*pceltFetched) < celt ) )
{
rgelt[(*pceltFetched)++] = _aStr.Get(_iCurrEnum++);
}
ULONG cAdded = *pceltFetched;
while ( cAdded < celt )
rgelt[cAdded++] = 0; // Must fill the remaining with NULLs.
return *pceltFetched == celt ? S_OK : S_FALSE;
}
//+---------------------------------------------------------------------------
//
// Member: CEnumString::Skip
//
// Synopsis: Skips the requested number of elements.
//
// Arguments: [celt] - Number of elements to skip.
//
// Returns: S_OK if skipped the specified number; S_FALSE o/w
//
// History: 3-19-97 srikants Created
//
// Notes: If we cannot skip as many as requested, we don't skip any.
//
//----------------------------------------------------------------------------
STDMETHODIMP CEnumString::Skip( ULONG celt )
{
Win4Assert( _iCurrEnum <= _cValid );
if ( _iCurrEnum + celt <= _cValid )
{
_iCurrEnum += celt;
return S_OK;
}
else
{
return S_FALSE;
}
}
//+---------------------------------------------------------------------------
//
// Member: CEnumString::Append
//
// Synopsis: Appends the given string to the collection.
//
// Arguments: [pwszString] -
//
// History: 3-19-97 srikants Created
//
//----------------------------------------------------------------------------
void CEnumString::Append( WCHAR const * pwszString )
{
Win4Assert( 0 != pwszString );
unsigned cwc = wcslen( pwszString ) + 1;
XArray<WCHAR> xwszCopy( cwc );
RtlCopyMemory( xwszCopy.GetPointer(), pwszString, cwc * sizeof WCHAR );
_aStr.Add( xwszCopy.GetPointer(), _cValid );
xwszCopy.Acquire();
_cValid++;
}
//+---------------------------------------------------------------------------
//
// Member: CEnumWorkid::QueryInterface
//
// History: 11-27-96 srikants Created
//
//----------------------------------------------------------------------------
STDMETHODIMP CEnumWorkid::QueryInterface(
REFIID riid,
void **ppvObject)
{
Win4Assert( 0 != ppvObject );
if ( RtlEqualMemory( &riid, &IID_IUnknown, sizeof(REFIID)) )
{
AddRef();
*ppvObject = (void *)((IUnknown *)this);
return S_OK;
}
else if ( RtlEqualMemory( &riid, &IID_ICiEnumWorkids, sizeof(REFIID)) )
{
AddRef();
*ppvObject = (void *)((ICiEnumWorkids *)this);
return S_OK;
}
else
{
*ppvObject = 0;
return E_NOINTERFACE;
}
} //QueryInterface
//+---------------------------------------------------------------------------
//
// Member: CEnumWorkid::AddRef
//
// History: 11-22-96 srikants Created
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CEnumWorkid::AddRef()
{
InterlockedIncrement(&_refCount);
return (ULONG) _refCount;
} //AddRef
//+---------------------------------------------------------------------------
//
// Member: CEnumWorkid::Release
//
// History: 11-22-96 srikants Created
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CEnumWorkid::Release()
{
Win4Assert( _refCount > 0 );
LONG refCount = InterlockedDecrement(&_refCount);
if ( refCount <= 0 )
delete this;
return (ULONG) refCount;
} //Release
//+---------------------------------------------------------------------------
//
// Member: CEnumWorkid::Next
//
// Synopsis: Retrieves the specified number of workids. If there are
// fewer workids than requested, then the returned number is
// indicated in the pceltFetched parameter.
//
// Arguments: [celt] - Number of elements requested
// [rgelt] - Array to fill the workids in
// [pceltFetched] - Number fetched.
//
// Returns: S_OK if fetched celt.
// S_FALSE otherwise.
//
// History: 3-19-97 srikants Created
//
//----------------------------------------------------------------------------
STDMETHODIMP CEnumWorkid::Next( ULONG celt,
WORKID * rgelt,
ULONG * pceltFetched )
{
Win4Assert( _iCurrEnum <= _cValid );
*pceltFetched = 0;
while ( (_iCurrEnum < _cValid) && ( (*pceltFetched) < celt ) )
{
rgelt[(*pceltFetched)++] = _aWorkids.Get(_iCurrEnum++);
}
ULONG cAdded = *pceltFetched;
while ( cAdded < celt )
rgelt[cAdded++] = 0; // Must fill the remaining with NULLs.
return *pceltFetched == celt ? S_OK : S_FALSE;
}
//+---------------------------------------------------------------------------
//
// Member: CEnumWorkid::Skip
//
// Synopsis: Skips the requested number of elements.
//
// Arguments: [celt] - Number of elements to skip.
//
// Returns: S_OK if skipped the specified number; S_FALSE o/w
//
// History: 3-19-97 srikants Created
//
// Notes: If we cannot skip as many as requested, we don't skip any.
//
//----------------------------------------------------------------------------
STDMETHODIMP CEnumWorkid::Skip( ULONG celt )
{
Win4Assert( _iCurrEnum <= _cValid );
if ( _iCurrEnum + celt <= _cValid )
{
_iCurrEnum += celt;
return S_OK;
}
else
{
return S_FALSE;
}
}
//+---------------------------------------------------------------------------
//
// Member: CEnumWorkid::Append
//
// Synopsis: Appends the given string to the collection.
//
// Arguments: [wid] - Appends the given workid to the collection.
//
// History: 3-19-97 srikants Created
//
//----------------------------------------------------------------------------
void CEnumWorkid::Append( WORKID wid )
{
_aWorkids.Add( wid, _cValid );
_cValid++;
}