skins/AknSkins/sdcsrc/SDCReader.cpp
changeset 0 05e9090e2422
child 32 d9c996538b26
equal deleted inserted replaced
-1:000000000000 0:05e9090e2422
       
     1 /*
       
     2 * Copyright (c) 2003-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Reader class.
       
    15 *
       
    16 */
       
    17 
       
    18 #include "SDCGlobals.h"
       
    19 #include "SDCReader.h"
       
    20 #include "SDCIIDConstants.h"
       
    21 #include "SDCException.h"
       
    22 
       
    23 // Make std namespace available for compatibility
       
    24 namespace std {}
       
    25 using namespace std;
       
    26 
       
    27 //////////////////////////////////////////////////////////////////////
       
    28 // Construction/Destruction
       
    29 //////////////////////////////////////////////////////////////////////
       
    30 
       
    31 CSDCReader::CSDCReader( CSDCData* aData )
       
    32     {
       
    33     iData = aData;
       
    34     }
       
    35 
       
    36 CSDCReader::~CSDCReader()
       
    37     {
       
    38     }
       
    39 
       
    40 //////////////////////////////////////////////////////////////////////
       
    41 // Other methods
       
    42 //////////////////////////////////////////////////////////////////////
       
    43 
       
    44 void CSDCReader::Parse()
       
    45     {
       
    46     gInput.NextTokenAllowLF();
       
    47     if( _wcsicmp( gInput.iToken, L"SKINTYPE" ) != 0 ) UnexpectedTokenError( gInput.iToken, L"SKINTYPE" );
       
    48     ParseSkintype();
       
    49 
       
    50     gInput.NextTokenAllowLF();
       
    51     if( _wcsicmp( gInput.iToken, L"UID" ) == 0 )
       
    52         {
       
    53         ParseUID();
       
    54         gInput.NextTokenAllowLF();
       
    55         }
       
    56     else if( _wcsicmp( gInput.iToken, L"PID" ) == 0 )
       
    57         {
       
    58         ParsePID();
       
    59         gInput.NextTokenAllowLF();
       
    60         }
       
    61     else
       
    62         {
       
    63         GeneratePID();
       
    64         }
       
    65 
       
    66     if( _wcsicmp( gInput.iToken, L"NAME" ) != 0 ) UnexpectedTokenError( gInput.iToken, L"NAME" );
       
    67     ParseName();
       
    68 
       
    69     while( gInput.NextTokenAllowLF() )
       
    70         {
       
    71         if( _wcsicmp( gInput.iToken, L"NAME" ) == 0 )
       
    72             {
       
    73             ParseName();
       
    74             }
       
    75         else if( _wcsicmp( gInput.iToken, L"LANGUAGEOVERRIDE" ) == 0 )
       
    76             {
       
    77             ParseLanguageOverride();
       
    78             }
       
    79         else if( _wcsicmp( gInput.iToken, L"LANGUAGEPARENT" ) == 0 )
       
    80             {
       
    81             ParseParentUID();
       
    82             }
       
    83         else if( _wcsicmp( gInput.iToken, L"PROTECT" ) == 0 )
       
    84             {
       
    85             ParseProtect();
       
    86             }
       
    87         else if( _wcsicmp( gInput.iToken, L"AUTHOR" ) == 0 )
       
    88             {
       
    89             ParseAuthor();
       
    90             }
       
    91         else if( _wcsicmp( gInput.iToken, L"COPYRIGHT" ) == 0 )
       
    92             {
       
    93             ParseCopyright();
       
    94             }
       
    95         else if( _wcsicmp( gInput.iToken, L"TARGETDEVICE" ) == 0 )
       
    96             {
       
    97             ParseTargetDevice();
       
    98             }
       
    99         else if( _wcsicmp( gInput.iToken, L"TOOL" ) == 0 )
       
   100             {
       
   101             ParseTool();
       
   102             }
       
   103         else if( _wcsicmp( gInput.iToken, L"BITMAP" ) == 0 )
       
   104             {
       
   105             ParseBitmap();
       
   106             }
       
   107         else if( _wcsicmp( gInput.iToken, L"COLORTABLE" ) == 0 )
       
   108             {
       
   109             ParseColorTable();
       
   110             }
       
   111         else if( _wcsicmp( gInput.iToken, L"FRAME" ) == 0 )
       
   112             {
       
   113             ParseFrame();
       
   114             }
       
   115         else if( _wcsicmp( gInput.iToken, L"BMPANIM" ) == 0 )
       
   116             {
       
   117             ParseBmpAnim();
       
   118             }
       
   119         else if( _wcsicmp( gInput.iToken, L"APPICON" ) == 0 )
       
   120             {
       
   121             ParseAppIcon();
       
   122             }
       
   123         else if( _wcsicmp( gInput.iToken, L"PALETTE" ) == 0 )
       
   124             {
       
   125             ParsePalette();
       
   126             }
       
   127         else if( (_wcsicmp( gInput.iToken, L"SOUND" ) == 0)
       
   128             || (_wcsicmp( gInput.iToken, L"STRING" ) == 0) )
       
   129             {
       
   130             ParseString();
       
   131             }
       
   132         else if( _wcsicmp( gInput.iToken, L"SCALABLEITEM" ) == 0 )
       
   133             {
       
   134             if( !iData->IsScalable() ) throw CSDCException( ESDCContentError, "SCALABLEITEM can only be included in scalable skins" );
       
   135             ParseScalableItem();
       
   136             }
       
   137         else if( _wcsicmp( gInput.iToken, L"ANIMATION" ) == 0 )
       
   138             {
       
   139             if( !iData->IsScalable() ) throw CSDCException( ESDCContentError, "ANIMATION can only be included in scalable skins" );
       
   140             ParseAnimation();
       
   141             }
       
   142         else if( _wcsicmp( gInput.iToken, L"BITMAPPATH" ) == 0 )
       
   143             {
       
   144             ParseBitmapPath();
       
   145             }
       
   146         else if( _wcsicmp( gInput.iToken, L"RESTRICTION" ) == 0 )
       
   147             {
       
   148             ParseRestriction();
       
   149             }
       
   150         else
       
   151             {
       
   152             wprintf(L"DEBUG: Unknown token: \"%s\"\n", gInput.iToken );
       
   153             throw CSDCException( ESDCParseError, "Unknown token encountered or syntax error" );
       
   154             }
       
   155         }
       
   156     }
       
   157 
       
   158 void CSDCReader::ParseSkintype()
       
   159     {
       
   160     gInput.NextToken();
       
   161 
       
   162     if( _wcsicmp( gInput.iToken, L"normal" ) == 0 )
       
   163         {
       
   164         iData->iSkinType = 0x0;
       
   165         }
       
   166     else if( _wcsicmp( gInput.iToken, L"system" ) == 0 )
       
   167         {
       
   168         iData->iSkinType = 0x1;
       
   169         }
       
   170     else if( _wcsicmp( gInput.iToken, L"scalable" ) == 0 )
       
   171         {
       
   172 #if !defined( RD_ENHANCED_SKINNING )
       
   173         throw CSDCException( ESDCNotSupportedError, "Scalable skins not supported" );
       
   174 #endif
       
   175         iData->iSkinType = 0x80;
       
   176         return; // No other types are supported, if scalable
       
   177         }
       
   178     else
       
   179         {
       
   180         throw CSDCException( ESDCParseError, "Unknown or missing parameter for SKINTYPE" );
       
   181         }
       
   182 
       
   183     if( gInput.NextToken() )
       
   184         {
       
   185         if( _wcsicmp( gInput.iToken, L"language=AH" ) == 0 )
       
   186             {
       
   187             iData->iSkinType |= 0x102;
       
   188             }
       
   189         else
       
   190             {
       
   191             throw CSDCException( ESDCParseError, "Unknown or missing additional parameter for SKINTYPE" );
       
   192             }
       
   193         }
       
   194     }
       
   195 
       
   196 void CSDCReader::ParseUID()
       
   197     {
       
   198     gInput.NextToken();
       
   199     iData->iPid.iPID2 = 0; // Timestamp
       
   200     iData->iPid.iPID1 = gInput.ConvertToNumber( gInput.iToken ); // UID
       
   201     }
       
   202 
       
   203 void CSDCReader::ParsePID()
       
   204     {
       
   205     gInput.NextToken();
       
   206     iData->iPid.iPID2 = gInput.ConvertToNumber( gInput.iToken ); // Timestamp
       
   207 
       
   208     if( iData->iPid.iPID2 == 0 )
       
   209         {
       
   210         throw CSDCException( ESDCParseError, "PID can not start with zero" );
       
   211         }
       
   212 
       
   213     gInput.NextToken();
       
   214     iData->iPid.iPID1 = gInput.ConvertToNumber( gInput.iToken ); // Random number
       
   215     }
       
   216 
       
   217 void CSDCReader::GeneratePID()
       
   218     {
       
   219     iData->iPid.iPID2 = 0;
       
   220     iData->iPid.iPID1 = 0;
       
   221     }
       
   222 
       
   223 void CSDCReader::ParseName()
       
   224     {
       
   225     gInput.NextToken();
       
   226     int languageID = gInput.ConvertToNumber( gInput.iToken );
       
   227 
       
   228     gInput.NextStringToken();
       
   229     iData->AppendNameEntry( languageID, gInput.iToken );
       
   230     }
       
   231 
       
   232 void CSDCReader::ParseLanguageOverride()
       
   233     {
       
   234     if( iData->IsScalable() )
       
   235         throw CSDCException( ESDCParseError, "Language override can not be used with scalable skins" );
       
   236 
       
   237     gInput.NextToken();
       
   238     if( _wcsicmp( gInput.iToken, L"AH" ) != 0 )
       
   239         {
       
   240         throw CSDCException( ESDCParseError, "Unknown or missing parameter for LANGUAGEOVERRIDE" );
       
   241         }
       
   242 
       
   243     gInput.NextToken();
       
   244     int value = gInput.ConvertToNumber( gInput.iToken );
       
   245     if( gInput.NextToken() )
       
   246         {
       
   247         iData->iAHOverridePid.iPID1 = gInput.ConvertToNumber( gInput.iToken );
       
   248         iData->iAHOverridePid.iPID2 = value;
       
   249         }
       
   250     else
       
   251         {
       
   252         iData->iAHOverridePid.iPID2 = 0;
       
   253         iData->iAHOverridePid.iPID1 = value;
       
   254         }
       
   255     }
       
   256 
       
   257 void CSDCReader::ParseParentUID()
       
   258     {
       
   259     if( iData->IsScalable() )
       
   260         throw CSDCException( ESDCParseError, "Parent UID can not be used with scalable skins" );
       
   261 
       
   262     gInput.NextToken();
       
   263     int value = gInput.ConvertToNumber( gInput.iToken );
       
   264     if( gInput.NextToken() )
       
   265         {
       
   266         iData->iParentPid.iPID1 = gInput.ConvertToNumber( gInput.iToken );
       
   267         iData->iParentPid.iPID2 = value;
       
   268         }
       
   269     else
       
   270         {
       
   271         iData->iParentPid.iPID2 = 0;
       
   272         iData->iParentPid.iPID1 = value;
       
   273         }
       
   274     }
       
   275 
       
   276 void CSDCReader::ParseProtect()
       
   277     {
       
   278     gInput.NextToken();
       
   279     if( _wcsicmp( gInput.iToken, L"disablecopy" ) != 0 )
       
   280         {
       
   281         throw CSDCException( ESDCParseError, "Unknown or missing parameter for PROTECT" );
       
   282         }
       
   283 
       
   284     iData->iProtection = 1;
       
   285     }
       
   286 
       
   287 void CSDCReader::ParseAuthor()
       
   288     {
       
   289     gInput.NextStringToken();
       
   290     wcscpy( iData->iAuthor, gInput.iToken );
       
   291     }
       
   292 
       
   293 void CSDCReader::ParseCopyright()
       
   294     {
       
   295     gInput.NextStringToken();
       
   296     wcscpy( iData->iCopyright, gInput.iToken );
       
   297     }
       
   298 
       
   299 void CSDCReader::ParseTargetDevice()
       
   300     {
       
   301     gInput.NextStringToken();
       
   302     iData->AppendTargetDeviceEntry( gInput.iToken );
       
   303     }
       
   304 
       
   305 void CSDCReader::ParseTool()
       
   306     {
       
   307     gInput.NextStringToken();
       
   308     wcscpy( iData->iTool, gInput.iToken );
       
   309     }
       
   310 
       
   311 void CSDCReader::ParseBitmap()
       
   312     {
       
   313     gInput.NextToken();
       
   314 
       
   315     bool appIcon = false;
       
   316     if( _wcsicmp( gInput.iToken, L"CLASS=appicon" ) == 0 )
       
   317         {
       
   318         appIcon = true;
       
   319         gInput.NextToken();
       
   320         }
       
   321 
       
   322     int restriction( iData->iCurrentRestriction );
       
   323     const TSDCIIDEntry* iid = NULL;
       
   324     if( _wcsnicmp( gInput.iToken, L"IID=", 4 ) == 0 )
       
   325         {
       
   326         wchar_t iidBuf[512];
       
   327         wcscpy( iidBuf, gInput.iToken+4 );
       
   328         StripIIDPrefix( iidBuf, restriction );
       
   329         iid = SDCIIDConstants::FindPlain( iidBuf );
       
   330         if( !iid ) UnknownIIDError( gInput.iToken+4 );
       
   331 
       
   332         gInput.NextToken();
       
   333         }
       
   334 
       
   335     TSDCColorDepth colorDepth = gInput.ConvertToColorDepth( gInput.iToken );
       
   336 
       
   337     gInput.NextToken();
       
   338     if( !iid )
       
   339         {
       
   340         iid = SDCIIDConstants::FindBmpName( gInput.iToken );
       
   341         if( !iid ) UnknownIIDError( gInput.iToken );
       
   342         }
       
   343 
       
   344     bool svg = CSDCInput::IsSvgFile( gInput.iToken );
       
   345     TSDCMBMEntry* mbmEntry = iData->AppendMbmEntry( svg, colorDepth, gInput.iToken );
       
   346     int mbmIndex = mbmEntry->iIndex;
       
   347 
       
   348     TSDCImageAttributes attributes;
       
   349     attributes.iAttributeFlags = ESDCImageAttributeNone;
       
   350     attributes.iCoordX = 0;
       
   351     attributes.iCoordY = 0;
       
   352     attributes.iSizeW = 0;
       
   353     attributes.iSizeH = 0;
       
   354     attributes.iAlignmentFlags = ESDCImageAlignNone;
       
   355 
       
   356     if( iData->IsScalable() ) {
       
   357         attributes.iAttributeFlags |= ESDCImageAttributeNBC;
       
   358         }
       
   359 
       
   360     int maskIndex = -1;
       
   361 
       
   362     while( gInput.NextToken() )
       
   363         {
       
   364         if( _wcsnicmp( gInput.iToken, L"MASK=", 5 ) == 0 )
       
   365             {
       
   366             if( svg ) throw CSDCException( ESDCParseError, "SVG icon can not have a named mask" );
       
   367             if( mbmEntry->iMaskColorDepth!=ESDCColorDepthNone )
       
   368                 {
       
   369                 printf("NOTE: Mask already defined, second definition ignored (line %i)\n", gInput.iLineNumber );
       
   370                 }
       
   371             else
       
   372                 {
       
   373                 const wchar_t* maskFile = gInput.iToken+5;
       
   374                 mbmEntry->iMaskColorDepth = ESDCColorDepth1;
       
   375                 wcscpy( mbmEntry->iMaskSourceFilename, maskFile );
       
   376                 }
       
   377             maskIndex = mbmIndex+1;
       
   378             }
       
   379         else if( _wcsnicmp( gInput.iToken, L"SOFTMASK=", 9 ) == 0 )
       
   380             {
       
   381             if( svg ) throw CSDCException( ESDCParseError, "SVG icon can not have a named mask" );
       
   382             if( mbmEntry->iMaskColorDepth!=ESDCColorDepthNone )
       
   383                 {
       
   384                 printf("NOTE: Mask already defined, second definition ignored (line %i)\n", gInput.iLineNumber );
       
   385                 }
       
   386             else
       
   387                 {
       
   388                 const wchar_t* maskFile = gInput.iToken+9;
       
   389                 mbmEntry->iMaskColorDepth = ESDCColorDepth8;
       
   390                 wcscpy( mbmEntry->iMaskSourceFilename, maskFile );
       
   391                 }
       
   392             maskIndex = mbmIndex+1;
       
   393             }
       
   394         else if( _wcsicmp( gInput.iToken, L"MASK" ) == 0 )
       
   395             {
       
   396             if( !svg ) throw CSDCException( ESDCParseError, "Non-SVG icon can not have an unnamed mask" );
       
   397             mbmEntry->iMaskColorDepth = ESDCColorDepth1;
       
   398             maskIndex = mbmIndex+1;
       
   399             }
       
   400         else if( _wcsicmp( gInput.iToken, L"SOFTMASK" ) == 0 )
       
   401             {
       
   402             if( !svg ) throw CSDCException( ESDCParseError, "Non-SVG icon can not have an unnamed mask" );
       
   403             mbmEntry->iMaskColorDepth = ESDCColorDepth8;
       
   404             maskIndex = mbmIndex+1;
       
   405             }
       
   406         else
       
   407             {
       
   408             ProcessAttribute( attributes, gInput.iToken );
       
   409             }
       
   410         }
       
   411 
       
   412     TSDCIID realIid;
       
   413     realIid.iMajor = iid->iMajor;
       
   414     realIid.iMinor = iid->iMinor;
       
   415     iData->CreateBitmapDef( realIid, mbmIndex, maskIndex, attributes, appIcon, restriction );
       
   416     }
       
   417 
       
   418 void CSDCReader::ParseColorTable()
       
   419     {
       
   420     gInput.NextToken();
       
   421 
       
   422     TSDCIID realIid;
       
   423     int restriction( iData->iCurrentRestriction );
       
   424     if( _wcsnicmp( gInput.iToken, L"IID=", 4 ) == 0 )
       
   425         {
       
   426         wchar_t iidBuf[512];
       
   427         wcscpy( iidBuf, gInput.iToken+4 );
       
   428         StripIIDPrefix( iidBuf, restriction );
       
   429         const TSDCIIDEntry* iid = SDCIIDConstants::FindPlain( iidBuf );
       
   430         if( !iid ) UnknownIIDError( gInput.iToken+4 );
       
   431         realIid.iMajor = iid->iMajor;
       
   432         realIid.iMinor = iid->iMinor;
       
   433         }
       
   434     else
       
   435         {
       
   436         throw CSDCException( ESDCParseError, "IID parameter expected for COLORTABLE" );
       
   437         }
       
   438 
       
   439     vector<TSDCColorTableEntry> colors;
       
   440 
       
   441     while( gInput.NextTokenAllowLF() )
       
   442         {
       
   443         if( _wcsicmp( gInput.iToken, L"END" ) == 0 )
       
   444             {
       
   445             iData->CreateColorTableDef( realIid, colors, restriction );
       
   446             return;
       
   447             }
       
   448         else if( _wcsnicmp( gInput.iToken, L"IDX=", 4 ) == 0 )
       
   449             {
       
   450             TSDCColorTableEntry entry;
       
   451             entry.iIndex = gInput.ConvertToNumber( gInput.iToken+4 );
       
   452             entry.iRgb = 0;
       
   453             colors.push_back( entry );
       
   454             }
       
   455         else if( _wcsnicmp( gInput.iToken, L"RGB=", 4 ) == 0 )
       
   456             {
       
   457             TSDCColorTableEntry entry;
       
   458             entry.iIndex = -1;
       
   459             int rgb = gInput.ConvertToNumber( gInput.iToken+4 );
       
   460             // SymbianOS actually uses BGR order
       
   461             entry.iRgb =
       
   462                 ((rgb&0xff)<<16) | (rgb&0xff00) | ((rgb&0xff0000)>>16);
       
   463             colors.push_back( entry );
       
   464             }
       
   465         else throw CSDCException( ESDCParseError, "Unknown token inside COLORTABLE" );
       
   466         }
       
   467 
       
   468     throw CSDCException( ESDCParseError, "No END token for COLORTABLE" );
       
   469     }
       
   470 
       
   471 void CSDCReader::ParseFrame()
       
   472     {
       
   473     gInput.NextToken();
       
   474 
       
   475     TSDCIID realIid;
       
   476     int restriction( iData->iCurrentRestriction );
       
   477     if( _wcsnicmp( gInput.iToken, L"IID=", 4 ) == 0 )
       
   478         {
       
   479         wchar_t iidBuf[512];
       
   480         wcscpy( iidBuf, gInput.iToken+4 );
       
   481         StripIIDPrefix( iidBuf, restriction );
       
   482         const TSDCIIDEntry* iid = SDCIIDConstants::FindPlain( iidBuf );
       
   483         if( !iid ) UnknownIIDError( gInput.iToken+4 );
       
   484         realIid.iMajor = iid->iMajor;
       
   485         realIid.iMinor = iid->iMinor;
       
   486         }
       
   487     else
       
   488         {
       
   489         throw CSDCException( ESDCParseError, "IID parameter expected for FRAME" );
       
   490         }
       
   491 
       
   492     vector<TSDCIID> elements;
       
   493 
       
   494     while( gInput.NextTokenAllowLF() )
       
   495         {
       
   496         if( _wcsicmp( gInput.iToken, L"END" ) == 0)
       
   497             {
       
   498             iData->CreateFrameDef( realIid, elements, restriction );
       
   499             return;
       
   500             }
       
   501         else
       
   502             {
       
   503             elements.push_back( ParseBitmapSource( false, restriction ) );
       
   504             }
       
   505         }
       
   506 
       
   507     throw CSDCException( ESDCParseError, "No END token for FRAME" );
       
   508     }
       
   509 
       
   510 void CSDCReader::ParseBmpAnim()
       
   511     {
       
   512     gInput.NextToken();
       
   513 
       
   514     TSDCIID realIid;
       
   515     int restriction( iData->iCurrentRestriction );
       
   516     if( _wcsnicmp( gInput.iToken, L"IID=", 4 ) == 0 )
       
   517         {
       
   518         wchar_t iidBuf[512];
       
   519         wcscpy( iidBuf, gInput.iToken+4 );
       
   520         StripIIDPrefix( iidBuf, restriction );
       
   521         const TSDCIIDEntry* iid = SDCIIDConstants::FindPlain( iidBuf );
       
   522         if( !iid ) UnknownIIDError( gInput.iToken+4 );
       
   523         realIid.iMajor = iid->iMajor;
       
   524         realIid.iMinor = iid->iMinor;
       
   525         }
       
   526     else
       
   527         {
       
   528         throw CSDCException( ESDCParseError, "IID parameter expected for BMPANIM" );
       
   529         }
       
   530 
       
   531     int interval = -1;
       
   532     int playMode = 0;
       
   533     int flash = 0;
       
   534     bool svganim = false;
       
   535 
       
   536     while( gInput.NextToken() )
       
   537         {
       
   538         if( _wcsnicmp( gInput.iToken, L"INTERVAL=", 9 ) == 0 )
       
   539             {
       
   540             interval = gInput.ConvertToNumber( gInput.iToken+9 );
       
   541             }
       
   542         else if( _wcsicmp( gInput.iToken, L"MODE=play" ) == 0 )
       
   543             {
       
   544             playMode = 0;
       
   545             }
       
   546         else if( _wcsicmp( gInput.iToken, L"MODE=cycle" ) == 0 )
       
   547             {
       
   548             playMode = 1;
       
   549             }
       
   550         else if( _wcsicmp( gInput.iToken, L"MODE=bounce" ) == 0 )
       
   551             {
       
   552             playMode = 2;
       
   553             }
       
   554         else if( _wcsicmp( gInput.iToken, L"MODE=svganim" ) == 0 )
       
   555             {
       
   556             playMode = 255;
       
   557             svganim = true;
       
   558             }
       
   559         else if( _wcsicmp( gInput.iToken, L"FLASH" ) == 0 )
       
   560             {
       
   561             flash = 1;
       
   562             }
       
   563         else
       
   564             {
       
   565             UnexpectedTokenError( gInput.iToken, L"<BMPANIM parameter>" );
       
   566             }
       
   567         }
       
   568 
       
   569     vector<TSDCBmpAnimFrame> frames;
       
   570 
       
   571     int time = -1;
       
   572     int posx = 0;
       
   573     int posy = 0;
       
   574     while( gInput.NextTokenAllowLF() )
       
   575         {
       
   576         if( _wcsnicmp( gInput.iToken, L"TIME=", 5 ) == 0 )
       
   577             {
       
   578             time = gInput.ConvertToNumber( gInput.iToken+5 );
       
   579             }
       
   580         else if( _wcsnicmp( gInput.iToken, L"POS=", 4 ) == 0 )
       
   581             {
       
   582             wchar_t buf[512];
       
   583             wcscpy( buf, gInput.iToken+4 );
       
   584             wchar_t* p = wcsstr( buf, L"," );
       
   585             if( !p ) throw CSDCException( ESDCParseError, "No comma found in POS parameter of BMPANIM" );
       
   586             *p = 0;
       
   587             posx = gInput.ConvertToNumber( buf );
       
   588             posy = gInput.ConvertToNumber( p+1 );
       
   589             }
       
   590         else if( _wcsicmp( gInput.iToken, L"END" ) == 0 )
       
   591             {
       
   592             iData->CreateBmpAnimDef( realIid, interval, playMode, flash, frames, restriction );
       
   593             return;
       
   594             }
       
   595         else
       
   596             {
       
   597             TSDCIID frameIid = ParseBitmapSource( false, restriction, svganim );
       
   598 
       
   599             TSDCBmpAnimFrame entry;
       
   600             entry.iIID = frameIid;
       
   601             entry.iTime = time;
       
   602             entry.iPosX = posx;
       
   603             entry.iPosY = posy;
       
   604             frames.push_back( entry );
       
   605             time = -1;
       
   606             posx = 0;
       
   607             posy = 0;
       
   608             }
       
   609         }
       
   610 
       
   611     throw CSDCException( ESDCParseError, "No END token for BMPANIM" );
       
   612     }
       
   613 
       
   614 void CSDCReader::ParseAppIcon()
       
   615     {
       
   616     gInput.NextToken();
       
   617     int uid;
       
   618     if( _wcsnicmp( gInput.iToken, L"UID=", 4 ) == 0 )
       
   619         {
       
   620         uid = gInput.ConvertToNumber( gInput.iToken+4 );
       
   621         }
       
   622     else
       
   623         {
       
   624         throw CSDCException( ESDCParseError, "UID parameter expected for APPICON" );
       
   625         }
       
   626 
       
   627     int restriction( iData->iCurrentRestriction );
       
   628 
       
   629     vector<TSDCIID> iconBitmaps;
       
   630     while( gInput.NextTokenAllowLF() )
       
   631         {
       
   632         if( _wcsicmp( gInput.iToken, L"END" ) == 0)
       
   633             {
       
   634             TSDCIID realIid;
       
   635             realIid.iMajor = EAknsMajorAppIcon;
       
   636             realIid.iMinor = uid;
       
   637             iData->CreateAppIconDef( realIid, iconBitmaps, restriction );
       
   638             return;
       
   639             }
       
   640         else
       
   641             {
       
   642             TSDCIID iconIid = ParseBitmapSource( true, restriction );
       
   643             iconBitmaps.push_back( iconIid );
       
   644             TSDCBitmapDef* bmpDef = iData->GetBitmapDef( iconIid );
       
   645             if( !bmpDef )
       
   646                 {
       
   647                 printf( "WARNING: Application icon possibly uses a bitmap outside its class (line %i)\n", gInput.iLineNumber );
       
   648                 }
       
   649             else if( bmpDef->iAppIconBitmap == false )
       
   650                 {
       
   651                 printf( "WARNING: Application icon uses a bitmap outside its class (line %i)\n", gInput.iLineNumber );
       
   652                 }
       
   653             }
       
   654         }
       
   655 
       
   656     throw CSDCException( ESDCParseError, "No END token for APPICON" );
       
   657     }
       
   658 
       
   659 void CSDCReader::ParsePalette()
       
   660     {
       
   661     gInput.NextToken();
       
   662     if( _wcsnicmp( gInput.iToken, L"SCHEME=", 7 ) == 0 )
       
   663         {
       
   664         iData->iPalettePid.iPID2 = 0;
       
   665         iData->iPalettePid.iPID1 = gInput.ConvertToNumber( gInput.iToken+7 );
       
   666         }
       
   667     else
       
   668         {
       
   669         throw CSDCException( ESDCParseError, "SCHEME parameter expected for PALETTE" );
       
   670         }
       
   671     }
       
   672 
       
   673 void CSDCReader::ParseString()
       
   674     {
       
   675     gInput.NextToken();
       
   676     TSDCIID realIid;
       
   677     int restriction( iData->iCurrentRestriction );
       
   678     if( _wcsnicmp( gInput.iToken, L"IID=", 4 ) == 0 )
       
   679         {
       
   680         wchar_t iidBuf[512];
       
   681         wcscpy( iidBuf, gInput.iToken+4 );
       
   682         StripIIDPrefix( iidBuf, restriction );
       
   683         const TSDCIIDEntry* iid = SDCIIDConstants::FindPlain( iidBuf );
       
   684         if( !iid ) UnknownIIDError( gInput.iToken+4 );
       
   685         realIid.iMajor = iid->iMajor;
       
   686         realIid.iMinor = iid->iMinor;
       
   687         }
       
   688     else
       
   689         {
       
   690         throw CSDCException( ESDCParseError, "IID parameter expected for SOUND/STRING" );
       
   691         }
       
   692 
       
   693     gInput.NextStringToken();
       
   694     iData->CreateStringDef( realIid, gInput.iToken, restriction );
       
   695     }
       
   696 
       
   697 void CSDCReader::ParseScalableItem()
       
   698     {
       
   699     gInput.NextToken();
       
   700     TSDCIID realIid;
       
   701     int restriction( iData->iCurrentRestriction );
       
   702     if( _wcsnicmp( gInput.iToken, L"IID=", 4 ) == 0 )
       
   703         {
       
   704         wchar_t iidBuf[512];
       
   705         wcscpy( iidBuf, gInput.iToken+4 );
       
   706         StripIIDPrefix( iidBuf, restriction );
       
   707         const TSDCIIDEntry* iid = SDCIIDConstants::FindPlain( iidBuf );
       
   708         if( !iid ) UnknownIIDError( gInput.iToken+4 );
       
   709         realIid.iMajor = iid->iMajor;
       
   710         realIid.iMinor = iid->iMinor;
       
   711         }
       
   712     else
       
   713         {
       
   714         throw CSDCException( ESDCParseError, "IID parameter expected for SCALABLEITEM" );
       
   715         }
       
   716 
       
   717     gInput.NextToken();
       
   718     int input = 0;
       
   719     if( _wcsnicmp( gInput.iToken, L"INPUT=", 6 ) == 0 )
       
   720         {
       
   721         input = CSDCInput::ConvertToLayer( gInput.iToken+6 );
       
   722         }
       
   723     else if( _wcsnicmp( gInput.iToken, L"REFIID=", 7 ) == 0 )
       
   724         {
       
   725         // Reference only
       
   726         TSDCIID refIid;
       
   727         int ignored;
       
   728         wchar_t iidBuf[512];
       
   729         wcscpy( iidBuf, gInput.iToken+7 );
       
   730         StripIIDPrefix( iidBuf, ignored );
       
   731         const TSDCIIDEntry* iid = SDCIIDConstants::FindPlain( iidBuf );
       
   732         if( !iid ) UnknownIIDError( gInput.iToken+7 );
       
   733         refIid.iMajor = iid->iMajor;
       
   734         refIid.iMinor = iid->iMinor;
       
   735         char buf[512];
       
   736         CSDCInput::ConvertToAscii( buf, gInput.iToken );
       
   737         if( !iData->IsDefined( refIid ) )
       
   738             {
       
   739             printf( "INFO: IID reference (%s) currently points to non-existent element (line %i)\n", buf, gInput.iLineNumber );
       
   740             }
       
   741         iData->CreateScalableItemRefDef( realIid, refIid, restriction );
       
   742         return;
       
   743         }
       
   744     else
       
   745         {
       
   746         throw CSDCException( ESDCParseError, "INPUT parameter expected for SCALABLEITEM" );
       
   747         }
       
   748 
       
   749     gInput.NextToken();
       
   750     int output = 0;
       
   751     if( _wcsnicmp( gInput.iToken, L"OUTPUT=", 7 ) == 0 )
       
   752         {
       
   753         output = CSDCInput::ConvertToLayer( gInput.iToken+7 );
       
   754         }
       
   755     else
       
   756         {
       
   757         throw CSDCException( ESDCParseError, "OUTPUT parameter expected for SCALABLEITEM" );
       
   758         }
       
   759 
       
   760     vector<TSDCEffectCommand> commands;
       
   761     while( gInput.NextTokenAllowLF() )
       
   762         {
       
   763         if( _wcsicmp( gInput.iToken, L"END" ) == 0)
       
   764             {
       
   765             iData->CreateScalableItemDef( realIid, input, output, commands, restriction );
       
   766             return;
       
   767             }
       
   768         else if( _wcsicmp( gInput.iToken, L"EFFECT" ) == 0)
       
   769             {
       
   770             TSDCEffectCommand command;
       
   771             ParseEffectCommand( command );
       
   772             commands.push_back( command );
       
   773             }
       
   774         else
       
   775             {
       
   776             UnexpectedTokenError( gInput.iToken, L"EFFECT or END" );
       
   777             }
       
   778         }
       
   779 
       
   780     throw CSDCException( ESDCParseError, "No END token for SCALABLEITEM" );
       
   781     }
       
   782 
       
   783 void CSDCReader::ParseAnimation()
       
   784     {
       
   785     gInput.NextToken();
       
   786     TSDCIID realIid;
       
   787     int restriction( iData->iCurrentRestriction );
       
   788     if( _wcsnicmp( gInput.iToken, L"IID=", 4 ) == 0 )
       
   789         {
       
   790         wchar_t iidBuf[512];
       
   791         wcscpy( iidBuf, gInput.iToken+4 );
       
   792         StripIIDPrefix( iidBuf, restriction );
       
   793         const TSDCIIDEntry* iid = SDCIIDConstants::FindPlain( iidBuf );
       
   794         if( !iid ) UnknownIIDError( gInput.iToken+4 );
       
   795         realIid.iMajor = iid->iMajor;
       
   796         realIid.iMinor = iid->iMinor;
       
   797         }
       
   798     else
       
   799         {
       
   800         throw CSDCException( ESDCParseError, "IID parameter expected for ANIMATION" );
       
   801         }
       
   802 
       
   803     gInput.NextToken();
       
   804     int input = 0;
       
   805     if( _wcsnicmp( gInput.iToken, L"INPUT=", 6 ) == 0 )
       
   806         {
       
   807         input = CSDCInput::ConvertToLayer( gInput.iToken+6 );
       
   808         }
       
   809     else
       
   810         {
       
   811         throw CSDCException( ESDCParseError, "INPUT parameter expected for ANIMATION" );
       
   812         }
       
   813 
       
   814     gInput.NextToken();
       
   815     int output = 0;
       
   816     if( _wcsnicmp( gInput.iToken, L"OUTPUT=", 7 ) == 0 )
       
   817         {
       
   818         output = CSDCInput::ConvertToLayer( gInput.iToken+7 );
       
   819         }
       
   820     else
       
   821         {
       
   822         throw CSDCException( ESDCParseError, "OUTPUT parameter expected for ANIMATION" );
       
   823         }
       
   824 
       
   825     gInput.NextToken();
       
   826     int mininterval = 0;
       
   827     if( _wcsnicmp( gInput.iToken, L"MININTERVAL=", 12 ) == 0 )
       
   828         {
       
   829         mininterval = CSDCInput::ConvertToNumber( gInput.iToken+12 );
       
   830         }
       
   831     else
       
   832         {
       
   833         throw CSDCException( ESDCParseError, "MININTERVAL parameter expected for ANIMATION" );
       
   834         }
       
   835 
       
   836     gInput.NextTokenAllowLF();
       
   837 
       
   838     bool morphing = false;
       
   839     if( _wcsicmp( gInput.iToken, L"MORPHING" ) == 0 )
       
   840         {
       
   841         morphing = true;
       
   842 
       
   843         gInput.NextTokenAllowLF();
       
   844         }
       
   845 
       
   846     vector<TSDCEffectCommand> preprocessCommands;
       
   847     if( _wcsicmp( gInput.iToken, L"PREPROCESS" ) == 0 )
       
   848         {
       
   849         bool terminated( false );
       
   850         while( gInput.NextTokenAllowLF() )
       
   851             {
       
   852             if( _wcsicmp( gInput.iToken, L"END" ) == 0)
       
   853                 {
       
   854                 terminated = true;
       
   855                 break;
       
   856                 }
       
   857             else if( _wcsicmp( gInput.iToken, L"EFFECT" ) == 0)
       
   858                 {
       
   859                 TSDCEffectCommand command;
       
   860                 ParseEffectCommand( command );
       
   861                 preprocessCommands.push_back( command );
       
   862                 }
       
   863             else
       
   864                 {
       
   865                 UnexpectedTokenError( gInput.iToken, L"EFFECT or END" );
       
   866                 }
       
   867             }
       
   868         if( !terminated ) throw CSDCException( ESDCParseError, "No END token for ANIMATION/PREPROCESS" );
       
   869 
       
   870         gInput.NextTokenAllowLF();
       
   871         }
       
   872 
       
   873     vector<TSDCEffectCommand> animCommands;
       
   874     vector<TSDCAnimParamGroup> values;
       
   875     vector<TSDCAnimParamGroup> timingModels;
       
   876     vector<TSDCAnimParamGroup> sizeBoundParams;
       
   877 
       
   878     bool terminated( false );
       
   879     do
       
   880         {
       
   881         if( _wcsicmp( gInput.iToken, L"END" ) == 0)
       
   882             {
       
   883             terminated = true;
       
   884             break;
       
   885             }
       
   886         else if( _wcsicmp( gInput.iToken, L"COMMAND" ) == 0)
       
   887             {
       
   888             TSDCEffectCommand command;
       
   889             ParseEffectCommand( command );
       
   890             animCommands.push_back( command );
       
   891             }
       
   892         else if( _wcsicmp( gInput.iToken, L"VALUE" ) == 0)
       
   893             {
       
   894             gInput.NextToken();
       
   895             if( _wcsnicmp( gInput.iToken, L"UID=", 4 ) )
       
   896                 throw new CSDCException( ESDCParseError, "UID parameter expected for VALUE" );
       
   897             int uid = CSDCInput::ConvertToNumber( gInput.iToken+4 );
       
   898 
       
   899             gInput.NextToken();
       
   900             if( _wcsnicmp( gInput.iToken, L"TIMINGID=", 9 ) )
       
   901                 throw new CSDCException( ESDCParseError, "TIMINGID parameter expected for VALUE" );
       
   902             int timingId = CSDCInput::ConvertToNumber( gInput.iToken+9 );
       
   903 
       
   904             TSDCAnimParamGroup paramGroup;
       
   905 
       
   906             while( gInput.NextTokenAllowLF() && _wcsicmp( gInput.iToken, L"END" ) )
       
   907                 {
       
   908                 TSDCEffectParameter parameter;
       
   909                 ParseEffectParameter( parameter );
       
   910                 paramGroup.iParameters.push_back( parameter );
       
   911                 }
       
   912 
       
   913             paramGroup.iValueA = uid;
       
   914             paramGroup.iValueB = timingId;
       
   915             values.push_back( paramGroup );
       
   916             }
       
   917         else if( _wcsicmp( gInput.iToken, L"TIMINGMODEL" ) == 0)
       
   918             {
       
   919             gInput.NextToken();
       
   920             if( _wcsnicmp( gInput.iToken, L"UID=", 4 ) )
       
   921                 throw new CSDCException( ESDCParseError, "UID parameter expected for TIMINGMODEL" );
       
   922             int uid = CSDCInput::ConvertToNumber( gInput.iToken+4 );
       
   923 
       
   924             TSDCAnimParamGroup paramGroup;
       
   925 
       
   926             while( gInput.NextTokenAllowLF() && _wcsicmp( gInput.iToken, L"END" ) )
       
   927                 {
       
   928                 TSDCEffectParameter parameter;
       
   929                 ParseEffectParameter( parameter );
       
   930                 paramGroup.iParameters.push_back( parameter );
       
   931                 }
       
   932 
       
   933             paramGroup.iValueA = uid;
       
   934             paramGroup.iValueB = 0;
       
   935             timingModels.push_back( paramGroup );
       
   936             }
       
   937         else if( _wcsicmp( gInput.iToken, L"SIZEBOUNDPARAM" ) == 0)
       
   938             {
       
   939             gInput.NextToken();
       
   940             TSDCEffectParameter parameter;
       
   941             parameter.iType = 0;
       
   942             wcscpy( parameter.iName, gInput.iToken );
       
   943             parameter.iNumber = 0;
       
   944 
       
   945             gInput.NextToken();
       
   946             if( _wcsnicmp( gInput.iToken, L"VALUEID=", 8 ) )
       
   947                 throw new CSDCException( ESDCParseError, "VALUEID parameter expected for SIZEBOUNDPARAM" );
       
   948             int valueId = CSDCInput::ConvertToNumber( gInput.iToken+8 );
       
   949 
       
   950             gInput.NextToken();
       
   951             int flags = 0;
       
   952             if( _wcsicmp( gInput.iToken, L"FLAGS=W" ) == 0 )
       
   953                 {
       
   954                 flags = 1;
       
   955                 }
       
   956             else if( _wcsicmp( gInput.iToken, L"FLAGS=H" ) == 0 )
       
   957                 {
       
   958                 flags = 2;
       
   959                 }
       
   960             else if( _wcsicmp( gInput.iToken, L"FLAGS=W_AND_H" ) == 0 )
       
   961                 {
       
   962                 flags = 3;
       
   963                 }
       
   964             else throw new CSDCException( ESDCParseError, "FLAGS=W|H|W_AND_H parameter expected for SIZEBOUNDPARAM" );
       
   965 
       
   966             TSDCAnimParamGroup paramGroup;
       
   967             paramGroup.iValueA = valueId;
       
   968             paramGroup.iValueB = flags;
       
   969             paramGroup.iParameters.push_back( parameter );
       
   970             sizeBoundParams.push_back( paramGroup );
       
   971             }
       
   972         else
       
   973             {
       
   974             UnexpectedTokenError( gInput.iToken, L"COMMAND, VALUE, TIMINGMODEL, SIZEBOUNDPARAM, or END" );
       
   975             }
       
   976         }
       
   977     while( gInput.NextTokenAllowLF() );
       
   978     if( !terminated ) throw CSDCException( ESDCParseError, "No END token for ANIMATION" );
       
   979 
       
   980     iData->CreateAnimationDef( realIid, input, output, mininterval, preprocessCommands, animCommands,
       
   981         values, timingModels, sizeBoundParams, morphing, restriction );
       
   982     }
       
   983 
       
   984 void CSDCReader::ParseBitmapPath()
       
   985     {
       
   986     if( gInput.NextToken() )
       
   987         {
       
   988         bool changed( true );
       
   989         if( _wcsicmp( gInput.iToken, iData->iBmpPath ) == 0 ) changed = false;
       
   990         iData->SetBmpPath( gInput.iToken );
       
   991         char buf[512];
       
   992         CSDCInput::ConvertToAscii( buf, gInput.iToken );
       
   993         if( changed )
       
   994             printf("NOTE: Bitmap source path set to %s\n", buf );
       
   995         }
       
   996     else
       
   997         {
       
   998         iData->SetBmpPath( NULL );
       
   999         printf("NOTE: Bitmap source path set to automatic.\n" );
       
  1000         }
       
  1001     }
       
  1002 
       
  1003 void CSDCReader::ParseRestriction()
       
  1004     {
       
  1005     if( !iData->IsScalable() )
       
  1006         printf( "WARNING: RESTRICTION elements is only allowed in scalable skins, layout types will not work with this skin (line %i)\n", gInput.iLineNumber );
       
  1007 
       
  1008     gInput.NextToken();
       
  1009     if( _wcsicmp( gInput.iToken, L"S60_2_6" ) == 0 )
       
  1010         {
       
  1011         iData->iCurrentRestriction = 0x0206;
       
  1012         printf("NOTE: Current restriction set to 2.6\n");
       
  1013         }
       
  1014     else if( _wcsicmp( gInput.iToken, L"S60_2_7" ) == 0 )
       
  1015         {
       
  1016         iData->iCurrentRestriction = 0x0207;
       
  1017         printf("NOTE: Current restriction set to 2.7\n");
       
  1018         }
       
  1019     else if( _wcsicmp( gInput.iToken, L"S60_2_8" ) == 0 )
       
  1020         {
       
  1021         iData->iCurrentRestriction = 0x0208;
       
  1022         printf("NOTE: Current restriction set to 2.8\n");
       
  1023         }
       
  1024     else if( _wcsicmp( gInput.iToken, L"S60_3_0" ) == 0 )
       
  1025         {
       
  1026         iData->iCurrentRestriction = 0x0300;
       
  1027         printf("NOTE: Current restriction set to 3.0\n");
       
  1028         }
       
  1029     else if( _wcsicmp( gInput.iToken, L"S60_3_1" ) == 0 )
       
  1030         {
       
  1031         iData->iCurrentRestriction = 0x0301;
       
  1032         printf("NOTE: Current restriction set to 3.1\n");
       
  1033         }
       
  1034     else if( _wcsicmp( gInput.iToken, L"S60_3_2" ) == 0 )
       
  1035         {
       
  1036         iData->iCurrentRestriction = 0x0302;
       
  1037         printf("NOTE: Current restriction set to 3.2\n");
       
  1038         }
       
  1039     else if( _wcsicmp( gInput.iToken, L"S60_5_0" ) == 0 )
       
  1040         {
       
  1041         iData->iCurrentRestriction = 0x0500;
       
  1042         printf("NOTE: Current restriction set to 5.0\n");
       
  1043         }
       
  1044     else if( _wcsicmp( gInput.iToken, L"LAY_W" ) == 0 )
       
  1045         {
       
  1046         iData->iCurrentRestriction = 0x00010000;
       
  1047         printf("NOTE: Current restriction set to Layout/Non-Mirrored\n");
       
  1048         }
       
  1049     else if( _wcsicmp( gInput.iToken, L"LAY_AH" ) == 0 )
       
  1050         {
       
  1051         iData->iCurrentRestriction = 0x00020000;
       
  1052         printf("NOTE: Current restriction set to Layout/Mirrored\n");
       
  1053         }
       
  1054     else if( _wcsnicmp( gInput.iToken, L"LANG=", 5 ) == 0 )
       
  1055         {
       
  1056         int language = (CSDCInput::ConvertToNumber( gInput.iToken+5 ))&0xffff;
       
  1057         printf("NOTE: Current restriction set to Language/langcode:%d\n", language);
       
  1058         iData->iCurrentRestriction = language|0x00030000;
       
  1059         iData->iLanguageVector.push_back(language|0x00030000);
       
  1060         }
       
  1061     else if( _wcsicmp( gInput.iToken, L"NONE" ) == 0 )
       
  1062         {
       
  1063         iData->iCurrentRestriction = 0;
       
  1064         printf("NOTE: Current restriction cleared\n");
       
  1065         }
       
  1066     else
       
  1067         {
       
  1068         throw CSDCException( ESDCParseError, "Unknown specifier for RESTRICTION element" );
       
  1069         }
       
  1070     }
       
  1071 
       
  1072 TSDCIID CSDCReader::ParseBitmapSource( const bool aAppIcon, const int aRestriction, const bool aSvgAnim )
       
  1073     {
       
  1074     int restriction( iData->iCurrentRestriction );
       
  1075     if( _wcsnicmp( gInput.iToken, L"IID=", 4 ) == 0 )
       
  1076         {
       
  1077         wchar_t iidBuf[512];
       
  1078         wcscpy( iidBuf, gInput.iToken+4 );
       
  1079         StripIIDPrefix( iidBuf, restriction );
       
  1080         char buf[512];
       
  1081         gInput.ConvertToAscii( buf, gInput.iToken );
       
  1082         if( restriction && (restriction == aRestriction) )
       
  1083             {
       
  1084             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 );
       
  1085             }
       
  1086         else if( restriction )
       
  1087             {
       
  1088             printf( "WARNING: IID reference (%s) is restricted. Relative validity can not be checked and may be broken (line %i)\n", buf, gInput.iLineNumber );
       
  1089             }
       
  1090         else if( aRestriction )
       
  1091             {
       
  1092             printf( "NOTE: Non-restricted IID reference (%s) inside restricted compound (line %i)\n", buf, gInput.iLineNumber );
       
  1093             }
       
  1094         const TSDCIIDEntry* iid = SDCIIDConstants::FindPlain( iidBuf );
       
  1095         if( !iid ) UnknownIIDError( gInput.iToken+4 );
       
  1096         TSDCIID realIid;
       
  1097         realIid.iMajor = iid->iMajor;
       
  1098         realIid.iMinor = iid->iMinor;
       
  1099         return realIid;
       
  1100         }
       
  1101     restriction = aRestriction;
       
  1102 
       
  1103     TSDCColorDepth colorDepth = CSDCInput::ConvertToColorDepth( gInput.iToken );
       
  1104 
       
  1105     gInput.NextToken();
       
  1106     TSDCIID realIid;
       
  1107     const TSDCIIDEntry* iid = SDCIIDConstants::FindBmpName( gInput.iToken );
       
  1108     if( iid )
       
  1109         {
       
  1110         realIid.iMajor = iid->iMajor;
       
  1111         realIid.iMinor = iid->iMinor;
       
  1112         if( restriction )
       
  1113             {
       
  1114             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 );
       
  1115             }
       
  1116         }
       
  1117     else
       
  1118         {
       
  1119         if( (iData->iPid.iPID2==0) && (iData->iPid.iPID1!=0) )
       
  1120             {
       
  1121             realIid.iMajor = iData->iPid.iPID1;
       
  1122             }
       
  1123         else
       
  1124             {
       
  1125             realIid.iMajor = -4;
       
  1126             }
       
  1127         realIid.iMinor = iData->iNextOwnMinor++;
       
  1128         char buf[512];
       
  1129         gInput.ConvertToAscii( buf, gInput.iToken );
       
  1130         printf( "NOTE: Generated IID (0x%x,0x%x) for %s (line %i)\n", realIid.iMajor, realIid.iMinor, buf, gInput.iLineNumber );
       
  1131         if( restriction )
       
  1132             {
       
  1133             printf( "NOTE: Restriction inherited to generated IID (0x%x,0x%x) for %s (line %i)\n", realIid.iMajor, realIid.iMinor, buf, gInput.iLineNumber );
       
  1134             }
       
  1135         }
       
  1136 
       
  1137     bool svg = CSDCInput::IsSvgFile( gInput.iToken );
       
  1138     TSDCMBMEntry* mbmEntry = iData->AppendMbmEntry( svg, colorDepth, gInput.iToken, aSvgAnim );
       
  1139     int mbmIndex = mbmEntry->iIndex;
       
  1140 
       
  1141     TSDCImageAttributes attributes;
       
  1142     attributes.iAttributeFlags = ESDCImageAttributeNone;
       
  1143     attributes.iCoordX = 0;
       
  1144     attributes.iCoordY = 0;
       
  1145     attributes.iSizeW = 0;
       
  1146     attributes.iSizeH = 0;
       
  1147     attributes.iAlignmentFlags = ESDCImageAlignNone;
       
  1148 
       
  1149     if( iData->IsScalable() ) {
       
  1150         attributes.iAttributeFlags |= ESDCImageAttributeNBC;
       
  1151         }
       
  1152 
       
  1153     int maskIndex = -1;
       
  1154 
       
  1155     while( gInput.NextToken() )
       
  1156         {
       
  1157         if( _wcsnicmp( gInput.iToken, L"MASK=", 5 ) == 0 )
       
  1158             {
       
  1159             if( svg ) throw CSDCException( ESDCParseError, "SVG icon can not have a named mask" );
       
  1160             if( mbmEntry->iMaskColorDepth!=ESDCColorDepthNone )
       
  1161                 {
       
  1162                 printf("NOTE: Mask already defined, second definition ignored (line %i)\n", gInput.iLineNumber );
       
  1163                 }
       
  1164             else
       
  1165                 {
       
  1166                 const wchar_t* maskFile = gInput.iToken+5;
       
  1167                 mbmEntry->iMaskColorDepth = ESDCColorDepth1;
       
  1168                 wcscpy( mbmEntry->iMaskSourceFilename, maskFile );
       
  1169                 }
       
  1170             maskIndex = mbmIndex+1;
       
  1171             }
       
  1172         else if( _wcsnicmp( gInput.iToken, L"SOFTMASK=", 9 ) == 0 )
       
  1173             {
       
  1174             if( svg ) throw CSDCException( ESDCParseError, "SVG icon can not have a named mask" );
       
  1175             if( mbmEntry->iMaskColorDepth!=ESDCColorDepthNone )
       
  1176                 {
       
  1177                 printf("NOTE: Mask already defined, second definition ignored (line %i)\n", gInput.iLineNumber );
       
  1178                 }
       
  1179             else
       
  1180                 {
       
  1181                 const wchar_t* maskFile = gInput.iToken+9;
       
  1182                 mbmEntry->iMaskColorDepth = ESDCColorDepth8;
       
  1183                 wcscpy( mbmEntry->iMaskSourceFilename, maskFile );
       
  1184                 }
       
  1185             maskIndex = mbmIndex+1;
       
  1186             }
       
  1187         else if( _wcsicmp( gInput.iToken, L"MASK" ) == 0 )
       
  1188             {
       
  1189             if( !svg ) throw CSDCException( ESDCParseError, "Non-SVG icon can not have an unnamed mask" );
       
  1190             mbmEntry->iMaskColorDepth = ESDCColorDepth1;
       
  1191             maskIndex = mbmIndex+1;
       
  1192             }
       
  1193         else if( _wcsicmp( gInput.iToken, L"SOFTMASK" ) == 0 )
       
  1194             {
       
  1195             if( !svg ) throw CSDCException( ESDCParseError, "Non-SVG icon can not have an unnamed mask" );
       
  1196             mbmEntry->iMaskColorDepth = ESDCColorDepth8;
       
  1197             maskIndex = mbmIndex+1;
       
  1198             }
       
  1199         else
       
  1200             {
       
  1201             ProcessAttribute( attributes, gInput.iToken );
       
  1202             }
       
  1203         }
       
  1204 
       
  1205     if( (maskIndex!=-1) && (attributes.iAttributeFlags&ESDCImageAttributeTile) )
       
  1206         {
       
  1207         printf( "WARNING: TILE attribute used with masked bitmap (line %i)\n", gInput.iLineNumber );
       
  1208         }
       
  1209 
       
  1210     iData->CreateBitmapDef( realIid, mbmIndex, maskIndex, attributes, aAppIcon, restriction );
       
  1211     return realIid;
       
  1212     }
       
  1213 
       
  1214 void CSDCReader::ProcessAttribute( TSDCImageAttributes& aAttributes, wchar_t* aSource )
       
  1215     {
       
  1216     wchar_t buf[512];
       
  1217     wcscpy( buf, aSource );
       
  1218 
       
  1219     if( _wcsnicmp( buf, L"COORDS=", 7 ) == 0 )
       
  1220         {
       
  1221         wchar_t* p = wcsstr( buf, L"," );
       
  1222         if( !p ) throw CSDCException( ESDCParseError, "No comma in image attribute COORDS" );
       
  1223         *p = 0;
       
  1224         aAttributes.iAttributeFlags |= ESDCImageAttributeCoords;
       
  1225         aAttributes.iCoordX = gInput.ConvertToNumber( buf+7 );
       
  1226         aAttributes.iCoordY = gInput.ConvertToNumber( p+1 );
       
  1227         }
       
  1228     else if( _wcsnicmp( buf, L"SIZE=", 5 ) == 0 )
       
  1229         {
       
  1230         wchar_t* p = wcsstr( buf, L"," );
       
  1231         if( !p ) throw CSDCException( ESDCParseError, "No comma in image attribute SIZE" );
       
  1232         *p = 0;
       
  1233         aAttributes.iAttributeFlags |= ESDCImageAttributeSize;
       
  1234         aAttributes.iSizeW = gInput.ConvertToNumber( buf+5 );
       
  1235         aAttributes.iSizeH  = gInput.ConvertToNumber( p+1 );
       
  1236         }
       
  1237     else if( _wcsicmp( buf, L"STRETCH" ) == 0 )
       
  1238         {
       
  1239         aAttributes.iAttributeFlags |= ESDCImageAttributeStretch;
       
  1240         }
       
  1241     else if( _wcsicmp( buf, L"TILE" ) == 0 )
       
  1242         {
       
  1243         aAttributes.iAttributeFlags |= ESDCImageAttributeTile;
       
  1244         }
       
  1245     else if( _wcsicmp( buf, L"TILEX" ) == 0 )
       
  1246         {
       
  1247         aAttributes.iAttributeFlags |= ESDCImageAttributeTileX;
       
  1248         }
       
  1249     else if( _wcsicmp( buf, L"TILEY" ) == 0 )
       
  1250         {
       
  1251         aAttributes.iAttributeFlags |= ESDCImageAttributeTileY;
       
  1252         }
       
  1253     else if( _wcsnicmp( buf, L"ALIGN=", 6 ) == 0 )
       
  1254         {
       
  1255         if( _wcsicmp( buf+6, L"TL" ) == 0 ) aAttributes.iAlignmentFlags = ESDCImageAlignTL;
       
  1256         else if( _wcsicmp( buf+6, L"TC" ) == 0 ) aAttributes.iAlignmentFlags = ESDCImageAlignTC;
       
  1257         else if( _wcsicmp( buf+6, L"TR" ) == 0 ) aAttributes.iAlignmentFlags = ESDCImageAlignTR;
       
  1258         else if( _wcsicmp( buf+6, L"CL" ) == 0 ) aAttributes.iAlignmentFlags = ESDCImageAlignCL;
       
  1259         else if( _wcsicmp( buf+6, L"CC" ) == 0 ) aAttributes.iAlignmentFlags = ESDCImageAlignCC;
       
  1260         else if( _wcsicmp( buf+6, L"CR" ) == 0 ) aAttributes.iAlignmentFlags = ESDCImageAlignCR;
       
  1261         else if( _wcsicmp( buf+6, L"BL" ) == 0 ) aAttributes.iAlignmentFlags = ESDCImageAlignBL;
       
  1262         else if( _wcsicmp( buf+6, L"BC" ) == 0 ) aAttributes.iAlignmentFlags = ESDCImageAlignBC;
       
  1263         else if( _wcsicmp( buf+6, L"BR" ) == 0 ) aAttributes.iAlignmentFlags = ESDCImageAlignBR;
       
  1264         else throw CSDCException( ESDCParseError, "Unknown parameter for image attribute ALIGN" );
       
  1265 
       
  1266         aAttributes.iAttributeFlags |= ESDCImageAttributeAlign;
       
  1267         }
       
  1268     else throw CSDCException( ESDCParseError, "Unknown attribute parameter" );
       
  1269     }
       
  1270 
       
  1271 void CSDCReader::ParseEffectCommand( TSDCEffectCommand& aCommand )
       
  1272     {
       
  1273     gInput.NextToken();
       
  1274     if( _wcsnicmp( gInput.iToken, L"UID=", 4 ) == 0 )
       
  1275         {
       
  1276         aCommand.iUid = CSDCInput::ConvertToNumber( gInput.iToken+4 );
       
  1277         }
       
  1278     else
       
  1279         {
       
  1280         throw CSDCException( ESDCParseError, "UID parameter expected for EFFECT" );
       
  1281         }
       
  1282 
       
  1283     gInput.NextToken();
       
  1284     if( _wcsnicmp( gInput.iToken, L"INPUTA=", 7 ) == 0 )
       
  1285         {
       
  1286         aCommand.iInputA = CSDCInput::ConvertToLayer( gInput.iToken+7 );
       
  1287         }
       
  1288     else
       
  1289         {
       
  1290         throw CSDCException( ESDCParseError, "INPUTA parameter expected for EFFECT" );
       
  1291         }
       
  1292 
       
  1293     gInput.NextToken();
       
  1294     if( _wcsnicmp( gInput.iToken, L"INPUTB=", 7 ) == 0 )
       
  1295         {
       
  1296         aCommand.iInputB = CSDCInput::ConvertToLayer( gInput.iToken+7 );
       
  1297         }
       
  1298     else
       
  1299         {
       
  1300         throw CSDCException( ESDCParseError, "INPUTB parameter expected for EFFECT" );
       
  1301         }
       
  1302 
       
  1303     gInput.NextToken();
       
  1304     if( _wcsnicmp( gInput.iToken, L"OUTPUT=", 7 ) == 0 )
       
  1305         {
       
  1306         aCommand.iOutput = CSDCInput::ConvertToLayer( gInput.iToken+7 );
       
  1307         }
       
  1308     else
       
  1309         {
       
  1310         throw CSDCException( ESDCParseError, "OUTPUT parameter expected for EFFECT" );
       
  1311         }
       
  1312 
       
  1313     while( gInput.NextTokenAllowLF() )
       
  1314         {
       
  1315         if( _wcsicmp( gInput.iToken, L"END" ) == 0)
       
  1316             {
       
  1317             // Just return, everything should be in the struct by now
       
  1318             return;
       
  1319             }
       
  1320         else
       
  1321             {
       
  1322             TSDCEffectParameter parameter;
       
  1323             ParseEffectParameter( parameter );
       
  1324             aCommand.iParameters.push_back( parameter );
       
  1325             }
       
  1326         }
       
  1327 
       
  1328     throw CSDCException( ESDCParseError, "No END token for EFFECT" );
       
  1329     }
       
  1330 
       
  1331 void CSDCReader::ParseEffectParameter( TSDCEffectParameter& aParameter )
       
  1332     {
       
  1333     if( _wcsicmp( gInput.iToken, L"INT" ) == 0)
       
  1334         {
       
  1335         aParameter.iType = 0;
       
  1336         }
       
  1337     else if( _wcsicmp( gInput.iToken, L"STR" ) == 0)
       
  1338         {
       
  1339         aParameter.iType = 1;
       
  1340         }
       
  1341     else if( _wcsicmp( gInput.iToken, L"BMP" ) == 0)
       
  1342         {
       
  1343         aParameter.iType = 2;
       
  1344         }
       
  1345     else if( _wcsicmp( gInput.iToken, L"NAMEDREF" ) == 0)
       
  1346         {
       
  1347         aParameter.iType = 3;
       
  1348         }
       
  1349     else if( _wcsicmp( gInput.iToken, L"RAW" ) == 0)
       
  1350         {
       
  1351         aParameter.iType = 4;
       
  1352         }
       
  1353     else
       
  1354         {
       
  1355         UnexpectedTokenError( gInput.iToken, L"STR, INT, BMP, RAW or NAMEDREF");
       
  1356         }
       
  1357 
       
  1358     gInput.NextToken();
       
  1359     wcscpy( aParameter.iName, gInput.iToken );
       
  1360 
       
  1361     if( aParameter.iType == 0 )
       
  1362         {
       
  1363         gInput.NextToken();
       
  1364         aParameter.iNumber =  CSDCInput::ConvertToNumber( gInput.iToken );
       
  1365         }
       
  1366     else if( aParameter.iType == 1 )
       
  1367         {
       
  1368         gInput.NextStringToken();
       
  1369         wcscpy( aParameter.iString, gInput.iToken );
       
  1370         }
       
  1371     else if( aParameter.iType == 2 )
       
  1372         {
       
  1373         // Color depth
       
  1374         gInput.NextToken();
       
  1375         aParameter.iColorDepth = CSDCInput::ConvertToColorDepth( gInput.iToken );
       
  1376 
       
  1377         // Filename
       
  1378         gInput.NextToken();
       
  1379         bool svg = CSDCInput::IsSvgFile( gInput.iToken );
       
  1380         TSDCMBMEntry* mbmEntry = iData->AppendMbmEntry( svg, aParameter.iColorDepth, gInput.iToken );
       
  1381         aParameter.iBmpIndex = mbmEntry->iIndex;
       
  1382 
       
  1383         // Mask
       
  1384         aParameter.iMaskIndex = -1;
       
  1385         if( gInput.NextToken() )
       
  1386             {
       
  1387             if( _wcsnicmp( gInput.iToken, L"MASK=", 5 ) == 0 )
       
  1388                 {
       
  1389                 if( svg ) throw CSDCException( ESDCParseError, "SVG icon can not have a named mask" );
       
  1390                 if( mbmEntry->iMaskColorDepth!=ESDCColorDepthNone )
       
  1391                     {
       
  1392                     printf("NOTE: Mask already defined, second definition ignored (line %i)\n", gInput.iLineNumber );
       
  1393                     }
       
  1394                 else
       
  1395                     {
       
  1396                     const wchar_t* maskFile = gInput.iToken+5;
       
  1397                     mbmEntry->iMaskColorDepth = ESDCColorDepth1;
       
  1398                     wcscpy( mbmEntry->iMaskSourceFilename, maskFile );
       
  1399                     }
       
  1400                 aParameter.iMaskIndex = aParameter.iBmpIndex+1;
       
  1401                 }
       
  1402             else if( _wcsnicmp( gInput.iToken, L"SOFTMASK=", 9 ) == 0 )
       
  1403                 {
       
  1404                 if( svg ) throw CSDCException( ESDCParseError, "SVG icon can not have a named mask" );
       
  1405                 if( mbmEntry->iMaskColorDepth!=ESDCColorDepthNone )
       
  1406                     {
       
  1407                     printf("NOTE: Mask already defined, second definition ignored (line %i)\n", gInput.iLineNumber );
       
  1408                     }
       
  1409                 else
       
  1410                     {
       
  1411                     const wchar_t* maskFile = gInput.iToken+9;
       
  1412                     mbmEntry->iMaskColorDepth = ESDCColorDepth8;
       
  1413                     wcscpy( mbmEntry->iMaskSourceFilename, maskFile );
       
  1414                     }
       
  1415                 aParameter.iMaskIndex = aParameter.iBmpIndex+1;
       
  1416                 }
       
  1417             else if( _wcsicmp( gInput.iToken, L"MASK" ) == 0 )
       
  1418                 {
       
  1419                 if( !svg ) throw CSDCException( ESDCParseError, "Non-SVG icon can not have an unnamed mask" );
       
  1420                 mbmEntry->iMaskColorDepth = ESDCColorDepth1;
       
  1421                 aParameter.iMaskIndex = aParameter.iBmpIndex+1;
       
  1422                 }
       
  1423             else if( _wcsicmp( gInput.iToken, L"SOFTMASK" ) == 0 )
       
  1424                 {
       
  1425                 if( !svg ) throw CSDCException( ESDCParseError, "Non-SVG icon can not have an unnamed mask" );
       
  1426                 mbmEntry->iMaskColorDepth = ESDCColorDepth8;
       
  1427                 aParameter.iMaskIndex = aParameter.iBmpIndex+1;
       
  1428                 }
       
  1429             else
       
  1430                 {
       
  1431                 UnexpectedTokenError( gInput.iToken, L"MASK or SOFTMASK" );
       
  1432                 }
       
  1433             }
       
  1434         }
       
  1435     else if( aParameter.iType == 3 )
       
  1436         {
       
  1437         gInput.NextToken();
       
  1438         if( _wcsnicmp( gInput.iToken, L"VALUEID=", 8 ) == 0 )
       
  1439             {
       
  1440             aParameter.iNumber = CSDCInput::ConvertToNumber( gInput.iToken+8 );
       
  1441             }
       
  1442         else
       
  1443             {
       
  1444             throw CSDCException( ESDCParseError, "VALUEID parameter expected for NAMEDREF" );
       
  1445             }
       
  1446         }
       
  1447     else if( aParameter.iType == 4 )
       
  1448         {
       
  1449         int tokens = gInput.NextRawToken();
       
  1450         aParameter.iRawDataCount = tokens;
       
  1451         memcpy( aParameter.iString, gInput.iToken, tokens * sizeof(wchar_t) );
       
  1452         }
       
  1453     }
       
  1454 
       
  1455 void CSDCReader::UnexpectedTokenError( wchar_t* aWrongToken, wchar_t* aRightToken )
       
  1456     {
       
  1457     char wrongBuf[512];
       
  1458     gInput.ConvertToAscii( wrongBuf, aWrongToken );
       
  1459     char rightBuf[512];
       
  1460     gInput.ConvertToAscii( rightBuf, aRightToken );
       
  1461 
       
  1462     char buf[512];
       
  1463     strcpy( buf, "Expected \"" );
       
  1464     strcat( buf, rightBuf );
       
  1465     strcat( buf, "\", but \"" );
       
  1466     strcat( buf, wrongBuf );
       
  1467     strcat( buf, "\" found instead" );
       
  1468     throw CSDCException( ESDCParseError, buf );
       
  1469     }
       
  1470 
       
  1471 void CSDCReader::UnknownIIDError( wchar_t* aWrongIID )
       
  1472     {
       
  1473     char wrongBuf[512];
       
  1474     gInput.ConvertToAscii( wrongBuf, aWrongIID );
       
  1475 
       
  1476     char buf[512];
       
  1477     strcpy( buf, "No match found for item ID \"" );
       
  1478     strcat( buf, wrongBuf );
       
  1479     strcat( buf, "\"" );
       
  1480     throw CSDCException( ESDCParseError, buf );
       
  1481     }
       
  1482 
       
  1483 void CSDCReader::StripIIDPrefix( wchar_t* aIID, int& aRestriction )
       
  1484     {
       
  1485     wchar_t* delimiter = wcschr( aIID, '%' );
       
  1486     if( !delimiter )
       
  1487         {
       
  1488         return;
       
  1489         }
       
  1490 
       
  1491     if( iData->iCurrentRestriction )
       
  1492         throw CSDCException( ESDCParseError, "No item-based restriction can be used where RESTRICTION element already applies" );
       
  1493 
       
  1494     wchar_t buf[512];
       
  1495     wcscpy( buf, delimiter+1 );
       
  1496 
       
  1497     *delimiter = 0;
       
  1498     if( _wcsicmp( aIID, L"S60_2_6" ) == 0 )
       
  1499         {
       
  1500         aRestriction = 0x0206;
       
  1501         }
       
  1502     else if( _wcsicmp( aIID, L"S60_2_7" ) == 0 )
       
  1503         {
       
  1504         aRestriction = 0x0207;
       
  1505         }
       
  1506     else if( _wcsicmp( aIID, L"S60_2_8" ) == 0 )
       
  1507         {
       
  1508         aRestriction = 0x0208;
       
  1509         }
       
  1510     else if( _wcsicmp( aIID, L"S60_3_0" ) == 0 )
       
  1511         {
       
  1512         aRestriction = 0x0300;
       
  1513         }
       
  1514     else if( _wcsicmp( aIID, L"S60_3_1" ) == 0 )
       
  1515         {
       
  1516         aRestriction = 0x0301;
       
  1517         }
       
  1518     else if( _wcsicmp( aIID, L"S60_3_2" ) == 0 )
       
  1519         {
       
  1520         aRestriction = 0x0302;
       
  1521         }
       
  1522     else if( _wcsicmp( aIID, L"S60_5_0" ) == 0 )
       
  1523         {
       
  1524         aRestriction = 0x0500;
       
  1525         }
       
  1526     else if( _wcsicmp( aIID, L"LAY_W" ) == 0 )
       
  1527         {
       
  1528         aRestriction = 0x00010000;
       
  1529         }
       
  1530     else if( _wcsicmp( aIID, L"LAY_AH" ) == 0 )
       
  1531         {
       
  1532         aRestriction = 0x00020000;
       
  1533         }
       
  1534     else
       
  1535         {
       
  1536         throw CSDCException( ESDCParseError, "Unknown release restriction prefix in IID" );
       
  1537         }
       
  1538 
       
  1539     wcscpy( aIID, buf );
       
  1540     }
       
  1541 
       
  1542 // End of file