📄 dialplanparser.cpp
字号:
}
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_DIALRULES, (L"Total of %d auto-dial rules", pThisRules->size()));
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_DIALRULES, (L""));
#endif
}
/*------------------------------------------------------------------------------
DialPlanParser_t::DuplicateTemplateString
Duplicates a template string and replaces any token it may contain
Parameters:
: IN - const WCHAR* - The attribute's value
: IN - int - The length of the value
: OUT - BSTR* - The template string
Returns:
- S_OK returned if is a valid regular expression
- E_OUTOFMEMORY returned if allocation fails
- Error code returned otherwise
------------------------------------------------------------------------------*/
HRESULT
DialPlanParser_t::DuplicateTemplateString(
const WCHAR *pAttributeValue,
int AttributeValueLength,
BSTR* pTemplateString
)
{
ce::wistring CopyOfString;
int Position;
bool bDuplicateTemplateOnly;
bDuplicateTemplateOnly = true;
if (m_XMLTokens[DialPlanTokenHost].m_Value.empty())
{
// Nothing to replace, just duplicate string
goto exit;
}
if (!CopyOfString.append(pAttributeValue, AttributeValueLength))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"OOM - Failed to allocate template string"));
return E_OUTOFMEMORY;
}
Position = CopyOfString.find(m_XMLTokens[DialPlanTokenHost].m_pName);
if (Position == ce::wistring::npos)
{
// Nothing to replace, just duplicate string
goto exit;
}
bDuplicateTemplateOnly = false;
if (!CopyOfString.replace(
Position,
wcslen(m_XMLTokens[DialPlanTokenHost].m_pName),
m_XMLTokens[DialPlanTokenHost].m_Value.get_buffer()
))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"OOM - Failed to replace token in template string"));
return E_OUTOFMEMORY;
}
exit:
if (bDuplicateTemplateOnly)
{
*pTemplateString = SysAllocStringLen(pAttributeValue, AttributeValueLength);
}
else
{
*pTemplateString = SysAllocString(CopyOfString.get_buffer());
}
if (*pTemplateString == NULL)
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"OOM - Failed to allocate template string"));
return E_OUTOFMEMORY;
}
return S_OK;
}
/*------------------------------------------------------------------------------
DialPlanParser_t::FlushNewDialingRules
Flushes the new rules
FlushOperationTransfer - Transfer new rules to the passed
DialingRuleQueue.
FlushOperationDiscard - Throw away the new dialing rules
Parameters:
: IN - FlushOperation_e - one of the operations defined
: OUT - DialingRule_t* - Pointer to the queue receiving the dialing rules
: OUT - AutoDialRule_t* - Pointer to the queue receiving the autodial rules
Returns:
- (HRESULT) indicating success or failure
On all cases the new DialingRuleQueue will be empty and
the FLUSHED_NEW_RULES DialPlanParser_t's flag will be set
------------------------------------------------------------------------------*/
HRESULT
DialPlanParser_t::FlushNewRules(
FlushOperation_e Operation,
DialingRuleQueue* pDialingRuleQueue,
AutoDialRuleQueue* pAutoDialRuleQueue
)
{
HRESULT hr;
ASSERT(Operation <= FlushOperationLast);
ASSERT(!(m_Flags & FLUSHED_NEW_RULES) ||
(m_NewDialingRules.empty() && m_NewAutoDialRules.empty()));
if (Operation == FlushOperationTransfer)
{
if (pDialingRuleQueue != NULL)
{
// Release the current dialing rules
hr = CleanUpDialingRuleQueue(pDialingRuleQueue);
// Transfer new rules to the active DialingRuleQueue
while (!m_NewDialingRules.empty())
{
DialingRule_t *pNewRule = m_NewDialingRules.back();
if (!pDialingRuleQueue->push_front(pNewRule))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"OOM - Failed to push new dialing rule into queue"));
// Remove rules transferred so far
CleanUpDialingRuleQueue(pDialingRuleQueue);
// Discard remaining rules
CleanUpDialingRuleQueue(&m_NewDialingRules);
break;
}
m_NewDialingRules.pop_back();
}
}
else
{
// Discard the new dialing rules if user doesn't provide the target queue
CleanUpDialingRuleQueue(&m_NewDialingRules);
}
if (pAutoDialRuleQueue != NULL)
{
// Release the current auto dial rules
hr = CleanUpAutoDialRuleQueue(pAutoDialRuleQueue);
// Transfer new rules to the active DialingRuleQueue
while (!m_NewAutoDialRules.empty())
{
AutoDialRule_t *pNewRule = m_NewAutoDialRules.back();
if (!pAutoDialRuleQueue->push_front(pNewRule))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"OOM - Failed to push new auto-dial rule into queue"));
// Remove rules transferred so far
CleanUpAutoDialRuleQueue(pAutoDialRuleQueue);
// Discard remaining rules
CleanUpAutoDialRuleQueue(&m_NewAutoDialRules);
break;
}
m_NewAutoDialRules.pop_back();
}
}
else
{
// Discard the new auto dial rules if user doesn't provide the target queue
CleanUpAutoDialRuleQueue(&m_NewAutoDialRules);
}
hr = (pDialingRuleQueue->empty()) ? E_FAIL : S_OK; //there should be at least one valid dialing rule
}
else
{
// Discard the new dialing rules
CleanUpDialingRuleQueue(&m_NewDialingRules);
CleanUpAutoDialRuleQueue(&m_NewAutoDialRules);
hr = (m_NewDialingRules.empty() && m_NewAutoDialRules.empty()) ? S_OK : E_UNEXPECTED;
}
ASSERT(m_NewDialingRules.empty() && m_NewAutoDialRules.empty());
m_Flags |= FLUSHED_NEW_RULES;
return hr;
}
/*------------------------------------------------------------------------------
DialPlanParser_t::GetElementType
Gets the type of dial plan element
Parameters:
: IN - const WCHAR* - The element's name
: IN - int - The length of the name
: OUT - DialPlanElement_e* - The type of element
Returns:
- S_OK returned if no errors occur
- E_INVALIDARG returned if caller passed a NULL pointer
------------------------------------------------------------------------------*/
HRESULT
DialPlanParser_t::GetElementType(
const WCHAR *pElementName,
int ElementNameLength,
DialPlanElement_e *pElementType
)
{
int Index;
ASSERT(pElementType);
if (!pElementName)
{
return E_INVALIDARG;
}
CASSERT(UnknownElement == _countof(sc_DialPlanElements));
for (Index = 0; Index < _countof(sc_DialPlanElements); Index++)
{
if ((ElementNameLength == wcslen(sc_DialPlanElements[Index].m_pName)) &&
(0 == PhoneAppUtilities_t::InvStrCmpNI(
sc_DialPlanElements[Index].m_pName,
pElementName,
ElementNameLength
)))
{
// Found supported element
break;
}
}
ASSERT(Index <= UnknownElement);
*pElementType = static_cast<DialPlanElement_e>(Index);
return S_OK;
}
/*------------------------------------------------------------------------------
DialPlanParser_t::GetRuleAttributeType
Gets the type of rule attribute
Parameters:
: IN - const WCHAR* - The attribute's name
: IN - int - The length of the name
: OUT - DialingRuleAttribute_e* - The type of attribute
Returns:
- S_OK if no errors occur
- E_INVALIDARG returned if caller passed a NULL pointer
------------------------------------------------------------------------------*/
HRESULT
DialPlanParser_t::GetRuleAttributeType(
const WCHAR *pAttributeName,
int AttributeNameLength,
DialingRuleAttribute_e* pRuleAttributeType
)
{
int Index;
ASSERT(pRuleAttributeType);
if (!pAttributeName)
{
return E_INVALIDARG;
}
CASSERT(UnknownAttribute == _countof(sc_RuleAttributes));
Index = FindString(
pAttributeName,
AttributeNameLength,
sc_RuleAttributes,
_countof(sc_RuleAttributes)
);
ASSERT(Index <= UnknownAttribute);
*pRuleAttributeType = static_cast<DialingRuleAttribute_e>(Index);
return S_OK;
}
/*------------------------------------------------------------------------------
DialPlanParser_t::GetAutoDialAttributeType
Gets the type of auto dial attribute
Parameters:
: IN - const WCHAR* - The attribute's name
: IN - int - The length of the name
: OUT - AutoDialAttribute_e* - The type of attribute
Returns:
- S_OK if no errors occur
- E_INVALIDARG returned if caller passed a NULL pointer
------------------------------------------------------------------------------*/
HRESULT
DialPlanParser_t::GetAutoDialAttributeType(
const WCHAR *pAttributeName,
int AttributeNameLength,
AutoDialAttribute_e* pAutoDialAttributeType
)
{
int Index;
ASSERT(pAutoDialAttributeType);
if (!pAttributeName)
{
return E_INVALIDARG;
}
CASSERT(UnknownAutoDialAttribute == _countof(sc_AutoDialAttributes));
Index = FindString(
pAttributeName,
AttributeNameLength,
sc_AutoDialAttributes,
_countof(sc_AutoDialAttributes)
);
ASSERT(Index <= UnknownAttribute);
*pAutoDialAttributeType = static_cast<AutoDialAttribute_e>(Index);
return S_OK;
}
/*------------------------------------------------------------------------------
DialPlanParser_t::IsXMLElementHierarchyValid
Verifies hierarchy for an XMLElement_t
Parameters:
: IN - XMLElement_t* - The XML element to verify
Returns:
- true returned if both parent and depth level match the stack
- false returned otherwise
------------------------------------------------------------------------------*/
inline
bool
DialPlanParser_t::IsXMLElementHierarchyValid(
const XMLElement_t * pThisElement
)
{
return ((pThisElement->m_Level == m_ElementsStack.size()) &&
(pThisElement->m_Parent == m_ElementsStack.front()));
}
/*------------------------------------------------------------------------------
DialPlanParser_t::ProcessDialingRule
Parses a dialing rule element and processes it at the same time
Parameters:
: IN - ISAXAttributes* - The attributes of the rule
Returns:
- S_OK returned if no errors occur
- Error code returned otherwise
------------------------------------------------------------------------------*/
HRESULT
DialPlanParser_t::ProcessDialingRule(
ISAXAttributes * pAttributes
)
{
HRESULT hr;
DialingRule_t ThisRule;
DialingRule_t *pNewRule;
int NumberOfAttributes;
int Index;
if (pAttributes == NULL)
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Missing dialing rule attributes"));
return E_INVALIDARG;
}
hr = pAttributes->getLength(&NumberOfAttributes);
if (FAILED(hr) || (NumberOfAttributes < 2))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Missing dialing rule attributes. Error 0x%08x -- ", hr));
return hr;
}
// Reset rule's structure
memset(&ThisRule, 0, sizeof(ThisRule));
// Process the rule attributes
for (Index = 0; Index < NumberOfAttributes; Index++)
{
const wchar_t* pAttributeName;
const wchar_t* pAttributeValue;
int AttributeNameLength;
int AttributeValueLength;
DialingRuleAttribute_e RuleAttributeType;
hr = pAttributes->getLocalName(Index, &pAttributeName, &AttributeNameLength);
if (FAILED(hr))
{
ASSERT(0);
goto exit;
}
hr = GetRuleAttributeType(pAttributeName,AttributeNameLength, &RuleAttributeType);
if (FAILED(hr))
{
ASSERT(0);
goto exit;
}
hr = pAttributes->getValue(Index, &pAttributeValue, &AttributeValueLength);
if (FAILED(hr))
{
ASSERT(0);
goto exit;
}
TraceDialingRuleAttribute(
L"%s=%s",
pAttributeName,
AttributeNameLength,
pAttributeValue,
AttributeValueLength
);
switch (RuleAttributeType)
{
case DialingRuleAttributePattern:
hr = ValidateRegularExpressionAttribute(
pAttributeValue,
AttributeValueLength,
&ThisRule.m_RegexString
);
if (FAILED(hr))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Rule does not define regular expression. Error 0x%08x -- ", hr));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -