///////////////////////////////////////////////////////
// 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);
}
}