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

📄 dialplanparser.cpp

📁 一个WinCE6。0下的IP phone的源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        *pEnabled = false;
        return E_INVALIDARG;
    }
}

/*------------------------------------------------------------------------------
    DialPlanParser_t::ValidateRegularExpressionAttribute

    Validates a regular expression attribute

    Parameters:
        : IN - const WCHAR* - The attribute's value
        : IN - int - The length of the value
        : OUT - BSTR* - The regular expression string

    Returns:
        - S_OK returned if is a valid regular expression
        - E_OUTOFMEMORY returned if allocation fails
        - Error code returned otherwise
------------------------------------------------------------------------------*/
HRESULT
DialPlanParser_t::ValidateRegularExpressionAttribute(
    const WCHAR *pAttributeValue,
    int AttributeValueLength,
    BSTR* pRegexString
    )
{
    HRESULT hr;
    ce::auto_bstr CopyOfRegexString;

    ASSERT(pRegexString);
    *pRegexString = NULL;

    CopyOfRegexString = SysAllocStringLen(pAttributeValue, AttributeValueLength);
    if (CopyOfRegexString == NULL)
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"OOM - Failed to allocate rule's regex string"));
        return E_OUTOFMEMORY;
    }

    // Validate regular expression
    hr = m_pIRegularExpressionParser->SetExpression(CopyOfRegexString);
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Invalid regular expression. Error 0x%08x -- ", hr));
        return hr;
    }

    *pRegexString = CopyOfRegexString.release();

    return S_OK;
}

/*------------------------------------------------------------------------------
    DialPlanParser_t::ValidateDialPlan

    Validates XML dial plan

    Parameters:
        : IN - BSTR - The element's name space URI

    Returns:
        - S_OK returned if no errors occur
        - Error code returned otherwise
------------------------------------------------------------------------------*/
HRESULT
DialPlanParser_t::ValidateDialPlan(
    BSTR DialPlanXML
    )
{
    HRESULT hr;

    if (DialPlanXML == NULL)
    {
        return E_INVALIDARG;
    }

    // Parse the XML (Validate only)
    hr = ProcessXML(DialPlanXML, TRUE);
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to parse custom dial plan. Error 0x%08x -- ", hr));
        return hr;
    }

    DebugDumpDialingRuleQueue(&m_NewDialingRules);
    DebugDumpAutoDialRuleQueue(&m_NewAutoDialRules); 

    // Discard any new rules that could have been created
    FlushNewRules(FlushOperationDiscard);

    return hr;
}

////////////////////////////////////////////////////////////////////////////////
// IUnknown

/*------------------------------------------------------------------------------
    DialPlanParser_t::AddRef

    IUnknown::AddRef - adds a reference to the object
------------------------------------------------------------------------------*/
ULONG
DialPlanParser_t::AddRef(
    void
    )
{
    InterlockedIncrement(reinterpret_cast<LONG*>(&m_RefCount));
    PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_REFCOUNT, (L"New ref count: %d", m_RefCount));
    return m_RefCount;
}

/*------------------------------------------------------------------------------
    DialPlanParser_t::Release

    IUnknown::Release implementation
------------------------------------------------------------------------------*/
ULONG
DialPlanParser_t::Release(
    void
    )
{
    LONG cRet = InterlockedDecrement(reinterpret_cast<LONG*>(&m_RefCount));
    PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_REFCOUNT, (L"New ref count: %d", cRet));

    if (cRet == 0)
    {
        delete this;
    }

    return cRet;
}

/*------------------------------------------------------------------------------
    DialPlanParser_t::QueryInterface

    IUnknown::QueryInterface implementation
------------------------------------------------------------------------------*/
HRESULT
DialPlanParser_t::QueryInterface(
    REFIID riid, 
    void** ppvObject
    )
{
    if (! ppvObject)
    {
        return E_POINTER;
    }

    if (riid == IID_IUnknown)
    {
        *ppvObject = static_cast<IUnknown*>(this);
    }
    else if (riid == IID_ISAXContentHandler)
    {
        *ppvObject = static_cast<ISAXContentHandler*>(this);
    }
    else
    {
        *ppvObject = NULL;
        return E_NOINTERFACE;
    }

    static_cast<IUnknown*>(*ppvObject)->AddRef();
    return S_OK;
}

