⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dialplanparser.cpp

📁 一个WinCE6。0下的IP phone的源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                    goto exit;
                }
                break;

            case DialingRuleAttributeDial:
            case DialingRuleAttributeDisplay:
            case DialingRuleAttributeTransfer:
            {
                TemplateAttribute_t sc_TemplateMappings[3] =
                {
                    {&ThisRule.m_DialString    , DRF_TYPE_DIAL_STRING     },
                    {&ThisRule.m_DisplayString , DRF_TYPE_DISPLAY_STRING  },
                    {&ThisRule.m_TransferString, DRF_TYPE_TRANSFER_STRING },
                };

                // Mapping assumes template-type attributes are grouped together in enum
                CASSERT(DialingRuleAttributeDisplay == (DialingRuleAttributeDial + 1));
                CASSERT(DialingRuleAttributeTransfer == (DialingRuleAttributeDisplay + 1));

                int i = static_cast<int>(RuleAttributeType - DialingRuleAttributeDial);
                ASSERT(i < _countof(sc_TemplateMappings));

                if ((m_Flags & VALIDATE_XML_ONLY) || (AttributeValueLength == 0))
                {
                    // No need to allocate
                    ThisRule.m_Flags |= sc_TemplateMappings[i].Flags;
                    break;
                }

                hr = DuplicateTemplateString(
                                pAttributeValue,
                                AttributeValueLength,
                                sc_TemplateMappings[i].pTemplate
                                );
                if (FAILED(hr))
                {
                    PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to duplicate rule's template(%d). Error 0x%08x -- ", i, hr));
                    goto exit;
                }
                ThisRule.m_Flags |= sc_TemplateMappings[i].Flags;
                break;
            }

            case DialingRuleAttributeRestrict:
                {
                    ce::wstring CopyOfCharacters;
                    const WCHAR* pNextOption = pAttributeValue;
                    int CharactersToRead = AttributeValueLength;
                    while (pNextOption && SUCCEEDED(hr))
                    {
                        const WCHAR *pOption = pNextOption;
                        int OptionIndex;

                        while ((CharactersToRead > 0) && (*pNextOption != L','))
                        {
                            pNextOption++;
                            CharactersToRead--;
                        }

                        // Make a copy of the current option
                        if (!CopyOfCharacters.assign(pOption, (pNextOption - pOption)))
                        {
                            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"OOM - Failed to allocate restrict option"));

                            // break out of this loop
                            hr = E_OUTOFMEMORY;
                            break;
                        }

                        // Remove any spaces it could have
                        CopyOfCharacters.trim(sc_Spaces);

                        CASSERT(UnknownOption == _countof(sc_RestrictOptions));
                        CASSERT(DRF_RESTRICT_OPTION_VOIP == (DRF_RESTRICT_OPTION_VOIP << RestrictOptionVoIP));
                        CASSERT(DRF_RESTRICT_OPTION_CELL == (DRF_RESTRICT_OPTION_VOIP << RestrictOptionCell));
                        CASSERT(DRF_RESTRICT_OPTION_SMS == (DRF_RESTRICT_OPTION_VOIP << RestrictOptionSMS));

                        OptionIndex = FindString(
                                        CopyOfCharacters.get_buffer(),
                                        CopyOfCharacters.length(),
                                        sc_RestrictOptions,
                                        _countof(sc_RestrictOptions)
                                        );
                        switch (OptionIndex)
                        {
                            case RestrictOptionVoIP:
                            case RestrictOptionCell:
                            case RestrictOptionSMS:
                                if (ThisRule.m_Flags & (DRF_RESTRICT_OPTION_VOIP << OptionIndex))
                                {
                                    // Do not allow invalid syntax (duplicated option)
                                    hr = E_UNEXPECTED;
                                }
                                else
                                {
                                    // Enable the restriction
                                    ThisRule.m_Flags |= (DRF_RESTRICT_OPTION_VOIP << OptionIndex);
                                }
                                break;

                            case RestrictOptionAll:
                                hr = (ThisRule.m_Flags & DRF_RESTRICT_OPTION_ALL) ? E_UNEXPECTED : S_OK;
                                ThisRule.m_Flags |= DRF_RESTRICT_OPTION_ALL;
                                break;

                            default:
                                ASSERT(UnknownOption == OptionIndex);
                                hr = E_INVALIDARG;
                                break;
                        }

                        // Skip over the separator; if there are no more characters to read
                        // then there is no next option
                        if (CharactersToRead > 0)
                        {
                            pNextOption++;
                            CharactersToRead--;
                        }
                        else
                        {
                            pNextOption = NULL;
                        }
                    }

                    if (FAILED(hr))
                    {
                        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Invalid restrict option(s). Error 0x%08x -- ", hr));
                        goto exit;
                    }
                }
                break;

            default:
                ASSERT(UnknownAttribute == RuleAttributeType);
                // Ignore unknown attribute
                break;
        }
    }

    // A rule must be defined by the regular expression and
    // should define at least another supported attribute    
    ASSERT((ThisRule.m_RegexString != NULL) && (ThisRule.m_Flags & DRF_ALL_FLAGS_MASK));

    pNewRule = new DialingRule_t();
    *pNewRule = ThisRule;

    if (!m_NewDialingRules.push_back(pNewRule))
    {
        delete pNewRule;
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"OOM - Failed to push rule into queue"));
        hr = E_OUTOFMEMORY;
    }

