797 lines
21 KiB
C++
797 lines
21 KiB
C++
|
//--------------------------------------------------------------------------//
|
||
|
// Application Header Files. //
|
||
|
//--------------------------------------------------------------------------//
|
||
|
#include "precomp.h"
|
||
|
#include "callto.h"
|
||
|
#include "calltoContext.h"
|
||
|
#include "calltoResolver.h"
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------------------//
|
||
|
// CCalltoResolver::CCalltoResolver. //
|
||
|
//--------------------------------------------------------------------------//
|
||
|
CCalltoResolver::CCalltoResolver(void):
|
||
|
m_registeredResolvers( 0 )
|
||
|
{
|
||
|
|
||
|
addResolver( &m_phoneResolver );
|
||
|
addResolver( &m_emailResolver );
|
||
|
addResolver( &m_ipResolver );
|
||
|
addResolver( &m_computerResolver );
|
||
|
addResolver( &m_ilsResolver );
|
||
|
addResolver( &m_unrecognizedTypeResolver );
|
||
|
addResolver( &m_stringResolver );
|
||
|
|
||
|
} // End of CCalltoResolver::CCalltoResolver.
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------------------//
|
||
|
// CCalltoResolver::~CCalltoResolver. //
|
||
|
//--------------------------------------------------------------------------//
|
||
|
CCalltoResolver::~CCalltoResolver()
|
||
|
{
|
||
|
} // End of CCalltoResolver::~CCalltoResolver.
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------------------//
|
||
|
// CCalltoResolver::resolve. //
|
||
|
//--------------------------------------------------------------------------//
|
||
|
HRESULT
|
||
|
CCalltoResolver::resolve
|
||
|
(
|
||
|
ICalltoContext * const calltoContext,
|
||
|
CCalltoProperties * const calltoProperties,
|
||
|
CCalltoCollection * const resolvedCalltoCollection,
|
||
|
const TCHAR * url,
|
||
|
const bool strict
|
||
|
){
|
||
|
HRESULT result;
|
||
|
|
||
|
if( (calltoContext == NULL) || (calltoProperties == NULL) || (resolvedCalltoCollection == NULL) )
|
||
|
{
|
||
|
result = E_POINTER;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TCHAR * params = StrStrI( url, TEXT( "phone:+" ) );
|
||
|
|
||
|
params = StrChr( (params != NULL)? params + strlen_literal( TEXT( "phone:+" ) ): url, '+' );
|
||
|
|
||
|
int paramsLength = (params == NULL)? 0: lstrlen( params );
|
||
|
int urlLength = lstrlen( url ) - paramsLength + 1;
|
||
|
int prefixLength = 0;
|
||
|
|
||
|
if( !StrCmpNI_literal( url, TEXT( "callto:" ) ) )
|
||
|
{
|
||
|
prefixLength = strlen_literal( TEXT( "callto:" ) );
|
||
|
}
|
||
|
else if( StrCmpNI_literal( url, TEXT( "callto://" ) ) )
|
||
|
{
|
||
|
prefixLength = strlen_literal( TEXT( "callto:" ) );
|
||
|
url += strlen_literal( TEXT( "callto://" ) );
|
||
|
urlLength -= strlen_literal( TEXT( "callto://" ) ) - strlen_literal( TEXT( "callto:" ) );
|
||
|
}
|
||
|
|
||
|
TCHAR * urlBuffer = NULL;
|
||
|
|
||
|
if( (urlBuffer = new TCHAR [ urlLength + prefixLength ]) == NULL )
|
||
|
{
|
||
|
result = E_OUTOFMEMORY;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if( paramsLength > 0 )
|
||
|
{
|
||
|
// Save params...
|
||
|
calltoProperties->set_params( params );
|
||
|
}
|
||
|
|
||
|
// Save original callto...
|
||
|
calltoProperties->set_callto( url, urlLength );
|
||
|
|
||
|
result = S_FALSE;
|
||
|
|
||
|
resolvedCalltoCollection->reset();
|
||
|
|
||
|
if( urlLength > 1 )
|
||
|
{
|
||
|
bool strictChecked = !strict;
|
||
|
|
||
|
for( int nn = 0; nn < m_registeredResolvers; nn++ )
|
||
|
{
|
||
|
if( prefixLength > 0 )
|
||
|
{
|
||
|
lstrcpy( urlBuffer, TEXT( "callto:" ) ); // Prepend default of callto: ...
|
||
|
lstrcpyn( urlBuffer + strlen_literal( TEXT( "callto:" ) ), url, urlLength );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
lstrcpyn( urlBuffer, url, urlLength );
|
||
|
}
|
||
|
|
||
|
if( !strictChecked )
|
||
|
{
|
||
|
if( !strictCheck( urlBuffer ) )
|
||
|
{
|
||
|
result = E_INVALIDARG;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
strictChecked = true;
|
||
|
}
|
||
|
|
||
|
HRESULT resolveResult = m_resolvers[ nn ]->resolve( resolvedCalltoCollection, urlBuffer );
|
||
|
|
||
|
if( FAILED( resolveResult ) && (!FAILED( result )) )
|
||
|
{
|
||
|
result = resolveResult;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( !FAILED( result ) )
|
||
|
{
|
||
|
result = (resolvedCalltoCollection->get_count() > 0)? S_OK: S_FALSE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
delete [] urlBuffer;
|
||
|
}
|
||
|
|
||
|
return( result );
|
||
|
|
||
|
} // End of class CCalltoResolver::resolve.
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------------------//
|
||
|
// CCalltoResolver::addResolver. //
|
||
|
//--------------------------------------------------------------------------//
|
||
|
bool
|
||
|
CCalltoResolver::addResolver
|
||
|
(
|
||
|
IResolver * const resolver
|
||
|
){
|
||
|
//assert( resolver != NULL, TEXT( "attempted to add NULL resolver\r\n" ) );
|
||
|
//assert( m_registeredResolvers < elementsof( m_resolvers ), TEXT( "attempted to add to many resolvers: %d\r\n" ), m_registeredResolvers );
|
||
|
|
||
|
if( (resolver != NULL) && (m_registeredResolvers < elementsof( m_resolvers )) )
|
||
|
{
|
||
|
m_resolvers[ m_registeredResolvers++ ] = resolver;
|
||
|
}
|
||
|
|
||
|
return( (resolver != NULL) && (m_registeredResolvers <= elementsof( m_resolvers )) );
|
||
|
|
||
|
} // End of CCalltoResolver::addResolver.
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------------------//
|
||
|
// CCalltoResolver::strictCheck. //
|
||
|
//--------------------------------------------------------------------------//
|
||
|
const bool
|
||
|
CCalltoResolver::strictCheck
|
||
|
(
|
||
|
const TCHAR * const url
|
||
|
) const
|
||
|
{
|
||
|
//assert( url != NULL, TEXT( "attempted to strictCheck NULL url\r\n" ) );
|
||
|
|
||
|
return( (url != NULL) &&
|
||
|
(StrCmpNI_literal( url, TEXT( "callto:phone:" ) ) ||
|
||
|
StrCmpNI_literal( url, TEXT( "callto:email:" ) ) ||
|
||
|
StrCmpNI_literal( url, TEXT( "callto:ip:" ) ) ||
|
||
|
StrCmpNI_literal( url, TEXT( "callto:computer:" ) ) ||
|
||
|
StrCmpNI_literal( url, TEXT( "callto:ils:" ) ) ||
|
||
|
StrCmpNI_literal( url, TEXT( "callto:string:" ) ) ||
|
||
|
(StrStrI( url, TEXT( "|phone:" ) ) != NULL) ||
|
||
|
(StrStrI( url, TEXT( "|email:" ) ) != NULL) ||
|
||
|
(StrStrI( url, TEXT( "|ip:" ) ) != NULL) ||
|
||
|
(StrStrI( url, TEXT( "|computer:" ) ) != NULL) ||
|
||
|
(StrStrI( url, TEXT( "|ils:" ) ) != NULL) ||
|
||
|
(StrStrI( url, TEXT( "|string:" ) ) != NULL)) );
|
||
|
|
||
|
} // End of CCalltoResolver::strictCheck.
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------------------//
|
||
|
// CPhoneResolver::resolve. //
|
||
|
//--------------------------------------------------------------------------//
|
||
|
HRESULT
|
||
|
CPhoneResolver::resolve
|
||
|
(
|
||
|
IMutableCalltoCollection * const calltoCollection,
|
||
|
TCHAR * const url
|
||
|
){
|
||
|
HRESULT result = E_INVALIDARG;
|
||
|
|
||
|
if( (calltoCollection != NULL) && (url != NULL) )
|
||
|
{
|
||
|
TCHAR * phoneType;
|
||
|
TCHAR * phoneNumber = NULL;
|
||
|
|
||
|
result = S_FALSE;
|
||
|
|
||
|
if( StrCmpNI_literal( url, TEXT( "callto:phone:" ) ) ) // Check for phone type without gateway...
|
||
|
{
|
||
|
phoneType = url;
|
||
|
phoneNumber = url + strlen_literal( TEXT( "callto:phone:" ) );
|
||
|
}
|
||
|
else if( (phoneType = StrStrI( url, TEXT( "|phone:" ) )) != NULL ) // Check for phone type with gateway...
|
||
|
{
|
||
|
phoneNumber = phoneType + strlen_literal( TEXT( "|phone:" ) );
|
||
|
}
|
||
|
|
||
|
if( phoneNumber != NULL )
|
||
|
{
|
||
|
// phone: type was specified for this callto:...
|
||
|
if( CCalltoContext::toE164( phoneNumber, NULL, 0 ) )
|
||
|
{
|
||
|
ICallto * const resolvedCallto = calltoCollection->get_nextUnused();
|
||
|
|
||
|
if( resolvedCallto != NULL )
|
||
|
{
|
||
|
CCalltoContext::toE164( phoneNumber, phoneNumber, lstrlen( phoneNumber ) );
|
||
|
resolvedCallto->set_qualifiedName( url );
|
||
|
resolvedCallto->set_confidence( S_CONFIDENCE_HIGH );
|
||
|
|
||
|
result = S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
result = E_OUTOFMEMORY;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
phoneNumber = url + strlen_literal( TEXT( "callto:" ) );
|
||
|
|
||
|
if( CCalltoContext::isPhoneNumber( phoneNumber ) )
|
||
|
{
|
||
|
// It smells like E164...
|
||
|
result = E_OUTOFMEMORY;
|
||
|
|
||
|
CCalltoContext::toE164( phoneNumber, phoneNumber, lstrlen( phoneNumber ) );
|
||
|
|
||
|
TCHAR * buffer = new TCHAR [ lstrlen( phoneNumber ) + strlen_literal( TEXT( "callto:phone:%s" ) ) ];
|
||
|
|
||
|
if( buffer != NULL )
|
||
|
{
|
||
|
ICallto * const resolvedCallto = calltoCollection->get_nextUnused();
|
||
|
|
||
|
if( resolvedCallto != NULL )
|
||
|
{
|
||
|
wsprintf( buffer, TEXT( "callto:phone:%s" ), phoneNumber );
|
||
|
resolvedCallto->set_qualifiedName( buffer );
|
||
|
resolvedCallto->set_confidence( S_CONFIDENCE_MEDIUM );
|
||
|
|
||
|
result = S_OK;
|
||
|
}
|
||
|
|
||
|
delete [] buffer;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return( result );
|
||
|
|
||
|
} // End of CPhoneResolver::resolve.
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------------------//
|
||
|
// CEMailResolver::resolve. //
|
||
|
//--------------------------------------------------------------------------//
|
||
|
HRESULT
|
||
|
CEMailResolver::resolve
|
||
|
(
|
||
|
IMutableCalltoCollection * const calltoCollection,
|
||
|
TCHAR * const url
|
||
|
){
|
||
|
HRESULT result = E_INVALIDARG;
|
||
|
|
||
|
if( (calltoCollection != NULL) && (url != NULL) )
|
||
|
{
|
||
|
TCHAR * emailType;
|
||
|
TCHAR * emailAddress = NULL;
|
||
|
|
||
|
result = S_FALSE;
|
||
|
|
||
|
if( StrCmpNI_literal( url, TEXT( "callto:email:" ) ) ) // Check for email type without gateway...
|
||
|
{
|
||
|
emailType = url;
|
||
|
emailAddress = url + strlen_literal( TEXT( "callto:email:" ) );
|
||
|
}
|
||
|
else if( (emailType = StrStrI( url, TEXT( "|email:" ) )) != NULL ) // Check for email type with gateway...
|
||
|
{
|
||
|
emailAddress = emailType + strlen_literal( TEXT( "|email:" ) );
|
||
|
}
|
||
|
|
||
|
if( emailAddress != NULL )
|
||
|
{
|
||
|
// email: type was specified for this callto:...
|
||
|
ICallto * const resolvedCallto = calltoCollection->get_nextUnused();
|
||
|
|
||
|
if( resolvedCallto != NULL )
|
||
|
{
|
||
|
resolvedCallto->set_qualifiedName( url );
|
||
|
resolvedCallto->set_confidence( S_CONFIDENCE_HIGH );
|
||
|
result = S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
result = E_OUTOFMEMORY;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
emailAddress = url + strlen_literal( TEXT( "callto:" ) );
|
||
|
|
||
|
if( (StrChr( emailAddress, ':' ) == NULL) && // isn't some other type:...
|
||
|
(StrChr( emailAddress, ' ' ) == NULL) && // doesn't contain spaces...
|
||
|
(StrChr( emailAddress, '|' ) == NULL) && // doesn't contain a bar (gateway)...
|
||
|
(StrChr( emailAddress, '/' ) == NULL) && // isn't an old style ilsserver/email...
|
||
|
((StrChr( emailAddress, '.' ) == NULL) || // doesn't have a dot unless it also
|
||
|
(StrChr( emailAddress, '@' ) != NULL)) ) // has a @ so it can't be an ip address...
|
||
|
{
|
||
|
// It smells like an email address...
|
||
|
result = E_OUTOFMEMORY;
|
||
|
|
||
|
TCHAR * buffer = new TCHAR [ lstrlen( emailAddress ) + strlen_literal( TEXT( "callto:email:%s" ) ) ];
|
||
|
|
||
|
if( buffer != NULL )
|
||
|
{
|
||
|
ICallto * const resolvedCallto = calltoCollection->get_nextUnused();
|
||
|
|
||
|
if( resolvedCallto != NULL )
|
||
|
{
|
||
|
wsprintf( buffer, TEXT( "callto:email:%s" ), emailAddress );
|
||
|
resolvedCallto->set_qualifiedName( buffer );
|
||
|
resolvedCallto->set_confidence( S_CONFIDENCE_MEDIUM );
|
||
|
|
||
|
result = S_OK;
|
||
|
}
|
||
|
|
||
|
delete [] buffer;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return( result );
|
||
|
|
||
|
} // End of CEMailResolver::resolve.
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------------------//
|
||
|
// CIPResolver::resolve. //
|
||
|
//--------------------------------------------------------------------------//
|
||
|
HRESULT
|
||
|
CIPResolver::resolve
|
||
|
(
|
||
|
IMutableCalltoCollection * const calltoCollection,
|
||
|
TCHAR * const url
|
||
|
){
|
||
|
HRESULT result = E_INVALIDARG;
|
||
|
|
||
|
if( (calltoCollection != NULL) && (url != NULL) )
|
||
|
{
|
||
|
TCHAR * ipType;
|
||
|
TCHAR * ipAddress = NULL;
|
||
|
|
||
|
result = S_FALSE;
|
||
|
|
||
|
if( StrCmpNI_literal( url, TEXT( "callto:ip:" ) ) ) // Check for ip type without gateway...
|
||
|
{
|
||
|
ipType = url;
|
||
|
ipAddress = url + strlen_literal( TEXT( "callto:ip:" ) );
|
||
|
}
|
||
|
else if( (ipType = StrStrI( url, TEXT( "|ip:" ) )) != NULL ) // Check for ip type with gateway...
|
||
|
{
|
||
|
ipAddress = ipType + strlen_literal( TEXT( "|ip:" ) );
|
||
|
}
|
||
|
|
||
|
if( (ipAddress != NULL) && CCalltoContext::isIPAddress( ipAddress ) )
|
||
|
{
|
||
|
// ip: type was specified for this callto:...
|
||
|
ICallto * const resolvedCallto = calltoCollection->get_nextUnused();
|
||
|
|
||
|
if( resolvedCallto != NULL )
|
||
|
{
|
||
|
resolvedCallto->set_qualifiedName( url );
|
||
|
resolvedCallto->set_confidence( S_CONFIDENCE_HIGH );
|
||
|
|
||
|
result = S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
result = E_OUTOFMEMORY;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ipAddress = url + strlen_literal( TEXT( "callto:" ) );
|
||
|
|
||
|
if( CCalltoContext::isIPAddress( ipAddress ) )
|
||
|
{
|
||
|
// It smells like an ip address...
|
||
|
ICallto * const resolvedCallto = calltoCollection->get_nextUnused();
|
||
|
|
||
|
if( resolvedCallto != NULL )
|
||
|
{
|
||
|
TCHAR buffer[ MAX_PATH ];
|
||
|
|
||
|
wsprintf( buffer, TEXT( "callto:ip:%s" ), ipAddress );
|
||
|
resolvedCallto->set_qualifiedName( buffer );
|
||
|
resolvedCallto->set_confidence( S_CONFIDENCE_MEDIUM );
|
||
|
|
||
|
result = S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
result = E_OUTOFMEMORY;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return( result );
|
||
|
|
||
|
} // End of CIPResolver::resolve.
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------------------//
|
||
|
// CComputerResolver::resolve. //
|
||
|
//--------------------------------------------------------------------------//
|
||
|
HRESULT
|
||
|
CComputerResolver::resolve
|
||
|
(
|
||
|
IMutableCalltoCollection * const calltoCollection,
|
||
|
TCHAR * const url
|
||
|
){
|
||
|
HRESULT result = E_INVALIDARG;
|
||
|
|
||
|
if( (calltoCollection != NULL) && (url != NULL) )
|
||
|
{
|
||
|
TCHAR * computerType;
|
||
|
TCHAR * hostName = NULL;
|
||
|
|
||
|
result = S_FALSE;
|
||
|
|
||
|
if( StrCmpNI_literal( url, TEXT( "callto:computer:" ) ) ) // Check for computer type without gateway...
|
||
|
{
|
||
|
computerType = url;
|
||
|
hostName = url + strlen_literal( TEXT( "callto:computer:" ) );
|
||
|
}
|
||
|
else if( (computerType = StrStrI( url, TEXT( "|computer:" ) )) != NULL ) // Check for computer type with gateway...
|
||
|
{
|
||
|
hostName = computerType + strlen_literal( TEXT( "|computer:" ) );
|
||
|
}
|
||
|
|
||
|
if( hostName != NULL )
|
||
|
{
|
||
|
// host: type was specified for this callto:...
|
||
|
ICallto * const resolvedCallto = calltoCollection->get_nextUnused();
|
||
|
|
||
|
if( resolvedCallto != NULL )
|
||
|
{
|
||
|
resolvedCallto->set_qualifiedName( url );
|
||
|
resolvedCallto->set_confidence( S_CONFIDENCE_HIGH );
|
||
|
|
||
|
result = S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
result = E_OUTOFMEMORY;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hostName = url + strlen_literal( TEXT( "callto:" ) );
|
||
|
|
||
|
TCHAR * slash = hostName;
|
||
|
|
||
|
// Remove any trailing /....
|
||
|
while( (slash = StrChr( slash, '/' )) != NULL )
|
||
|
{
|
||
|
if( slash[ 1 ] == '\0' )
|
||
|
{
|
||
|
slash[ 0 ] = '\0';
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
slash++;
|
||
|
}
|
||
|
|
||
|
if( (StrChr( hostName, ':' ) == NULL) && // isn't some other type:...
|
||
|
(StrChr( hostName, ' ' ) == NULL) && // doesn't contain spaces...
|
||
|
(StrChr( hostName, '|' ) == NULL) && // doesn't contain a bar (gateway)...
|
||
|
(StrChr( hostName, '/' ) == NULL) && // doesn't contain a slash (ils)...
|
||
|
(StrChr( hostName, '@' ) == NULL) ) // doesn't contain an @...
|
||
|
{
|
||
|
// It smells like a dns host name...
|
||
|
result = E_OUTOFMEMORY;
|
||
|
|
||
|
TCHAR * buffer = new TCHAR [ lstrlen( hostName ) + strlen_literal( TEXT( "callto:computer:%s" ) ) ];
|
||
|
|
||
|
if( buffer != NULL )
|
||
|
{
|
||
|
ICallto * const resolvedCallto = calltoCollection->get_nextUnused();
|
||
|
|
||
|
if( resolvedCallto != NULL )
|
||
|
{
|
||
|
wsprintf( buffer, TEXT( "callto:computer:%s" ), hostName );
|
||
|
resolvedCallto->set_qualifiedName( buffer );
|
||
|
resolvedCallto->set_confidence( StrCmpNI_literal( hostName, TEXT( "\\\\" ) )? S_CONFIDENCE_HIGH: S_CONFIDENCE_MEDIUM );
|
||
|
|
||
|
result = S_OK;
|
||
|
}
|
||
|
|
||
|
delete [] buffer;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return( result );
|
||
|
|
||
|
} // End of CComputerResolver::resolve.
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------------------//
|
||
|
// CILSResolver::resolve. //
|
||
|
//--------------------------------------------------------------------------//
|
||
|
HRESULT
|
||
|
CILSResolver::resolve
|
||
|
(
|
||
|
IMutableCalltoCollection * const calltoCollection,
|
||
|
TCHAR * const url
|
||
|
){
|
||
|
HRESULT result = E_INVALIDARG;
|
||
|
|
||
|
if( (calltoCollection != NULL) && (url != NULL) )
|
||
|
{
|
||
|
const TCHAR * ilsType;
|
||
|
const TCHAR * emailAddress = NULL;
|
||
|
|
||
|
result = S_FALSE;
|
||
|
|
||
|
if( StrCmpNI_literal( url, TEXT( "callto:ils:" ) ) ) // Check for ils type without gateway...
|
||
|
{
|
||
|
ilsType = url;
|
||
|
emailAddress = url + strlen_literal( TEXT( "callto:ils:" ) );
|
||
|
}
|
||
|
else if( (ilsType = StrStrI( url, TEXT( "|ils:" ) )) != NULL ) // Check for ils type with gateway...
|
||
|
{
|
||
|
emailAddress = ilsType + strlen_literal( TEXT( "|ils:" ) );
|
||
|
}
|
||
|
|
||
|
if( emailAddress != NULL )
|
||
|
{
|
||
|
// ils: type was specified for this callto:...
|
||
|
ICallto * const resolvedCallto = calltoCollection->get_nextUnused();
|
||
|
|
||
|
if( resolvedCallto != NULL )
|
||
|
{
|
||
|
resolvedCallto->set_qualifiedName( url );
|
||
|
resolvedCallto->set_confidence( S_CONFIDENCE_HIGH );
|
||
|
|
||
|
result = S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
result = E_OUTOFMEMORY;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
emailAddress = url + strlen_literal( TEXT( "callto:" ) );
|
||
|
|
||
|
if( (StrChr( emailAddress, ' ' ) == NULL) && // doesn't contain spaces...
|
||
|
(StrChr( emailAddress, '|' ) == NULL) && // doesn't contain a bar (gateway)...
|
||
|
(StrChr( emailAddress, '/' ) != NULL) ) // has a /...
|
||
|
{
|
||
|
// It smells like an ilsserver/emailaddress...
|
||
|
result = E_OUTOFMEMORY;
|
||
|
|
||
|
TCHAR * buffer = new TCHAR [ lstrlen( emailAddress ) + strlen_literal( TEXT( "callto:ils:%s" ) ) ];
|
||
|
|
||
|
if( buffer != NULL )
|
||
|
{
|
||
|
ICallto * const resolvedCallto = calltoCollection->get_nextUnused();
|
||
|
|
||
|
if( resolvedCallto != NULL )
|
||
|
{
|
||
|
wsprintf( buffer, TEXT( "callto:ils:%s" ), emailAddress );
|
||
|
resolvedCallto->set_qualifiedName( buffer );
|
||
|
resolvedCallto->set_confidence( S_CONFIDENCE_MEDIUM );
|
||
|
|
||
|
result = S_OK;
|
||
|
}
|
||
|
|
||
|
delete [] buffer;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return( result );
|
||
|
|
||
|
} // End of CILSResolver::resolve.
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------------------//
|
||
|
// CUnrecognizedTypeResolver::resolve. //
|
||
|
//--------------------------------------------------------------------------//
|
||
|
HRESULT
|
||
|
CUnrecognizedTypeResolver::resolve
|
||
|
(
|
||
|
IMutableCalltoCollection * const calltoCollection,
|
||
|
TCHAR * const url
|
||
|
){
|
||
|
HRESULT result = E_INVALIDARG;
|
||
|
|
||
|
if( (calltoCollection != NULL) && (url != NULL) )
|
||
|
{
|
||
|
TCHAR * type;
|
||
|
TCHAR * unrecognized = url + strlen_literal( TEXT( "callto:" ) );
|
||
|
TCHAR * gateway = NULL;
|
||
|
TCHAR * value = NULL;
|
||
|
|
||
|
result = S_FALSE;
|
||
|
|
||
|
if( ((type = StrChr( unrecognized, ':' )) != NULL) && // Check for a type, but not a known one...
|
||
|
(!StrCmpNI_literal( url, TEXT( "callto:phone:" ) )) && (StrStrI( url, TEXT( "|phone:" ) ) == NULL) && // isn't a phone: type...
|
||
|
(!StrCmpNI_literal( url, TEXT( "callto:email:" ) )) && (StrStrI( url, TEXT( "|email:" ) ) == NULL) && // isn't an email: type...
|
||
|
(!StrCmpNI_literal( url, TEXT( "callto:computer:" ) )) && (StrStrI( url, TEXT( "|computer:" ) ) == NULL) && // isn't a computer: type...
|
||
|
(!StrCmpNI_literal( url, TEXT( "callto:ils:" ) )) && (StrStrI( url, TEXT( "|ils:" ) ) == NULL) && // isn't an ils: type...
|
||
|
(!StrCmpNI_literal( url, TEXT( "callto:ip:" ) )) && (StrStrI( url, TEXT( "|ip:" ) ) == NULL) && // isn't an ip: type...
|
||
|
(!StrCmpNI_literal( url, TEXT( "callto:string:" ) )) && (StrStrI( url, TEXT( "|string:" ) ) == NULL) ) // isn't an string: type...
|
||
|
{
|
||
|
*type++ = NULL;
|
||
|
value = type;
|
||
|
|
||
|
if( (gateway = StrChr( url, '|' )) != NULL ) // Check for a gateway...
|
||
|
{
|
||
|
*gateway++ = NULL;
|
||
|
type = gateway;
|
||
|
gateway = unrecognized;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( value != NULL )
|
||
|
{
|
||
|
// Some unrecognized type was specified...
|
||
|
result = E_OUTOFMEMORY;
|
||
|
|
||
|
int length = strlen_literal( TEXT( "callto:|%s" ) ) + lstrlen( value );
|
||
|
|
||
|
if( gateway == NULL )
|
||
|
{
|
||
|
length += lstrlen( unrecognized );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
length += lstrlen( gateway ) + lstrlen( type );
|
||
|
}
|
||
|
|
||
|
TCHAR * buffer = new TCHAR [ length ];
|
||
|
|
||
|
if( buffer != NULL )
|
||
|
{
|
||
|
ICallto * const resolvedCallto = calltoCollection->get_nextUnused();
|
||
|
|
||
|
if( resolvedCallto != NULL )
|
||
|
{
|
||
|
if( gateway == NULL )
|
||
|
{
|
||
|
wsprintf( buffer, TEXT( "callto:%s:%s" ), unrecognized, value );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
wsprintf( buffer, TEXT( "callto:%s|%s:%s" ), gateway, type, value );
|
||
|
}
|
||
|
|
||
|
resolvedCallto->set_qualifiedName( buffer );
|
||
|
resolvedCallto->set_confidence( S_CONFIDENCE_LOW );
|
||
|
|
||
|
result = S_OK;
|
||
|
}
|
||
|
|
||
|
delete [] buffer;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return( result );
|
||
|
|
||
|
} // End of CUnrecognizedTypeResolver::resolve.
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------------------//
|
||
|
// CStringResolver::resolve. //
|
||
|
//--------------------------------------------------------------------------//
|
||
|
HRESULT
|
||
|
CStringResolver::resolve
|
||
|
(
|
||
|
IMutableCalltoCollection * const calltoCollection,
|
||
|
TCHAR * const url
|
||
|
){
|
||
|
HRESULT result = E_INVALIDARG;
|
||
|
|
||
|
if( (calltoCollection != NULL) && (url != NULL) )
|
||
|
{
|
||
|
TCHAR * stringType;
|
||
|
TCHAR * string = NULL;
|
||
|
|
||
|
result = S_FALSE;
|
||
|
|
||
|
if( StrCmpNI_literal( url, TEXT( "callto:string:" ) ) ) // Check for string type without gateway...
|
||
|
{
|
||
|
stringType = url;
|
||
|
string = url + strlen_literal( TEXT( "callto:string:" ) );
|
||
|
}
|
||
|
else if( (stringType = StrStrI( url, TEXT( "|string:" ) )) != NULL ) // Check for string type with gateway...
|
||
|
{
|
||
|
string = stringType + strlen_literal( TEXT( "|string:" ) );
|
||
|
}
|
||
|
|
||
|
if( string != NULL )
|
||
|
{
|
||
|
// string: type was specified for this callto:...
|
||
|
ICallto * const resolvedCallto = calltoCollection->get_nextUnused();
|
||
|
|
||
|
if( resolvedCallto != NULL )
|
||
|
{
|
||
|
resolvedCallto->set_qualifiedName( url );
|
||
|
resolvedCallto->set_confidence( S_CONFIDENCE_HIGH );
|
||
|
|
||
|
result = S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
result = E_OUTOFMEMORY;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
string = url + strlen_literal( TEXT( "callto:" ) );
|
||
|
|
||
|
if( StrChr( string, ':' ) == NULL )
|
||
|
{
|
||
|
// It doesn't have a type so set it to string...
|
||
|
result = E_OUTOFMEMORY;
|
||
|
TCHAR * slash;
|
||
|
TCHAR * buffer = new TCHAR [ lstrlen( string ) + strlen_literal( TEXT( "callto:%s|string:%s" ) ) ];
|
||
|
|
||
|
if( buffer != NULL )
|
||
|
{
|
||
|
ICallto * const resolvedCallto = calltoCollection->get_nextUnused();
|
||
|
|
||
|
if( resolvedCallto != NULL )
|
||
|
{
|
||
|
if( (slash = StrChr( string, '|' )) == NULL ) // Check for a gateway...
|
||
|
{
|
||
|
wsprintf( buffer, TEXT( "callto:string:%s" ), string );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*slash++ = NULL;
|
||
|
wsprintf( buffer, TEXT( "callto:%s|string:%s" ), string, slash );
|
||
|
}
|
||
|
|
||
|
resolvedCallto->set_qualifiedName( buffer );
|
||
|
resolvedCallto->set_confidence( S_CONFIDENCE_LOW );
|
||
|
|
||
|
result = S_OK;
|
||
|
}
|
||
|
|
||
|
delete [] buffer;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return( result );
|
||
|
|
||
|
} // End of CStringResolver::resolve.
|