//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1997. // // File: enumstr.cxx // // Contents: // // Classes: // // Functions: // // History: 3-19-97 srikants Created // //---------------------------------------------------------------------------- #include #pragma hdrstop #include //+--------------------------------------------------------------------------- // // 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 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++; }