exit:
    if (FAILED(hr))
    {
        ThisRule.CleanUpDialingRule();
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Cannot process dialing rule. Error 0x%08x -- ", hr));
    }

    return hr;
}


/*------------------------------------------------------------------------------
    DialPlanParser_t::ProcessAutoDial

    Parses a auto dial 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::ProcessAutoDial(
    ISAXAttributes * pAttributes
    )
{
    HRESULT hr;
    AutoDialRule_t  ThisRule;
    AutoDialRule_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;
        AutoDialAttribute_e AutoDialAttributeType;

        hr = pAttributes->getLocalName(Index, &pAttributeName, &AttributeNameLength);
        if (FAILED(hr))
        {
            ASSERT(0);
            goto exit;
        }

        hr = GetAutoDialAttributeType(pAttributeName,AttributeNameLength, &AutoDialAttributeType);
        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 (AutoDialAttributeType)
        {
            case AutoDialAttributePrefix:                
                if (pAttributeValue != NULL)
                {
                    ThisRule.m_Prefix = SysAllocStringLen(pAttributeValue, AttributeValueLength);
                    if (ThisRule.m_Prefix == NULL)
                    {
                        hr = E_OUTOFMEMORY; 
                        goto exit; 
                    }
                    ThisRule.m_PrefixLength = AttributeValueLength; 
                }
                
                break; 
                
            case AutoDialAttributeLength: 
                if (pAttributeValue != NULL)
                {
                    hr = ConvertAttributeToNumber(pAttributeValue, AttributeValueLength, &ThisRule.m_TotalLength); 
                    if (FAILED(hr))
                    {
                        goto exit; 
                    }
                }
                
                break; 

            default:
                ASSERT(UnknownAutoDialAttribute == AutoDialAttributeType);
                // Ignore unknown attribute
                break;
        }
    }

    pNewRule = new AutoDialRule_t();
    *pNewRule = ThisRule;

    if (!m_NewAutoDialRules.push_back(pNewRule))
    {
        delete pNewRule;
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"OOM - Failed to push rule into queue"));
        hr = E_OUTOFMEMORY;
    }

exit:
    
    if (FAILED(hr))
    {
        ThisRule.CleanUpAutoDialRule(); 
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Cannot process dialing rule. Error 0x%08x -- ", hr));
    }

    return hr;
}


/*------------------------------------------------------------------------------
    DialPlanParser_t::ProcessXML

    Parses the XML and processes it at the same time

    Parameters:
        : IN - BSTR - The XML string for the dial plan

    Returns:
        - S_OK returned if no errors occur
        - Error code returned if the operation fails
------------------------------------------------------------------------------*/
HRESULT
DialPlanParser_t::ProcessXML(
    BSTR DialPlan,
    BOOL ValidateOnly
    )
{
    HRESULT hr;
    CComPtr<ISAXXMLReader> cpISAXReader;
    VARIANT varXML;

    VariantInit(&varXML);

    if ((m_Flags & PROCESSING_XML) || !(m_Flags & FLUSHED_NEW_RULES))
    {
        return E_FAIL;
    }

    m_Flags |= PROCESSING_XML;
    m_Flags &= ~FLUSHED_NEW_RULES;

    if (ValidateOnly)
    {
        m_Flags |= VALIDATE_XML_ONLY;
    }

    // Instantiate the SAX reader and add our event hook
    hr = cpISAXReader.CoCreateInstance(__uuidof(SAXXMLReader));
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Cannot co create the SAX XML reader. Error 0x%08x -- ", hr));
        goto exit;
    }

    hr = cpISAXReader->putContentHandler(this);
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Cannot register ContentHandler. Error 0x%08x -- ", hr));
        goto exit;
    }

    // Create regular expression parser once
    if (m_pIRegularExpressionParser == NULL)
    {
        hr = CreateRegularExpression(&m_pIRegularExpressionParser);
        if (FAILED(hr))
        {
            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to create Regex parser. Error 0x%08x -- ", hr));
            goto exit;
        }
    }

    static const WCHAR sc_FileScheme[] = L"file:\\\\";
    if (0 != PhoneAppUtilities_t::InvStrCmpNI(
                        DialPlan,
                        sc_FileScheme,
                        _countof(sc_FileScheme)-1
                        ))
    {
        varXML.vt = VT_BSTR;
        varXML.bstrVal = DialPlan;

        // Parse the XML and process it at the same time
        hr = cpISAXReader->parse(varXML);
    }
    else
    {
        // Parse XML from file and process it at the same time
        hr = cpISAXReader->parseURL(DialPlan);
    }

    // Always reset the stack
    m_ElementsStack.clear();
    // Clear token buffers
    m_XMLTokens[DialPlanTokenHost].m_Value.clear();

    if (m_pIRegularExpressionParser != NULL)
    {
        m_pIRegularExpressionParser->Release();
        m_pIRegularExpressionParser = NULL;
    }

