Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / May 2005

Tip: Looking for answers? Try searching our database.

LastIndexOf similar C++ code?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Egbert Nierop \(MVP for IIS\) - 13 May 2005 07:36 GMT
Hi,

I'm 'improving' CComBSTR (yes, I do still program unmanaged code in addition
to C# ) to contain features, not found in it.

Does anybody have good code which maches LastIndexOf()?

If this is ready, I will publish the full CComBSTR class on my weblog.

int LastIndexOf(const wchar_t *src, const int startIndex = -1, const bool
caseInsensitive = false) throw()

{

// use _wcsnicmp and wcsncmp  instead?

int result = -1;

if (m_str != NULL && src != NULL)

{

SIZE_T compLen = wcslen(src);

SIZE_T maxLen = Length();

SIZE_T startIdx = startIndex == 0 ? maxLen : startIndex;

SIZE_T maxScan = maxLen - startIndex;

BSTR temp, findThis;

if (caseInsensitive)

{

temp = _wcslwr(Substring(startIndex));

findThis = _wcslwr(::SysAllocString(src));

}

else

{

temp = (PWSTR)m_str;

findThis = (PWSTR)src;

}

PWSTR found = 0;//wcsrchr(temp, findThis);

if (found != NULL)

result = found - temp;

if (caseInsensitive)

{

::SysFreeString(findThis);

::SysFreeString(temp);

}

}

return result;

}
Egbert Nierop \(MVP for IIS\) - 14 May 2005 10:49 GMT
"Egbert Nierop (MVP for IIS)" <egbert_nierop@nospam.invalid> wrote in
message news:OC%23SYY4VFHA.2984@tk2msftngp13.phx.gbl...
> Hi,
>
> I'm 'improving' CComBSTR (yes, I do still program unmanaged code in
> addition to C# ) to contain features, not found in it.
>
> Does anybody have good code which maches LastIndexOf()?

Ok, ok, I did it myself, however it could be improved a little, still...

These improvements also has been optimized -not- to reallocate the string so
often as the original does with Append

/////////////////////////////////////////////////////////////////////////////
// CComBSTR