////////////////////////////////////////////////////////////////////////////////
// ISAXContentHandler methods

/*------------------------------------------------------------------------------
    DialPlanParser_t::characters

    Receives notification of character data

    Parameters:
        : IN - const wchar_t* - The character data
        : IN - int - The length of the character string

    Returns:
        - S_OK returned if no errors occur
        - E_FAIL returned if the parse operation should be aborted
------------------------------------------------------------------------------*/
HRESULT
DialPlanParser_t::characters(
    const wchar_t *pwchChars,
    int cchChars
    )
{
    ce::wstring CopyOfCharacters;

    if (DialPlanElementHost != m_ElementsStack.front())
    {
        // Ignore characters invoked for other elements
        return S_OK;
    }

    if (!CopyOfCharacters.append(pwchChars, cchChars))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"OOM - Failed to allocate Host string"));
        return E_OUTOFMEMORY;
    }

    // Remove spaces
    CopyOfCharacters.trim(sc_Spaces);

    // Store these characters in member variable
    if (!m_XMLTokens[DialPlanTokenHost].m_Value.append(CopyOfCharacters.get_buffer()))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"OOM - Failed to allocate Host string"));
        return E_OUTOFMEMORY;
    }
    return S_OK;
}

/*------------------------------------------------------------------------------
    DialPlanParser_t::endDocument

    Receives notification of the end of document

    Parameters:
        : none

    Returns:
        - S_OK returned if no errors occur
        - E_FAIL returned if the parse operation should be aborted
------------------------------------------------------------------------------*/
HRESULT
DialPlanParser_t::endDocument(
    void
    )
{
    // XML dial plan must have at least one valid dialing rule
    return (m_NewDialingRules.empty() ? E_FAIL : S_OK);
}

/*------------------------------------------------------------------------------
    DialPlanParser_t::endElement

    Receives notification of the end of an element

    Parameters:
        : IN - const wchar_t* - The element's name space URI
        : IN - int - The length for the namespace URI
        : IN - const wchar_t* - The element's local name string
        : IN - int - The length of the local name
        : IN - const wchar_t* - The QName (with prefix)
        : IN - int - The length of the QName
        : IN - ISAXAttributes* - The attributes attached to the element

    Returns:
        - S_OK returned if no errors occur
        - E_FAIL returned if the parse operation should be aborted
------------------------------------------------------------------------------*/
HRESULT
DialPlanParser_t::endElement(
    const wchar_t *pwchNamespaceUri,
    int cchNamespaceUri,
    const wchar_t *pwchLocalName,
    int cchLocalName,
    const wchar_t *pwchQName,
    int cchQName
    )
{
    HRESULT hr;
    DialPlanElement_e DialPlanElementType;

    TraceDialPlanElement(L"XML End of Element <%s>", pwchLocalName, cchLocalName);

    if (m_ElementsStack.empty())
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Unexpected XML End of Element"));
        return E_FAIL;
    }

    hr = GetElementType(pwchLocalName, cchLocalName, &DialPlanElementType);
    if (SUCCEEDED(hr))
    {
        hr = (DialPlanElementType == m_ElementsStack.front()) ? S_OK : E_FAIL;
        if (SUCCEEDED(hr))
        {
            m_ElementsStack.pop_front();
            ASSERT((DialPlanElementStart != DialPlanElementType) || m_ElementsStack.empty());
        }
    }

    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Invalid XML End of Element. Error 0x%08x -- ", hr));
    }

    return hr;
}

