📄 dialplanparser.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include "DialPlanParser.hpp"
#include "Debug.hpp"
#include "CommonFunctions.hpp"
//constants
const WCHAR DialPlanParser_t::sc_NameSpaceURI[] = L"http://schemas.microsoft.com/embedded/VoIP";
// DialPlanParser_t flags
const DWORD DialPlanParser_t::PROCESSING_XML = 0x00000001;
const DWORD DialPlanParser_t::VALIDATE_XML_ONLY = 0x00000002;
const DWORD DialPlanParser_t::FLUSHED_NEW_RULES = 0x00000004;
// Supported dial plan elements must match DialPlanElement_e enumeration
const DialPlanParser_t::XMLElement_t DialPlanParser_t::sc_DialPlanElements[] =
{
{L"DialPlan", DialPlanParser_t::UnknownElement, 0 }, // Opening
{L"DialPlan-Header", DialPlanParser_t::DialPlanElementStart, 1}, // Dial Plan Header
{L"Host", DialPlanParser_t::DialPlanElementHeader, 2}, // Host (sip:user@host)
{L"Rule", DialPlanParser_t::DialPlanElementStart, 1}, // Dial Plan "Rule" Elements
{L"AutoDial", DialPlanParser_t::DialPlanElementStart, 1}, // Dial Plan "AutoDial" Elements
};
// Supported rule attributes must match DialingRuleAttribute_e enumeration
const WCHAR* DialPlanParser_t::sc_RuleAttributes[] =
{
L"Pattern", // Regular expression which defines the rule
L"Dial", // String to dial (in terms of the groups defined by regex)
L"Display", // String to display (in terms of the groups defined by regex)
L"Transfer", // String to transfer (in terms of the groups defined by regex)
L"Restrict", // Does this rule has any restrictions?
};
// Supported restrict options must match RestrictOption_e enumeration
const WCHAR* DialPlanParser_t::sc_RestrictOptions[] =
{
L"VoIP", // Cannot make VoIP call for numbers matching this rule
L"Cell", // Cannot make Cell call for numbers matching this rule
L"SMS", // Cannot send SMS messages for numbers matching this rule
L"All", // All services are blocked for numbers matching this rule
};
const WCHAR* DialPlanParser_t::sc_AutoDialAttributes[] =
{
L"Prefix", // Prefix for this auto dial string
L"Length", // Length of the whole auto dial string
};
struct TemplateAttribute_t
{
BSTR* pTemplate;
WORD Flags;
};
// white-space character codes used by iswspace (0x09-0x0D or 0x20)
static const WCHAR sc_Spaces[] =
{
0x0009, // Horizontal tab
0x000A, // Line feed
0x000B, // Vertical tab
0x000C, // Form feed
0x000D, // Carriage return
0x0020, // Space
0x0000, // Null character
};
static
HRESULT
ConvertAttributeToNumber(
__in_ecount(AttributeValueLength) const WCHAR* pAttributeValue,
int AttributeValueLength,
__out unsigned int* pNumber
)
{
if (pAttributeValue == NULL ||
AttributeValueLength <= 0 ||
pNumber == NULL)
{
return E_INVALIDARG;
}
*pNumber = 0;
WCHAR* pCharacter = const_cast<WCHAR*>(pAttributeValue);
unsigned int Number = 0;
for (unsigned int Index = 0; Index < AttributeValueLength; Index++)
{
//return error if we see there are non-integer chars
if (pCharacter[Index]> L'9' || pCharacter[Index] < L'0')
{
return E_INVALIDARG;
}
Number = Number * 10 + (pCharacter[Index] - L'0');
}
*pNumber = Number;
return S_OK;
}
/*------------------------------------------------------------------------------
FindString
Returns the index of the lookup string in an array of strings
Parameters:
: IN - const WCHAR* - The lookup string
: IN - int - The length of the string
: IN - const WCHAR* []- The array of strings
: IN - int - The size of array
Returns:
- ArraySize returned if string was not found
- Index into ArrayOfStrings returned otherwise
------------------------------------------------------------------------------*/
static
int
FindString(
__in_ecount(LookupStringLength) const WCHAR *pLookupString,
int LookupStringLength,
__in_ecount(ArraySize)const WCHAR* ArrayOfStrings[],
int ArraySize
)
{
int Index;
for (Index = 0; Index < ArraySize; Index++)
{
if ((LookupStringLength == wcslen(ArrayOfStrings[Index])) &&
(0 == PhoneAppUtilities_t::InvStrCmpNI(
ArrayOfStrings[Index],
pLookupString,
LookupStringLength
)))
{
// Found lookup string
break;
}
}
return Index;
}
/*------------------------------------------------------------------------------
DialPlanParser_t::CreateDialPlanParser
Creates a new DialPlanParser_t object
Parameters:
: OUT - DialPlanParser_t** - Pointer to the new DialPlanParser_t object
Returns:
- S_OK returned if no errors occur
- E_INVALIDARG returned if caller passed a NULL pointer
- E_OUTOFMEMORY returned if allocation fails
------------------------------------------------------------------------------*/
HRESULT
DialPlanParser_t::CreateDialPlanParser(
DialPlanParser_t** ppNewDialPlanParser
)
{
DialPlanParser_t *pNewObject;
if (!ppNewDialPlanParser)
{
ASSERT(0);
return E_INVALIDARG;
}
*ppNewDialPlanParser = NULL;
pNewObject = new DialPlanParser_t();
if (! pNewObject)
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"OOM - could not create DialPlanParser_t object"));
return E_OUTOFMEMORY;
}
*ppNewDialPlanParser = pNewObject;
return S_OK;
}
/*------------------------------------------------------------------------------
DialPlanParser_t::DialPlanParser_t
Constructor
------------------------------------------------------------------------------*/
DialPlanParser_t::DialPlanParser_t(
)
{
// TRACE(ZONE_VOIP_CTOR);
m_RefCount = 1;
// No new rules created so far
m_Flags = FLUSHED_NEW_RULES;
m_pIRegularExpressionParser = NULL;
// Tokens to replace in a rule template
m_XMLTokens[DialPlanTokenHost].m_pName = L"$host$";
}
/*------------------------------------------------------------------------------
DialPlanParser_t::~DialPlanParser_t
Destructor
------------------------------------------------------------------------------*/
DialPlanParser_t::~DialPlanParser_t(
)
{
// TRACE(ZONE_VOIP_CTOR);
ASSERT(m_RefCount == 0);
if (!m_ElementsStack.empty())
{
ASSERT(0);
m_ElementsStack.clear();
}
if (m_pIRegularExpressionParser != NULL)
{
ASSERT(0);
m_pIRegularExpressionParser->Release();
}
// Discard any new rules that could have been created
FlushNewRules(FlushOperationDiscard);
}
/*------------------------------------------------------------------------------
DialPlanParser_t::CleanUpDialingRuleQueue
Cleans up a DialingRuleQueue
Parameters:
: IN - DialingRuleQueue* - The queue to be cleaned up
Returns:
- S_OK returned if the queue was succesfully cleaned up
- S_FALSE returned if the queue is already empty
- E_UNEXPECTED returned if errors occur
------------------------------------------------------------------------------*/
HRESULT
DialPlanParser_t::CleanUpDialingRuleQueue(
DialingRuleQueue* pThisRules
)
{
ASSERT(pThisRules);
if (pThisRules->empty())
{
return S_FALSE;
}
do
{
// Clean structure at the top
DialingRule_t *pRule = pThisRules->front();
pRule->CleanUpDialingRule();
delete pRule;
// Remove it from the queue
pThisRules->pop_front();
} while (pThisRules->size() != 0);
// This should never fail
return (pThisRules->empty() ? S_OK : E_UNEXPECTED);
}
/*------------------------------------------------------------------------------
DialPlanParser_t::CleanUpAutoDialRuleQueue
Cleans up a AutoDialRuleQueue
Parameters:
: IN - AutoDialRuleQueue* - The queue to be cleaned up
Returns:
- S_OK returned if the queue was succesfully cleaned up
- S_FALSE returned if the queue is already empty
- E_UNEXPECTED returned if errors occur
------------------------------------------------------------------------------*/
HRESULT
DialPlanParser_t::CleanUpAutoDialRuleQueue(
AutoDialRuleQueue* pThisRules
)
{
ASSERT(pThisRules);
if (pThisRules->empty())
{
return S_FALSE;
}
do
{
// Clean structure at the top
AutoDialRule_t *pRule = pThisRules->front();
pRule->CleanUpAutoDialRule();
delete pRule;
// Remove it from the queue
pThisRules->pop_front();
} while (pThisRules->size() != 0);
// This should never fail
return (pThisRules->empty() ? S_OK : E_UNEXPECTED);
}
/*------------------------------------------------------------------------------
DialPlanParser_t::DebugDumpDialingRuleQueue
[DEBUG] Dumps out the rules from a DialingRuleQueue
Parameters:
: IN - DialingRuleQueue* - The queue to dump
------------------------------------------------------------------------------*/
void
DialPlanParser_t::DebugDumpDialingRuleQueue(
DialingRuleQueue *pThisRules
)
{
#ifdef DEBUG
if (!pThisRules)
{
return;
}
DialingRuleQueue::iterator Item;
int Index;
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_DIALRULES, (L""));
for (
Item = pThisRules->begin(), Index = 1;
Item != pThisRules->end();
Item++, Index++
)
{
// PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_DIALRULES, (L"Dialing Rule %d: %s", Index, (*Item)->m_RegexString));
if ((*Item)->m_Flags & DRF_TYPE_DIAL_STRING)
{
PHONEAPP_DEBUGMSG(
ZONE_PHONEAPP_DIALRULES,
(L"\tTemplate for Dial string: %s", (*Item)->m_DialString)
);
}
if ((*Item)->m_Flags & DRF_TYPE_DISPLAY_STRING)
{
PHONEAPP_DEBUGMSG(
ZONE_PHONEAPP_DIALRULES,
(L"\tTemplate for Display string: %s", (*Item)->m_DisplayString)
);
}
if ((*Item)->m_Flags & DRF_TYPE_TRANSFER_STRING)
{
PHONEAPP_DEBUGMSG(
ZONE_PHONEAPP_DIALRULES,
(L"\tTemplate for Transfer string: %s", (*Item)->m_TransferString)
);
}
// Look for any restrictions
if ((*Item)->m_Flags & DRF_RESTRICT_OPTION_ALL)
{
ce::wstring Options;
if (DRF_RESTRICT_OPTION_ALL == ((*Item)->m_Flags & DRF_RESTRICT_OPTION_ALL))
{
Options.append(L" All");
}
else
{
if ((*Item)->m_Flags & DRF_RESTRICT_OPTION_VOIP)
{
Options.append(L" VoIP");
}
if ((*Item)->m_Flags & DRF_RESTRICT_OPTION_CELL)
{
Options.append(L" Cell");
}
if ((*Item)->m_Flags & DRF_RESTRICT_OPTION_SMS)
{
Options.append(L" SMS");
}
}
PHONEAPP_DEBUGMSG(
ZONE_PHONEAPP_DIALRULES,
(L"\tRestrict =%s", (const WCHAR*)Options.get_buffer())
);
}
}
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_DIALRULES, (L"Total of %d rules", pThisRules->size()));
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_DIALRULES, (L""));
#endif
}
/*------------------------------------------------------------------------------
DialPlanParser_t::DebugDumpAutoDialRuleQueue
[DEBUG] Dumps out the rules from an AutoDialRuleQueue
Parameters:
: IN - AutoDialRuleQueue* - The queue to dump
------------------------------------------------------------------------------*/
void
DialPlanParser_t::DebugDumpAutoDialRuleQueue(
AutoDialRuleQueue *pThisRules
)
{
#ifdef DEBUG
if (!pThisRules)
{
return;
}
AutoDialRuleQueue::iterator Item;
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_DIALRULES, (L""));
for (Item = pThisRules->begin(); Item != pThisRules->end(); Item++)
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_DIALRULES, (L"\tPrefix for this auto-dial rule: %s", (*Item)->m_Prefix));
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_DIALRULES, (L"\tLength of this auto-dial string is: %d \n", (*Item)->m_TotalLength));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -