Logo Search packages:      
Sourcecode: libpodofo version File versions  Download package

EPdfDataType PoDoFo::PdfTokenizer::DetermineDataType ( const char *  pszToken,
EPdfTokenType  eType,
PdfVariant rVariant 
) [protected, inherited]

Determine the possible datatype of a token. Numbers, reals, bools or NULL values are parsed directly by this function and saved to a variant.

Returns:
the expected datatype

Definition at line 384 of file PdfTokenizer.cpp.

References PoDoFo::PdfError::DebugMessage(), PoDoFo::PdfRefCountedInputDevice::Device(), PoDoFo::ePdfDataType_Array, PoDoFo::ePdfDataType_Bool, PoDoFo::ePdfDataType_Dictionary, PoDoFo::ePdfDataType_HexString, PoDoFo::ePdfDataType_Name, PoDoFo::ePdfDataType_Null, PoDoFo::ePdfDataType_Number, PoDoFo::ePdfDataType_Real, PoDoFo::ePdfDataType_Reference, PoDoFo::ePdfDataType_String, PoDoFo::ePdfDataType_Unknown, PoDoFo::ePdfError_InvalidDataType, PoDoFo::PdfTokenizer::GetNextToken(), PoDoFo::PdfVariant::GetNumber(), PoDoFo::PdfTokenizer::m_doubleParser, PODOFO_RAISE_ERROR_INFO, PoDoFo::PdfTokenizer::QuequeToken(), and PoDoFo::PdfInputDevice::Tell().

Referenced by PoDoFo::PdfTokenizer::GetNextVariant(), and PoDoFo::PdfContentsTokenizer::ReadNext().

{
    if( eTokenType == ePdfTokenType_Token ) 
    {
        // check for the two special datatypes
        // null and boolean.
        // check for numbers
        if( strncmp( "null", pszToken, NULL_LENGTH ) == 0 )
        {
            rVariant = PdfVariant();
            return ePdfDataType_Null;
        }
        else if( strncmp( "true", pszToken, TRUE_LENGTH ) == 0 )
        {
            rVariant = PdfVariant( true );
            return ePdfDataType_Bool;
        }
        else if( strncmp( "false", pszToken, FALSE_LENGTH ) == 0 )
        {
            rVariant = PdfVariant( false );
            return ePdfDataType_Bool;
        }

        EPdfDataType eDataType = ePdfDataType_Number;
        const char*  pszStart  = pszToken;

        while( *pszStart )
        {
            if( *pszStart == '.' )
                eDataType = ePdfDataType_Real;
            else if( !(isdigit( static_cast<const unsigned char>(*pszStart) ) || *pszStart == '-' || *pszStart == '+' ) )
            {
                eDataType = ePdfDataType_Unknown;
                break;
            }
            
            ++pszStart;
        }

        if( eDataType == ePdfDataType_Real ) 
        {
            // DOM: strtod is locale dependend,
            //      do not use it
            //double dVal = strtod( pszToken, NULL );
            double dVal;

            m_doubleParser.clear(); // clear error state
            m_doubleParser.str( pszToken );
            if( !(m_doubleParser >> dVal) )
            {
                m_doubleParser.clear(); // clear error state
                PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDataType, pszToken );
            }

            rVariant = PdfVariant( dVal );
            return ePdfDataType_Real;
        }
        else if( eDataType == ePdfDataType_Number ) 
        {
#ifdef _WIN64
            rVariant = PdfVariant( static_cast<pdf_int64>(_strtoui64( pszToken, NULL, 10 )) );
#else
            rVariant = PdfVariant( static_cast<pdf_int64>(strtol( pszToken, NULL, 10 )) );
#endif
            // read another two tokens to see if it is a reference
            // we cannot be sure that there is another token
            // on the input device, so if we hit EOF just return
            // ePdfDataType_Number .
            EPdfTokenType eSecondTokenType;
            bool gotToken = this->GetNextToken( pszToken, &eSecondTokenType );
            if (!gotToken)
                // No next token, so it can't be a reference
                return eDataType;
            if( eSecondTokenType != ePdfTokenType_Token ) 
            {
                this->QuequeToken( pszToken, eSecondTokenType );
                return eDataType;
            }
            
            
            pszStart = pszToken;
#ifdef _WIN64            
            pdf_long  l   = _strtoui64( pszStart, const_cast<char**>(&pszToken), 10 );
#else
            long  l   = strtol( pszStart, const_cast<char**>(&pszToken), 10 );
#endif
            if( pszToken == pszStart ) 
            {
                this->QuequeToken( pszStart, eSecondTokenType );
                return eDataType;
            }

            std::string backup( pszStart );
            EPdfTokenType eThirdTokenType;
            gotToken = this->GetNextToken( pszToken, &eThirdTokenType );
            if (!gotToken)
                // No third token, so it can't be a reference
                return eDataType;
            if( eThirdTokenType == ePdfTokenType_Token &&
                pszToken[0] == 'R' && pszToken[1] == '\0' )
            {
                rVariant = PdfReference( static_cast<unsigned int>(rVariant.GetNumber()), 
                                         static_cast<const pdf_uint16>(l) );
                return ePdfDataType_Reference;
            }
            else
            {
                this->QuequeToken( backup.c_str(), eSecondTokenType );
                this->QuequeToken( pszToken, eThirdTokenType );
                return eDataType;
            }
        } 
    }
    else if( eTokenType == ePdfTokenType_Delimiter ) 
    {
        if( strncmp( "<<", pszToken, DICT_SEP_LENGTH ) == 0 )
            return ePdfDataType_Dictionary;
        else if( pszToken[0] == '[' )
            return ePdfDataType_Array;
        else if( pszToken[0] == '(' )
            return ePdfDataType_String;
        else if( pszToken[0] == '<' ) 
            return ePdfDataType_HexString;
        else if( pszToken[0] == '/' )
            return ePdfDataType_Name;
    }

    if( false ) 
    {
        std::ostringstream ss;
#if defined(_MSC_VER)  &&  _MSC_VER <= 1200
        ss << "Got unexpected PDF data in" << __FILE__ << ", line " << __LINE__
#else
        ss << "Got unexpected PDF data in" << PODOFO__FUNCTION__
#endif
           << ": \""
           << pszToken
           << "\". Current read offset is "
           << m_device.Device()->Tell()
           << " which should be around the problem.\n";
        PdfError::DebugMessage(ss.str().c_str());
    }

    return ePdfDataType_Unknown;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Generated by  Doxygen 1.6.0   Back to index