exit:
    
    m_Flags &= ~(PROCESSING_XML | VALIDATE_XML_ONLY);

    if (FAILED(hr))
    {
        // Discard any new rules that could have been created
        FlushNewRules(FlushOperationDiscard);
    }

    return hr;
}

/*------------------------------------------------------------------------------
    DialPlanParser_t::ValidateBooleanAttribute

    Validates a boolean attribute

    Parameters:
        : IN - const WCHAR* - The attribute's value
        : IN - int - The length of the value
        : OUT - bool* - The attribute's boolean value

    Returns:
        - S_OK returned if is a valid boolen value
        - E_INVALIDARG returned otherwise
------------------------------------------------------------------------------*/
HRESULT
DialPlanParser_t::ValidateBooleanAttribute(
    const WCHAR *pAttributeValue,
    int AttributeValueLength,
    bool *pEnabled
    )
{
    static const WCHAR sc_BooleanValueTrue[] = L"true";
    static const WCHAR sc_BooleanValueFalse[] = L"false";

    ASSERT(pEnabled);

    if (((AttributeValueLength == 1) && (pAttributeValue[0] == L'1')) ||
        (AttributeValueLength == _countof(sc_BooleanValueTrue)-1) &&
        (0 == PhoneAppUtilities_t::InvStrCmpNI(sc_BooleanValueTrue, pAttributeValue, AttributeValueLength)))
    {
        *pEnabled = true;
        return S_OK;
    }
    else if (((AttributeValueLength == 1) && (pAttributeValue[0] == L'0')) ||
        (AttributeValueLength == _countof(sc_BooleanValueFalse)-1) &&
        (0 == PhoneAppUtilities_t::InvStrCmpNI(sc_BooleanValueFalse, pAttributeValue, AttributeValueLength)))
    {
        *pEnabled = false;
        return S_OK;
    }
    else
    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -