Ejemplo n.º 1
0
// ToUnsigned
static bool ToUnsigned(
    const COpcString& cString, 
    ULong&            nValue,
    ULong             nMax, 
    ULong             nMin
)
{
    // extract base
    COpcText cText;
    COpcTextReader cReader(cString);

    UINT uBase = 10;

    cText.SetType(COpcText::Literal);
    cText.SetText(L"0x");
    cText.SetIgnoreCase();

    if (cReader.GetNext(cText))
    {
        uBase = 16;
    }

    // read unsigned value.
    return ToUnsigned(cReader.GetBuf(), nValue, nMax, nMin, uBase);
}
Ejemplo n.º 2
0
// CheckForDelim
bool COpcTextReader::CheckForDelim(COpcText& cToken, UINT uPosition)
{
    // check for new line delim.
    if (cToken.GetNewLineDelim())
    {
        if (m_szBuf[uPosition] == L'\n' || m_szBuf[uPosition] == L'\r')
        {
            cToken.SetNewLine();
            cToken.SetDelimChar(m_szBuf[uPosition]);
            return true;
        }
    }

    // check for one of the delim chars.
    LPCWSTR szDelims = cToken.GetDelims();
    UINT    uCount   = (szDelims != NULL)?wcslen(szDelims):0;

    for (UINT ii = 0; ii < uCount; ii++)
    {
        if (IsEqual(cToken, m_szBuf[uPosition], szDelims[ii]))
        {
            cToken.SetDelimChar(szDelims[ii]);
            return true;
        }
    }

    return false;
}
Ejemplo n.º 3
0
// FindDelimited
bool COpcTextReader::FindDelimited(COpcText& cToken)
{
    OPC_ASSERT(m_szBuf != NULL);
    OPC_ASSERT(m_uLength != 0);

    // skip leading whitespace
    UINT uPosition = SkipWhitespace(cToken);

    // check if there is still data left to read.
    if (uPosition >= m_uEndOfData)
    {
        return false;
    } 

    // read until a delimiter.
    for (UINT ii = uPosition; ii < m_uEndOfData; ii++)
    {
        // check if search halted.
        if (CheckForHalt(cToken, ii))
        {
            return false;
        }

        // check if delimiter found.
        if (CheckForDelim(cToken, ii))
        {
            // copy token - empty tokens are valid.
            CopyData(cToken, uPosition, ii);
            return true;
        }
    }

    // check for end of data - true if EOF is a delim.
    if (ii >= m_uEndOfData)
    {
        cToken.SetEof();
        
        if (cToken.GetEofDelim())
        {
            CopyData(cToken, uPosition, ii);
            return true;
        }
    }

    return false;
}
Ejemplo n.º 4
0
// FindLiteral
bool COpcTextReader::FindLiteral(COpcText& cToken)
{
    OPC_ASSERT(m_szBuf != NULL);
    OPC_ASSERT(m_uLength != 0);

    LPCWSTR szText  = cToken.GetText();
    UINT    uLength = (szText != NULL)?wcslen(szText):0; 

    // check for trivial case
    if (uLength == 0)
    {
        return false;
    }

    UINT uPosition = SkipWhitespace(cToken);

    // check if there is enough data.
    if (uLength > (m_uEndOfData - uPosition))
    {
        return false;
    }

    for (UINT ii = uPosition; ii < m_uEndOfData-uLength+1; ii++)
    {
        // check if search halted.
        if (CheckForHalt(cToken, ii))
        {
            return false;
        }

        // compare text at current position.
        if (IsEqual(cToken, m_szBuf+ii, szText, uLength))
        {
            CopyData(cToken, ii, ii+uLength);
            return true;
        }

        // stop search if leading unmatching characters are not ignored.
        if (!cToken.GetSkipLeading())
        {
            break;
        }
    }

    return false;
}
Ejemplo n.º 5
0
// ToSigned
static bool ToSigned(
    const COpcString& cString, 
    Long&             nValue,
    Long              nMax, 
    Long              nMin
)
{
    nValue = 0;
     
    // extract plus sign
    bool bSign = true;

    COpcText cText;
    COpcTextReader cReader(cString);

    cText.SetType(COpcText::Literal);
    cText.SetText(L"+");

    if (!cReader.GetNext(cText))
    {
        // extract minus sign
        cText.SetType(COpcText::Literal);
        cText.SetText(L"-");

        bSign = !cReader.GetNext(cText);
    }

    // read unsigned value.
    ULong uValue = 0;
    
    if (!ToUnsigned(cReader.GetBuf(), uValue, (bSign)?nMax:-nMin, 0, 10))
    {
        return false;
    }

    nValue = (Long)uValue;

    // apply sign.
    if (!bSign)
    {
        nValue = -nValue;
    }

    return true;
}
Ejemplo n.º 6
0
// Read
template<> bool OpcXml::Read(const COpcString& cString, Decimal& cValue)
{
    bool bResult = true;

    TRY
    {
        COpcText cText;
        COpcTextReader cReader(cString);

        // parse whole integer portion.
        cText.SetType(COpcText::Delimited);
        cText.SetDelims(L".");
        cText.SetEofDelim();

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

        // convert to signed integer.
        Long nValue = 0;

        if (!ToSigned(cText, nValue, MAX_DECIMAL, MIN_DECIMAL))
        {
            THROW_(bResult, false);
        }

        cValue.int64 = nValue*10000;
        
        if (cText.GetDelimChar() == L'.')
        {
            // parse decimal portion.
            cText.SetType(COpcText::Delimited);
            cText.SetEofDelim();

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

            // convert to unsigned integer.
            ULong uValue = 0;

            if (!ToUnsigned(cText, uValue, MAX_DEC_FRACTION, 0, 10))
            {
                THROW_(bResult, false);
            }

            cValue.int64 += (Long)uValue;
        }
    }
    CATCH
    {
        cValue.int64 = 0;
    }

    return bResult;
}
Ejemplo n.º 7
0
// ToReal
static bool ToReal(
    const COpcString& cString, 
    Double&           nValue, 
    Double            nMax, 
    Double            nMin
)
{
    bool bResult = true;

    TRY
    {
        // extract non-whitespace token.
        COpcText cText;
        COpcTextReader cReader(cString);

        cText.SetType(COpcText::NonWhitespace);
        cText.SetSkipLeading();

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

        // parse double with C runtime function.
        WCHAR* pzEnd = NULL;
        nValue = (Double)wcstod((LPCWSTR)(COpcString&)cText, &pzEnd);

        // check for error - all text must have been parsed.
        if (pzEnd == NULL || wcslen(pzEnd) != 0) 
        {
            THROW_(bResult, false);
        }

        // check limits.
        if (nValue > nMax && nValue < nMin) THROW_(bResult, false);
    }
    CATCH
    {
        nValue = 0;
    }

    return bResult;
}
Ejemplo n.º 8
0
// FindWhitespace
bool COpcTextReader::FindWhitespace(COpcText& cToken)
{
    OPC_ASSERT(m_szBuf != NULL);
    OPC_ASSERT(m_uLength != 0);

    UINT uPosition = 0;

    // skip leading non-whitespace
    if (cToken.GetSkipLeading())
    {
        for (UINT ii = 0; ii < m_uEndOfData; ii++)
        {
            if (CheckForHalt(cToken, ii))
            {
               return false;
            }

            if (iswspace(m_szBuf[ii]))
            {
               uPosition = ii;
               break;
            }
        }
    }

    // check if there is still data left to read.
    if (uPosition >= m_uEndOfData)
    {
        return false;
    } 

    // read until a non-whitespace.
    for (UINT ii = uPosition; ii < m_uEndOfData; ii++)
    {
        if (CheckForHalt(cToken, ii))
        {
            break;
        }

        if (!iswspace(m_szBuf[ii]))
        {
            break;
        }
    }

    // check for empty token
    if (ii == uPosition)
    {
        return false;
    }

    // copy token.
    CopyData(cToken, uPosition, ii);
    return true;
}
Ejemplo n.º 9
0
// IsEqual
static bool IsEqual(COpcText& cToken, WCHAR zValue1, WCHAR zValue2)
{
    if (cToken.GetIgnoreCase())
    {
        WCHAR z1 = (iswlower(zValue1))?towupper(zValue1):zValue1;
        WCHAR z2 = (iswlower(zValue2))?towupper(zValue2):zValue2;

        return (z1 == z2);
    }

    return (zValue1 == zValue2);
}
Ejemplo n.º 10
0
// IsEqual
static bool IsEqual(COpcText& cToken, LPCWSTR szValue1, LPCWSTR szValue2, UINT uSize = -1)
{
    if (szValue1 == NULL || szValue2 == NULL)
    {
        return (szValue1 == szValue2);
    }

    else if (uSize == -1 && cToken.GetIgnoreCase())
    {
        return (wcsicmp(szValue1, szValue2) == 0);
    }

    else if (uSize == -1)
    {
        return (wcscmp(szValue1, szValue2) == 0);
    }

    else if (cToken.GetIgnoreCase())
    {
        return (wcsnicmp(szValue1, szValue2, uSize) == 0);
    }
    
    return (wcsncmp(szValue1, szValue2, uSize) == 0);
}
Ejemplo n.º 11
0
// FindToken
bool COpcTextReader::FindToken(COpcText& cToken)
{
    OPC_ASSERT(m_szBuf != NULL);
    OPC_ASSERT(m_uLength != 0);

    switch (cToken.GetType())
    {
        case COpcText::Literal:       return FindLiteral(cToken);
        case COpcText::NonWhitespace: return FindNonWhitespace(cToken);
        case COpcText::Whitespace:    return FindWhitespace(cToken);
        case COpcText::Delimited:     return FindDelimited(cToken);
    }

    return false;
}
Ejemplo n.º 12
0
// ToDate
static bool ToDate(
    const COpcString& cString, 
    WORD&             wYear,
    WORD&             wMonth,
    WORD&             wDay
)
{
    bool bResult = true;

    TRY
    {
        COpcText cText;
        COpcTextReader cReader(cString);

        ULong uValue = 0;

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

        if (!cReader.GetNext(cText)) THROW_(bResult, false);
        if (!ToUnsigned(cText, uValue, MAX_YEAR, MIN_YEAR, 10)) THROW_(bResult, false);
        wYear = (WORD)uValue;

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

        if (!cReader.GetNext(cText)) THROW_(bResult, false);
        if (!ToUnsigned(cText, uValue, MAX_MONTH, MIN_MONTH, 10)) THROW_(bResult, false);
        wMonth = (WORD)uValue;

        // parse day field.
        cText.SetType(COpcText::Delimited);
        cText.SetEofDelim();

        if (!cReader.GetNext(cText)) THROW_(bResult, false);
        if (!ToUnsigned(cText, uValue, MAX_DAY, MIN_DAY, 10)) THROW_(bResult, false);
        wDay = (WORD)uValue;
    }
    CATCH
    {
        wYear  = 0;
        wMonth = 0;
        wDay   = 0;
    }

    return bResult;
}
Ejemplo n.º 13
0
// SkipWhitespace 
UINT COpcTextReader::SkipWhitespace(COpcText& cToken)
{
    if (!cToken.GetSkipWhitespace())
    {
        return 0;
    }

    for (UINT ii = 0; ii < m_uEndOfData; ii++)
    {
        if (CheckForHalt(cToken, ii) || !iswspace(m_szBuf[ii]))
        {
            return ii;
        }
    }

    return m_uEndOfData;
}
Ejemplo n.º 14
0
// ToOffset
static bool ToOffset(
    const COpcString& cString, 
	bool              bNegative,
    SHORT&            sMinutes
)
{
    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);
      
		sMinutes = (SHORT)uValue*60;

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

        if (!cReader.GetNext(cText)) THROW_(bResult, false);
        if (!ToUnsigned(cText, uValue, MAX_MINUTE, MIN_MINUTE, 10)) THROW_(bResult, false);
        
		sMinutes += (SHORT)uValue;

		// add sign.
		if (bNegative)
		{
			sMinutes = -sMinutes;
		}
    }
    CATCH
    {
        sMinutes = 0;
    }

    return bResult;
}
Ejemplo n.º 15
0
// CheckForHalt
bool COpcTextReader::CheckForHalt(COpcText& cToken, UINT uPosition)
{
    // check if max chars exceeded.
    if (cToken.GetMaxChars() > 0)
    {
        if (cToken.GetMaxChars() <= uPosition)
        {
            return false;
        }
    }

    // check for end of data - halts if EOF is not a delim.
    if (uPosition >= m_uEndOfData)
    {
        cToken.SetEof();
        return !cToken.GetEofDelim();
    }

    // check for one of halt characters.
    LPCWSTR szHaltChars = cToken.GetHaltChars();

    if (szHaltChars == NULL)
    {
        return false;
    }

    UINT uCount = wcslen(szHaltChars);

    for (UINT ii = 0; ii < uCount; ii++)
    {
        if (IsEqual(cToken, m_szBuf[uPosition], szHaltChars[ii]))
        {
            cToken.SetHaltChar(szHaltChars[ii]);
            return true;
        }
    }

    return false;
}
Ejemplo n.º 16
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;
}
Ejemplo n.º 17
0
// FindEnclosed
bool COpcTextReader::FindEnclosed(COpcText& cToken)
{
    OPC_ASSERT(m_szBuf != NULL);
    OPC_ASSERT(m_uLength != 0);
      
    WCHAR zStart = 0;
    WCHAR zEnd   = 0;
    cToken.GetBounds(zStart, zEnd);

    // skip leading whitespace
    UINT uPosition = SkipWhitespace(cToken);

    // check if there is still data left to read.
    if (uPosition >= m_uEndOfData)
    {
        return false;
    } 

    // read until finding the start delimiter,
    for (UINT ii = uPosition; ii < m_uEndOfData; ii++)
    {
        // check if search halted.
        if (CheckForHalt(cToken, ii))
        {
            return false;
        }

        // check for start character.
        if (IsEqual(cToken, m_szBuf[ii], zStart)) 
        {
            uPosition = ii;
            break;
        }
    }
    
    // check if there is still data left to read.
    if (ii >= m_uEndOfData)
    {
        return false;
    } 

    // read until finding the end delimiter,
    for (ii = uPosition+1; ii < m_uEndOfData; ii++)
    {
        // check if search halted.
        if (CheckForHalt(cToken, ii))
        {
            return false;
        }

        // check for end character.
        if (IsEqual(cToken, m_szBuf[ii], zStart)) 
        {
            // ignore if character is escaped.
            if (cToken.GetAllowEscape() && (uPosition < ii-1))
            {
                if (m_szBuf[ii-1] == L'\\')
                {
                    continue;
                }
            }

            // copy token - empty tokens are valid.
            CopyData(cToken, uPosition+1, ii);
            return true;
        }
    }

    return false;
}
Ejemplo n.º 18
0
// CopyData
void COpcTextReader::CopyData(COpcText& cToken, UINT uStart, UINT uEnd)
{
    cToken.CopyData(m_szBuf+uStart, uEnd-uStart);
    cToken.SetStart(uStart);
    cToken.SetEnd(uEnd-1);
}
Ejemplo n.º 19
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;
}
Ejemplo n.º 20
0
// Read
template<> bool OpcXml::Read(const COpcString& cString, DateTime& cValue)
{
    bool bResult = true;

    FILETIME cFileTime;

	// check for invalid date.
	if (cString.IsEmpty())
	{
		cValue = OpcMinDate();
		return true;
	}

    TRY
    {
        SYSTEMTIME cSystemTime; ZeroMemory(&cSystemTime, sizeof(cSystemTime));

        COpcText cText;
        COpcTextReader cReader(cString);

        // parse date fields.
        cText.SetType(COpcText::Delimited);
        cText.SetDelims(L"T");

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

        if (!ToDate(cText, cSystemTime.wYear, cSystemTime.wMonth, cSystemTime.wDay))
        {
            THROW_(bResult, false);
        }

        // parse time fields.
        cText.SetType(COpcText::Delimited);
        cText.SetDelims(L"Z-+");
        cText.SetEofDelim();

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

        bResult = ToTime(
            cText, 
            cSystemTime.wHour, 
            cSystemTime.wMinute, 
            cSystemTime.wSecond, 
            cSystemTime.wMilliseconds);

        if (!bResult)
        {
            THROW_(bResult, false);
        }

		// convert to a UTC file time.
		if (!SystemTimeToFileTime(&cSystemTime, &cFileTime))
		{
			THROW_(bResult, false);
		}

		if (cText.GetDelimChar() != _T('Z'))
		{
			// convert local system time to UTC file time.
			if (cText.GetEof())
			{
				FILETIME ftUtcTime;

				if (!OpcLocalTimeToUtcTime(cFileTime, ftUtcTime))
				{
					THROW_(bResult, false);
				}
				
				cFileTime = ftUtcTime;
			}

			// apply offset specified in the datetime string.
			else
			{
				bool bNegative = (cText.GetDelimChar() == _T('-'));

				// parse time fields.
				cText.SetType(COpcText::Delimited);
				cText.SetEofDelim();

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

				SHORT sMinutes = 0;

				bResult = ToOffset(
					cText, 
					bNegative,
					sMinutes);

				if (!bResult)
				{
					THROW_(bResult, false);
				}

				// apply timezone offset.
				LONGLONG llTime = OpcToInt64(cFileTime);

				llTime -= ((LONGLONG)sMinutes)*60*10000000;

				cFileTime = OpcToFILETIME(llTime);	
			}
		}
			
	    cValue = cFileTime;
    }
    CATCH
    {
        ZeroMemory(&cFileTime, sizeof(cFileTime));
        cValue = cFileTime;
    }

    return bResult;
}
Ejemplo n.º 21
0
// GetNext
bool COpcTextReader::GetNext(COpcText& cToken)
{
    // no more data to get - give up
    if (m_uEndOfData == 0)
    {
        return false;
    }

    // find the token
    if (!FindToken(cToken))
    {
        return false;
    }     

    // all done if token is not being extracted.
    if (cToken.GetNoExtract())
    {
        return true;
    }

    UINT uEndOfToken = cToken.GetEnd() + 1;
    UINT uDataLeft   = m_uEndOfData - uEndOfToken;
  
    // extract the delimiter if extracting token.

    // new line delimiter found.
    if (cToken.GetNewLine())
    {
        if (cToken.GetDelimChar() == _T('\r'))
        {
            uEndOfToken += 2;
            uDataLeft   -= 2;
        }

        else
        {
            uEndOfToken += 1;
            uDataLeft   -= 1;
        }
    }

    // specific delimiter found.
    else if (cToken.GetDelimChar() > 0 && !cToken.GetEof())
    {
        uEndOfToken++;
        uDataLeft--;
    }

    // move leftover data to the start of the buffer
    for (UINT ii = 0; ii < uDataLeft; ii++)
    {
        m_szBuf[ii] = m_szBuf[uEndOfToken+ii];
    }

    m_szBuf[ii]  = L'\0';
    m_uEndOfData = uDataLeft;

	// set EOF flag if no data left in buffer.
	if (m_uEndOfData == 0)
	{
		cToken.SetEof();
	}
    
    return true;
}