/*++ Copyright (c) 1999 Microsoft Corporation Module Name: vs_str.hxx Abstract: Various defines for general usage Author: Adi Oltean [aoltean] 07/09/1999 Revision History: Name Date Comments aoltean 07/09/1999 Created aoltean 08/11/1999 Adding throw specification aoltean 09/03/1999 Adding DuplicateXXX functions aoltean 09/09/1999 dss -> vss aoltean 09/20/1999 Adding ThrowIf, Err, Msg, MsgNoCR, etc. --*/ #ifndef __VSS_STR_HXX__ #define __VSS_STR_HXX__ #if _MSC_VER > 1000 #pragma once #endif //////////////////////////////////////////////////////////////////////// // Standard foo for file name aliasing. This code block must be after // all includes of VSS header files. // #ifdef VSS_FILE_ALIAS #undef VSS_FILE_ALIAS #endif #define VSS_FILE_ALIAS "INCSTRH" // //////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // Misc string routines //#define ARRAY_LEN(A) (sizeof(A)/sizeof((A)[0])) inline void VssDuplicateStr( OUT LPWSTR& pwszDestination, IN LPCWSTR pwszSource ) { BS_ASSERT(pwszDestination == NULL); if (pwszSource == NULL) pwszDestination = NULL; else { pwszDestination = (LPWSTR)::CoTaskMemAlloc(sizeof(WCHAR)*(1 + ::wcslen(pwszSource))); if (pwszDestination != NULL) ::wcscpy(pwszDestination, pwszSource); } } inline void VssSafeDuplicateStr( IN CVssFunctionTracer& ft, OUT LPWSTR& pwszDestination, IN LPCWSTR pwszSource ) throw(HRESULT) { BS_ASSERT(pwszDestination == NULL); if (pwszSource == NULL) pwszDestination = NULL; else { pwszDestination = (LPWSTR)::CoTaskMemAlloc(sizeof(WCHAR)*(1 + ::wcslen(pwszSource))); if (pwszDestination == NULL) ft.Throw( VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error"); ::wcscpy(pwszDestination, pwszSource); } } inline LPWSTR VssAllocString( IN CVssFunctionTracer& ft, IN size_t nStringLength ) { BS_ASSERT(nStringLength > 0); LPWSTR pwszStr = reinterpret_cast(::CoTaskMemAlloc((nStringLength + 1) * sizeof(WCHAR))); if (pwszStr == NULL) ft.Throw( VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error"); return pwszStr; } inline void VssFreeString( IN OUT LPCWSTR& pwszString ) { ::CoTaskMemFree(const_cast(pwszString)); pwszString = NULL; } inline LPWSTR VssReallocString( IN CVssFunctionTracer& ft, IN LPWSTR pwszString, IN LONG lNewStrLen // Without the zero character. ) { LPWSTR pwszNewString = (LPWSTR)::CoTaskMemRealloc( (PVOID)(pwszString), sizeof(WCHAR) * (lNewStrLen + 1)); if (pwszNewString == NULL) ft.Throw( VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error"); return pwszNewString; } inline bool VssIsStrEqual( IN LPCWSTR wsz1, IN LPCWSTR wsz2 ) { if ((wsz1 == NULL) && (wsz2 == NULL)) return true; if (wsz1 && wsz2 && (::wcscmp(wsz1, wsz2) == 0) ) return true; return false; } inline void VssConcatenate( IN CVssFunctionTracer& ft, IN OUT LPWSTR pwszDestination, IN size_t nDestinationLength, IN LPCWSTR wszSource1, IN LPCWSTR wszSource2 ) { BS_ASSERT(pwszDestination); BS_ASSERT(wszSource1); BS_ASSERT(wszSource2); BS_ASSERT(nDestinationLength > 0); // Check if the buffer is passed if (::wcslen(wszSource1) + ::wcslen(wszSource2) > nDestinationLength ) { BS_ASSERT(false); ft.Throw( VSSDBG_SWPRV, E_UNEXPECTED, L"Buffer not large enough. ( %d + %d > %d )", ::wcslen(wszSource1), ::wcslen(wszSource2), nDestinationLength); } ::wcscpy(pwszDestination, wszSource1); ::wcscat(pwszDestination, wszSource2); } ///////////////////////////////////////////////////////////////////////////// // Automatic auto-string class class CVssAutoPWSZ { // Constructors/destructors private: CVssAutoPWSZ(const CVssAutoPWSZ&); public: CVssAutoPWSZ(LPWSTR pwsz = NULL): m_pwsz(pwsz) {}; // Automatically closes the handle ~CVssAutoPWSZ() { Clear(); }; // Operations public: void Allocate(size_t nCharCount) throw(HRESULT) { CVssFunctionTracer ft( VSSDBG_GEN, L"CVssAutoPWSZ::Allocate" ); Clear(); m_pwsz = ::VssAllocString(ft, nCharCount); } bool CopyFrom(LPCWSTR pwsz) { ::VssFreeString(m_pwsz); ::VssDuplicateStr(m_pwsz, pwsz); return (m_pwsz != NULL); } void TransferFrom(CVssAutoPWSZ& source) { Clear(); m_pwsz = source.Detach(); } void Attach(LPWSTR pwsz) { Clear(); m_pwsz = pwsz; } LPWSTR Detach() { LPWSTR pwsz = m_pwsz; m_pwsz = NULL; return pwsz; } // Returns the value of the actual handle LPWSTR & GetRef() { return m_pwsz; } // Clears the contents of the auto string void Clear() { ::VssFreeString(m_pwsz); } // Returns the value of the actual handle operator LPWSTR () const { return m_pwsz; } // Returns the value of the actual handle operator LPCWSTR () const { return const_cast(m_pwsz); } // Implementation private: LPWSTR m_pwsz; }; #endif // __VSS_STR_HXX__