class CComBSTR
{
public:
BSTR m_str;
CComBSTR() throw()
{
 m_str = NULL;
}
CComBSTR(int nSize)
{
 //if (nSize == 0) //BUG it should be possible to assign a L"" string
 // m_str = NULL;
 m_str = ::SysAllocStringLen(NULL, nSize);
 if (m_str == NULL)
  AtlThrow(E_OUTOFMEMORY);

}
CComBSTR(int nSize, LPCOLESTR sz)
{
 if (nSize == 0)
  m_str = NULL;
 else
 {
  m_str = ::SysAllocStringLen(sz, nSize);
  if (m_str == NULL)
   AtlThrow(E_OUTOFMEMORY);
 }
}
CComBSTR(LPCOLESTR pSrc)
{
 if (pSrc == NULL)
  m_str = NULL;
 else
 {
  m_str = ::SysAllocString(pSrc);
  if (m_str == NULL)
   AtlThrow(E_OUTOFMEMORY);
 }
}
CComBSTR(const CComBSTR& src)
{
 m_str = src.Copy();
 if (!!src && m_str == NULL)
  AtlThrow(E_OUTOFMEMORY);

}
CComBSTR(REFGUID guid)
{
 OLECHAR szGUID[64];
 ::StringFromGUID2(guid, szGUID, 64);
 m_str = ::SysAllocString(szGUID);
 if (m_str == NULL)
  AtlThrow(E_OUTOFMEMORY);
}

CComBSTR& operator=(const CComBSTR& src)
{
 if (m_str != src.m_str)
 {
  if (::SysReAllocStringLen(&m_str, src, src.Length()) == FALSE)
   AtlThrow(E_OUTOFMEMORY);
 }
 return *this;
}

CComBSTR& operator=(LPCOLESTR pSrc)
{
 if (pSrc != m_str)
 {
  if (pSrc != NULL)
  {
   if (::SysReAllocString(&m_str, pSrc) == FALSE)
    AtlThrow(E_OUTOFMEMORY);
  }
  else
  {
   ::SysFreeString(m_str);
   m_str = NULL;
  }
 }
 return *this;
}

~CComBSTR() throw()
{
 ::SysFreeString(m_str);
}
unsigned int Length() const throw()
{
 return (m_str == NULL)? 0 : SysStringLen(m_str);
}
unsigned int ByteLength() const throw()
{
 return (m_str == NULL)? 0 : SysStringByteLen(m_str);
}
operator BSTR() const throw()
{
 return m_str;
}
BSTR* operator&() throw()
{
 return &m_str;
}
BSTR Copy() const throw()
{
 if (m_str == NULL)
  return NULL;
 return ::SysAllocStringByteLen((char*)m_str, ::SysStringByteLen(m_str));
}
HRESULT CopyTo(BSTR* pbstr) throw()
{
 ATLASSERT(pbstr != NULL);
 if (pbstr == NULL)
  return E_POINTER;
 *pbstr = Copy();
 if ((*pbstr == NULL) && (m_str != NULL))
  return E_OUTOFMEMORY;
 return S_OK;
}

/* added by may 2005 e.n. needs #include 'wchar.h'*/
HRESULT __cdecl Format(PCWSTR pszFormat, ...) throw()
{
 va_list args;
 HRESULT hr = S_OK;

 va_start( args, pszFormat );

 int len = _vscwprintf( pszFormat, args );
 if (::SysReAllocStringLen(&m_str, NULL, len) == FALSE)
  hr = E_OUTOFMEMORY;
 else
  vswprintf( m_str, (SIZE_T)Length(), pszFormat, args );
 va_end(args);

 return hr;
}

BSTR Substring(const int startIndex) throw()
{
 int maxIdx = Length();
 if (m_str != NULL && startIndex >= 0 && startIndex <= maxIdx)
 {
  return ::SysAllocStringLen(m_str + startIndex, maxIdx - startIndex);
 }
 else
  return NULL;
}

BSTR Substring(const int startIndex, int length) throw()
{
 int maxIdx = Length();
 if (length < 0) length = 0;
 if (startIndex + length > maxIdx)
  length = maxIdx - startIndex;
 if (m_str != NULL && startIndex > 0 && startIndex <= maxIdx)
 {
  return ::SysAllocStringLen(m_str + startIndex, length);
 }
 else
  return NULL;
}
int LastIndexOf(const wchar_t *src, const unsigned int startIndex = 0,
const bool caseInsensitive = false) throw()
{
 // use _wcsnicmp and  wcsncmp
 int result = -1;

 if (m_str != NULL && src != NULL)
 {
  int compLen = ocslen(src);
  int maxLen = Length();

  for(int x = maxLen - compLen; x >= 0; x--)
  {
   if (
    (caseInsensitive ? _wcsnicmp(m_str + x, src, compLen) :  wcsncmp(m_str
+ x, src, compLen)
    ) == 0)
   {
    result = x;
    break;
   }
  }

 }
 return result;
}

int IndexOf(const wchar_t src, const unsigned int startIndex = 0, const
bool caseInsensitive = false) throw()
{
 int result = -1;
 if (m_str != NULL)
 {
  unsigned int maxLen = Length();
  unsigned int startIdx = startIndex > maxLen ? maxLen : startIndex;

  unsigned int maxScan = maxLen - startIndex;

  BSTR temp;
  wchar_t src2;
  if (caseInsensitive)
  {
   wchar_t tol[2] = {src, 0};
   _wcslwr(tol);
   src2 = tol[0];

   temp = _wcslwr(Substring((UINT)startIdx));
  }
  else
  {
   temp  = m_str;
   src2 = src;
  }

  wchar_t *found = wmemchr(temp, src2, maxScan);

  if (found != NULL)
   result = PtrToInt(found - temp);

  if (caseInsensitive)
   ::SysFreeString(temp);
 }
 return result;
}

/*
 * Addded by E.N.
 */
int IndexOf(const PWSTR src, const unsigned int startIndex = 0, const bool
caseInsensitive = false) throw()
{
 int result = -1;

 if (src != NULL && m_str != NULL)
 {
  unsigned int maxLen = Length();
  unsigned int startIdx = startIndex > maxLen ? maxLen : startIndex;
  BSTR temp, findThis;
  if (caseInsensitive)
  {
   temp = _wcslwr(Substring(startIdx));
   findThis = _wcslwr(::SysAllocString(src));
  }
  else
  {
   temp = m_str + startIdx;
   findThis = src;
  }
  wchar_t *found = wcsstr(temp, findThis);

  if (found != NULL)
   result = PtrToInt(found - temp);

  if (caseInsensitive)
  {
   ::SysFreeString(temp);
   ::SysFreeString(findThis);
  }
 }
 return result;

}

// copy BSTR to VARIANT
HRESULT CopyTo(VARIANT *pvarDest) throw()
{
 ATLASSERT(pvarDest != NULL);
 HRESULT hRes = E_POINTER;
 if (pvarDest != NULL)
 {
  pvarDest->vt = VT_BSTR;
  pvarDest->bstrVal = Copy();
  if (pvarDest->bstrVal == NULL && m_str != NULL)
   hRes = E_OUTOFMEMORY;
  else
   hRes = S_OK;
 }
 return hRes;
}
void Attach(BSTR src) throw()
{
 if (m_str != src)
 {
  ::SysFreeString(m_str);
  m_str = src;
 }
}
BSTR Detach() throw()
{
 BSTR s = m_str;
 m_str = NULL;
 return s;
}
void Empty() throw()
{
 ::SysFreeString(m_str);
 m_str = NULL;
}
bool operator!() const throw()
{
 return (m_str == NULL);
}
HRESULT Append(const CComBSTR& bstrSrc) throw()
{
 return AppendBSTR(bstrSrc.m_str);
}
HRESULT Append(LPCOLESTR lpsz) throw()
{
 return Append(lpsz, UINT(ocslen(lpsz)));
}
// a BSTR is just a LPCOLESTR so we need a special version to signify
// that we are appending a BSTR
HRESULT AppendBSTR(BSTR p) throw()
{
 return Append((LPCOLESTR)p, ::SysStringLen(p));
}
HRESULT Append(LPCOLESTR lpsz, int nLen) throw()
{
 if (lpsz == NULL || (m_str != NULL && nLen == 0))
  return S_OK;
 int n1 = Length();
 if ( ::SysReAllocStringLen(&m_str, NULL, n1+nLen) == FALSE)
  return E_OUTOFMEMORY;
 memcpy(m_str+n1, lpsz, nLen*sizeof(OLECHAR));
 return S_OK;
}
HRESULT Append(char ch) throw()
{
 OLECHAR chO = ch;

 return( Append( &chO, 1 ) );
}
HRESULT Append(wchar_t ch) throw()
{
 return( Append( &ch, 1 ) );
}
HRESULT AppendBytes(const char* lpsz, int nLen) throw()
{
 if (lpsz == NULL || nLen == 0)
  return S_OK;
 int n1 = ByteLength();
 BSTR b;
 b = ::SysAllocStringByteLen(NULL, n1+nLen);
 if (b == NULL)
  return E_OUTOFMEMORY;
 memcpy(b, m_str, n1);
 memcpy(((char*)b)+n1, lpsz, nLen);
 *((OLECHAR*)(((char*)b)+n1+nLen)) = NULL;
 SysFreeString(m_str);
 m_str = b;
 return S_OK;
}
HRESULT AssignBSTR(const BSTR bstrSrc) throw()
{
 HRESULT hr = S_OK;
 if (m_str != bstrSrc)
 {

  if (bstrSrc != NULL)
  {
   if (::SysReAllocStringLen(&m_str, bstrSrc, ::SysStringLen(bstrSrc)) ==
FALSE)
    hr = E_OUTOFMEMORY;
  }
  else
   m_str = NULL;
 }

 return hr;
}
HRESULT ToLower() throw()
{
 if (m_str != NULL)
 {
#ifdef _UNICODE
  // Convert in place
  CharLowerBuff(m_str, Length());
#else
  // Cannot use conversion macros due to possible embedded NULLs
  UINT _acp = _AtlGetConversionACP();
  int _convert = WideCharToMultiByte(_acp, 0, m_str, Length(), NULL, 0,
NULL, NULL);
  CTempBuffer<char> pszA;
  ATLTRY(pszA.Allocate(_convert));
  if (pszA == NULL)
   return E_OUTOFMEMORY;

  int nRet = WideCharToMultiByte(_acp, 0, m_str, Length(), pszA, _convert,
NULL, NULL);
  if (nRet == 0)
  {
   ATLASSERT(0);
   return AtlHresultFromLastError();
  }

  CharLowerBuff(pszA, nRet);

  _convert = MultiByteToWideChar(_acp, 0, pszA, nRet, NULL, 0);

  CTempBuffer<WCHAR> pszW;
  ATLTRY(pszW.Allocate(_convert));
  if (pszW == NULL)
   return E_OUTOFMEMORY;

  nRet = MultiByteToWideChar(_acp, 0, pszA, nRet, pszW, _convert);
  if (nRet == 0)
  {
   ATLASSERT(0);
   return AtlHresultFromLastError();
  }

  if (::SysReAllocStringLen(&m_str, pszW, nRet) == FALSE)
   return E_OUTOFMEMORY;
#endif
 }
 return S_OK;
}
HRESULT ToUpper() throw()
{
 if (m_str != NULL)
 {
#ifdef _UNICODE
  // Convert in place
  CharUpperBuff(m_str, Length());
#else
  // Cannot use conversion macros due to possible embedded NULLs
  UINT _acp = _AtlGetConversionACP();
  int _convert = WideCharToMultiByte(_acp, 0, m_str, Length(), NULL, 0,
NULL, NULL);
  CTempBuffer<char> pszA;
  ATLTRY(pszA.Allocate(_convert));
  if (pszA == NULL)
   return E_OUTOFMEMORY;

  int nRet = WideCharToMultiByte(_acp, 0, m_str, Length(), pszA, _convert,
NULL, NULL);
  if (nRet == 0)
  {
   ATLASSERT(0);
   return AtlHresultFromLastError();
  }

  CharUpperBuff(pszA, nRet);

  _convert = MultiByteToWideChar(_acp, 0, pszA, nRet, NULL, 0);

  CTempBuffer<WCHAR> pszW;
  ATLTRY(pszW.Allocate(_convert));
  if (pszW == NULL)
   return E_OUTOFMEMORY;

  nRet = MultiByteToWideChar(_acp, 0, pszA, nRet, pszW, _convert);
  if (nRet == 0)
  {
   ATLASSERT(0);
   return AtlHresultFromLastError();
  }

  if (::SysReAllocStringLen(&m_str, pszW, nRet) == FALSE);
   return E_OUTOFMEMORY;

#endif
 }
 return S_OK;
}
bool LoadString(HINSTANCE hInst, UINT nID) throw()
{
 ::SysFreeString(m_str);
 m_str = NULL;
 return LoadStringResource(hInst, nID, m_str);
}
bool LoadString(UINT nID) throw()
{
 ::SysFreeString(m_str);
 m_str = NULL;
 return LoadStringResource(nID, m_str);
}

CComBSTR& operator+=(const CComBSTR& bstrSrc)
{
 HRESULT hr;
 hr = AppendBSTR(bstrSrc.m_str);
 if (FAILED(hr))
  AtlThrow(hr);
 return *this;
}
CComBSTR& operator+=(LPCOLESTR pszSrc)
{
 HRESULT hr;
 hr = Append(pszSrc);
 if (FAILED(hr))
  AtlThrow(hr);
 return *this;
}

bool operator<(const CComBSTR& bstrSrc) const throw()
{
 return VarBstrCmp(m_str, bstrSrc.m_str, LOCALE_USER_DEFAULT, 0) ==
VARCMP_LT;
}
bool operator<(LPCOLESTR pszSrc) const
{
 CComBSTR bstr2(pszSrc);
 return operator<(bstr2);
}
bool operator<(LPOLESTR pszSrc) const
{
 return operator<((LPCOLESTR)pszSrc);
}

bool operator>(const CComBSTR& bstrSrc) const throw()
{
 return VarBstrCmp(m_str, bstrSrc.m_str, LOCALE_USER_DEFAULT, 0) ==
VARCMP_GT;
}
bool operator>(LPCOLESTR pszSrc) const
{
 CComBSTR bstr2(pszSrc);
 return operator>(bstr2);
}
bool operator>(LPOLESTR pszSrc) const
{
 return operator>((LPCOLESTR)pszSrc);
}

bool operator!=(const CComBSTR& bstrSrc) const throw()
{
 return !operator==(bstrSrc);
}
bool operator!=(LPCOLESTR pszSrc) const
{
 return !operator==(pszSrc);
}
bool operator!=(int nNull) const throw()
{
 return !operator==(nNull);
}
bool operator!=(LPOLESTR pszSrc) const
{
 return operator!=((LPCOLESTR)pszSrc);
}

bool operator==(const CComBSTR& bstrSrc) const throw()
{
 return VarBstrCmp(m_str, bstrSrc.m_str, LOCALE_USER_DEFAULT, 0) ==
VARCMP_EQ;
}
bool operator==(LPCOLESTR pszSrc) const
{
 CComBSTR bstr2(pszSrc);
 return operator==(bstr2);
}
bool operator==(LPOLESTR pszSrc) const
{
 return operator==((LPCOLESTR)pszSrc);
}

bool operator==(int nNull) const throw()
{
 ATLASSERT(nNull == NULL);
 (void)nNull;
 return (m_str == NULL);
}
CComBSTR(LPCSTR pSrc)
{
 if (pSrc != NULL)
 {
  m_str = A2WBSTR(pSrc);
  if (m_str == NULL)
   AtlThrow(E_OUTOFMEMORY);
 }
 else
  m_str = NULL;
}

CComBSTR(int nSize, LPCSTR sz)
{
 if (nSize != 0 && sz == NULL)
 {
  m_str = ::SysAllocStringLen(NULL, nSize);
  if (m_str == NULL)
   AtlThrow(E_OUTOFMEMORY);
  return;
 }

 m_str = A2WBSTR(sz, nSize);
 if (m_str == NULL && nSize != 0)
  AtlThrow(E_OUTOFMEMORY);
}

HRESULT Append(LPCSTR lpsz) throw()
{
 if (lpsz == NULL)
  return S_OK;

 CComBSTR bstrTemp;
 ATLTRY(bstrTemp = lpsz);
 if (bstrTemp.m_str == NULL)
  return E_OUTOFMEMORY;
 return Append(bstrTemp);
}

CComBSTR& operator=(LPCSTR pSrc)
{
 ::SysFreeString(m_str);
 m_str = A2WBSTR(pSrc);
 if (m_str == NULL && pSrc != NULL)
  AtlThrow(E_OUTOFMEMORY);
 return *this;
}
bool operator<(LPCSTR pszSrc) const
{
 CComBSTR bstr2(pszSrc);
 return operator<(bstr2);
}
bool operator>(LPCSTR pszSrc) const
{
 CComBSTR bstr2(pszSrc);
 return operator>(bstr2);
}
bool operator!=(LPCSTR pszSrc) const
{
 return !operator==(pszSrc);
}
bool operator==(LPCSTR pszSrc) const
{
 CComBSTR bstr2(pszSrc);
 return operator==(bstr2);
}
HRESULT WriteToStream(IStream* pStream) throw()
{
 ATLASSERT(pStream != NULL);
 if(pStream == NULL)
  return E_INVALIDARG;

 ULONG cb;
 ULONG cbStrLen = ULONG(m_str ? SysStringByteLen(m_str)+sizeof(OLECHAR) :
0);
 HRESULT hr = pStream->Write((void*) &cbStrLen, sizeof(cbStrLen), &cb);
 if (FAILED(hr))
  return hr;
 return cbStrLen ? pStream->Write((void*) m_str, cbStrLen, &cb) : S_OK;
}
HRESULT ReadFromStream(IStream* pStream) throw()
{
 ATLASSERT(pStream != NULL);
 if(pStream == NULL)
  return E_INVALIDARG;

 ATLASSERT(m_str == NULL); // should be empty
 Empty();

 ULONG cbStrLen = 0;
 HRESULT hr = pStream->Read((void*) &cbStrLen, sizeof(cbStrLen), NULL);
 if ((hr == S_OK) && (cbStrLen != 0))
 {
  //subtract size for terminating NULL which we wrote out
  //since SysAllocStringByteLen overallocates for the NULL
  m_str = SysAllocStringByteLen(NULL, cbStrLen-sizeof(OLECHAR));
  if (m_str == NULL)
   hr = E_OUTOFMEMORY;
  else
   hr = pStream->Read((void*) m_str, cbStrLen, NULL);
  // If SysAllocStringByteLen or IStream::Read failed, reset seek
  // pointer to start of BSTR size.
  if (hr != S_OK)
  {
   LARGE_INTEGER nOffset;
   nOffset.QuadPart = -(static_cast<LONGLONG>(sizeof(cbStrLen)));
   pStream->Seek(nOffset, STREAM_SEEK_CUR, NULL);
  }
 }
 if (hr == S_FALSE)
  hr = E_FAIL;
 return hr;
}
static bool LoadStringResource(HINSTANCE hInstance, UINT uID, BSTR&
bstrText) throw()
{
 const ATLSTRINGRESOURCEIMAGE* pImage;

 ATLASSERT(bstrText == NULL);

 pImage = AtlGetStringResourceImage(hInstance, uID);
 if (pImage != NULL)
 {
  bstrText = ::SysAllocStringLen(pImage->achString, pImage->nLength);
 }

 return (bstrText != NULL) ? true : false;
}

static bool LoadStringResource(UINT uID, BSTR& bstrText) throw()
{
 const ATLSTRINGRESOURCEIMAGE* pImage;

 ATLASSERT(bstrText == NULL);

 pImage = AtlGetStringResourceImage(uID);
 if (pImage != NULL)
 {
  bstrText = ::SysAllocStringLen(pImage->achString, pImage->nLength);
 }

 return (bstrText != NULL) ? true : false;
}

// each character in BSTR is copied to each element in SAFEARRAY
HRESULT BSTRToArray(LPSAFEARRAY *ppArray) throw()
{
 return VectorFromBstr(m_str, ppArray);
}

// first character of each element in SAFEARRAY is copied to BSTR
HRESULT ArrayToBSTR(const SAFEARRAY *pSrc) throw()
{
 ::SysFreeString(m_str);
 return BstrFromVector((LPSAFEARRAY)pSrc, &m_str);
}
};

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.