//  Beta release only.
//
//  Copyright(c) Ivyware Pty Ltd  2013
//               MELBOURNE, VICTORIA, AUSTRALIA, 3130
//
//  Provided no fee is charged (either by the distributer or user)
//  permission to use, copy, modify, and distribute this software and
//  its documentation for any purpose and without fee is hereby granted,
//  provided that the above copyright notice appear in all copies and
//  that both that copyright notice and this permission notice appear
//  in supporting documentation.
//
//  No waranty or suitablity for purpose is implied.
//
//
#include "StdAfx.h"

#include "MAPI_Ext.h"

///////////////////////////////////////////////////////////////////////
//  Stack based safe MAPI buffer container
//  NOTES: MAPIAllocateBuffer()'s are managed within the life cycle
//         of this object.

P2PsafeMAPIbuffer::P2PsafeMAPIbuffer ( )
{   
    m_lpvBuffer = 0;
}
P2PsafeMAPIbuffer::P2PsafeMAPIbuffer ( LPVOID rhs )
{
    m_lpvBuffer = rhs;
}
P2PsafeMAPIbuffer::~P2PsafeMAPIbuffer ( )
{   
    if ( m_lpvBuffer )
      MAPIFreeBuffer ( m_lpvBuffer );
}
LPVOID
P2PsafeMAPIbuffer::operator = ( LPVOID lpvBuffer )
{   
    if ( m_lpvBuffer              &&
         m_lpvBuffer != lpvBuffer    )
      MAPIFreeBuffer ( m_lpvBuffer );
    m_lpvBuffer = lpvBuffer;
    return m_lpvBuffer;
}

///////////////////////////////////////////////////////////////////////
//  Stack based safe MAPI SRowSet container
//  NOTES: MAPI SRowSet pointers are managed within the life cycle
//         of this object.

P2PsafeSRowSet::P2PsafeSRowSet ( )
{   
    m_pSRowSet = nullptr;
}
P2PsafeSRowSet::P2PsafeSRowSet ( SRowSet *rhs )
{
    m_pSRowSet = rhs;
}
P2PsafeSRowSet::~P2PsafeSRowSet ( )
{   
    if ( m_pSRowSet )
      FreeProws ( m_pSRowSet );
    if ( m_pSRowSet )
      MAPIFreeBuffer ( m_pSRowSet );
}
SRowSet*
P2PsafeSRowSet::operator = ( SRowSet *pSRowSet )
{   
    if ( m_pSRowSet             &&
         m_pSRowSet != pSRowSet    )
    {
      FreeProws ( m_pSRowSet );
      MAPIFreeBuffer ( m_pSRowSet );
    }
    m_pSRowSet = pSRowSet;
    return m_pSRowSet;
}
SRowSet*
P2PsafeSRowSet::operator*()
{ 
    return m_pSRowSet;
}
P2PsafeSRowSet::operator SRowSet** ( )
{
    (*this) = 0;
    return &m_pSRowSet;
}
SRowSet*
P2PsafeSRowSet::operator->() const
{
    return m_pSRowSet;
}

///////////////////////////////////////////////////////////////////////
//  Helpers and static environment extensions

//
//  Sets up last P2Pevent for thread
//
//  Parameters:  LPCTSTR lpsModule
//               Reporting module
//
//               LPCTSTR lpszMessage
//               Associated message
//
//               HRESULT
//
//  Returns:     P2Pevent*
//               Generated event with internally managed life cycle
P2Pevent*
SetP2PeventMAPI ( LPCTSTR lpszModule, LPCTSTR lpszMessage, HRESULT hr )
{
    P2Pevent *pEVT = EVERR;
    if ( lpszModule && lpszModule[0] )
      pEVT -> Module ( lpszModule );
    if ( lpszMessage && lpszMessage[0] )
      pEVT -> Message ( lpszMessage );
    if ( hr != S_OK )
      pEVT -> HResult ( hr );
    pEVT -> SetLast ( );
    return pEVT;
}

//
//  Retrieves and verifies SPropValue string contents
//  NOTES: Empty string contents substituted for invalid strings
//
//  Parameters:  SPropValue& oProp
//
//  Returns:     LPCTSTR
//               Retrieved and verified string
LPCTSTR
MAPI_GetValidString ( SPropValue& oProp )
{
    return MAPI_Check4BadString ( oProp.Value.LPSZ );
}

//
//  Retrieves and verifies SPropValue indexed string contents
//  NOTES: Empty string contents substituted for invalid strings
//
//  Parameters:  SPropValue& oProp
//
//  Returns:     LPCTSTR
//               Retrieved and verified string
LPCTSTR
MAPI_GetValidMVString ( SPropValue& oProp, int nIndex )
{
    return MAPI_Check4BadString ( oProp.Value.MVSZ.LPPSZ[nIndex] );
}

// special case of GetValidString to take the narrow string in UNICODE
void
MAPI_GetNarrowString ( SPropValue& oProp, CString& strNarrow )
{
	LPCTSTR s=MAPI_GetValidString(oProp);
	if(!s) strNarrow=_T("");
	else {
#ifdef UNICODE
		// VS2005 can copy directly
		if(_MSC_VER>=1400) 
		{
			strNarrow=(char*)s;
		} 
		else 
		{
			WCHAR wszWide[256];
			MultiByteToWideChar(CP_ACP, 0, (LPCSTR)s,-1,wszWide,255);
			strNarrow=wszWide;
		}
#else
		strNarrow=s;
#endif
	}
}

//
//  On occasion string obtained from SPropValue is invalid
//  NOTES: Provide NULL substitution for such occasions
LPCTSTR
MAPI_Check4BadString ( LPCTSTR lpszString )
{
    if (  lpszString && 
         !IsBadStringPtr(lpszString, (UINT_PTR)-1) )
      return lpszString;
	  return nullptr;
}
