skins/AknSkins/sdcsrc/SDCInput.cpp
author William Roberts <williamr@symbian.org>
Tue, 23 Mar 2010 16:09:27 +0000
branchSymbian3_Theme
changeset 35 838be9535c06
parent 0 05e9090e2422
child 32 d9c996538b26
permissions -rw-r--r--
Start integration branch for Symbian^3 Theme The theme has been built using Carbide.ui on S60 5th Edition using the N97 plugin The source code in sf/mw/uiresources/skins/Symbian/srcdata was used to generate the installable SIS file which lives in the group directory, but the aim here is to build the theme for delivery in the ROM (preferrably as the default theme). Running "sbs -b bld.inf -c winscw" should build cleanly and deliver a matched set of files which then show up in the Settings | Themes | General list. Attempting to install it produces "Theme Corrupted".

/*
* Copyright (c) 2003-2008 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  ?Description
*
*/


#include <string.h>
#include "SDCGlobals.h"
#include "SDCInput.h"

// Make std namespace available for compatibility
namespace std {}
using namespace std;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSDCInput::CSDCInput()
    {
    iLineNumber = -1;
    iFile = NULL;
    iHash = 0;
    }

CSDCInput::~CSDCInput()
    {
    if( iFile )
        {
        fclose( iFile );
        iFile = NULL;
        }
    }

//////////////////////////////////////////////////////////////////////
// Other methods
//////////////////////////////////////////////////////////////////////

void CSDCInput::Open( const char *aFilename )
    {
    iLineNumber = 1;
    iFile = fopen( aFilename, "rb" );
    if( !iFile ) throw CSDCException( ESDCFileOpenError, "Cannot open input file" );

    int testChar1, testChar2;
    testChar1 = fgetc( iFile );
    testChar2 = fgetc( iFile );
    if( (testChar1==EOF) || (testChar2==EOF) ) throw CSDCException( ESDCPrematureEOIError, "Unicode detection failed" );
    if( (testChar1==255) && (testChar2==254) )
        {
        iUnicode = true;
        }
    else
        {
        iUnicode = false;
        }

    if( !iUnicode )
        {
        if( fseek( iFile, 0, SEEK_SET ) ) throw CSDCException( ESDCSeekError, "Seek failed after Unicode detection" );
        }

    iFirstInLine = true;

    ReadNextChar();
    }

bool CSDCInput::NextToken()
    {
    return ParseToken( L" \t", L" \t\r\n" );
    }

bool CSDCInput::NextTokenAllowLF()
    {
    return ParseToken( L" \t\r\n", L" \t\r\n" );
    }

bool CSDCInput::NextStringToken()
    {
    wcscpy( iToken, L"" );

    while( wcschr( L" \t", iNextChar ) ) ReadNextChar();
    if( iNextChar != L'\"' ) throw CSDCException( ESDCParseError, "No opening quotation mark for string found" );

    bool escaped = false;
    wchar_t escapeToken[512];
    wcscpy( escapeToken, L"" );

    ReadNextChar();
    while( iNextChar != L'\"' )
        {
        if( (iNextChar==L'\n') || (iNextChar==L'\r') || (iNextChar==WEOF) ) throw CSDCException( ESDCParseError, "Unterminated string" );
        if( escaped )
            {
            if( iNextChar == L'>' )
                {
                escaped = false;
                wchar_t escapedCh = (wchar_t)ConvertToNumber( escapeToken );
                wcsncat( iToken, &escapedCh, 1 );
                wcscpy( escapeToken, L"" );
                }
            else
                {
                wcsncat( escapeToken, &iNextChar, 1 );
                }
            }
        else
            {
            if( iNextChar == L'<' )
                {
                escaped = true;
                }
            else
                {
                wcsncat( iToken, &iNextChar, 1 );
                }
            }
        ReadNextChar();
        }
    if( escaped ) throw CSDCException( ESDCParseError, "Unterminated escape in string" );
    ReadNextChar();

    return wcslen(iToken)>0?true:false;
    }

int CSDCInput::NextRawToken()
    {
    wcscpy( iToken, L"" );
    int count = 0;

    while( wcschr( L" \t", iNextChar ) ) ReadNextChar();
    if( iNextChar != L'[' ) throw CSDCException( ESDCParseError, "No opening [ for raw data found" );

    bool inData = false;
    wchar_t dataToken[512];
    wcscpy( dataToken, L"" );

    ReadNextChar();
    bool quit = false;
    while( !quit )
        {
        if( (iNextChar==L'\n') || (iNextChar==L'\r') || (iNextChar==WEOF) )
            throw CSDCException( ESDCParseError, "Unterminated raw data sequence, ] missing" );

        if( inData )
            {
            if( iNextChar == L' ' || iNextChar == L']')
                {
                inData = false;
                wchar_t data = (wchar_t)ConvertToNumber( dataToken );
                iToken[count] = data;
                wcscpy( dataToken, L"" );
                count++;
                }
            else
                {
                wcsncat( dataToken, &iNextChar, 1 );
                }
            }
        else
            {
            if( iNextChar != L' ' && iNextChar != L']')
                {
                inData = true;
                if( count+1 >= 512 )
                    throw CSDCException( ESDCParseError, "Raw data sequence too long, maximum is 512 items" );
                continue; // We need to skip that ReadNextChar because 0 is part of the number token
                }
            }

        if( iNextChar == L']' )
            {
            quit = true;
            // Because the next ReadNextChar is executed the trailing ] is
            // skipped.
            }

        ReadNextChar();
        }

    return count;
    }

int CSDCInput::ConvertToNumber( const wchar_t* aToken )
    {
    bool hexadecimal = false;
    if( _wcsnicmp( aToken, L"0x", 2 ) == 0 ) hexadecimal = true;

    int result = 0;
    const wchar_t *p = aToken;
    if( hexadecimal ) p = p+2;

    if( *p == 0 ) throw CSDCException( ESDCParseError, "Number token is empty" );

    bool negative = false;
    if( *p == L'-' )
        {
        negative = true;
        p = p+1;
        }

    while( *p )
        {
        if( hexadecimal )
            {
            result *= 16;
            if( (*p>=L'0') && (*p<=L'9') ) result += *p - L'0';
            else if( (*p>=L'A') && (*p<=L'F') ) result += *p - L'A' + 10;
            else if( (*p>=L'a') && (*p<=L'f') ) result += *p - L'a' + 10;
            else throw CSDCException( ESDCParseError, "Non-hexadecimal character in number token" );
            }
        else
            {
            result *= 10;
            if( (*p>=L'0') && (*p<=L'9') ) result += *p - L'0';
            else throw CSDCException( ESDCParseError, "Non-numeric character in number token" );
            }

        p = p+1;
        }

    if( negative ) result = 0-result;
    return result;
    }

void CSDCInput::ConvertToAscii( char* aTarget, const wchar_t* aSource )
    {
    int i = 0;
    while( true )
        {
        aTarget[i] = (char)aSource[i];
        if( !aSource[i] ) break;
        i++;
        }
    }

void CSDCInput::ConvertToAsciiWithCPPEscapes( char* aTarget, const wchar_t* aSource )
    {
    int srcI = 0;
    int trgI = 0;
    while( true )
        {
        char ch = (char)aSource[srcI++];
        if( !ch )
            {
            aTarget[trgI++] = ch;
            break;
            }

        switch( ch )
            {
            case '\\':
                aTarget[trgI++] = '\\';
                aTarget[trgI++] = '\\';
                break;
            default:
                aTarget[trgI++] = ch;
            }
        }
    }

TSDCColorDepth CSDCInput::ConvertToColorDepth( const wchar_t* aToken )
    {
    if( _wcsicmp( aToken, L"1" ) == 0) return ESDCColorDepth1;
    else if( _wcsicmp( aToken, L"2" ) == 0) return ESDCColorDepth2;
    else if( _wcsicmp( aToken, L"4" ) == 0) return ESDCColorDepth4;
    else if( _wcsicmp( aToken, L"8" ) == 0) return ESDCColorDepth8;
    else if( _wcsicmp( aToken, L"c4" ) == 0) return ESDCColorDepthC4;
    else if( _wcsicmp( aToken, L"c8" ) == 0) return ESDCColorDepthC8;
    else if( _wcsicmp( aToken, L"c12" ) == 0) return ESDCColorDepthC12;
    else if( _wcsicmp( aToken, L"c16" ) == 0) return ESDCColorDepthC16;
    else if( _wcsicmp( aToken, L"c24" ) == 0) return ESDCColorDepthC24;
    else if( _wcsicmp( aToken, L"c32" ) == 0) return ESDCColorDepthC32;
    throw CSDCException( ESDCParseError, "Unknown color depth parameter" );
    }

int CSDCInput::ConvertToLayer( const wchar_t* aToken )
    {
    if( _wcsicmp( aToken, L"none" ) == 0 ) return 0x0001;

    wchar_t buf[512];
    wcscpy( buf, aToken );

    wchar_t* p = wcsstr( buf, L"/" );
    if( !p ) throw CSDCException( ESDCParseError, "Slash expected in layer parameter" );
    *p = 0;
    p = p+1;

    int layer = ConvertToNumber( buf ) << 8;
    if( _wcsicmp( p, L"RGB" ) == 0 )
        {
        layer |= 0x02;
        }
    else if( _wcsicmp( p, L"A" ) == 0 )
        {
        layer |= 0x04;
        }
    else if( _wcsicmp( p, L"RGBA" ) == 0 )
        {
        layer |= 0x08;
        }
    else
        {
        throw CSDCException( ESDCParseError, "Unidentified layer specifier" );
        }

    return layer;
    }

bool CSDCInput::IsSvgFile( const wchar_t* aFilename )
    {
    int len = wcslen( aFilename );
    if( len<4 ) return false;

    const wchar_t* p = aFilename + len - 4;
    if( _wcsicmp( p, L".svg" ) == 0 )
        {
        return true;
        }
    return false;
    }

void CSDCInput::RawRead()
    {
    if( iUnicode )
        {
        iNextChar = fgetwc( iFile );
        }
    else
        {
        int ch = fgetc( iFile );
        if( ch == EOF )
            {
            iNextChar = WEOF;
            }
        else
            {
            iNextChar = ch;
            }
        }

    iHash += iNextChar;
    }

bool CSDCInput::ReadNextChar()
    {
    RawRead();

    if( iFirstInLine )
        {
        iFirstInLine = false;
        if( iNextChar == L'/' )
            {
            while( (iNextChar!=L'\n') && (iNextChar!=WEOF) ) RawRead();
            }
        }

    if( iNextChar == L'\n' )
        {
        iLineNumber++;
        iFirstInLine = true;
        }

    return iNextChar==WEOF?false:true;
    }

bool CSDCInput::ParseToken( const wchar_t* aSeparators, const wchar_t* aTerminators )
    {
    wcscpy( iToken, L"" );

    while( wcschr( aSeparators, iNextChar ) )
        {
        ReadNextChar();
        }
    if( iNextChar == WEOF ) return false;

    while( !wcschr( aTerminators, iNextChar ) )
        {
        if( iNextChar == WEOF ) break;

        wcsncat( iToken, &iNextChar, 1 );

        ReadNextChar();
        }

    return wcslen(iToken)>0?true:false;
    }

// End of file