/*------------------------------------------------------------------------------
    DialPlanParser_t::startDocument

    Receives notification of the beginning of document

    Parameters:
        : none

    Returns:
        - S_OK returned if no errors occur
        - E_FAIL returned if the parse operation should be aborted
------------------------------------------------------------------------------*/
HRESULT
DialPlanParser_t::startDocument(
    void
    )
{
    // Before parsing the XML the state should be the following:
    // 1. No XML elements in the stack
    // 2. No new rules
    // 3. No auto dial rules
    if (!m_ElementsStack.empty() || !m_NewDialingRules.empty() || !m_NewAutoDialRules.empty())
    {
        ASSERT(0);
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Invalid parser state... cannot process XML"));
        return E_FAIL;
    }

    return S_OK;
}

/*------------------------------------------------------------------------------
    DialPlanParser_t::startElement

    Receives notification of the start of an element

    Parameters:
        : IN - const wchar_t* - The element's name space URI
        : IN - int - The length for the namespace URI
        : IN - const wchar_t* - The element's local name string
        : IN - int - The length of the local name
        : IN - const wchar_t* - The QName (with prefix)
        : IN - int - The length of the QName
        : IN - ISAXAttributes* - The attributes attached to the element

    Returns:
        - S_OK returned if no errors occur
        - E_FAIL returned if the parse operation should be aborted
------------------------------------------------------------------------------*/
HRESULT
DialPlanParser_t::startElement(
    const wchar_t *pwchNamespaceUri,
    int cchNamespaceUri,
    const wchar_t *pwchLocalName,
    int cchLocalName,
    const wchar_t *pwchQName,
    int cchQName,
    ISAXAttributes *pAttributes
    )
{
    HRESULT hr;
    DialPlanElement_e DialPlanElementType;

    TraceDialPlanElement(L"XML Start of Element <%s>", pwchLocalName, cchLocalName);

    hr = GetElementType(pwchLocalName, cchLocalName, &DialPlanElementType);
    if (FAILED(hr))
    {
        goto exit;
    }

    // Assume XML is malformed
    hr = E_FAIL;
    switch (DialPlanElementType)
    {
        case DialPlanElementStart:
            // Opening element must be at level 0
            if (m_ElementsStack.empty() &&
                (cchNamespaceUri == _countof(sc_NameSpaceURI)-1) &&
                (0 == PhoneAppUtilities_t::InvStrCmpNI(
                        sc_NameSpaceURI,
                        pwchNamespaceUri,
                        cchNamespaceUri
                        )))
            {
                hr = S_OK;
            }
            break;

        case DialPlanElementHeader:
        case DialPlanElementHost:
            if (IsXMLElementHierarchyValid(&sc_DialPlanElements[DialPlanElementType]))
            {
                hr = S_OK;
            }
            break;

        case DialPlanElementRule:
            // Rule element must be at level 1
            if (!IsXMLElementHierarchyValid(&sc_DialPlanElements[DialPlanElementType]))
            {
                break;
            }

            hr = ProcessDialingRule(pAttributes);
            if (FAILED(hr) && (hr != E_OUTOFMEMORY))
            {
                // Ignore this rule... but do not abort XML processing
                hr = S_OK;
            }
            break;

        case DialPlanElementAutoDial: 
            //AutoDial element must be at level 1
            if (!IsXMLElementHierarchyValid(&sc_DialPlanElements[DialPlanElementType]))
            {
                break; 
            }

            hr = ProcessAutoDial(pAttributes); 
            if (FAILED(hr) && (hr != E_OUTOFMEMORY))
            {
                // Ignore this rule.. but do not abort XML processing
                hr = S_OK; 
            }
            break; 

        default:
            ASSERT(UnknownElement == DialPlanElementType);
            break;
    }

exit:
    if (SUCCEEDED(hr))
    {
        if (!m_ElementsStack.push_front(DialPlanElementType))
        {
            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"OOM - Failed to push XML element into the stack"));
            hr = E_OUTOFMEMORY;
        }
    }
    else
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Invalid XML Start of Element. Error 0x%08x -- ", hr));
    }

    return hr;
}

⌨️ 快捷键说明

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