Click here to Skip to main content
15,891,473 members
Articles / Desktop Programming / ATL

En/Decode MIME-Content with MimeSniffer

Rate me:
Please Sign up or sign in to vote.
4.88/5 (26 votes)
2 Dec 20022 min read 375.7K   7K   74  
RFC-compliant Mime-En/Decoder
///////////////////////////////////////////////////////
// class CYYSType


#include "stdafx.h"
#include "yystype.h"
#include "DateTime.h" 
#include "quote.h"
#include "ISSHelper.h"


void CYYSType::Init()
{
	m_nCurrentType	= type_Invalid;

	m_nVal			= 0;
	m_cVal			= 0;

	if (!m_sVal.empty())
		m_sVal.erase();

	if (!m_pVal.first.empty())
		m_pVal.first.erase();
	if (!m_pVal.second.vt != VT_EMPTY)
		m_pVal.second.Clear();

	if (!m_mVal.empty())
		m_mVal.clear();
	if (!m_Container.empty())
		m_Container.clear();

	if (m_streamVal != NULL)
		m_streamVal.Release();

	m_nDay			= 0;			
	m_nMonth		= 0;			
	m_nYear			= 0;			
	m_nHour			= 0;			
	m_nMinute		= 0;			
	m_nSecond		= 0;			

	if (!m_strZone.empty())
		m_strZone.erase();
}

bool CYYSType::IsValid()
{
	return m_nCurrentType != type_Invalid;
}

CYYSType::CYYSType()
{
	Init();
}


CYYSType::CYYSType(const CYYSType& e)
{
	*this = e;
}

CYYSType::CYYSType(const long n)
{
	*this = n;
}

CYYSType::CYYSType(const char* s)
{
	*this = s;
}

CYYSType::CYYSType(const string& s)
{
	*this = s;
}

CYYSType::CYYSType(const VARIANT v)
{
	*this = v;
}

/*
CYYSType::CYYSType(const char c)
{
	*this = c;
}
*/

CYYSType::CYYSType(const param& p)
{
	*this = p;
}

CYYSType::~CYYSType()
{
}


////////////////////////////////////////////////////////
// operator=

CYYSType& CYYSType::operator=(const CYYSType& e)
{
	Init();

	m_nCurrentType = e.m_nCurrentType;

	switch(e.m_nCurrentType)
	{
		case type_Invalid:
		{
		}
		break;

		case type_Container:
		{
			m_Container = e.m_Container;
		}
		break;

		case type_String:
		{
			m_sVal = e.m_sVal;
		}
		break;

		case type_Char:
		{
			m_cVal = e.m_cVal;
		}
		break;

		case type_Long:
		{
			m_nVal = e.m_nVal;
		}
		break;

		case type_Param:
		{
			m_pVal	= e.m_pVal;
		}
		break;

		case type_ParamMap:
		{
			m_mVal = e.m_mVal;
		}
		break;

		case type_Time:
		case type_Date:
		{
			m_nDay		= e.m_nDay;			
			m_nMonth	= e.m_nMonth;			
			m_nYear		= e.m_nYear;			
			m_nHour		= e.m_nHour;			
			m_nMinute	= e.m_nMinute;			
			m_nSecond	= e.m_nSecond;			
			m_strZone	= e.m_strZone;
		}
		break;

		case type_Bulk:
		{
			m_streamVal = e.m_streamVal;
		}
		break;

		default:
		{
			ATLASSERT(FALSE);
		}
		break;
	}
	return *this;
}

CYYSType& CYYSType::operator=(const string& s)
{
	return operator=(s.c_str());
}

CYYSType& CYYSType::operator=(const param& p)
{
	Init();

	m_pVal			= p;
	m_nCurrentType	= type_Param;
	return *this;
}

CYYSType& CYYSType::operator=(const long n)
{
	Init();

	m_nVal			= n;
	m_nCurrentType	= type_Long;
	return *this;
}

CYYSType& CYYSType::operator=(const char* s)
{
	Init();

	m_sVal			= s;
	m_nCurrentType	= type_String;
	return *this;
}

CYYSType& CYYSType::operator=(const VARIANT v)
{
	switch (v.vt)
	{
		case VT_BSTR:
		{
			USES_CONVERSION;

			return operator=(OLE2CT(v.bstrVal));
		}

		case VT_DATE:
		{
			CDT dt(v.date);

			SetDate(dt.GetDay(), dt.GetMonth(), dt.GetYear(), dt.GetHour(), dt.GetMinute(), dt.GetSecond());

			return *this;
		}

		case VT_I4:
		case VT_I2:
		case VT_UI4:
		case VT_UI2:
		case VT_INT:
		case VT_UINT:
		{
			return operator=(v.lVal);
		}

		case VT_DISPATCH:
		{
			InitType(type_Bulk);

			if (v.pdispVal != NULL)
				v.pdispVal->QueryInterface(&m_streamVal);

			return *this;
		}

		case VT_UNKNOWN:
		{
			InitType(type_Bulk);

			if (v.punkVal != NULL)
				v.punkVal->QueryInterface(&m_streamVal);

			return *this;
		}

		default:
		{
			ATLASSERT(FALSE);
		}
	}
	return *this;
}

/*
CYYSType& CYYSType::operator=(const char c)
{
	Init();

	m_cVal			= c;
	m_nCurrentType	= type_Char;
	return *this;
}
*/

void CYYSType::SetTime(long nHour, long nMinute, long nSecond /*= 0*/, const char* strZone /*= NULL*/)
{
	Init();

	m_nHour		= nHour;			
	m_nMinute	= nMinute;			
	m_nSecond	= nSecond;			
	m_strZone	= strZone != NULL ? strZone : "";

	m_nCurrentType	= type_Time;
}

void CYYSType::SetTime(const CYYSType& e, const char* strZone /*= NULL*/)
{
	SetTime(e.m_nHour, e.m_nMinute, e.m_nSecond, strZone);
}

void CYYSType::SetDate(long nDay, long nMonth, long nYear, long nHour, long nMinute, long nSecond, const char* strZone)
{
	Init();

	if (nYear < 100)
		nYear += 1900;

	m_nDay		= nDay;			
	m_nMonth	= nMonth;			
	m_nYear		= nYear;			
	m_nHour		= nHour;			
	m_nMinute	= nMinute;			
	m_nSecond	= nSecond;			
	m_strZone	= strZone != NULL ? strZone : "";

	m_nCurrentType	= type_Date;
	
}

void CYYSType::SetDate(const CYYSType& dt, const CYYSType& tm)
{
	SetDate(dt.m_nDay, dt.m_nMonth, dt.m_nYear, tm.m_nHour, tm.m_nMinute, tm.m_nSecond, tm.m_strZone.c_str());
}

void CYYSType::Contains(const CYYSType& e)
{
	InitType(type_Container);

	m_Container.push_back(e);
}

////////////////////////////////////////////////////////
// operator+=

CYYSType& CYYSType::operator+=(const CYYSType& e)
{
	switch(m_nCurrentType)
	{
		case type_Container:
		{
			m_Container.push_back(e);
		}
		break;

		case type_String:
		{
			ATLASSERT(e.m_nCurrentType == type_String || e.m_nCurrentType == type_Char);
			
			if		(e.m_nCurrentType == type_String)
				m_sVal += e.m_sVal;
			else if (e.m_nCurrentType == type_Char)
				m_sVal += e.m_cVal;
		}
		break;

		case type_Char:
		{
			ATLASSERT(e.m_nCurrentType == type_Char);
			m_cVal += e.m_cVal;
		}
		break;

		case type_Long:
		{
			ATLASSERT(e.m_nCurrentType == type_Long);
			m_nVal += e.m_nVal;
		}
		break;

		case type_Param:
		{
			ATLASSERT(FALSE);
		}
		break;

		case type_ParamMap:
		{
			ATLASSERT(e.m_nCurrentType == type_Param || e.m_nCurrentType == type_ParamMap);
			
			if		(e.m_nCurrentType == type_ParamMap)
			{
				for (CYYSType::param_map::const_iterator i = e.m_mVal.begin(); i != e.m_mVal.end(); ++i)
				{
					m_mVal.insert(*i);
				}
			}
			else if (e.m_nCurrentType == type_Param)
			{
				m_mVal.insert(e.m_pVal);
			}
		}
		break;

		case type_Bulk:
		{
			ATLASSERT(e.m_nCurrentType == type_String);
			
			if		(e.m_nCurrentType == type_String)
			{
				m_streamVal->Write(e.m_sVal.c_str(), e.m_sVal.length(), NULL);
			}
		}
		break;

		default:
		{
			ATLASSERT(FALSE);
		}
		break;
	}
	return *this;
}

CYYSType& CYYSType::operator+=(const long n)
{
	ATLASSERT(m_nCurrentType == type_Long);

	m_nVal			+= n;

	return *this;
}

CYYSType& CYYSType::operator+=(const string& s)
{
	return operator+=(s.c_str());
}

CYYSType& CYYSType::operator+=(const char* s)
{
	switch(m_nCurrentType)
	{
		case type_String:
		{
			m_sVal			+= s;
		}
		break;

		case type_Param:
		{
			switch(m_pVal.second.vt)
			{
				case VT_EMPTY:
				{
					USES_CONVERSION;
					m_pVal.second = A2OLE(s);
				}
				break;

				case VT_BSTR:
				{
					USES_CONVERSION;

					string str(OLE2CT(m_pVal.second.bstrVal));

					str += s;

					m_pVal.second = T2OLE(str.c_str());
				}
				break;

				default:
				{
					ATLASSERT(FALSE);
				}
				break;
			}
		}
		break;

		default:
		{
			ATLASSERT(FALSE);
		}
		break;
	}
	return *this;
}

CYYSType& CYYSType::operator+=(const char c)
{
	ATLASSERT(m_nCurrentType == type_String);

	m_sVal			+= c;

	return *this;
}

////////////////////////////////////////////////////////
// operator+

CYYSType CYYSType::operator+(const CYYSType& e)
{
	CYYSType r(*this);
	
	r+=(e);

	return r;
}

CYYSType CYYSType::operator+(const long n)
{
	CYYSType r(*this);
	
	r+=(n);

	return r;
}

CYYSType CYYSType::operator+(const string& s)
{
	CYYSType r(*this);
	
	r+=(s);

	return r;
}

CYYSType CYYSType::operator+(const char* s)
{
	CYYSType r(*this);
	
	r+=(s);

	return r;
}

CYYSType CYYSType::operator+(const char c)
{
	CYYSType r(*this);
	
	r+=(c);

	return r;
}

////////////////////////////////////////////////////////
// operator (cast)

#ifdef _DEBUG
void CYYSType::Dump() const
{
static const char* s_names[] = { "Invalid", "String", "Long", "Char"
			, "Param", "ParamMap", "Time", "Date", "Container"
			, "Bulk-Stream", "_9", "_10", "_11", "_12", "_13", "_14", "_15" };
	
	ATLTRACE(_T("-->DUMPING type %s\n"), s_names[m_nCurrentType+1]);

	switch(m_nCurrentType)
	{
		case type_Invalid:
		{
			ATLTRACE(_T(" ** Invalid **\n"));
		}
		break;

		case type_Container:
		{
			for (vector<CYYSType>::const_iterator i = m_Container.begin(); i != m_Container.end(); ++i)
			{
				i->Dump();
			}
		}
		break;

		case type_ParamMap:
		{
			for (param_map::const_iterator i = m_mVal.begin(); i != m_mVal.end(); ++i)
			{
				CYYSType p(param(i->first, i->second));
				p.Dump();
			}
		}
		break;

		case type_Param:
		{
			CComVariant vtTemp(m_pVal.second);

			if (vtTemp.vt != VT_BSTR)
				vtTemp.ChangeType(VT_BSTR);

			if (vtTemp.vt == VT_BSTR)
			{
				USES_CONVERSION;
				ATLTRACE(_T("Key: %s             Value: %s"), m_pVal.first.c_str(), OLE2CT(vtTemp.bstrVal));
			}
			else
			{
				string strTemp(m_pVal.first);

				if (strTemp.length() > 256)
				{
					strTemp = strTemp.substr(0, 256);
					strTemp += _T("......");
				}
				ATLTRACE(_T("Key: %s"), strTemp.c_str());
			}
		}
		break;

		case type_Bulk:
		{
			DWORD dwLen;

			LENGTH_OF_STREAM(dwLen, m_streamVal)

			ATLTRACE(_T("!Blob with size of %ld Bytes!\n"), dwLen);

			char buf[256];

			memset(buf, 0, sizeof(buf));

			SEEK_TO_BEGIN(m_streamVal)
			m_streamVal->Read(buf, min(255, dwLen), NULL);
			SEEK_TO_BEGIN(m_streamVal)

			ATLTRACE(buf);
			ATLTRACE(_T("..."));
		}
		break;

		default:
		{
			string strTemp((const char*)*this);

			if (strTemp.length() > 256)
			{
				strTemp = strTemp.substr(0, 256);
				strTemp += _T("......");
			}
			ATLTRACE(strTemp.c_str());
		}
		break;
	}
	ATLTRACE(_T("<--DUMPING type %s\n"), s_names[m_nCurrentType+1]);
}
#endif

CYYSType::operator const char*() const
{
static	string		strTemp;
static  const char*		vecMonth[] = {	"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
										"Oct", "Nov", "Dec"
									 };

	switch(m_nCurrentType)
	{
		case type_String:
		{
			return m_sVal.c_str();
		}
		break;

		case type_Time:
		{
			TCHAR buf[32];

			_stprintf(buf, _T("%02ld:%02ld:%02ld"), m_nHour, m_nMinute, m_nSecond);

			strTemp = buf;

			if (m_strZone.length() > 0)
			{
				strTemp += _T(" ");
				strTemp += m_strZone.c_str();
			}
			return strTemp.c_str();
		}
		break;

		case type_Date:
		{
			char buf[64];

			sprintf(buf, "%ld %s %ld %02ld:%02ld:%02ld", m_nDay, vecMonth[m_nMonth-1], m_nYear, m_nHour, m_nMinute, m_nSecond);

			strTemp = buf;

			if (m_strZone.length() > 0)
			{
				strTemp += _T(" ");
				strTemp += m_strZone.c_str();
			}
			return strTemp.c_str();
		}
		break;

		default:
		{
			USES_CONVERSION;

			CComVariant vtVal = *this;

			if (vtVal.vt != VT_EMPTY && vtVal.vt != VT_BSTR)
				vtVal.ChangeType(VT_BSTR);

			if (vtVal.vt == VT_BSTR)
				strTemp = OLE2CT(vtVal.bstrVal);
			else
				strTemp = _T("");

			return strTemp.c_str();
		}
		break;
	}
	return NULL;
}

CYYSType::operator long() const
{
	ATLASSERT(m_nCurrentType == type_Long);

	return m_nVal;
}

CYYSType::operator CComVariant() const
{
	CComVariant vtResult;

	switch(m_nCurrentType)
	{
		case type_String:
		{
			vtResult = m_sVal.c_str();
		}
		break;

		case type_Char:
		{
			vtResult = (long)m_cVal;
		}
		break;

		case type_Long:
		{
			vtResult = m_nVal;
		}
		break;

		case type_Param:
		{
			vtResult = m_pVal.second;
		}
		break;

		case type_ParamMap:
		{
			ATLASSERT(FALSE);
		}
		break;

		case type_Date:
		{
			vtResult = (VARIANT) CDT(m_nYear, m_nMonth, m_nDay, m_nHour, m_nMinute, m_nSecond);
		}
		break;

		default:
		{
			ATLASSERT(FALSE);
		}
		break;
	}
	return vtResult;
}

void CYYSType::InitType(long nNewType)
{
	Init();

	m_nCurrentType = nNewType;

	if (m_nCurrentType == type_Bulk)
	{
		CISSHelper* pStream = new CISSHelper(true);

		pStream->QueryInterface(IID_IStream, (void**)&m_streamVal);
	}
}

CComVariant& CYYSType::operator[](string strIndex)
{
static	CComVariant resultDummy;

	ATLASSERT(m_nCurrentType == type_ParamMap);

	if (m_nCurrentType == type_ParamMap)
	{
		return m_mVal[strIndex];
	}
	return resultDummy;
}

DWORD CYYSType::length()
{
	DWORD dwResult;

	switch(m_nCurrentType)
	{
		case type_String:
		{
			dwResult = m_sVal.length();
		}
		break;

		case type_Bulk:
		{
			LENGTH_OF_STREAM(dwResult, m_streamVal)
		}
		break;

		default:
		{
			ATLASSERT(FALSE);
		}
		break;
	}
	return dwResult;
}

////////////////////////////////////////////////////////
// Format

void CYYSType::FormatAsMailbox(string& str) const
{
	str = (const char*) *this;

	if (m_nCurrentType == type_Param)
	{
		if (!str.empty())
			str += _T(" ");

		str += m_pVal.first;
	}
}

////////////////////////////////////////////////////////
// Convert to COM Classes

