355 lines
8.3 KiB
C++
355 lines
8.3 KiB
C++
//=--------------------------------------------------------------------------=
|
||
// StrColl.Cpp
|
||
//=--------------------------------------------------------------------------=
|
||
// Copyright 1995-1996 Microsoft Corporation. All Rights Reserved.
|
||
//
|
||
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||
// PARTICULAR PURPOSE.
|
||
//=--------------------------------------------------------------------------=
|
||
//
|
||
// implementation for our simple strings collections.
|
||
//
|
||
#include "IPServer.H"
|
||
|
||
#include "SimpleEnumVar.H"
|
||
#include "StringsColl.H"
|
||
|
||
|
||
// for asserts
|
||
//
|
||
SZTHISFILE
|
||
|
||
|
||
//=--------------------------------------------------------------------------=
|
||
// CStringsCollection::CStringsCollection
|
||
//=--------------------------------------------------------------------------=
|
||
// constructor. sets up the safearray pointer.
|
||
//
|
||
// Parameters:
|
||
// SAFEARRAY - [in] the collection we're working with.
|
||
//
|
||
// Notes:
|
||
//
|
||
CStringCollection::CStringCollection
|
||
(
|
||
SAFEARRAY *psa
|
||
)
|
||
: m_psa(psa)
|
||
{
|
||
ASSERT(m_psa, "Bogus Safearray pointer!");
|
||
}
|
||
|
||
//=--------------------------------------------------------------------------=
|
||
// CStringCollection::~CStringCollection
|
||
//=--------------------------------------------------------------------------=
|
||
//
|
||
// Notes:
|
||
//
|
||
CStringCollection::~CStringCollection()
|
||
{
|
||
}
|
||
|
||
//=--------------------------------------------------------------------------=
|
||
// CStringCollection::get_Count
|
||
//=--------------------------------------------------------------------------=
|
||
// returns the count of the things in the collection
|
||
//
|
||
// Parameters:
|
||
// long * - [out] the count
|
||
//
|
||
// Output:
|
||
// HRESULT - S_OK, one of the SAFEARRAY Scodes.
|
||
//
|
||
// Notes:
|
||
// - we're assuming the safearray's lower bound is zero!
|
||
//
|
||
STDMETHODIMP CStringCollection::get_Count
|
||
(
|
||
long *plCount
|
||
)
|
||
{
|
||
HRESULT hr;
|
||
|
||
ASSERT(m_psa, "Who created a collection without a SAFEARRAY?");
|
||
|
||
CHECK_POINTER(plCount);
|
||
|
||
// get the bounds.
|
||
//
|
||
hr = SafeArrayGetUBound(m_psa, 1, plCount);
|
||
CLEARERRORINFORET_ON_FAILURE(hr);
|
||
|
||
// add one since we're zero-offset
|
||
//
|
||
(*plCount)++;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
//=--------------------------------------------------------------------------=
|
||
// CStringCollection::get_Item
|
||
//=--------------------------------------------------------------------------=
|
||
// returns a string given an INDEX
|
||
//
|
||
// Parameters:
|
||
// long - [in] the index to get it from
|
||
// BSTR * - [out] the item
|
||
//
|
||
// Output:
|
||
// HRESULT - S_OK, E_OUTOFMEMORY
|
||
//
|
||
// Notes:
|
||
//
|
||
STDMETHODIMP CStringCollection::get_Item
|
||
(
|
||
long lIndex,
|
||
BSTR *pbstrItem
|
||
)
|
||
{
|
||
HRESULT hr;
|
||
|
||
CHECK_POINTER(pbstrItem);
|
||
|
||
// get the element from the safearray
|
||
//
|
||
hr = SafeArrayGetElement(m_psa, &lIndex, pbstrItem);
|
||
CLEARERRORINFORET_ON_FAILURE(hr);
|
||
|
||
// otherwise, we've got it, so we can return
|
||
//
|
||
return S_OK;
|
||
}
|
||
|
||
//=--------------------------------------------------------------------------=
|
||
// CStringCollection::get__NewEnum
|
||
//=--------------------------------------------------------------------------=
|
||
// returns a new IEnumVARIANT object with the collection in it.
|
||
//
|
||
// Parameters:
|
||
// IUnknown ** - [out] new enumvariant object.
|
||
//
|
||
// Output:
|
||
// HRESULT - S_OK, E_OUTOFMEMORY
|
||
//
|
||
// Notes:
|
||
//
|
||
STDMETHODIMP CStringCollection::get__NewEnum
|
||
(
|
||
IUnknown **ppUnkNewEnum
|
||
)
|
||
{
|
||
HRESULT hr;
|
||
long l;
|
||
|
||
CHECK_POINTER(ppUnkNewEnum);
|
||
|
||
// get the count of things in the SAFEARRAY
|
||
//
|
||
hr = get_Count(&l);
|
||
CLEARERRORINFORET_ON_FAILURE(hr);
|
||
|
||
// create the object.
|
||
//
|
||
*ppUnkNewEnum = (IUnknown *) new CSimpleEnumVariant(m_psa, l);
|
||
if (!*ppUnkNewEnum)
|
||
CLEARERRORINFORET(E_OUTOFMEMORY);
|
||
|
||
// refcount is already 1, so we can leave.
|
||
//
|
||
return S_OK;
|
||
}
|
||
|
||
//=--------------------------------------------------------------------------=
|
||
//=--------------------------------------------------------------------------=
|
||
// CStringDynaCollection::CStringDynaCollection
|
||
//=--------------------------------------------------------------------------=
|
||
// constructor for this object. doesn't do very much.
|
||
//
|
||
// Parameters:
|
||
// same as for CStringCollection
|
||
//
|
||
// Notes:
|
||
//
|
||
CStringDynaCollection::CStringDynaCollection
|
||
(
|
||
SAFEARRAY *psa
|
||
)
|
||
: CStringCollection(psa)
|
||
{
|
||
}
|
||
|
||
//=--------------------------------------------------------------------------=
|
||
// CStringDynaCollection::~CStringDynaCollection
|
||
//=--------------------------------------------------------------------------=
|
||
// destructor.
|
||
//
|
||
// Notes:
|
||
//
|
||
CStringDynaCollection::~CStringDynaCollection()
|
||
{
|
||
}
|
||
|
||
//=--------------------------------------------------------------------------=
|
||
// CStringDynaCollection::put_Item
|
||
//=--------------------------------------------------------------------------=
|
||
// sets the value of an item in the array.
|
||
//
|
||
// Parameters:
|
||
// long - [in] index at which to put it
|
||
// BSTR - [in] new value.
|
||
//
|
||
// Output:
|
||
// HRESULT - S_OK, safearray Scode.
|
||
//
|
||
// Notes:
|
||
// - NULLs are converted to ""
|
||
//
|
||
STDMETHODIMP CStringDynaCollection::put_Item
|
||
(
|
||
long lIndex,
|
||
BSTR bstr
|
||
)
|
||
{
|
||
HRESULT hr;
|
||
long l;
|
||
BSTR bstr2 = NULL;
|
||
|
||
// get the count and verify our index
|
||
//
|
||
hr = get_Count(&l);
|
||
RETURN_ON_FAILURE(hr);
|
||
if (lIndex < 0 || lIndex >= l)
|
||
CLEARERRORINFORET(E_INVALIDARG);
|
||
|
||
// put out the string, convert NULLs to ""
|
||
//
|
||
if (!bstr) {
|
||
bstr2 = SysAllocString(L"");
|
||
RETURN_ON_NULLALLOC(bstr2);
|
||
}
|
||
|
||
hr = SafeArrayPutElement(m_psa, &lIndex, (bstr) ? bstr : bstr2);
|
||
if (bstr2) SysFreeString(bstr2);
|
||
CLEARERRORINFORET_ON_FAILURE(hr);
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
//=--------------------------------------------------------------------------=
|
||
// CStringDynaCollection::Add
|
||
//=--------------------------------------------------------------------------=
|
||
// adds a new string to the end of the collection.
|
||
//
|
||
// Parameters:
|
||
// BSTR - [in] the new string to add
|
||
//
|
||
// Notes:
|
||
//
|
||
STDMETHODIMP CStringDynaCollection::Add
|
||
(
|
||
BSTR bstr
|
||
)
|
||
{
|
||
SAFEARRAYBOUND sab;
|
||
BSTR bstr2 = NULL;
|
||
HRESULT hr;
|
||
long l;
|
||
|
||
// get the current size of the array.
|
||
//
|
||
hr = get_Count(&l);
|
||
RETURN_ON_FAILURE(hr);
|
||
|
||
// add one new elemnt
|
||
//
|
||
sab.cElements = l + 1;
|
||
sab.lLbound = 0;
|
||
|
||
// redim the array.
|
||
//
|
||
hr = SafeArrayRedim(m_psa, &sab);
|
||
CLEARERRORINFORET_ON_FAILURE(hr);
|
||
|
||
// put the out string, converting NULLs to ""
|
||
//
|
||
if (!bstr) {
|
||
bstr2 = SysAllocString(L"");
|
||
RETURN_ON_NULLALLOC(bstr2);
|
||
}
|
||
|
||
hr = SafeArrayPutElement(m_psa, &l, (bstr) ? bstr : bstr2);
|
||
if (bstr2) SysFreeString(bstr2);
|
||
CLEARERRORINFORET_ON_FAILURE(hr);
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
//=--------------------------------------------------------------------------=
|
||
// CStringDynaCollection::Remove
|
||
//=--------------------------------------------------------------------------=
|
||
// removes an element from the collection, and shuffles all the rest down to
|
||
// fill up the space.
|
||
//
|
||
// Parameters:
|
||
// long - [in] index of dude to remove.
|
||
//
|
||
// Output:
|
||
// HRESULT - S_OK, safearray Scodes.
|
||
//
|
||
// Notes:
|
||
//
|
||
STDMETHODIMP CStringDynaCollection::Remove
|
||
(
|
||
long lIndex
|
||
)
|
||
{
|
||
SAFEARRAYBOUND sab;
|
||
HRESULT hr;
|
||
BSTR bstr;
|
||
long lCount;
|
||
long x, y;
|
||
|
||
// first get the count of things in our array.
|
||
//
|
||
hr = get_Count(&lCount);
|
||
RETURN_ON_FAILURE(hr);
|
||
|
||
// check the index
|
||
//
|
||
if (lIndex < 0 || lIndex >= lCount)
|
||
CLEARERRORINFORET(E_INVALIDARG);
|
||
|
||
// let's go through, shuffling everything down one.
|
||
//
|
||
for (x = lIndex, y = x + 1; x < lCount - 1; x++, y++) {
|
||
// get the next element.
|
||
//
|
||
hr = SafeArrayGetElement(m_psa, &y, &bstr);
|
||
CLEARERRORINFORET_ON_FAILURE(hr);
|
||
|
||
// set it at the current location
|
||
//
|
||
hr = SafeArrayPutElement(m_psa, &x, bstr);
|
||
CLEARERRORINFORET_ON_FAILURE(hr);
|
||
}
|
||
|
||
// we're at the last element. let's go and kill it.
|
||
//
|
||
sab.cElements = lCount - 1;
|
||
sab.lLbound = 0;
|
||
|
||
// CONSIDER: 9.95 -- there is a bug in oleaut32.dll which causes the
|
||
// below to fail if cElements = 0.
|
||
//
|
||
hr = SafeArrayRedim(m_psa, &sab);
|
||
CLEARERRORINFORET_ON_FAILURE(hr);
|
||
|
||
// we're done. go bye-bye.
|
||
//
|
||
return S_OK;
|
||
}
|
||
|
||
|