// PSLIPv4.cpp : Implementation of CPSLIPv4
#include "stdafx.h"
#include "PSLIPv4.h"
CPSLIPv4::CPSLIPv4()
{
::memset(m_uAddr, 0, sizeof(m_uAddr));
m_uPort = 0;
m_Format = ip4Default;
}
HRESULT CPSLIPv4::FinalConstruct()
{
return S_OK;
}
void CPSLIPv4::FinalRelease()
{
}
/*
Accepted format: x.x.x.x:x
Numbers can be decimal, hex or combination;
Any hex must have 0x or 0X in front of it;
An empty string is a valid zero address
when passed during object initialization,
i.e. bCreating = true;
*/
bool CPSLIPv4::Initialize(LPCTSTR sIP, bool bCreating)
{
tstring s(sIP);
remove_chars(s, SPACES);
size_t size = s.length();
if(!size)
{
if(bCreating)
{
// It is Ok to pass an empty string
// to create a zero-address object;
Clear(VARIANT_FALSE);
return true;
}
return false;
}
if(size < 7) // 7 is the smallest size of a valid IP address;
return false; // Invalid IP address;
make_upper(s);
LPCTSTR text = s.c_str();
TCHAR buffer[10];
short addr[4] = {0, 0, 0, 0};
size_t idx = 0, last_idx = 0;
size_t n = 0;
TCHAR separator = '.';
for(int i = 0; i < 4;i ++)
{
if(i == 3)
separator = ':';
last_idx = idx;
idx = s.find_first_of(separator, idx);
if(i == 3)
{
if(idx == -1)
idx = size;
else
if(idx == size - 1) // Has double column in the end but nothing else;
return false;
}
n = idx - last_idx;
if(idx == -1 || n > 4 || n < 1)
return false;
_tcsncpy_s(buffer, 10, text, n);
if(buffer[0] == '0' && buffer[1] == 'X')
{
if(!fromhex(buffer, addr[i]))
return false;
}
else
{
if(!fromint(buffer, addr[i]))
return false;
}
idx ++;
text += n + 1;
if(addr[i] > 255)
return false; // Cannot have more than 255 for any octet;
}
if(idx + 6 < size)
return false; // Cannot have more than 6 digits in the port address (0xFFFF);
if(idx < size) // If has port in the address;
{
_tcscpy_s(buffer, 10, text);
long lValue;
bool bValid = false;
if(buffer[0] == '0' && buffer[1] == 'X')
bValid = fromhex(buffer, lValue)?true:false;
else
bValid = fromint(buffer, lValue)?true:false;
if(!bValid || lValue > 65535)
return false;
m_uPort = (short)lValue;
}
else
m_uPort = 0;
::memcpy(m_uAddr, addr, sizeof(addr));
return true;
}
void CPSLIPv4::GetAddrValue(tstring & s, USHORT uValue, long PaddingBase)
{
if(m_Format & ip4Hex)
{
tstring tmp;
s = _T("0x");
if(m_Format & ip4Padded)
tohexfill(tmp, uValue, PaddingBase);
else
tohex(tmp, uValue);
if(m_Format & ip4UpperCase)
make_upper(tmp);
s += tmp;
}
else
{
if(m_Format & ip4Padded)
tointfill(s, uValue, PaddingBase + 1);
else
toint(s, uValue);
}
}
_bstr_t CPSLIPv4::GetIPName()
{
tstring s, s1, s2, s3, s4;
GetAddrValue(s1, m_uAddr[0]);
GetAddrValue(s2, m_uAddr[1]);
GetAddrValue(s3, m_uAddr[2]);
GetAddrValue(s4, m_uAddr[3]);
s.resize(20);
::wsprintf((LPTSTR)s.c_str(), _T("%s.%s.%s.%s"), s1.c_str(), s2.c_str(), s3.c_str(), s4.c_str());
shrink(s);
if(m_uPort)
{
tstring sPort;
GetAddrValue(sPort, m_uPort, 4);
s += _T(":");
s += sPort.c_str();
}
return s.c_str();
}
////////////////////////////////////////////////////////////////////////
// Interface Implementation;
////////////////////////////////////////////////////////////////////////
STDMETHODIMP CPSLIPv4::get_A1(short * pValue)
{
PSL_BEGIN
*pValue = m_uAddr[0];
PSL_END
}
STDMETHODIMP CPSLIPv4::put_A1(short newValue)
{
PSL_BEGIN
if(newValue < 0 || newValue > 255)
return MakeException(exInvalidParameter);
m_uAddr[0] = newValue;
PSL_END
}
STDMETHODIMP CPSLIPv4::get_A2(short * pValue)
{
PSL_BEGIN
*pValue = m_uAddr[1];
PSL_END
}
STDMETHODIMP CPSLIPv4::put_A2(short newValue)
{
PSL_BEGIN
if(newValue < 0 || newValue > 255)
return MakeException(exInvalidParameter);
m_uAddr[1] = newValue;
PSL_END
}
STDMETHODIMP CPSLIPv4::get_A3(short * pValue)
{
PSL_BEGIN
*pValue = m_uAddr[2];
PSL_END
}
STDMETHODIMP CPSLIPv4::put_A3(short newValue)
{
PSL_BEGIN
if(newValue < 0 || newValue > 255)
return MakeException(exInvalidParameter);
m_uAddr[2] = newValue;
PSL_END
}
STDMETHODIMP CPSLIPv4::get_A4(short * pValue)
{
PSL_BEGIN
*pValue = m_uAddr[3];
PSL_END
}
STDMETHODIMP CPSLIPv4::put_A4(short newValue)
{
PSL_BEGIN
if(newValue < 0 || newValue > 255)
return MakeException(exInvalidParameter);
m_uAddr[3] = newValue;
PSL_END
}
STDMETHODIMP CPSLIPv4::get_Port(long * pValue)
{
PSL_BEGIN
*pValue = m_uPort;
PSL_END
}
STDMETHODIMP CPSLIPv4::put_Port(long newValue)
{
PSL_BEGIN
if(newValue < 0 || newValue > 0xFFFF)
return MakeException(exInvalidParameter);
m_uPort = (USHORT)newValue;
PSL_END
}
STDMETHODIMP CPSLIPv4::get_Address(long * pValue)
{
PSL_BEGIN
*pValue = MAKELONG(MAKEWORD(m_uAddr[0], m_uAddr[1]), MAKEWORD(m_uAddr[2], m_uAddr[3]));
PSL_END
}
STDMETHODIMP CPSLIPv4::put_Address(long newValue)
{
PSL_BEGIN
m_uAddr[0] = LOBYTE(LOWORD(newValue));
m_uAddr[1] = HIBYTE(LOWORD(newValue));
m_uAddr[2] = LOBYTE(HIWORD(newValue));
m_uAddr[3] = HIBYTE(HIWORD(newValue));
PSL_END
}
STDMETHODIMP CPSLIPv4::get_Text(BSTR * pValue)
{
PSL_BEGIN
*pValue = GetIPName().copy();
PSL_END
}
STDMETHODIMP CPSLIPv4::put_Text(BSTR newValue)
{
PSL_BEGIN
if(!newValue)
return MakeException(exInvalidParameter);
if(!Initialize(_bstr_t(newValue), false))
SetException(exInvalidParameter);
PSL_END
}
STDMETHODIMP CPSLIPv4::get_Format(PSLIPv4Format * pValue)
{
PSL_BEGIN
*pValue = m_Format;
PSL_END
}
STDMETHODIMP CPSLIPv4::put_Format(PSLIPv4Format newValue)
{
PSL_BEGIN
m_Format = newValue;
PSL_END
}
STDMETHODIMP CPSLIPv4::Clear(VARIANT_BOOL bClearFormat)
{
PSL_BEGIN
::memset(m_uAddr, 0, sizeof(m_uAddr));
m_uPort = 0;
if(bClearFormat)
m_Format = ip4Default;
PSL_END
}