bool CYYSType::GetAsMailAddresses(VARIANT& vt)
{
	CComDispatchDriverEx vecMails;

	::VariantClear(&vt);

	if (SUCCEEDED(vecMails.CreateInstance(_T("MimeSniffer.Collection"))))
	{
		switch (m_nCurrentType)
		{
			case type_String:
			{
				CComDispatchDriverEx addr;

				if (SUCCEEDED(addr.CreateInstance(_T("MimeSniffer.MailAddress"))))
				{
					addr.PutProperty(L"Address", m_sVal.c_str());
					vecMails.Add(addr);

					return SUCCEEDED(::VariantCopyInd(&vt, &CComVariant((LPDISPATCH)vecMails)));
				}
			}
			break;

			case type_Param:
			{
				CComDispatchDriverEx addr;

				if (SUCCEEDED(addr.CreateInstance(_T("MimeSniffer.MailAddress"))))
				{
					addr.PutProperty(L"Address", m_pVal.first.c_str());
					addr.PutPropertyByName(L"NameRaw", &m_pVal.second);
					vecMails.Add(addr);

					return SUCCEEDED(::VariantCopyInd(&vt, &CComVariant((LPDISPATCH)vecMails)));
				}
			}
			break;

			case type_ParamMap:
			{
				CComDispatchDriverEx addr;

				for (param_map::iterator i = m_mVal.begin(); i != m_mVal.end(); ++i)
				{
					if (SUCCEEDED(addr.CreateInstance(_T("MimeSniffer.MailAddress"))))
					{
						addr.PutProperty(L"Address", i->first.c_str());
						addr.PutPropertyByName(L"NameRaw", &i->second);
						vecMails.Add(addr);
					}
					else
						return false;
				}
				return SUCCEEDED(::VariantCopyInd(&vt, &CComVariant((LPDISPATCH)vecMails)));
			}
			break;

			default:
			{
				ATLASSERT(FALSE);
			}
			break;
		}
	}
	return false;
}

void CYYSType::PutAsMailAddresses(const VARIANT& vt)
{
	Init();

	m_nCurrentType = type_ParamMap;

	switch( vt.vt )
	{
		case VT_BSTR:
		{
			USES_CONVERSION;

			m_mVal[OLE2CT(vt.bstrVal)] = L"";
		}
		break;

		case VT_DISPATCH:
		{
			USES_CONVERSION;

			CComDispatchDriverEx driver(vt.pdispVal);

			// Wird Enum unterst�tzt?
			IEnumVARIANTPtr enumVar;

			if (SUCCEEDED(driver.Enum(&enumVar)))
			{
				ULONG			nCeltFetched = 0;
				CComVariant		vtItem;

				while (SUCCEEDED(enumVar->Next(1, &vtItem, &nCeltFetched)) && nCeltFetched == 1)
				{
					switch( vtItem.vt )
					{
						case VT_BSTR:
						{
							m_mVal[OLE2CT(vtItem.bstrVal)] = L"";
						}
						break;

						case VT_DISPATCH:
						{
							CComDispatchDriverEx driverItem(vtItem.pdispVal);

							string strName;
							string strRoute;

							if (	SUCCEEDED(driverItem.GetProperty(L"NameRaw", strName))
								&&	SUCCEEDED(driverItem.GetProperty(L"RouteAddress", strRoute))
							   )
							{
								m_mVal[strRoute] = strName.c_str();
							}
							else
							{
								ATLASSERT(FALSE);
							}
						}
						break;

						default:
						{
							ATLASSERT(FALSE);
						}
						break;
					}
					vtItem.Clear();
				}
			}
			else
			{
				CComDispatchDriverEx driverItem(vt.pdispVal);

				string strName;
				string strRoute;

				if (	SUCCEEDED(driverItem.GetProperty(L"NameRaw", strName))
					&&	SUCCEEDED(driverItem.GetProperty(L"RouteAddress", strRoute))
				   )
				{
					m_mVal[strRoute] = strName.c_str();
				}
				else
				{
					ATLASSERT(FALSE);
				}
			}
		}
		break;

		default:
		{
			ATLASSERT(FALSE);
		}
		break;
	}
}

bool CYYSType::GetAsMailAddress(VARIANT& vt)
{
	switch (m_nCurrentType)
	{
		case type_String:
		{
			CComDispatchDriverEx addr;

			if (SUCCEEDED(addr.CreateInstance(_T("MimeSniffer.MailAddress"))))
			{
				addr.PutProperty(L"Address", m_sVal.c_str());
				return SUCCEEDED(::VariantCopyInd(&vt, &CComVariant((LPDISPATCH)addr)));
			}
		}
		break;

		case type_Param:
		{
			CComDispatchDriverEx addr;

			if (SUCCEEDED(addr.CreateInstance(_T("MimeSniffer.MailAddress"))))
			{
				addr.PutProperty(L"Address", m_pVal.first.c_str());
				addr.PutPropertyByName(L"NameRaw", &m_pVal.second);

				return SUCCEEDED(::VariantCopyInd(&vt, &CComVariant((LPDISPATCH)addr)));
			}
		}
		break;

		default:
		{
			ATLASSERT(FALSE);
		}
		break;
	}
	return false;
}

