예제 #1
0
// Find
COpcBrowseElement* COpcBrowseElement::Find(const COpcString& cPath)
{
    // remove leading separator - if it exists.
    COpcString cPrefix    = GetSeparator();
    COpcString cLocalPath = cPath;

    while (cLocalPath.Find(GetSeparator()) == 0)
    {
        cLocalPath = cLocalPath.SubStr(cPrefix.GetLength());
    }
    
    // recursively search children.
    OPC_POS pos = m_cChildren.GetHeadPosition();

    while (pos != NULL)
    {           
        COpcBrowseElement* pChild = m_cChildren.GetNext(pos);

        // check for a child with an exact name match.
        if (cLocalPath == pChild->m_cName)
        {
            return pChild;
        }

        // check if the path starts with the child name.
        COpcString cPrefix = pChild->m_cName + pChild->GetSeparator();

        // check for a child with an exact name match plus trailing separator.
        if (cLocalPath == cPrefix)
        {
            return pChild;
        }

        UINT uIndex = cLocalPath.Find(cPrefix);

        // search the child node if there is a match.
        if (uIndex == 0)
        {
            cLocalPath = cLocalPath.SubStr(cPrefix.GetLength());
            return pChild->Find(cLocalPath);
        }       
    }

    return NULL;
}
예제 #2
0
// ToTime
static bool ToTime(
    const COpcString& cString, 
    WORD&             wHour,
    WORD&             wMinute,
    WORD&             wSeconds,
    WORD&             wFraction
)
{
    bool bResult = true;

    TRY
    {
        COpcText cText;
        COpcTextReader cReader(cString);

        ULong uValue = 0;

        // parse hour field.
        cText.SetType(COpcText::Delimited);
        cText.SetDelims(L":");

        if (!cReader.GetNext(cText)) THROW_(bResult, false);
        if (!ToUnsigned(cText, uValue, MAX_HOUR, MIN_HOUR, 10)) THROW_(bResult, false);
        wHour = (WORD)uValue;

        // parse month field.
        cText.SetType(COpcText::Delimited);
        cText.SetDelims(L":");

        if (!cReader.GetNext(cText)) THROW_(bResult, false);
        if (!ToUnsigned(cText, uValue, MAX_MINUTE, MIN_MINUTE, 10)) THROW_(bResult, false);
        wMinute = (WORD)uValue;

        // parse seconds field.
        cText.SetType(COpcText::Delimited);
        cText.SetDelims(L".");
        cText.SetEofDelim();

        if (!cReader.GetNext(cText)) THROW_(bResult, false);
        if (!ToUnsigned(cText, uValue, MAX_SECOND, MIN_SECOND, 10)) THROW_(bResult, false);
        wSeconds = (WORD)uValue;

        // parse seconds fraction field.
        wFraction = 0;

        if (cText.GetDelimChar() == L'.')
        {
            cText.SetType(COpcText::Delimited);
            cText.SetEofDelim();

            if (!cReader.GetNext(cText)) THROW_(bResult, false);

            // preprocess text.
            COpcString cFraction = cText;

            // add trailing zeros.
            while (cFraction.GetLength() < 3) cFraction += _T("0");

            // truncate extra digits.
            if (cFraction.GetLength() > 3) cFraction = cFraction.SubStr(0,3);

            if (!ToUnsigned(cFraction, uValue, MAX_ULONG, 0, 10))
            {
                THROW_(bResult, false);
            }

            // result is in milliseconds.
            wFraction = (WORD)uValue;
        }
    }
    CATCH
    {
        wHour     = 0;
        wMinute   = 0;
        wSeconds  = 0;
        wFraction = 0;
    }

    return bResult;
}
예제 #3
0
// ToUnsigned
static bool ToUnsigned(
    const COpcString& cString, 
    ULong&            nValue,
    ULong             nMax, 
    ULong             nMin, 
    UINT              uBase
)
{ 
    bool bResult = true;

    TRY
    {
        COpcText cText;
        COpcTextReader cReader(cString);

        // extract non-whitespace.
        cText.SetType(COpcText::NonWhitespace);
        cText.SetEofDelim();

        if (!cReader.GetNext(cText))
        {
            THROW_(bResult, false);
        }

        COpcString cValue = cText;

        nValue = 0;

        for (UINT ii = 0; ii < cValue.GetLength(); ii++)
        {
            UINT uDigit = CharToValue(cValue[ii], uBase);

            // invalid digit found.
            if (uDigit == -1) 
            {
                bResult = false;
                break;
            }

            // detect overflow
            if (nValue > nMax/uBase) THROW_(bResult, false);

            // shift result up by base.
            nValue *= uBase;

            // detect overflow
            if (nValue > nMax - uDigit) THROW_(bResult, false);

            // add digit.
            nValue += uDigit;
        }

        // detect underflow
        if (nMin > nValue) THROW_(bResult, false);
    }
    CATCH
    {
        nValue = 0;
    }

    return bResult;
}