// RuntimeTrace.cpp : Implementation of CRuntimeTrace
#include "stdafx.h"
#include "Tracing.h"
#include "RuntimeTrace.h"
#ifdef _DEBUG
void Print_(int, char *);
#endif
/////////////////////////////////////////////////////////////////////////////
// CRuntimeTrace
void CRuntimeTrace::DeleteList()
{
m_nCurrent=0;
for (int i=0; i<m_nParameters; i++)
switch (m_arVariants[i])
{
case VT_UI1:
case VT_BYREF | VT_UI1:
case VT_BOOL:
case VT_I2:
case VT_BYREF | VT_BOOL:
case VT_BYREF | VT_I2:
case VT_I4:
case VT_R4:
case VT_BYREF | VT_I4:
case VT_BYREF | VT_R4:
m_nCurrent+=4;
break;
case VT_R8:
case VT_CY:
case VT_BYREF | VT_R8:
case VT_BYREF | VT_CY:
m_nCurrent+=8;
break;
case VT_BSTR:
case VT_DATE:
case VT_BYREF | VT_BSTR:
case VT_BYREF | VT_DATE:
delete [] *(LPTSTR *)(m_szListBuffer+m_nCurrent);
m_nCurrent+=4;
break;
}
m_nParameters=m_nCurrent=0;
}
STDMETHODIMP CRuntimeTrace::Drop()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
DeleteList();
m_szError.Empty();
m_bReadyMessage=TRUE;
return S_OK;
}
STDMETHODIMP CRuntimeTrace::get_ErrorReason(BSTR *pVal)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
*pVal=m_szError.AllocSysString();
return S_OK;
}
STDMETHODIMP CRuntimeTrace::Add(VARIANT Val, VARIANT_BOOL *pRetval)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
_bstr_t bst;
LPTSTR szMan;
SYSTEMTIME st;
*pRetval=VARIANT_FALSE;
if (!m_bConnected)
{
m_szError.Format(_T("Not connected!"));
return S_OK;
}
if (!m_bReadyMessage) return S_OK;
switch (Val.vt)
{
case VT_UI1:
*(UINT *)(m_szListBuffer+m_nCurrent)=(UINT)Val.bVal;
m_nCurrent+=sizeof(UINT);
break;
case VT_BOOL:
*(BOOL *)(m_szListBuffer+m_nCurrent)=
Val.boolVal==VARIANT_FALSE ? FALSE : TRUE;
m_nCurrent+=sizeof(BOOL);
break;
case VT_I2:
*(int *)(m_szListBuffer+m_nCurrent)=(int)Val.iVal;
m_nCurrent+=sizeof(int);
break;
case VT_I4:
*(long *)(m_szListBuffer+m_nCurrent)=Val.lVal;
m_nCurrent+=sizeof(long);
break;
case VT_R4:
*(double *)(m_szListBuffer+m_nCurrent)=(double)
(Val.fltVal);
m_nCurrent+=sizeof(double);
break;
case VT_R8:
*(double *)(m_szListBuffer+m_nCurrent)=Val.dblVal;
m_nCurrent+=sizeof(double);
break;
case VT_CY:
*(LONGLONG *)(m_szListBuffer+m_nCurrent)=
Val.cyVal.int64;
m_nCurrent+=sizeof(LONGLONG);
break;
case VT_BSTR:
bst=Val.bstrVal;
szMan=new TCHAR[bst.length()+2];
_tcscpy(szMan, (LPTSTR)bst);
*(LPTSTR *)(m_szListBuffer+m_nCurrent)=szMan;
m_nCurrent+=sizeof(LPTSTR);
break;
case VT_DATE:
VariantTimeToSystemTime(Val.date, &st);
szMan=new TCHAR[12];
wsprintf(szMan, _T("%d-%d-%d"), st.wMonth, st.wDay,
st.wYear);
*(LPTSTR *)(m_szListBuffer+m_nCurrent)=szMan;
m_nCurrent+=sizeof(LPTSTR);
break;
case VT_BYREF | VT_UI1:
*(UINT *)(m_szListBuffer+m_nCurrent)=(UINT)*Val.pbVal;
m_nCurrent+=sizeof(UINT);
break;
case VT_BYREF | VT_BOOL:
*(BOOL *)(m_szListBuffer+m_nCurrent)=
*Val.pboolVal==VARIANT_FALSE ? FALSE : TRUE;
m_nCurrent+=sizeof(BOOL);
break;
case VT_BYREF | VT_I2:
*(int *)(m_szListBuffer+m_nCurrent)=(int)*Val.piVal;
m_nCurrent+=sizeof(int);
break;
case VT_BYREF | VT_I4:
*(long *)(m_szListBuffer+m_nCurrent)=*Val.plVal;
m_nCurrent+=sizeof(long);
break;
case VT_BYREF | VT_R4:
*(double *)(m_szListBuffer+m_nCurrent)=(double)
(*Val.pfltVal);
m_nCurrent+=sizeof(double);
break;
case VT_BYREF | VT_R8:
*(double *)(m_szListBuffer+m_nCurrent)=*Val.pdblVal;
m_nCurrent+=sizeof(double);
break;
case VT_BYREF | VT_CY:
*(LONGLONG *)(m_szListBuffer+m_nCurrent)=
Val.pcyVal->int64;
m_nCurrent+=sizeof(LONGLONG);
break;
case VT_BYREF | VT_BSTR:
bst=*(Val.pbstrVal);
szMan=new TCHAR[bst.length()+2];
_tcscpy(szMan, (LPTSTR)bst);
*(LPTSTR *)(m_szListBuffer+m_nCurrent)=szMan;
m_nCurrent+=sizeof(LPTSTR);
break;
case VT_BYREF | VT_DATE:
VariantTimeToSystemTime(*Val.pdate, &st);
szMan=new TCHAR[12];
wsprintf(szMan, _T("%d-%d-%d"), st.wMonth, st.wDay,
st.wYear);
*(LPTSTR *)(m_szListBuffer+m_nCurrent)=szMan;
m_nCurrent+=sizeof(LPTSTR);
break;
case VT_BYREF | VT_VARIANT:
return Add(*(Val.pvarVal), pRetval);
default:
m_szError.Format(_T("Parameter type not supported!"));
DeleteList();
m_bReadyMessage=FALSE;
break;
}
m_arVariants[m_nParameters]=Val.vt;
m_nParameters++;
*pRetval=VARIANT_TRUE;
return S_OK;
}
STDMETHODIMP CRuntimeTrace::SetTarget(BSTR Name, BSTR IP, short Port, VARIANT_BOOL *pRetval)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
struct sockaddr_in serv;
struct sockaddr_in client;
m_szName.Format(_T("%s"), (LPCTSTR)_bstr_t(Name));
if (m_bConnected)
{
shutdown(m_sock, 2);
closesocket(m_sock);
}
*pRetval=VARIANT_FALSE;
if ((m_sock=socket(AF_INET, SOCK_DGRAM, 0))==
INVALID_SOCKET)
{
m_szError.Format(_T("Cannot create socket!"));
return S_OK;
}
memset((void *)&serv, 0, sizeof(serv));
serv.sin_family = AF_INET;
serv.sin_addr.s_addr = inet_addr((char *)_bstr_t(IP));
serv.sin_port = htons(Port);
memset((void *)&client, 0, sizeof(client));
client.sin_family = AF_INET;
try
{
if (bind(m_sock, (struct sockaddr*)&client,
sizeof(client))==SOCKET_ERROR)
throw CString(_T("Error on binding the socket!"));
if (!(m_bConnected=SOCKET_ERROR != connect(m_sock,
(struct sockaddr*)&serv, sizeof(serv))))
throw CString(_T("Error on connecting to socket!"));
}
catch (CString &szMan)
{
m_szError=szMan;
shutdown(m_sock, 2);
closesocket(m_sock);
return S_OK;
}
m_szError.Empty();
*pRetval=VARIANT_TRUE;
return S_OK;
}
STDMETHODIMP CRuntimeTrace::Trace(BSTR Format, VARIANT_BOOL *pRetval)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
*pRetval=VARIANT_FALSE;
if (!m_bConnected)
{
m_szError.Format(_T("Not connected!"));
return S_OK;
}
else
if (!m_bReadyMessage)
{
m_bReadyMessage=TRUE;
return S_OK;
}
COleDateTime now = COleDateTime::GetCurrentTime();
CString szMan, szFin;
char sz[100];
try
{
szMan.FormatV((LPCTSTR)_bstr_t(Format), m_szListBuffer);
}
catch (...)
{
DeleteList();
m_szError.Format(_T("Error on formatting!"));
return S_OK;
}
gethostname(sz, 100);
szFin+=CString(sz)+_T("\"")+m_szName+_T("\" ")+
now.Format(_T("[%H:%M:%S] "))+szMan;
DeleteList();
if (send(m_sock, (const char *)(LPCTSTR)szFin,
szFin.GetLength()*sizeof(TCHAR), 0)==SOCKET_ERROR)
{
m_szError.Format(_T("Error on sending message!"));
return S_OK;
}
*pRetval=VARIANT_TRUE;
return S_OK;
}
STDMETHODIMP CRuntimeTrace::Trace10(BSTR Format, VARIANT v1, VARIANT v2, VARIANT v3, VARIANT v4, VARIANT v5, VARIANT v6, VARIANT v7, VARIANT v8, VARIANT v9, VARIANT v10)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
VARIANT_BOOL vb;
Drop();
if (v1.vt!=VT_ERROR)
Add(v1, &vb);
else return Trace(Format, &vb);
if (v2.vt!=VT_ERROR)
Add(v2, &vb);
else return Trace(Format, &vb);
if (v3.vt!=VT_ERROR)
Add(v3, &vb);
else return Trace(Format, &vb);
if (v4.vt!=VT_ERROR)
Add(v4, &vb);
else return Trace(Format, &vb);
if (v5.vt!=VT_ERROR)
Add(v5, &vb);
else return Trace(Format, &vb);
if (v6.vt!=VT_ERROR)
Add(v6, &vb);
else return Trace(Format, &vb);
if (v7.vt!=VT_ERROR)
Add(v7, &vb);
else return Trace(Format, &vb);
if (v8.vt!=VT_ERROR)
Add(v8, &vb);
else return Trace(Format, &vb);
if (v9.vt!=VT_ERROR)
Add(v9, &vb);
else return Trace(Format, &vb);
if (v10.vt!=VT_ERROR)
Add(v10, &vb);
return Trace(Format, &vb);
}
#ifdef _DEBUG
void Print_(int d, LPTSTR sz)
{
CString szMan;
CFile fil(_T("c:\\rep.txt"), CFile::modeCreate
| CFile::modeNoTruncate | CFile::modeWrite);
fil.SeekToEnd();
szMan.Format(_T("%d, %s\r\n"), d, sz ? sz : _T("<no string>"));
if (d&VT_BYREF) szMan+=_T("da\n");
if (d&VT_VARIANT) szMan+=_T("da\n");
if (d&VT_R8) szMan+=_T("da\n");
if (d&VT_BSTR) szMan+=_T("da\n");
fil.Write(szMan, szMan.GetLength());
fil.Close();
}
#endif