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

📄 dialplanparser.cpp

📁 一个WinCE6。0下的IP phone的源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
// 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 + -