diff -r 000000000000 -r 05e9090e2422 skins/AknSkins/sdcsrc/SDCReader.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/skins/AknSkins/sdcsrc/SDCReader.cpp Thu Dec 17 09:14:12 2009 +0200 @@ -0,0 +1,1542 @@ +/* +* 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: Reader class. +* +*/ + +#include "SDCGlobals.h" +#include "SDCReader.h" +#include "SDCIIDConstants.h" +#include "SDCException.h" + +// Make std namespace available for compatibility +namespace std {} +using namespace std; + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CSDCReader::CSDCReader( CSDCData* aData ) + { + iData = aData; + } + +CSDCReader::~CSDCReader() + { + } + +////////////////////////////////////////////////////////////////////// +// Other methods +////////////////////////////////////////////////////////////////////// + +void CSDCReader::Parse() + { + gInput.NextTokenAllowLF(); + if( _wcsicmp( gInput.iToken, L"SKINTYPE" ) != 0 ) UnexpectedTokenError( gInput.iToken, L"SKINTYPE" ); + ParseSkintype(); + + gInput.NextTokenAllowLF(); + if( _wcsicmp( gInput.iToken, L"UID" ) == 0 ) + { + ParseUID(); + gInput.NextTokenAllowLF(); + } + else if( _wcsicmp( gInput.iToken, L"PID" ) == 0 ) + { + ParsePID(); + gInput.NextTokenAllowLF(); + } + else + { + GeneratePID(); + } + + if( _wcsicmp( gInput.iToken, L"NAME" ) != 0 ) UnexpectedTokenError( gInput.iToken, L"NAME" ); + ParseName(); + + while( gInput.NextTokenAllowLF() ) + { + if( _wcsicmp( gInput.iToken, L"NAME" ) == 0 ) + { + ParseName(); + } + else if( _wcsicmp( gInput.iToken, L"LANGUAGEOVERRIDE" ) == 0 ) + { + ParseLanguageOverride(); + } + else if( _wcsicmp( gInput.iToken, L"LANGUAGEPARENT" ) == 0 ) + { + ParseParentUID(); + } + else if( _wcsicmp( gInput.iToken, L"PROTECT" ) == 0 ) + { + ParseProtect(); + } + else if( _wcsicmp( gInput.iToken, L"AUTHOR" ) == 0 ) + { + ParseAuthor(); + } + else if( _wcsicmp( gInput.iToken, L"COPYRIGHT" ) == 0 ) + { + ParseCopyright(); + } + else if( _wcsicmp( gInput.iToken, L"TARGETDEVICE" ) == 0 ) + { + ParseTargetDevice(); + } + else if( _wcsicmp( gInput.iToken, L"TOOL" ) == 0 ) + { + ParseTool(); + } + else if( _wcsicmp( gInput.iToken, L"BITMAP" ) == 0 ) + { + ParseBitmap(); + } + else if( _wcsicmp( gInput.iToken, L"COLORTABLE" ) == 0 ) + { + ParseColorTable(); + } + else if( _wcsicmp( gInput.iToken, L"FRAME" ) == 0 ) + { + ParseFrame(); + } + else if( _wcsicmp( gInput.iToken, L"BMPANIM" ) == 0 ) + { + ParseBmpAnim(); + } + else if( _wcsicmp( gInput.iToken, L"APPICON" ) == 0 ) + { + ParseAppIcon(); + } + else if( _wcsicmp( gInput.iToken, L"PALETTE" ) == 0 ) + { + ParsePalette(); + } + else if( (_wcsicmp( gInput.iToken, L"SOUND" ) == 0) + || (_wcsicmp( gInput.iToken, L"STRING" ) == 0) ) + { + ParseString(); + } + else if( _wcsicmp( gInput.iToken, L"SCALABLEITEM" ) == 0 ) + { + if( !iData->IsScalable() ) throw CSDCException( ESDCContentError, "SCALABLEITEM can only be included in scalable skins" ); + ParseScalableItem(); + } + else if( _wcsicmp( gInput.iToken, L"ANIMATION" ) == 0 ) + { + if( !iData->IsScalable() ) throw CSDCException( ESDCContentError, "ANIMATION can only be included in scalable skins" ); + ParseAnimation(); + } + else if( _wcsicmp( gInput.iToken, L"BITMAPPATH" ) == 0 ) + { + ParseBitmapPath(); + } + else if( _wcsicmp( gInput.iToken, L"RESTRICTION" ) == 0 ) + { + ParseRestriction(); + } + else + { + wprintf(L"DEBUG: Unknown token: \"%s\"\n", gInput.iToken ); + throw CSDCException( ESDCParseError, "Unknown token encountered or syntax error" ); + } + } + } + +void CSDCReader::ParseSkintype() + { + gInput.NextToken(); + + if( _wcsicmp( gInput.iToken, L"normal" ) == 0 ) + { + iData->iSkinType = 0x0; + } + else if( _wcsicmp( gInput.iToken, L"system" ) == 0 ) + { + iData->iSkinType = 0x1; + } + else if( _wcsicmp( gInput.iToken, L"scalable" ) == 0 ) + { +#if !defined( RD_ENHANCED_SKINNING ) + throw CSDCException( ESDCNotSupportedError, "Scalable skins not supported" ); +#endif + iData->iSkinType = 0x80; + return; // No other types are supported, if scalable + } + else + { + throw CSDCException( ESDCParseError, "Unknown or missing parameter for SKINTYPE" ); + } + + if( gInput.NextToken() ) + { + if( _wcsicmp( gInput.iToken, L"language=AH" ) == 0 ) + { + iData->iSkinType |= 0x102; + } + else + { + throw CSDCException( ESDCParseError, "Unknown or missing additional parameter for SKINTYPE" ); + } + } + } + +void CSDCReader::ParseUID() + { + gInput.NextToken(); + iData->iPid.iPID2 = 0; // Timestamp + iData->iPid.iPID1 = gInput.ConvertToNumber( gInput.iToken ); // UID + } + +void CSDCReader::ParsePID() + { + gInput.NextToken(); + iData->iPid.iPID2 = gInput.ConvertToNumber( gInput.iToken ); // Timestamp + + if( iData->iPid.iPID2 == 0 ) + { + throw CSDCException( ESDCParseError, "PID can not start with zero" ); + } + + gInput.NextToken(); + iData->iPid.iPID1 = gInput.ConvertToNumber( gInput.iToken ); // Random number + } + +void CSDCReader::GeneratePID() + { + iData->iPid.iPID2 = 0; + iData->iPid.iPID1 = 0; + } + +void CSDCReader::ParseName() + { + gInput.NextToken(); + int languageID = gInput.ConvertToNumber( gInput.iToken ); + + gInput.NextStringToken(); + iData->AppendNameEntry( languageID, gInput.iToken ); + } + +void CSDCReader::ParseLanguageOverride() + { + if( iData->IsScalable() ) + throw CSDCException( ESDCParseError, "Language override can not be used with scalable skins" ); + + gInput.NextToken(); + if( _wcsicmp( gInput.iToken, L"AH" ) != 0 ) + { + throw CSDCException( ESDCParseError, "Unknown or missing parameter for LANGUAGEOVERRIDE" ); + } + + gInput.NextToken(); + int value = gInput.ConvertToNumber( gInput.iToken ); + if( gInput.NextToken() ) + { + iData->iAHOverridePid.iPID1 = gInput.ConvertToNumber( gInput.iToken ); + iData->iAHOverridePid.iPID2 = value; + } + else + { + iData->iAHOverridePid.iPID2 = 0; + iData->iAHOverridePid.iPID1 = value; + } + } + +void CSDCReader::ParseParentUID() + { + if( iData->IsScalable() ) + throw CSDCException( ESDCParseError, "Parent UID can not be used with scalable skins" ); + + gInput.NextToken(); + int value = gInput.ConvertToNumber( gInput.iToken ); + if( gInput.NextToken() ) + { + iData->iParentPid.iPID1 = gInput.ConvertToNumber( gInput.iToken ); + iData->iParentPid.iPID2 = value; + } + else + { + iData->iParentPid.iPID2 = 0; + iData->iParentPid.iPID1 = value; + } + } + +void CSDCReader::ParseProtect() + { + gInput.NextToken(); + if( _wcsicmp( gInput.iToken, L"disablecopy" ) != 0 ) + { + throw CSDCException( ESDCParseError, "Unknown or missing parameter for PROTECT" ); + } + + iData->iProtection = 1; + } + +void CSDCReader::ParseAuthor() + { + gInput.NextStringToken(); + wcscpy( iData->iAuthor, gInput.iToken ); + } + +void CSDCReader::ParseCopyright() + { + gInput.NextStringToken(); + wcscpy( iData->iCopyright, gInput.iToken ); + } + +void CSDCReader::ParseTargetDevice() + { + gInput.NextStringToken(); + iData->AppendTargetDeviceEntry( gInput.iToken ); + } + +void CSDCReader::ParseTool() + { + gInput.NextStringToken(); + wcscpy( iData->iTool, gInput.iToken ); + } + +void CSDCReader::ParseBitmap() + { + gInput.NextToken(); + + bool appIcon = false; + if( _wcsicmp( gInput.iToken, L"CLASS=appicon" ) == 0 ) + { + appIcon = true; + gInput.NextToken(); + } + + int restriction( iData->iCurrentRestriction ); + const TSDCIIDEntry* iid = NULL; + if( _wcsnicmp( gInput.iToken, L"IID=", 4 ) == 0 ) + { + wchar_t iidBuf[512]; + wcscpy( iidBuf, gInput.iToken+4 ); + StripIIDPrefix( iidBuf, restriction ); + iid = SDCIIDConstants::FindPlain( iidBuf ); + if( !iid ) UnknownIIDError( gInput.iToken+4 ); + + gInput.NextToken(); + } + + TSDCColorDepth colorDepth = gInput.ConvertToColorDepth( gInput.iToken ); + + gInput.NextToken(); + if( !iid ) + { + iid = SDCIIDConstants::FindBmpName( gInput.iToken ); + if( !iid ) UnknownIIDError( gInput.iToken ); + } + + bool svg = CSDCInput::IsSvgFile( gInput.iToken ); + TSDCMBMEntry* mbmEntry = iData->AppendMbmEntry( svg, colorDepth, gInput.iToken ); + int mbmIndex = mbmEntry->iIndex; + + TSDCImageAttributes attributes; + attributes.iAttributeFlags = ESDCImageAttributeNone; + attributes.iCoordX = 0; + attributes.iCoordY = 0; + attributes.iSizeW = 0; + attributes.iSizeH = 0; + attributes.iAlignmentFlags = ESDCImageAlignNone; + + if( iData->IsScalable() ) { + attributes.iAttributeFlags |= ESDCImageAttributeNBC; + } + + int maskIndex = -1; + + while( gInput.NextToken() ) + { + if( _wcsnicmp( gInput.iToken, L"MASK=", 5 ) == 0 ) + { + if( svg ) throw CSDCException( ESDCParseError, "SVG icon can not have a named mask" ); + if( mbmEntry->iMaskColorDepth!=ESDCColorDepthNone ) + { + printf("NOTE: Mask already defined, second definition ignored (line %i)\n", gInput.iLineNumber ); + } + else + { + const wchar_t* maskFile = gInput.iToken+5; + mbmEntry->iMaskColorDepth = ESDCColorDepth1; + wcscpy( mbmEntry->iMaskSourceFilename, maskFile ); + } + maskIndex = mbmIndex+1; + } + else if( _wcsnicmp( gInput.iToken, L"SOFTMASK=", 9 ) == 0 ) + { + if( svg ) throw CSDCException( ESDCParseError, "SVG icon can not have a named mask" ); + if( mbmEntry->iMaskColorDepth!=ESDCColorDepthNone ) + { + printf("NOTE: Mask already defined, second definition ignored (line %i)\n", gInput.iLineNumber ); + } + else + { + const wchar_t* maskFile = gInput.iToken+9; + mbmEntry->iMaskColorDepth = ESDCColorDepth8; + wcscpy( mbmEntry->iMaskSourceFilename, maskFile ); + } + maskIndex = mbmIndex+1; + } + else if( _wcsicmp( gInput.iToken, L"MASK" ) == 0 ) + { + if( !svg ) throw CSDCException( ESDCParseError, "Non-SVG icon can not have an unnamed mask" ); + mbmEntry->iMaskColorDepth = ESDCColorDepth1; + maskIndex = mbmIndex+1; + } + else if( _wcsicmp( gInput.iToken, L"SOFTMASK" ) == 0 ) + { + if( !svg ) throw CSDCException( ESDCParseError, "Non-SVG icon can not have an unnamed mask" ); + mbmEntry->iMaskColorDepth = ESDCColorDepth8; + maskIndex = mbmIndex+1; + } + else + { + ProcessAttribute( attributes, gInput.iToken ); + } + } + + TSDCIID realIid; + realIid.iMajor = iid->iMajor; + realIid.iMinor = iid->iMinor; + iData->CreateBitmapDef( realIid, mbmIndex, maskIndex, attributes, appIcon, restriction ); + } + +void CSDCReader::ParseColorTable() + { + gInput.NextToken(); + + TSDCIID realIid; + int restriction( iData->iCurrentRestriction ); + if( _wcsnicmp( gInput.iToken, L"IID=", 4 ) == 0 ) + { + wchar_t iidBuf[512]; + wcscpy( iidBuf, gInput.iToken+4 ); + StripIIDPrefix( iidBuf, restriction ); + const TSDCIIDEntry* iid = SDCIIDConstants::FindPlain( iidBuf ); + if( !iid ) UnknownIIDError( gInput.iToken+4 ); + realIid.iMajor = iid->iMajor; + realIid.iMinor = iid->iMinor; + } + else + { + throw CSDCException( ESDCParseError, "IID parameter expected for COLORTABLE" ); + } + + vector colors; + + while( gInput.NextTokenAllowLF() ) + { + if( _wcsicmp( gInput.iToken, L"END" ) == 0 ) + { + iData->CreateColorTableDef( realIid, colors, restriction ); + return; + } + else if( _wcsnicmp( gInput.iToken, L"IDX=", 4 ) == 0 ) + { + TSDCColorTableEntry entry; + entry.iIndex = gInput.ConvertToNumber( gInput.iToken+4 ); + entry.iRgb = 0; + colors.push_back( entry ); + } + else if( _wcsnicmp( gInput.iToken, L"RGB=", 4 ) == 0 ) + { + TSDCColorTableEntry entry; + entry.iIndex = -1; + int rgb = gInput.ConvertToNumber( gInput.iToken+4 ); + // SymbianOS actually uses BGR order + entry.iRgb = + ((rgb&0xff)<<16) | (rgb&0xff00) | ((rgb&0xff0000)>>16); + colors.push_back( entry ); + } + else throw CSDCException( ESDCParseError, "Unknown token inside COLORTABLE" ); + } + + throw CSDCException( ESDCParseError, "No END token for COLORTABLE" ); + } + +void CSDCReader::ParseFrame() + { + gInput.NextToken(); + + TSDCIID realIid; + int restriction( iData->iCurrentRestriction ); + if( _wcsnicmp( gInput.iToken, L"IID=", 4 ) == 0 ) + { + wchar_t iidBuf[512]; + wcscpy( iidBuf, gInput.iToken+4 ); + StripIIDPrefix( iidBuf, restriction ); + const TSDCIIDEntry* iid = SDCIIDConstants::FindPlain( iidBuf ); + if( !iid ) UnknownIIDError( gInput.iToken+4 ); + realIid.iMajor = iid->iMajor; + realIid.iMinor = iid->iMinor; + } + else + { + throw CSDCException( ESDCParseError, "IID parameter expected for FRAME" ); + } + + vector elements; + + while( gInput.NextTokenAllowLF() ) + { + if( _wcsicmp( gInput.iToken, L"END" ) == 0) + { + iData->CreateFrameDef( realIid, elements, restriction ); + return; + } + else + { + elements.push_back( ParseBitmapSource( false, restriction ) ); + } + } + + throw CSDCException( ESDCParseError, "No END token for FRAME" ); + } + +void CSDCReader::ParseBmpAnim() + { + gInput.NextToken(); + + TSDCIID realIid; + int restriction( iData->iCurrentRestriction ); + if( _wcsnicmp( gInput.iToken, L"IID=", 4 ) == 0 ) + { + wchar_t iidBuf[512]; + wcscpy( iidBuf, gInput.iToken+4 ); + StripIIDPrefix( iidBuf, restriction ); + const TSDCIIDEntry* iid = SDCIIDConstants::FindPlain( iidBuf ); + if( !iid ) UnknownIIDError( gInput.iToken+4 ); + realIid.iMajor = iid->iMajor; + realIid.iMinor = iid->iMinor; + } + else + { + throw CSDCException( ESDCParseError, "IID parameter expected for BMPANIM" ); + } + + int interval = -1; + int playMode = 0; + int flash = 0; + bool svganim = false; + + while( gInput.NextToken() ) + { + if( _wcsnicmp( gInput.iToken, L"INTERVAL=", 9 ) == 0 ) + { + interval = gInput.ConvertToNumber( gInput.iToken+9 ); + } + else if( _wcsicmp( gInput.iToken, L"MODE=play" ) == 0 ) + { + playMode = 0; + } + else if( _wcsicmp( gInput.iToken, L"MODE=cycle" ) == 0 ) + { + playMode = 1; + } + else if( _wcsicmp( gInput.iToken, L"MODE=bounce" ) == 0 ) + { + playMode = 2; + } + else if( _wcsicmp( gInput.iToken, L"MODE=svganim" ) == 0 ) + { + playMode = 255; + svganim = true; + } + else if( _wcsicmp( gInput.iToken, L"FLASH" ) == 0 ) + { + flash = 1; + } + else + { + UnexpectedTokenError( gInput.iToken, L"" ); + } + } + + vector frames; + + int time = -1; + int posx = 0; + int posy = 0; + while( gInput.NextTokenAllowLF() ) + { + if( _wcsnicmp( gInput.iToken, L"TIME=", 5 ) == 0 ) + { + time = gInput.ConvertToNumber( gInput.iToken+5 ); + } + else if( _wcsnicmp( gInput.iToken, L"POS=", 4 ) == 0 ) + { + wchar_t buf[512]; + wcscpy( buf, gInput.iToken+4 ); + wchar_t* p = wcsstr( buf, L"," ); + if( !p ) throw CSDCException( ESDCParseError, "No comma found in POS parameter of BMPANIM" ); + *p = 0; + posx = gInput.ConvertToNumber( buf ); + posy = gInput.ConvertToNumber( p+1 ); + } + else if( _wcsicmp( gInput.iToken, L"END" ) == 0 ) + { + iData->CreateBmpAnimDef( realIid, interval, playMode, flash, frames, restriction ); + return; + } + else + { + TSDCIID frameIid = ParseBitmapSource( false, restriction, svganim ); + + TSDCBmpAnimFrame entry; + entry.iIID = frameIid; + entry.iTime = time; + entry.iPosX = posx; + entry.iPosY = posy; + frames.push_back( entry ); + time = -1; + posx = 0; + posy = 0; + } + } + + throw CSDCException( ESDCParseError, "No END token for BMPANIM" ); + } + +void CSDCReader::ParseAppIcon() + { + gInput.NextToken(); + int uid; + if( _wcsnicmp( gInput.iToken, L"UID=", 4 ) == 0 ) + { + uid = gInput.ConvertToNumber( gInput.iToken+4 ); + } + else + { + throw CSDCException( ESDCParseError, "UID parameter expected for APPICON" ); + } + + int restriction( iData->iCurrentRestriction ); + + vector iconBitmaps; + while( gInput.NextTokenAllowLF() ) + { + if( _wcsicmp( gInput.iToken, L"END" ) == 0) + { + TSDCIID realIid; + realIid.iMajor = EAknsMajorAppIcon; + realIid.iMinor = uid; + iData->CreateAppIconDef( realIid, iconBitmaps, restriction ); + return; + } + else + { + TSDCIID iconIid = ParseBitmapSource( true, restriction ); + iconBitmaps.push_back( iconIid ); + TSDCBitmapDef* bmpDef = iData->GetBitmapDef( iconIid ); + if( !bmpDef ) + { + printf( "WARNING: Application icon possibly uses a bitmap outside its class (line %i)\n", gInput.iLineNumber ); + } + else if( bmpDef->iAppIconBitmap == false ) + { + printf( "WARNING: Application icon uses a bitmap outside its class (line %i)\n", gInput.iLineNumber ); + } + } + } + + throw CSDCException( ESDCParseError, "No END token for APPICON" ); + } + +void CSDCReader::ParsePalette() + { + gInput.NextToken(); + if( _wcsnicmp( gInput.iToken, L"SCHEME=", 7 ) == 0 ) + { + iData->iPalettePid.iPID2 = 0; + iData->iPalettePid.iPID1 = gInput.ConvertToNumber( gInput.iToken+7 ); + } + else + { + throw CSDCException( ESDCParseError, "SCHEME parameter expected for PALETTE" ); + } + } + +void CSDCReader::ParseString() + { + gInput.NextToken(); + TSDCIID realIid; + int restriction( iData->iCurrentRestriction ); + if( _wcsnicmp( gInput.iToken, L"IID=", 4 ) == 0 ) + { + wchar_t iidBuf[512]; + wcscpy( iidBuf, gInput.iToken+4 ); + StripIIDPrefix( iidBuf, restriction ); + const TSDCIIDEntry* iid = SDCIIDConstants::FindPlain( iidBuf ); + if( !iid ) UnknownIIDError( gInput.iToken+4 ); + realIid.iMajor = iid->iMajor; + realIid.iMinor = iid->iMinor; + } + else + { + throw CSDCException( ESDCParseError, "IID parameter expected for SOUND/STRING" ); + } + + gInput.NextStringToken(); + iData->CreateStringDef( realIid, gInput.iToken, restriction ); + } + +void CSDCReader::ParseScalableItem() + { + gInput.NextToken(); + TSDCIID realIid; + int restriction( iData->iCurrentRestriction ); + if( _wcsnicmp( gInput.iToken, L"IID=", 4 ) == 0 ) + { + wchar_t iidBuf[512]; + wcscpy( iidBuf, gInput.iToken+4 ); + StripIIDPrefix( iidBuf, restriction ); + const TSDCIIDEntry* iid = SDCIIDConstants::FindPlain( iidBuf ); + if( !iid ) UnknownIIDError( gInput.iToken+4 ); + realIid.iMajor = iid->iMajor; + realIid.iMinor = iid->iMinor; + } + else + { + throw CSDCException( ESDCParseError, "IID parameter expected for SCALABLEITEM" ); + } + + gInput.NextToken(); + int input = 0; + if( _wcsnicmp( gInput.iToken, L"INPUT=", 6 ) == 0 ) + { + input = CSDCInput::ConvertToLayer( gInput.iToken+6 ); + } + else if( _wcsnicmp( gInput.iToken, L"REFIID=", 7 ) == 0 ) + { + // Reference only + TSDCIID refIid; + int ignored; + wchar_t iidBuf[512]; + wcscpy( iidBuf, gInput.iToken+7 ); + StripIIDPrefix( iidBuf, ignored ); + const TSDCIIDEntry* iid = SDCIIDConstants::FindPlain( iidBuf ); + if( !iid ) UnknownIIDError( gInput.iToken+7 ); + refIid.iMajor = iid->iMajor; + refIid.iMinor = iid->iMinor; + char buf[512]; + CSDCInput::ConvertToAscii( buf, gInput.iToken ); + if( !iData->IsDefined( refIid ) ) + { + printf( "INFO: IID reference (%s) currently points to non-existent element (line %i)\n", buf, gInput.iLineNumber ); + } + iData->CreateScalableItemRefDef( realIid, refIid, restriction ); + return; + } + else + { + throw CSDCException( ESDCParseError, "INPUT parameter expected for SCALABLEITEM" ); + } + + gInput.NextToken(); + int output = 0; + if( _wcsnicmp( gInput.iToken, L"OUTPUT=", 7 ) == 0 ) + { + output = CSDCInput::ConvertToLayer( gInput.iToken+7 ); + } + else + { + throw CSDCException( ESDCParseError, "OUTPUT parameter expected for SCALABLEITEM" ); + } + + vector commands; + while( gInput.NextTokenAllowLF() ) + { + if( _wcsicmp( gInput.iToken, L"END" ) == 0) + { + iData->CreateScalableItemDef( realIid, input, output, commands, restriction ); + return; + } + else if( _wcsicmp( gInput.iToken, L"EFFECT" ) == 0) + { + TSDCEffectCommand command; + ParseEffectCommand( command ); + commands.push_back( command ); + } + else + { + UnexpectedTokenError( gInput.iToken, L"EFFECT or END" ); + } + } + + throw CSDCException( ESDCParseError, "No END token for SCALABLEITEM" ); + } + +void CSDCReader::ParseAnimation() + { + gInput.NextToken(); + TSDCIID realIid; + int restriction( iData->iCurrentRestriction ); + if( _wcsnicmp( gInput.iToken, L"IID=", 4 ) == 0 ) + { + wchar_t iidBuf[512]; + wcscpy( iidBuf, gInput.iToken+4 ); + StripIIDPrefix( iidBuf, restriction ); + const TSDCIIDEntry* iid = SDCIIDConstants::FindPlain( iidBuf ); + if( !iid ) UnknownIIDError( gInput.iToken+4 ); + realIid.iMajor = iid->iMajor; + realIid.iMinor = iid->iMinor; + } + else + { + throw CSDCException( ESDCParseError, "IID parameter expected for ANIMATION" ); + } + + gInput.NextToken(); + int input = 0; + if( _wcsnicmp( gInput.iToken, L"INPUT=", 6 ) == 0 ) + { + input = CSDCInput::ConvertToLayer( gInput.iToken+6 ); + } + else + { + throw CSDCException( ESDCParseError, "INPUT parameter expected for ANIMATION" ); + } + + gInput.NextToken(); + int output = 0; + if( _wcsnicmp( gInput.iToken, L"OUTPUT=", 7 ) == 0 ) + { + output = CSDCInput::ConvertToLayer( gInput.iToken+7 ); + } + else + { + throw CSDCException( ESDCParseError, "OUTPUT parameter expected for ANIMATION" ); + } + + gInput.NextToken(); + int mininterval = 0; + if( _wcsnicmp( gInput.iToken, L"MININTERVAL=", 12 ) == 0 ) + { + mininterval = CSDCInput::ConvertToNumber( gInput.iToken+12 ); + } + else + { + throw CSDCException( ESDCParseError, "MININTERVAL parameter expected for ANIMATION" ); + } + + gInput.NextTokenAllowLF(); + + bool morphing = false; + if( _wcsicmp( gInput.iToken, L"MORPHING" ) == 0 ) + { + morphing = true; + + gInput.NextTokenAllowLF(); + } + + vector preprocessCommands; + if( _wcsicmp( gInput.iToken, L"PREPROCESS" ) == 0 ) + { + bool terminated( false ); + while( gInput.NextTokenAllowLF() ) + { + if( _wcsicmp( gInput.iToken, L"END" ) == 0) + { + terminated = true; + break; + } + else if( _wcsicmp( gInput.iToken, L"EFFECT" ) == 0) + { + TSDCEffectCommand command; + ParseEffectCommand( command ); + preprocessCommands.push_back( command ); + } + else + { + UnexpectedTokenError( gInput.iToken, L"EFFECT or END" ); + } + } + if( !terminated ) throw CSDCException( ESDCParseError, "No END token for ANIMATION/PREPROCESS" ); + + gInput.NextTokenAllowLF(); + } + + vector animCommands; + vector values; + vector timingModels; + vector sizeBoundParams; + + bool terminated( false ); + do + { + if( _wcsicmp( gInput.iToken, L"END" ) == 0) + { + terminated = true; + break; + } + else if( _wcsicmp( gInput.iToken, L"COMMAND" ) == 0) + { + TSDCEffectCommand command; + ParseEffectCommand( command ); + animCommands.push_back( command ); + } + else if( _wcsicmp( gInput.iToken, L"VALUE" ) == 0) + { + gInput.NextToken(); + if( _wcsnicmp( gInput.iToken, L"UID=", 4 ) ) + throw new CSDCException( ESDCParseError, "UID parameter expected for VALUE" ); + int uid = CSDCInput::ConvertToNumber( gInput.iToken+4 ); + + gInput.NextToken(); + if( _wcsnicmp( gInput.iToken, L"TIMINGID=", 9 ) ) + throw new CSDCException( ESDCParseError, "TIMINGID parameter expected for VALUE" ); + int timingId = CSDCInput::ConvertToNumber( gInput.iToken+9 ); + + TSDCAnimParamGroup paramGroup; + + while( gInput.NextTokenAllowLF() && _wcsicmp( gInput.iToken, L"END" ) ) + { + TSDCEffectParameter parameter; + ParseEffectParameter( parameter ); + paramGroup.iParameters.push_back( parameter ); + } + + paramGroup.iValueA = uid; + paramGroup.iValueB = timingId; + values.push_back( paramGroup ); + } + else if( _wcsicmp( gInput.iToken, L"TIMINGMODEL" ) == 0) + { + gInput.NextToken(); + if( _wcsnicmp( gInput.iToken, L"UID=", 4 ) ) + throw new CSDCException( ESDCParseError, "UID parameter expected for TIMINGMODEL" ); + int uid = CSDCInput::ConvertToNumber( gInput.iToken+4 ); + + TSDCAnimParamGroup paramGroup; + + while( gInput.NextTokenAllowLF() && _wcsicmp( gInput.iToken, L"END" ) ) + { + TSDCEffectParameter parameter; + ParseEffectParameter( parameter ); + paramGroup.iParameters.push_back( parameter ); + } + + paramGroup.iValueA = uid; + paramGroup.iValueB = 0; + timingModels.push_back( paramGroup ); + } + else if( _wcsicmp( gInput.iToken, L"SIZEBOUNDPARAM" ) == 0) + { + gInput.NextToken(); + TSDCEffectParameter parameter; + parameter.iType = 0; + wcscpy( parameter.iName, gInput.iToken ); + parameter.iNumber = 0; + + gInput.NextToken(); + if( _wcsnicmp( gInput.iToken, L"VALUEID=", 8 ) ) + throw new CSDCException( ESDCParseError, "VALUEID parameter expected for SIZEBOUNDPARAM" ); + int valueId = CSDCInput::ConvertToNumber( gInput.iToken+8 ); + + gInput.NextToken(); + int flags = 0; + if( _wcsicmp( gInput.iToken, L"FLAGS=W" ) == 0 ) + { + flags = 1; + } + else if( _wcsicmp( gInput.iToken, L"FLAGS=H" ) == 0 ) + { + flags = 2; + } + else if( _wcsicmp( gInput.iToken, L"FLAGS=W_AND_H" ) == 0 ) + { + flags = 3; + } + else throw new CSDCException( ESDCParseError, "FLAGS=W|H|W_AND_H parameter expected for SIZEBOUNDPARAM" ); + + TSDCAnimParamGroup paramGroup; + paramGroup.iValueA = valueId; + paramGroup.iValueB = flags; + paramGroup.iParameters.push_back( parameter ); + sizeBoundParams.push_back( paramGroup ); + } + else + { + UnexpectedTokenError( gInput.iToken, L"COMMAND, VALUE, TIMINGMODEL, SIZEBOUNDPARAM, or END" ); + } + } + while( gInput.NextTokenAllowLF() ); + if( !terminated ) throw CSDCException( ESDCParseError, "No END token for ANIMATION" ); + + iData->CreateAnimationDef( realIid, input, output, mininterval, preprocessCommands, animCommands, + values, timingModels, sizeBoundParams, morphing, restriction ); + } + +void CSDCReader::ParseBitmapPath() + { + if( gInput.NextToken() ) + { + bool changed( true ); + if( _wcsicmp( gInput.iToken, iData->iBmpPath ) == 0 ) changed = false; + iData->SetBmpPath( gInput.iToken ); + char buf[512]; + CSDCInput::ConvertToAscii( buf, gInput.iToken ); + if( changed ) + printf("NOTE: Bitmap source path set to %s\n", buf ); + } + else + { + iData->SetBmpPath( NULL ); + printf("NOTE: Bitmap source path set to automatic.\n" ); + } + } + +void CSDCReader::ParseRestriction() + { + if( !iData->IsScalable() ) + printf( "WARNING: RESTRICTION elements is only allowed in scalable skins, layout types will not work with this skin (line %i)\n", gInput.iLineNumber ); + + gInput.NextToken(); + if( _wcsicmp( gInput.iToken, L"S60_2_6" ) == 0 ) + { + iData->iCurrentRestriction = 0x0206; + printf("NOTE: Current restriction set to 2.6\n"); + } + else if( _wcsicmp( gInput.iToken, L"S60_2_7" ) == 0 ) + { + iData->iCurrentRestriction = 0x0207; + printf("NOTE: Current restriction set to 2.7\n"); + } + else if( _wcsicmp( gInput.iToken, L"S60_2_8" ) == 0 ) + { + iData->iCurrentRestriction = 0x0208; + printf("NOTE: Current restriction set to 2.8\n"); + } + else if( _wcsicmp( gInput.iToken, L"S60_3_0" ) == 0 ) + { + iData->iCurrentRestriction = 0x0300; + printf("NOTE: Current restriction set to 3.0\n"); + } + else if( _wcsicmp( gInput.iToken, L"S60_3_1" ) == 0 ) + { + iData->iCurrentRestriction = 0x0301; + printf("NOTE: Current restriction set to 3.1\n"); + } + else if( _wcsicmp( gInput.iToken, L"S60_3_2" ) == 0 ) + { + iData->iCurrentRestriction = 0x0302; + printf("NOTE: Current restriction set to 3.2\n"); + } + else if( _wcsicmp( gInput.iToken, L"S60_5_0" ) == 0 ) + { + iData->iCurrentRestriction = 0x0500; + printf("NOTE: Current restriction set to 5.0\n"); + } + else if( _wcsicmp( gInput.iToken, L"LAY_W" ) == 0 ) + { + iData->iCurrentRestriction = 0x00010000; + printf("NOTE: Current restriction set to Layout/Non-Mirrored\n"); + } + else if( _wcsicmp( gInput.iToken, L"LAY_AH" ) == 0 ) + { + iData->iCurrentRestriction = 0x00020000; + printf("NOTE: Current restriction set to Layout/Mirrored\n"); + } + else if( _wcsnicmp( gInput.iToken, L"LANG=", 5 ) == 0 ) + { + int language = (CSDCInput::ConvertToNumber( gInput.iToken+5 ))&0xffff; + printf("NOTE: Current restriction set to Language/langcode:%d\n", language); + iData->iCurrentRestriction = language|0x00030000; + iData->iLanguageVector.push_back(language|0x00030000); + } + else if( _wcsicmp( gInput.iToken, L"NONE" ) == 0 ) + { + iData->iCurrentRestriction = 0; + printf("NOTE: Current restriction cleared\n"); + } + else + { + throw CSDCException( ESDCParseError, "Unknown specifier for RESTRICTION element" ); + } + } + +TSDCIID CSDCReader::ParseBitmapSource( const bool aAppIcon, const int aRestriction, const bool aSvgAnim ) + { + int restriction( iData->iCurrentRestriction ); + if( _wcsnicmp( gInput.iToken, L"IID=", 4 ) == 0 ) + { + wchar_t iidBuf[512]; + wcscpy( iidBuf, gInput.iToken+4 ); + StripIIDPrefix( iidBuf, restriction ); + char buf[512]; + gInput.ConvertToAscii( buf, gInput.iToken ); + if( restriction && (restriction == aRestriction) ) + { + printf( "NOTE: IID reference (%s) is restricted, but shares the restrictions of the compound. Relative validity can not be checked (line %i)\n", buf, gInput.iLineNumber ); + } + else if( restriction ) + { + printf( "WARNING: IID reference (%s) is restricted. Relative validity can not be checked and may be broken (line %i)\n", buf, gInput.iLineNumber ); + } + else if( aRestriction ) + { + printf( "NOTE: Non-restricted IID reference (%s) inside restricted compound (line %i)\n", buf, gInput.iLineNumber ); + } + const TSDCIIDEntry* iid = SDCIIDConstants::FindPlain( iidBuf ); + if( !iid ) UnknownIIDError( gInput.iToken+4 ); + TSDCIID realIid; + realIid.iMajor = iid->iMajor; + realIid.iMinor = iid->iMinor; + return realIid; + } + restriction = aRestriction; + + TSDCColorDepth colorDepth = CSDCInput::ConvertToColorDepth( gInput.iToken ); + + gInput.NextToken(); + TSDCIID realIid; + const TSDCIIDEntry* iid = SDCIIDConstants::FindBmpName( gInput.iToken ); + if( iid ) + { + realIid.iMajor = iid->iMajor; + realIid.iMinor = iid->iMinor; + if( restriction ) + { + printf( "NOTE: Known IID (0x%x,0x%x) referenced inside restricted compound. Relative validity can not be checked (line %i)\n", realIid.iMajor, realIid.iMinor, gInput.iLineNumber ); + } + } + else + { + if( (iData->iPid.iPID2==0) && (iData->iPid.iPID1!=0) ) + { + realIid.iMajor = iData->iPid.iPID1; + } + else + { + realIid.iMajor = -4; + } + realIid.iMinor = iData->iNextOwnMinor++; + char buf[512]; + gInput.ConvertToAscii( buf, gInput.iToken ); + printf( "NOTE: Generated IID (0x%x,0x%x) for %s (line %i)\n", realIid.iMajor, realIid.iMinor, buf, gInput.iLineNumber ); + if( restriction ) + { + printf( "NOTE: Restriction inherited to generated IID (0x%x,0x%x) for %s (line %i)\n", realIid.iMajor, realIid.iMinor, buf, gInput.iLineNumber ); + } + } + + bool svg = CSDCInput::IsSvgFile( gInput.iToken ); + TSDCMBMEntry* mbmEntry = iData->AppendMbmEntry( svg, colorDepth, gInput.iToken, aSvgAnim ); + int mbmIndex = mbmEntry->iIndex; + + TSDCImageAttributes attributes; + attributes.iAttributeFlags = ESDCImageAttributeNone; + attributes.iCoordX = 0; + attributes.iCoordY = 0; + attributes.iSizeW = 0; + attributes.iSizeH = 0; + attributes.iAlignmentFlags = ESDCImageAlignNone; + + if( iData->IsScalable() ) { + attributes.iAttributeFlags |= ESDCImageAttributeNBC; + } + + int maskIndex = -1; + + while( gInput.NextToken() ) + { + if( _wcsnicmp( gInput.iToken, L"MASK=", 5 ) == 0 ) + { + if( svg ) throw CSDCException( ESDCParseError, "SVG icon can not have a named mask" ); + if( mbmEntry->iMaskColorDepth!=ESDCColorDepthNone ) + { + printf("NOTE: Mask already defined, second definition ignored (line %i)\n", gInput.iLineNumber ); + } + else + { + const wchar_t* maskFile = gInput.iToken+5; + mbmEntry->iMaskColorDepth = ESDCColorDepth1; + wcscpy( mbmEntry->iMaskSourceFilename, maskFile ); + } + maskIndex = mbmIndex+1; + } + else if( _wcsnicmp( gInput.iToken, L"SOFTMASK=", 9 ) == 0 ) + { + if( svg ) throw CSDCException( ESDCParseError, "SVG icon can not have a named mask" ); + if( mbmEntry->iMaskColorDepth!=ESDCColorDepthNone ) + { + printf("NOTE: Mask already defined, second definition ignored (line %i)\n", gInput.iLineNumber ); + } + else + { + const wchar_t* maskFile = gInput.iToken+9; + mbmEntry->iMaskColorDepth = ESDCColorDepth8; + wcscpy( mbmEntry->iMaskSourceFilename, maskFile ); + } + maskIndex = mbmIndex+1; + } + else if( _wcsicmp( gInput.iToken, L"MASK" ) == 0 ) + { + if( !svg ) throw CSDCException( ESDCParseError, "Non-SVG icon can not have an unnamed mask" ); + mbmEntry->iMaskColorDepth = ESDCColorDepth1; + maskIndex = mbmIndex+1; + } + else if( _wcsicmp( gInput.iToken, L"SOFTMASK" ) == 0 ) + { + if( !svg ) throw CSDCException( ESDCParseError, "Non-SVG icon can not have an unnamed mask" ); + mbmEntry->iMaskColorDepth = ESDCColorDepth8; + maskIndex = mbmIndex+1; + } + else + { + ProcessAttribute( attributes, gInput.iToken ); + } + } + + if( (maskIndex!=-1) && (attributes.iAttributeFlags&ESDCImageAttributeTile) ) + { + printf( "WARNING: TILE attribute used with masked bitmap (line %i)\n", gInput.iLineNumber ); + } + + iData->CreateBitmapDef( realIid, mbmIndex, maskIndex, attributes, aAppIcon, restriction ); + return realIid; + } + +void CSDCReader::ProcessAttribute( TSDCImageAttributes& aAttributes, wchar_t* aSource ) + { + wchar_t buf[512]; + wcscpy( buf, aSource ); + + if( _wcsnicmp( buf, L"COORDS=", 7 ) == 0 ) + { + wchar_t* p = wcsstr( buf, L"," ); + if( !p ) throw CSDCException( ESDCParseError, "No comma in image attribute COORDS" ); + *p = 0; + aAttributes.iAttributeFlags |= ESDCImageAttributeCoords; + aAttributes.iCoordX = gInput.ConvertToNumber( buf+7 ); + aAttributes.iCoordY = gInput.ConvertToNumber( p+1 ); + } + else if( _wcsnicmp( buf, L"SIZE=", 5 ) == 0 ) + { + wchar_t* p = wcsstr( buf, L"," ); + if( !p ) throw CSDCException( ESDCParseError, "No comma in image attribute SIZE" ); + *p = 0; + aAttributes.iAttributeFlags |= ESDCImageAttributeSize; + aAttributes.iSizeW = gInput.ConvertToNumber( buf+5 ); + aAttributes.iSizeH = gInput.ConvertToNumber( p+1 ); + } + else if( _wcsicmp( buf, L"STRETCH" ) == 0 ) + { + aAttributes.iAttributeFlags |= ESDCImageAttributeStretch; + } + else if( _wcsicmp( buf, L"TILE" ) == 0 ) + { + aAttributes.iAttributeFlags |= ESDCImageAttributeTile; + } + else if( _wcsicmp( buf, L"TILEX" ) == 0 ) + { + aAttributes.iAttributeFlags |= ESDCImageAttributeTileX; + } + else if( _wcsicmp( buf, L"TILEY" ) == 0 ) + { + aAttributes.iAttributeFlags |= ESDCImageAttributeTileY; + } + else if( _wcsnicmp( buf, L"ALIGN=", 6 ) == 0 ) + { + if( _wcsicmp( buf+6, L"TL" ) == 0 ) aAttributes.iAlignmentFlags = ESDCImageAlignTL; + else if( _wcsicmp( buf+6, L"TC" ) == 0 ) aAttributes.iAlignmentFlags = ESDCImageAlignTC; + else if( _wcsicmp( buf+6, L"TR" ) == 0 ) aAttributes.iAlignmentFlags = ESDCImageAlignTR; + else if( _wcsicmp( buf+6, L"CL" ) == 0 ) aAttributes.iAlignmentFlags = ESDCImageAlignCL; + else if( _wcsicmp( buf+6, L"CC" ) == 0 ) aAttributes.iAlignmentFlags = ESDCImageAlignCC; + else if( _wcsicmp( buf+6, L"CR" ) == 0 ) aAttributes.iAlignmentFlags = ESDCImageAlignCR; + else if( _wcsicmp( buf+6, L"BL" ) == 0 ) aAttributes.iAlignmentFlags = ESDCImageAlignBL; + else if( _wcsicmp( buf+6, L"BC" ) == 0 ) aAttributes.iAlignmentFlags = ESDCImageAlignBC; + else if( _wcsicmp( buf+6, L"BR" ) == 0 ) aAttributes.iAlignmentFlags = ESDCImageAlignBR; + else throw CSDCException( ESDCParseError, "Unknown parameter for image attribute ALIGN" ); + + aAttributes.iAttributeFlags |= ESDCImageAttributeAlign; + } + else throw CSDCException( ESDCParseError, "Unknown attribute parameter" ); + } + +void CSDCReader::ParseEffectCommand( TSDCEffectCommand& aCommand ) + { + gInput.NextToken(); + if( _wcsnicmp( gInput.iToken, L"UID=", 4 ) == 0 ) + { + aCommand.iUid = CSDCInput::ConvertToNumber( gInput.iToken+4 ); + } + else + { + throw CSDCException( ESDCParseError, "UID parameter expected for EFFECT" ); + } + + gInput.NextToken(); + if( _wcsnicmp( gInput.iToken, L"INPUTA=", 7 ) == 0 ) + { + aCommand.iInputA = CSDCInput::ConvertToLayer( gInput.iToken+7 ); + } + else + { + throw CSDCException( ESDCParseError, "INPUTA parameter expected for EFFECT" ); + } + + gInput.NextToken(); + if( _wcsnicmp( gInput.iToken, L"INPUTB=", 7 ) == 0 ) + { + aCommand.iInputB = CSDCInput::ConvertToLayer( gInput.iToken+7 ); + } + else + { + throw CSDCException( ESDCParseError, "INPUTB parameter expected for EFFECT" ); + } + + gInput.NextToken(); + if( _wcsnicmp( gInput.iToken, L"OUTPUT=", 7 ) == 0 ) + { + aCommand.iOutput = CSDCInput::ConvertToLayer( gInput.iToken+7 ); + } + else + { + throw CSDCException( ESDCParseError, "OUTPUT parameter expected for EFFECT" ); + } + + while( gInput.NextTokenAllowLF() ) + { + if( _wcsicmp( gInput.iToken, L"END" ) == 0) + { + // Just return, everything should be in the struct by now + return; + } + else + { + TSDCEffectParameter parameter; + ParseEffectParameter( parameter ); + aCommand.iParameters.push_back( parameter ); + } + } + + throw CSDCException( ESDCParseError, "No END token for EFFECT" ); + } + +void CSDCReader::ParseEffectParameter( TSDCEffectParameter& aParameter ) + { + if( _wcsicmp( gInput.iToken, L"INT" ) == 0) + { + aParameter.iType = 0; + } + else if( _wcsicmp( gInput.iToken, L"STR" ) == 0) + { + aParameter.iType = 1; + } + else if( _wcsicmp( gInput.iToken, L"BMP" ) == 0) + { + aParameter.iType = 2; + } + else if( _wcsicmp( gInput.iToken, L"NAMEDREF" ) == 0) + { + aParameter.iType = 3; + } + else if( _wcsicmp( gInput.iToken, L"RAW" ) == 0) + { + aParameter.iType = 4; + } + else + { + UnexpectedTokenError( gInput.iToken, L"STR, INT, BMP, RAW or NAMEDREF"); + } + + gInput.NextToken(); + wcscpy( aParameter.iName, gInput.iToken ); + + if( aParameter.iType == 0 ) + { + gInput.NextToken(); + aParameter.iNumber = CSDCInput::ConvertToNumber( gInput.iToken ); + } + else if( aParameter.iType == 1 ) + { + gInput.NextStringToken(); + wcscpy( aParameter.iString, gInput.iToken ); + } + else if( aParameter.iType == 2 ) + { + // Color depth + gInput.NextToken(); + aParameter.iColorDepth = CSDCInput::ConvertToColorDepth( gInput.iToken ); + + // Filename + gInput.NextToken(); + bool svg = CSDCInput::IsSvgFile( gInput.iToken ); + TSDCMBMEntry* mbmEntry = iData->AppendMbmEntry( svg, aParameter.iColorDepth, gInput.iToken ); + aParameter.iBmpIndex = mbmEntry->iIndex; + + // Mask + aParameter.iMaskIndex = -1; + if( gInput.NextToken() ) + { + if( _wcsnicmp( gInput.iToken, L"MASK=", 5 ) == 0 ) + { + if( svg ) throw CSDCException( ESDCParseError, "SVG icon can not have a named mask" ); + if( mbmEntry->iMaskColorDepth!=ESDCColorDepthNone ) + { + printf("NOTE: Mask already defined, second definition ignored (line %i)\n", gInput.iLineNumber ); + } + else + { + const wchar_t* maskFile = gInput.iToken+5; + mbmEntry->iMaskColorDepth = ESDCColorDepth1; + wcscpy( mbmEntry->iMaskSourceFilename, maskFile ); + } + aParameter.iMaskIndex = aParameter.iBmpIndex+1; + } + else if( _wcsnicmp( gInput.iToken, L"SOFTMASK=", 9 ) == 0 ) + { + if( svg ) throw CSDCException( ESDCParseError, "SVG icon can not have a named mask" ); + if( mbmEntry->iMaskColorDepth!=ESDCColorDepthNone ) + { + printf("NOTE: Mask already defined, second definition ignored (line %i)\n", gInput.iLineNumber ); + } + else + { + const wchar_t* maskFile = gInput.iToken+9; + mbmEntry->iMaskColorDepth = ESDCColorDepth8; + wcscpy( mbmEntry->iMaskSourceFilename, maskFile ); + } + aParameter.iMaskIndex = aParameter.iBmpIndex+1; + } + else if( _wcsicmp( gInput.iToken, L"MASK" ) == 0 ) + { + if( !svg ) throw CSDCException( ESDCParseError, "Non-SVG icon can not have an unnamed mask" ); + mbmEntry->iMaskColorDepth = ESDCColorDepth1; + aParameter.iMaskIndex = aParameter.iBmpIndex+1; + } + else if( _wcsicmp( gInput.iToken, L"SOFTMASK" ) == 0 ) + { + if( !svg ) throw CSDCException( ESDCParseError, "Non-SVG icon can not have an unnamed mask" ); + mbmEntry->iMaskColorDepth = ESDCColorDepth8; + aParameter.iMaskIndex = aParameter.iBmpIndex+1; + } + else + { + UnexpectedTokenError( gInput.iToken, L"MASK or SOFTMASK" ); + } + } + } + else if( aParameter.iType == 3 ) + { + gInput.NextToken(); + if( _wcsnicmp( gInput.iToken, L"VALUEID=", 8 ) == 0 ) + { + aParameter.iNumber = CSDCInput::ConvertToNumber( gInput.iToken+8 ); + } + else + { + throw CSDCException( ESDCParseError, "VALUEID parameter expected for NAMEDREF" ); + } + } + else if( aParameter.iType == 4 ) + { + int tokens = gInput.NextRawToken(); + aParameter.iRawDataCount = tokens; + memcpy( aParameter.iString, gInput.iToken, tokens * sizeof(wchar_t) ); + } + } + +void CSDCReader::UnexpectedTokenError( wchar_t* aWrongToken, wchar_t* aRightToken ) + { + char wrongBuf[512]; + gInput.ConvertToAscii( wrongBuf, aWrongToken ); + char rightBuf[512]; + gInput.ConvertToAscii( rightBuf, aRightToken ); + + char buf[512]; + strcpy( buf, "Expected \"" ); + strcat( buf, rightBuf ); + strcat( buf, "\", but \"" ); + strcat( buf, wrongBuf ); + strcat( buf, "\" found instead" ); + throw CSDCException( ESDCParseError, buf ); + } + +void CSDCReader::UnknownIIDError( wchar_t* aWrongIID ) + { + char wrongBuf[512]; + gInput.ConvertToAscii( wrongBuf, aWrongIID ); + + char buf[512]; + strcpy( buf, "No match found for item ID \"" ); + strcat( buf, wrongBuf ); + strcat( buf, "\"" ); + throw CSDCException( ESDCParseError, buf ); + } + +void CSDCReader::StripIIDPrefix( wchar_t* aIID, int& aRestriction ) + { + wchar_t* delimiter = wcschr( aIID, '%' ); + if( !delimiter ) + { + return; + } + + if( iData->iCurrentRestriction ) + throw CSDCException( ESDCParseError, "No item-based restriction can be used where RESTRICTION element already applies" ); + + wchar_t buf[512]; + wcscpy( buf, delimiter+1 ); + + *delimiter = 0; + if( _wcsicmp( aIID, L"S60_2_6" ) == 0 ) + { + aRestriction = 0x0206; + } + else if( _wcsicmp( aIID, L"S60_2_7" ) == 0 ) + { + aRestriction = 0x0207; + } + else if( _wcsicmp( aIID, L"S60_2_8" ) == 0 ) + { + aRestriction = 0x0208; + } + else if( _wcsicmp( aIID, L"S60_3_0" ) == 0 ) + { + aRestriction = 0x0300; + } + else if( _wcsicmp( aIID, L"S60_3_1" ) == 0 ) + { + aRestriction = 0x0301; + } + else if( _wcsicmp( aIID, L"S60_3_2" ) == 0 ) + { + aRestriction = 0x0302; + } + else if( _wcsicmp( aIID, L"S60_5_0" ) == 0 ) + { + aRestriction = 0x0500; + } + else if( _wcsicmp( aIID, L"LAY_W" ) == 0 ) + { + aRestriction = 0x00010000; + } + else if( _wcsicmp( aIID, L"LAY_AH" ) == 0 ) + { + aRestriction = 0x00020000; + } + else + { + throw CSDCException( ESDCParseError, "Unknown release restriction prefix in IID" ); + } + + wcscpy( aIID, buf ); + } + +// End of file