xcfw/src/xcfwlocalizer.cpp
changeset 0 79c6a41cd166
child 11 bd874ee5e5e2
equal deleted inserted replaced
-1:000000000000 0:79c6a41cd166
       
     1 /*
       
     2 * Copyright (c) 2002-2005 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:  Implementation for XCFWLocalizer
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include    "xcfwlocalizer.h"
       
    22 #include    <bautils.h>
       
    23 #include    <e32std.h>
       
    24 #include    <badesca.h>
       
    25 #include    <s32file.h>
       
    26 #include    <s32strm.h>
       
    27 #include    <utf.h>
       
    28 #include    <pathinfo.h>    
       
    29 // CONSTANTS
       
    30 _LIT8( KEntityStart, "!ENTITY " );
       
    31 _LIT( KDrivePathChars, ":\\" );
       
    32 const TInt KDefaultGranularity = 10;
       
    33 //Maximum entity declaration length is rather long because
       
    34 //in RND builds the DTD files contain a lot of comments 
       
    35 //and parsing the file requires long enough buffer.
       
    36 const TInt KMaxEntityDeclLen = 1024; 
       
    37 const TInt KPathStartLoc = 2;
       
    38 
       
    39 // ============================ MEMBER FUNCTIONS ===============================
       
    40 
       
    41 // -----------------------------------------------------------------------------
       
    42 // CXCFWLocalizer::CXCFWLocalizer
       
    43 // C++ default constructor can NOT contain any code, that
       
    44 // might leave.
       
    45 // -----------------------------------------------------------------------------
       
    46 //
       
    47 CXCFWLocalizer::CXCFWLocalizer()
       
    48     {
       
    49     }
       
    50 
       
    51 // -----------------------------------------------------------------------------
       
    52 // CXCFWLocalizer::ConstructL
       
    53 // Symbian 2nd phase constructor can leave.
       
    54 // -----------------------------------------------------------------------------
       
    55 //
       
    56 void CXCFWLocalizer::ConstructL()
       
    57     {
       
    58     iReferences = new ( ELeave ) CDesCArraySeg( KDefaultGranularity );
       
    59     iLocStrings = new ( ELeave ) CDesCArraySeg( KDefaultGranularity );
       
    60     }
       
    61 
       
    62 // -----------------------------------------------------------------------------
       
    63 // CXCFWLocalizer::NewL
       
    64 // Two-phased constructor with Node Data initializer.
       
    65 // -----------------------------------------------------------------------------
       
    66 //
       
    67 CXCFWLocalizer* CXCFWLocalizer::NewL()
       
    68     {
       
    69     CXCFWLocalizer* self = new( ELeave ) CXCFWLocalizer;
       
    70     
       
    71     CleanupStack::PushL( self );
       
    72     self->ConstructL();
       
    73     CleanupStack::Pop( self );
       
    74 
       
    75     return self;
       
    76     }
       
    77 
       
    78    
       
    79 // Destructor
       
    80 CXCFWLocalizer::~CXCFWLocalizer()
       
    81     {
       
    82     delete iReferences;
       
    83     delete iLocStrings;
       
    84     }
       
    85 
       
    86 // -----------------------------------------------------------------------------
       
    87 // CXCFWLocalizer::LoadDTDL
       
    88 // Load entity references from DTD file
       
    89 // Function searches the DTD file first from session path (which is where
       
    90 // the loaded XML file is located). If it is not found there, it is sought
       
    91 // from ROM drive at the same location. 
       
    92 // If function can't find loc file for current language, it will search the
       
    93 // possible replacement using language downgrade path.
       
    94 // -----------------------------------------------------------------------------
       
    95 //
       
    96 void CXCFWLocalizer::LoadDTDL(
       
    97     const TDesC& aDTD,
       
    98     RFs& aFileSystem,
       
    99     TRequestStatus* aStatus )
       
   100     {
       
   101     const TInt KMaxLangCodeLen = 5;
       
   102     const TInt KMinLangCodeLen = 2;
       
   103 
       
   104     TBuf<KMaxLangCodeLen> lcstring;
       
   105 
       
   106     delete iLocStrings;
       
   107     iLocStrings = NULL;
       
   108     delete iReferences;
       
   109     iLocStrings = NULL;
       
   110     iReferences = new ( ELeave ) CDesCArraySeg( KDefaultGranularity );
       
   111     iLocStrings = new ( ELeave ) CDesCArraySeg( KDefaultGranularity );
       
   112     
       
   113     iStatus = aStatus;
       
   114     
       
   115 
       
   116     //First get filepath without drive character
       
   117     TPtrC filepath;
       
   118     if ( aDTD.Find( KDrivePathChars ) != KErrNotFound )
       
   119         {
       
   120         filepath.Set( aDTD.Mid( KPathStartLoc ) );             
       
   121         }
       
   122     else
       
   123         {
       
   124         filepath.Set( aDTD );
       
   125         }
       
   126 
       
   127     // format filepath with current language data
       
   128     TLanguage langcode = User::Language(); //current language
       
   129     lcstring.Num( (TInt64)langcode ); //to get decimal langcode length in characters
       
   130     //use always at least 2 digits.
       
   131     TInt codelen = lcstring.Length() > 1 ? lcstring.Length() : KMinLangCodeLen; 
       
   132 
       
   133     HBufC* locfile = HBufC::NewL( aDTD.Length() + KMaxLangCodeLen );
       
   134     CleanupStack::PushL( locfile );
       
   135     locfile->Des().Format( filepath, codelen, langcode );
       
   136 
       
   137     //Check for file, if not found, check language downgrade path
       
   138     if( !BaflUtils::FileExists( aFileSystem, locfile->Des() ) )
       
   139         {
       
   140         RArray<TLanguage> langs;
       
   141         BaflUtils::GetDowngradePathL( aFileSystem, langcode, langs );
       
   142         //add current language to array for ROM fetching
       
   143         langs.Append( langcode );
       
   144         TInt current = langs.Count() - 1;
       
   145         do 
       
   146             {
       
   147             lcstring.Num( (TInt64)langs[current] );
       
   148             codelen = lcstring.Length()>1?lcstring.Length():KMinLangCodeLen;
       
   149             locfile->Des().Format( filepath, codelen, langs[current] );
       
   150             current--;
       
   151             } 
       
   152         while ( current >= 0 && 
       
   153                 !BaflUtils::FileExists( aFileSystem, locfile->Des() ) );
       
   154         
       
   155         //If still not found, check from ROM
       
   156         if ( !BaflUtils::FileExists( aFileSystem, locfile->Des() ) )
       
   157             {
       
   158             current = langs.Count() - 1;
       
   159             do {
       
   160                 lcstring.Num( (TInt64)langs[current] );
       
   161                 codelen = lcstring.Length()>1?lcstring.Length():KMinLangCodeLen;
       
   162                 locfile->Des().Copy( PathInfo::RomRootPath().Left( KPathStartLoc ) );
       
   163                 locfile->Des().Append( filepath );
       
   164                 locfile->Des().Format( locfile->Des(), codelen, langs[current] );          
       
   165                 current--;
       
   166                 } while ( current >= 0 && 
       
   167                     !BaflUtils::FileExists( aFileSystem, locfile->Des() ) );
       
   168             }
       
   169         langs.Reset();
       
   170         langs.Close();
       
   171         }
       
   172 
       
   173 
       
   174     if ( BaflUtils::FileExists( aFileSystem, locfile->Des() ) )
       
   175         {
       
   176         RFile infile;
       
   177         User::LeaveIfError( infile.Open(aFileSystem, locfile->Des(), EFileRead) );
       
   178         CleanupClosePushL( infile );
       
   179         RFileReadStream readStream( infile,0 );
       
   180         CleanupClosePushL( readStream );
       
   181        
       
   182         ParseDTDL( readStream );
       
   183        
       
   184         CleanupStack::Pop( &readStream ); //readStream
       
   185         CleanupStack::Pop( &infile ); //infile
       
   186         }
       
   187     
       
   188 
       
   189     CleanupStack::PopAndDestroy( locfile );
       
   190 
       
   191     *aStatus = KRequestPending;
       
   192     User::RequestComplete( aStatus, KErrNone );
       
   193     
       
   194     }
       
   195 
       
   196 // -----------------------------------------------------------------------------
       
   197 // CXCFWLocalizer::LoadDTDL
       
   198 // Parse DTD file. Function assumes that the DTD contains ENTITY declarations
       
   199 // only.
       
   200 // -----------------------------------------------------------------------------
       
   201 //
       
   202 void CXCFWLocalizer::ParseDTDL( RFileReadStream& aStream )
       
   203     {
       
   204     
       
   205     TChar space = ' ';
       
   206     TChar quote = '"';
       
   207     TChar lessthan = '<';
       
   208     TChar morethan = '>';
       
   209 
       
   210     HBufC8* buf = HBufC8::NewLC( KMaxEntityDeclLen );
       
   211     TPtr8 p( buf->Des() );
       
   212 
       
   213     TInt streamError = KErrNone;
       
   214 
       
   215     do 
       
   216         {
       
   217         // Read until declaration start "<"
       
   218         TRAP( streamError, aStream.ReadL( p , lessthan)); 
       
   219         // This might be EOF, or other problem, we exit 
       
   220         if( streamError != KErrNone )   
       
   221             {
       
   222             aStream.Close();
       
   223             }
       
   224         else
       
   225             {
       
   226             aStream.ReadL( p , space); // Read until space " "
       
   227             
       
   228             // entity declaration handled, others are ignored
       
   229             if ( p.CompareC( KEntityStart ) == 0 ) 
       
   230                 {
       
   231                 p.Zero();
       
   232                 aStream.ReadL( p , space); // Read the reference name
       
   233                 p.TrimRight();  // Delete space from the end
       
   234                 
       
   235                 HBufC* ucsbuf = HBufC::NewLC( p.Length() );
       
   236                 TPtr ucsp( ucsbuf->Des() );
       
   237                 CnvUtfConverter::ConvertToUnicodeFromUtf8( ucsp, p );
       
   238                 iReferences->AppendL( ucsp );
       
   239                 CleanupStack::PopAndDestroy( ucsbuf );
       
   240                 
       
   241                 p.Zero();
       
   242                 aStream.ReadL( p , quote);
       
   243                 p.Zero();
       
   244                 aStream.ReadL( p , quote); 
       
   245                 p.SetLength(p.Length() - 1); // Delete quotation from the end
       
   246 
       
   247                 //Seek for percentage char symbol and do necessary conversion
       
   248                 const TInt KUCEntityLen = 8;
       
   249                 _LIT8( KUniCodeChar, "&#x0025;");
       
   250                 _LIT8( KPctage, "%" );
       
   251                 TInt pct = p.Find( KUniCodeChar );
       
   252                 while ( pct != KErrNotFound )
       
   253                     {
       
   254                     HBufC8* tmp = HBufC8::NewLC( KMaxEntityDeclLen );
       
   255                     tmp->Des().Copy ( p.Left( pct ) );
       
   256                     tmp->Des().Append( KPctage );
       
   257                     tmp->Des().Append( p.Mid( pct + KUCEntityLen ) );
       
   258                     p.Copy ( tmp->Des() );
       
   259                     CleanupStack::PopAndDestroy( tmp );
       
   260                     pct = p.Find( KUniCodeChar );
       
   261                     }
       
   262 
       
   263 
       
   264                 ucsbuf = HBufC::NewLC( p.Length() );
       
   265                 ucsp.Set ( ucsbuf->Des() );
       
   266                 CnvUtfConverter::ConvertToUnicodeFromUtf8( ucsp, p );
       
   267                 iLocStrings->AppendL( ucsp );
       
   268                 CleanupStack::PopAndDestroy( ucsbuf );
       
   269 
       
   270                 
       
   271                 p.Zero();
       
   272                 aStream.ReadL( p , morethan); // Read until declaration ends ">"           
       
   273                 }
       
   274             }
       
   275         
       
   276         } while ( streamError == KErrNone );
       
   277     
       
   278     CleanupStack::PopAndDestroy(buf);
       
   279     }
       
   280 
       
   281 // -----------------------------------------------------------------------------
       
   282 // CXCFWLocalizer::EntityRefToText
       
   283 // Gets localized text value for given entity reference
       
   284 // -----------------------------------------------------------------------------
       
   285 //
       
   286 TInt CXCFWLocalizer::EntityRefToText(
       
   287     TDesC& aRef, 
       
   288     TPtrC& aText)
       
   289     {
       
   290     TInt count = iReferences->Count();
       
   291     TInt ret = KErrNotFound;
       
   292     for ( TInt i = 0; i < count && ret == KErrNotFound; i++ )
       
   293         {
       
   294         if ( iReferences->MdcaPoint( i ).Compare( 
       
   295             aRef.Mid(1, aRef.Length()-2) ) == 0 )
       
   296             {
       
   297             ret = KErrNone;
       
   298             aText.Set( iLocStrings->MdcaPoint( i ) );
       
   299             }
       
   300         }
       
   301     return ret;
       
   302     }
       
   303 
       
   304 // -----------------------------------------------------------------------------
       
   305 // CXCFWLocalizer::TextToEntityRef
       
   306 // Gets entity reference for given text 
       
   307 // -----------------------------------------------------------------------------
       
   308 //
       
   309 TInt CXCFWLocalizer::TextToEntityRef(
       
   310     TDesC& aText, 
       
   311     TPtrC& aRef )
       
   312     {
       
   313     TInt count = iLocStrings->Count();
       
   314     TInt ret = KErrNotFound;
       
   315     for ( TInt i = 0; i < count && ret == KErrNotFound; i++ )
       
   316         {
       
   317         if ( iLocStrings->MdcaPoint( i ).Compare( aText ) == 0 )
       
   318             {
       
   319             ret = KErrNone;
       
   320             aRef.Set( iReferences->MdcaPoint( i ) );
       
   321             }
       
   322         }
       
   323     return ret;
       
   324     }
       
   325 
       
   326 // -----------------------------------------------------------------------------
       
   327 // CXCFWLocalizer::LastError
       
   328 // Returns error code from the parser.
       
   329 // -----------------------------------------------------------------------------
       
   330 //
       
   331 TInt CXCFWLocalizer::LastError()
       
   332     {
       
   333     TInt ret = KErrNone;
       
   334 
       
   335     if ( !iReferences || !iLocStrings )
       
   336         {
       
   337         ret = KErrNotReady;            
       
   338         }
       
   339     else
       
   340         {
       
   341         if ( iReferences->Count() != iLocStrings->Count() )
       
   342             {
       
   343             ret = KErrCorrupt;             
       
   344             }
       
   345         }
       
   346 
       
   347     return ret;        
       
   348 
       
   349     }
       
   350 
       
   351 
       
   352 
       
   353 //  End of File