void CYYSType::PutAsMailAddress(const VARIANT& vt)
{
	Init();

	m_nCurrentType = type_Param;

	switch( vt.vt )
	{
		case VT_BSTR:
		{
			USES_CONVERSION;

			m_pVal.first	= OLE2CT(vt.bstrVal);
			m_pVal.second	= L"";
		}
		break;

		case VT_DISPATCH:
		{
			USES_CONVERSION;

			CComDispatchDriverEx driverItem(vt.pdispVal);

			string strName;
			string strRoute;

			if (	SUCCEEDED(driverItem.GetProperty(L"NameRaw", strName))
				&&	SUCCEEDED(driverItem.GetProperty(L"RouteAddress", strRoute))
			   )
			{
				m_pVal.first	= strRoute.c_str();
				m_pVal.second	= strName.c_str();
			}
			else
			{
				ATLASSERT(FALSE);
			}
		}
		break;

		default:
		{
			ATLASSERT(FALSE);
		}
		break;
	}
}

bool CYYSType::GetAsDate(VARIANT& vt)
{
	CComVariant vtVal(*this);
	
	return SUCCEEDED(::VariantCopyInd(&vt, &vtVal));
}

void CYYSType::PutAsDate(const VARIANT& vt)
{
	if (type_Date != m_nCurrentType)
	{
		USES_CONVERSION;

		Init();

		m_nCurrentType = type_Date;

		TIME_ZONE_INFORMATION ti;

		memset(&ti, 0, sizeof(ti));

		if (GetTimeZoneInformation(&ti) != TIME_ZONE_ID_INVALID)
		{
			long nGMT = ti.Bias /= (-60);

			char buf[32];

			if (nGMT > 0)
				sprintf(buf, "+%02ld00", nGMT);
			else
				sprintf(buf, "-%02ld00", -nGMT);
			m_strZone = buf;
		}
	}
	CComVariant vtVal(vt);

	if (vtVal.vt != VT_DATE)
		vtVal.ChangeType(VT_DATE);
		
	if (vtVal.vt == VT_DATE)
	{
		CDT dt(vtVal.date);

		m_nDay		= dt.GetDay();	
		m_nMonth	= dt.GetMonth();
		m_nYear		= dt.GetYear();
		m_nHour		= dt.GetHour();
		m_nMinute	= dt.GetMinute();
		m_nSecond	= dt.GetSecond();
	}
}

bool CYYSType::GetAsPlainText(VARIANT& vt)
{
	return SUCCEEDED(::VariantCopyInd(&vt, &CComVariant((const char*)*this)));
}

void CYYSType::PutAsPlainText(const VARIANT& vt)
{
	Init();

	m_nCurrentType = type_String;

	switch( vt.vt )
	{
		case VT_BSTR:
		{
			USES_CONVERSION;

			m_sVal = OLE2CT(vt.bstrVal);
		}
		break;

		case VT_DISPATCH:
		{
			CComDispatchDriverEx driverItem(vt.pdispVal);

			if (FAILED(driverItem.GetProperty(L"TextRaw", m_sVal)))
			{
				ATLASSERT(FALSE);
			}
		}
		break;

		default:
		{
			CComVariant vtTemp(vt);

			vtTemp.ChangeType(VT_BSTR);

			if (vtTemp.vt == VT_BSTR)
			{
				USES_CONVERSION;

				m_sVal = OLE2CT(vtTemp.bstrVal);
			}
			else
				ATLASSERT(FALSE);
		}
		break;
	}
}

bool CYYSType::GetAsUnQuotedText(VARIANT& vt)
{
	string str((const char*)*this);

	UnQuote(str);

	return SUCCEEDED(::VariantCopyInd(&vt, &CComVariant(str.c_str())));
}

void CYYSType::PutAsQuotedInlineText(const VARIANT& vt)
{
	PutAsPlainText(vt);

	if (m_nCurrentType == type_String)
	{
		QuoteInline(m_sVal);
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions