webengine/osswebengine/cache/src/HttpCacheLookupTable.cpp
changeset 10 a359256acfc6
parent 5 10e98eab6f85
child 11 c8a366e56285
equal deleted inserted replaced
5:10e98eab6f85 10:a359256acfc6
    70 // Symbian 2nd phase constructor can leave.
    70 // Symbian 2nd phase constructor can leave.
    71 // -----------------------------------------------------------------------------
    71 // -----------------------------------------------------------------------------
    72 //
    72 //
    73 void CHttpCacheLookupTable::ConstructL()
    73 void CHttpCacheLookupTable::ConstructL()
    74     {
    74     {
    75   iEntries = new( ELeave )CArrayPtrFlat<CHttpCacheEntry>( KHttpCacheLookupTableSize );
    75     iEntries = new( ELeave )CArrayPtrFlat<CHttpCacheEntry>( KHttpCacheLookupTableSize );
    76     for( TInt i = 0; i < KHttpCacheLookupTableSize; i++ )
    76     for ( TInt i = 0; i < KHttpCacheLookupTableSize; i++ )
    77         {
    77         {
    78         iEntries->AppendL( NULL );
    78         iEntries->AppendL( NULL );
    79         }
    79         }
    80     }
    80     }
    81 
    81 
   116           }
   116           }
   117       iEntries->Reset();
   117       iEntries->Reset();
   118     }
   118     }
   119 
   119 
   120     delete iEntries;
   120     delete iEntries;
   121 
       
   122     }
   121     }
   123 
   122 
   124 // -----------------------------------------------------------------------------
   123 // -----------------------------------------------------------------------------
   125 // CHttpCacheLookupTable::InsertL
   124 // CHttpCacheLookupTable::InsertL
   126 //
   125 //
   138         CleanupStack::PopAndDestroy(); // entry
   137         CleanupStack::PopAndDestroy(); // entry
   139         entry = NULL;
   138         entry = NULL;
   140         }
   139         }
   141     else
   140     else
   142         {
   141         {
       
   142 #ifdef __CACHELOG__
       
   143         HttpCacheUtil::WriteFormatLog(0, _L("  Added entry %08x to list."), entry);
       
   144 #endif
   143         entry->Accessed();
   145         entry->Accessed();
       
   146         iStreamHandler->InitialiseCacheEntryL(*entry);
       
   147 
   144         // lookuptable takes ownership
   148         // lookuptable takes ownership
   145         CleanupStack::Pop(); // entry
   149         CleanupStack::Pop(); // entry
   146         }
   150         }
   147     return entry;
   151     return entry;
   148     }
   152     }
   154 //
   158 //
   155 CHttpCacheEntry* CHttpCacheLookupTable::Find( const TDesC8& aUrl )
   159 CHttpCacheEntry* CHttpCacheLookupTable::Find( const TDesC8& aUrl )
   156     {
   160     {
   157     CHttpCacheEntry* entry = NULL;
   161     CHttpCacheEntry* entry = NULL;
   158     TInt pos( Probe( aUrl, EFalse ) );
   162     TInt pos( Probe( aUrl, EFalse ) );
   159 
   163 #ifdef __CACHELOG__
       
   164     HttpCacheUtil::WriteUrlToLog(0, _L("CHttpCacheLookupTable::Find"), aUrl);
       
   165     HttpCacheUtil::WriteFormatLog(0, _L("  Probe returned position %d"), pos);
       
   166 #endif
   160     if ( Valid( pos ) )
   167     if ( Valid( pos ) )
   161         {
   168         {
       
   169 #ifdef __CACHELOG__
       
   170         HttpCacheUtil::WriteFormatLog(0, _L("  Entry %d valid."), pos);
       
   171 #endif
   162         entry = iEntries->At( pos );
   172         entry = iEntries->At( pos );
   163         
   173 
   164         if ( entry )
   174         if ( entry )
   165             {
   175             {
       
   176 #ifdef __CACHELOG__
       
   177             HttpCacheUtil::WriteFormatLog(0, _L("  BodySize is %d\n  State is %d"), entry->BodySize(), entry->State());
       
   178 #endif
   166             if ( entry->BodySize() == 0 &&
   179             if ( entry->BodySize() == 0 &&
   167                  entry->State() == CHttpCacheEntry::ECacheComplete )
   180                  entry->State() == CHttpCacheEntry::ECacheComplete )
   168                 {
   181                 {
   169 
   182 
   170 #ifdef __CACHELOG__
   183 #ifdef __CACHELOG__
   171                 HttpCacheUtil::WriteLogFilenameAndUrl( 0,
   184                 HttpCacheUtil::WriteLogFilenameAndUrl( 0,
   172                                            _L("CHttpCacheLookupTable::Find - Found ZERO size"),
   185                                            _L("CHttpCacheLookupTable::Find - Found ZERO size (can't reuse)"),
   173                                            entry->Filename(),
   186                                            entry->Filename(),
   174                                            entry->Url(),
   187                                            entry->Url(),
   175                                            pos,
   188                                            pos,
   176                                            ELogLookupTablePos );
   189                                            ELogLookupTablePos );
   177 #endif
   190 #endif
   178                 return NULL;
   191                 return NULL;
   179                 }
   192                 }
   180             }
   193             }
   181         }
   194         }
       
   195 #ifdef __CACHELOG__
       
   196     HttpCacheUtil::WriteFormatLog(0, _L("  returning entry pointer 0x%08x"), entry);
       
   197 #endif
   182 
   198 
   183     return entry;
   199     return entry;
   184     }
   200     }
   185 
   201 
   186 // -----------------------------------------------------------------------------
   202 // -----------------------------------------------------------------------------
   190 //
   206 //
   191 TInt CHttpCacheLookupTable::Remove( const TDesC8& aUrl )
   207 TInt CHttpCacheLookupTable::Remove( const TDesC8& aUrl )
   192     {
   208     {
   193     TInt status( KErrNotFound );
   209     TInt status( KErrNotFound );
   194     TInt pos( Probe( aUrl, EFalse ) );
   210     TInt pos( Probe( aUrl, EFalse ) );
   195 
   211 #ifdef __CACHELOG__
       
   212     HttpCacheUtil::WriteUrlToLog(0, _L("CHttpCacheLookupTable::Remove"), aUrl);
       
   213     HttpCacheUtil::WriteFormatLog(0, _L("  Probe returned position %d"), pos);
       
   214 #endif
   196     if( Valid( pos ) )
   215     if( Valid( pos ) )
   197         {
   216         {
   198         // remove only nonactive entry
   217         // remove only nonactive entry
   199         CHttpCacheEntry* entry = iEntries->At( pos );
   218         CHttpCacheEntry* entry = iEntries->At( pos );
   200         if ( entry->State() == CHttpCacheEntry::ECacheComplete )
   219         if ( entry->State() == CHttpCacheEntry::ECacheComplete )
   223                                            ELogLookupTablePos );
   242                                            ELogLookupTablePos );
   224             }
   243             }
   225         }
   244         }
   226     else
   245     else
   227         {
   246         {
   228         HttpCacheUtil::WriteLog( 0, _L( "CHttpCacheLookupTable::Remove - item is not valid. cannot be removed" ), pos );
   247         HttpCacheUtil::WriteFormatLog( 0, _L( "CHttpCacheLookupTable::Remove - item %d is not valid. cannot be removed" ), pos );
   229         }
   248         }
   230 #endif // __CACHELOG__
   249 #endif // __CACHELOG__
   231 
   250 
   232     return status;
   251     return status;
   233     }
   252     }
   234 
   253 
   235 // -----------------------------------------------------------------------------
   254 // -----------------------------------------------------------------------------
   236 // CHttpCacheLookupTable::RemoveByPosition
       
   237 //
       
   238 // -----------------------------------------------------------------------------
       
   239 //
       
   240 TInt CHttpCacheLookupTable::RemoveByPosition( TInt aPos )
       
   241     {
       
   242     TInt status( KErrNotFound );
       
   243 
       
   244     if ( Valid( aPos ) )
       
   245         {
       
   246         CHttpCacheEntry* entry = iEntries->At( aPos );
       
   247         SetDeleted( aPos );
       
   248         delete entry;
       
   249         iCount--;
       
   250         status = KErrNone;
       
   251         }
       
   252 
       
   253     return status;
       
   254     }
       
   255        
       
   256 // -----------------------------------------------------------------------------
       
   257 // CHttpCacheLookupTable::EraseCacheEntry
   255 // CHttpCacheLookupTable::EraseCacheEntry
   258 //
   256 //
   259 // -----------------------------------------------------------------------------
   257 // -----------------------------------------------------------------------------
   260 //
   258 //
   261 void CHttpCacheLookupTable::EraseCacheEntry( const TDesC8& aUrl )
   259 void CHttpCacheLookupTable::EraseCacheEntry( const TDesC8& aUrl )
   262     {
   260     {
   263     TInt pos( Probe( aUrl, EFalse ) );
   261     TInt pos( Probe( aUrl, EFalse ) );
   264     
   262 
   265     if ( Valid( pos ) )
   263     if ( Valid( pos ) )
   266         {
   264         {
   267         Erase( pos );
   265         Erase( pos );
   268         }
   266         }
   269 #ifdef __CACHELOG__
   267 #ifdef __CACHELOG__
   318 TInt CHttpCacheLookupTable::ListFiles(RPointerArray<TDesC>& aFilenameList)
   316 TInt CHttpCacheLookupTable::ListFiles(RPointerArray<TDesC>& aFilenameList)
   319     {
   317     {
   320     TInt count( 0 );
   318     TInt count( 0 );
   321     TInt error( KErrNone );
   319     TInt error( KErrNone );
   322 
   320 
   323     //1. Tally up 
   321     //1. Tally up
   324     for (TInt i = 0; i < iEntries->Count(); i++)
   322     for (TInt i = 0; i < iEntries->Count(); i++)
   325         {
   323         {
   326         if (Valid(i)) count++;
   324         if (Valid(i)) count++;
   327         }
   325         }
   328 
   326 
   329     //2. Preallocation. 
   327     //2. Preallocation.
   330     TInt existing( aFilenameList.Count() );
   328     TInt existing( aFilenameList.Count() );
   331     error = aFilenameList.Reserve( existing + count );
   329     error = aFilenameList.Reserve( existing + count );
   332 
   330 
   333     if (error == KErrNone)
   331     if (error == KErrNone)
   334         {
   332         {
   335         //3. Iterate once more and add pointers to filename strings
   333         //3. Iterate once more and add pointers to filename strings
   336         for (TInt i = 0; i < iEntries->Count(); i++)
   334         for (TInt i = 0; i < iEntries->Count(); i++)
   337             {
   335             {
   338             if (Valid(i))
   336             if (Valid(i))
   339                 {
   337                 {
   340                 //add filename pointer to the array. 
   338                 //add filename pointer to the array.
   341                 const TDesC* ptr = &(iEntries->At(i)->Filename());
   339                 const TDesC* ptr = &(iEntries->At(i)->Filename());
   342                 aFilenameList.Append( ptr ); // no ownership transfer happens here
   340                 aFilenameList.Append( ptr ); // no ownership transfer happens here
   343                 }
   341                 }
   344             }
   342             }
   345         }
   343         }
   346      
   344 
   347     return error;
   345     return error;
   348 
   346 
   349     }
   347     }
   350 
   348 
   351 // -----------------------------------------------------------------------------
   349 // -----------------------------------------------------------------------------
   352 // CHttpCacheLookupTable::InternalizeL
   350 // CHttpCacheLookupTable::InternalizeL
   353 //
   351 //
   354 // -----------------------------------------------------------------------------
   352 // -----------------------------------------------------------------------------
   355 //
   353 //
   356 void CHttpCacheLookupTable::InternalizeL(
   354 void CHttpCacheLookupTable::InternalizeL(
   357     RFileReadStream& aReadStream,
   355     RReadStream& aReadStream,
   358     const TDesC& /*aDirectory*/ )
   356     const TDesC& aDirectory )
   359     {
   357     {
   360     // get number of entries
   358     // get number of entries
   361     TInt version = 0;
   359     TInt version = 0;
   362     version = aReadStream.ReadInt32L();
   360     version = aReadStream.ReadInt32L();
   363     if( version == KCacheVersionNumber )
   361     if ( version == KCacheVersionNumber )
   364         {
   362         {
       
   363         // read directory stub and validate it
       
   364         TInt len = aReadStream.ReadInt32L();
       
   365         HBufC* dirstub = HBufC::NewLC(len);
       
   366         TPtr dirstubptr = dirstub->Des();
       
   367         aReadStream.ReadL( dirstubptr, len );
       
   368         ASSERT( aDirectory.CompareF( dirstubptr ) == 0 );
       
   369         CleanupStack::PopAndDestroy( dirstub );
       
   370 
   365         TInt count( aReadStream.ReadInt32L() );
   371         TInt count( aReadStream.ReadInt32L() );
   366         TInt contentSize( 0 );
   372         TInt contentSize( 0 );
   367         TInt err;
   373         TInt err;
   368         for( TInt i = 0; i < count; i++ )
   374         for( TInt i = 0; i < count; i++ )
   369             {
   375             {
   370             // create empty object
   376             // create empty object
   371             CHttpCacheEntry* entry = CHttpCacheEntry::NewLC( KNullDesC8, *iEvictionHandler );
   377             CHttpCacheEntry* entry = CHttpCacheEntry::NewLC( KNullDesC8, *iEvictionHandler );
   372             // read it
   378             // read it
   373             err = entry->Internalize( aReadStream );
   379             err = entry->Internalize( aReadStream, aDirectory );
   374 
   380             // leave only on no memory
   375             if ( err == KErrNone && entry->BodySize() > 0 )
   381             if( err == KErrNone )
   376                 {
   382                 {
   377                 // cacheEntry is valid, insert into the table
   383                 // insert to the table
   378                 InsertL( entry );
   384                 InsertL( entry );
   379                 contentSize += entry->HeaderSize();
   385                 contentSize += entry->HeaderSize();
   380                 contentSize += entry->BodySize();
   386                 contentSize += entry->BodySize();
   381                 }
   387                 }
   382             else if ( err == KErrNoMemory )
   388             else if ( err == KErrNoMemory )
   383                 {
   389                 {
   384                 // Only leave if no memory
       
   385                 User::Leave( KErrNoMemory );
   390                 User::Leave( KErrNoMemory );
   386                 }
   391                 }
   387             else if ( entry->BodySize() == 0 )
   392             else
   388                 {
   393                 {
   389                 // This is an empty cache entry, remove it from file system.
   394                 // suggestions
   390 				// Use CreateNewFilesL() to open file handles, so we can delete
       
   391 				// the files associated with the cache entry.
       
   392                 iStreamHandler->CreateNewFilesL( *entry );
       
   393                 iStreamHandler->EraseCacheFile( *entry );
       
   394                 }
   395                 }
   395 
   396 
   396             // takes ownership
   397             // takes ownership
   397             CleanupStack::Pop(); // entry
   398             CleanupStack::Pop(); // entry
   398             }
   399             }
   413 // CHttpCacheLookupTable::Externalize
   414 // CHttpCacheLookupTable::Externalize
   414 //
   415 //
   415 // -----------------------------------------------------------------------------
   416 // -----------------------------------------------------------------------------
   416 //
   417 //
   417 void CHttpCacheLookupTable::ExternalizeL(
   418 void CHttpCacheLookupTable::ExternalizeL(
   418     RFileWriteStream& aWriteStream )
   419     RWriteStream& aWriteStream, const TDesC& aDirectory )
   419     {
   420     {
   420     // write version number and the number of entries
   421     // write version number and the number of entries
   421     TRAP_IGNORE( aWriteStream.WriteInt32L( KCacheVersionNumber );
   422     TRAP_IGNORE( aWriteStream.WriteInt32L( KCacheVersionNumber ) );
   422     aWriteStream.WriteInt32L( iCount ) );
   423 
       
   424     // directory stub length
       
   425     aWriteStream.WriteInt32L( aDirectory.Length() ) ;
       
   426     // directory stub
       
   427     aWriteStream.WriteL( aDirectory );
       
   428 
       
   429     // entry count - don't write entries with zero body length, so precalculate this.
       
   430     TInt goingToWrite = 0;
   423     for( TInt i = 0; i < iEntries->Count(); i++ )
   431     for( TInt i = 0; i < iEntries->Count(); i++ )
   424         {
   432         {
   425         CHttpCacheEntry* entry = iEntries->At( i );
   433         CHttpCacheEntry* entry = iEntries->At( i );
   426         // save complete entries only
   434         // save complete entries only
   427         if( Valid( i ) )
   435         if( Valid( i ) && entry->BodySize() > 0 )
       
   436             {
       
   437             goingToWrite++;
       
   438             }
       
   439         }
       
   440     aWriteStream.WriteInt32L( goingToWrite );
       
   441 
       
   442     for( TInt i = 0; i < iEntries->Count(); i++ )
       
   443         {
       
   444         CHttpCacheEntry* entry = iEntries->At( i );
       
   445         // save complete entries only
       
   446         if( Valid( i ) && entry->BodySize() > 0 )
   428             {
   447             {
   429             // save entry
   448             // save entry
   430             TInt err;
   449             TInt err;
   431             err = entry->Externalize( aWriteStream );
   450             err = entry->Externalize( aWriteStream, aDirectory );
   432             // leave only on no memory
   451             // leave only on no memory
   433             if( err == KErrNoMemory )
   452             if ( err == KErrNoMemory )
   434                 {
   453                 {
   435                 User::Leave( KErrNoMemory );
   454                 User::Leave( KErrNoMemory );
   436                 }
   455                 }
   437             }
   456             }
   438         }
   457         }
   452     TInt pos( -1 );
   471     TInt pos( -1 );
   453 
   472 
   454     if ( aCacheEntry )
   473     if ( aCacheEntry )
   455         {
   474         {
   456         pos = Probe( aCacheEntry->Url(), ETrue );
   475         pos = Probe( aCacheEntry->Url(), ETrue );
       
   476 #ifdef __CACHELOG__
       
   477         HttpCacheUtil::WriteUrlToLog(0, _L("CHttpCacheLookupTable::InsertL"), aCacheEntry->Url());
       
   478         HttpCacheUtil::WriteFormatLog(0, _L("  Probe returned position %d"), pos);
       
   479 #endif
   457         // double check
   480         // double check
   458         if( Valid( pos ) )
   481         if( Valid( pos ) )
   459             {
   482             {
       
   483 #ifdef __CACHELOG__
       
   484             HttpCacheUtil::WriteLog(0, _L("  Valid entry already exists according to Valid(). Rehash table."));
       
   485 #endif
   460             // try to rehash the table if probe failed
   486             // try to rehash the table if probe failed
   461             ReHashL();
   487             ReHashL();
   462             pos = Probe( aCacheEntry->Url(), ETrue );
   488             pos = Probe( aCacheEntry->Url(), ETrue );
   463 
   489 #ifdef __CACHELOG__
       
   490             HttpCacheUtil::WriteFormatLog(0, _L("  ReProbe after rehash returned new position %d"), pos);
       
   491 #endif
   464             if( pos == -1 || Valid( pos ) )
   492             if( pos == -1 || Valid( pos ) )
   465                 {
   493                 {
       
   494 #ifdef __CACHELOG__
       
   495                 HttpCacheUtil::WriteLog(0, _L("  Pos already filled (or == -1) - Couldn't find an empty slot to store it."));
       
   496 #endif
   466                 // completly failed
   497                 // completly failed
   467                 pos = -1;
   498                 pos = -1;
   468                 }
   499                 }
   469             }
   500             }
   470 
   501 
   471         // insert
   502         // insert
   472         if( pos != -1 )
   503         if( pos != -1 )
   473             {
   504             {
   474             iEntries->At( pos ) = aCacheEntry;
   505             iEntries->At( pos ) = aCacheEntry;
   475             iCount++;
   506             iCount++;
   476 
   507 #ifdef __CACHELOG__
   477 #ifdef __CACHELOG__
   508             HttpCacheUtil::WriteFormatLog( 0, _L( "insert new item at %d in the lookuptable" ), pos );
   478             HttpCacheUtil::WriteLog( 0, _L( "insert new item to the lookuptable" ), pos );
       
   479 #endif
   509 #endif
   480             // check if the hashtable is full
   510             // check if the hashtable is full
   481             if ( iCount > ( iEntries->Count() >> 1 ) )
   511             if ( iCount > ( iEntries->Count() >> 1 ) )
   482                 {
   512                 {
       
   513 #ifdef __CACHELOG__
       
   514                 HttpCacheUtil::WriteLog(0, _L("  But! hashtable is full - rehash."));
       
   515 #endif
   483                 ReHashL();
   516                 ReHashL();
   484                 }
   517                 }
   485             }
   518             }
   486         else
   519         else
   487             {
   520             {
   685 
   718 
   686     CHttpCacheEntry* entry = iEntries->At( aPos );
   719     CHttpCacheEntry* entry = iEntries->At( aPos );
   687 
   720 
   688     if( entry )
   721     if( entry )
   689         {
   722         {
   690         // delete file associated with this entry
       
   691         TBool attached( EFalse );
       
   692         
       
   693 #ifdef __CACHELOG__
   723 #ifdef __CACHELOG__
   694         HttpCacheUtil::WriteLogFilenameAndUrl( 0,
   724         HttpCacheUtil::WriteLogFilenameAndUrl( 0,
   695                                            _L("CHttpCacheLookupTable::Erase"),
   725                                            _L("CHttpCacheLookupTable::Erase"),
   696                                            entry->Filename(),
   726                                            entry->Filename(),
   697                                            entry->Url(),
   727                                            entry->Url(),
   698                                            aPos,
   728                                            aPos,
   699                                            ELogLookupTablePos );
   729                                            ELogLookupTablePos );
   700 #endif        
   730 #endif
   701         TRAPD( err, attached = iStreamHandler->AttachL( *entry ) );
   731         iStreamHandler->Erase( *entry );
   702         if ( err == KErrNone && attached )
       
   703             {
       
   704             iStreamHandler->EraseCacheFile( *entry );
       
   705             iStreamHandler->Detach( *entry );
       
   706             }
       
   707 
       
   708         SetDeleted( aPos );
   732         SetDeleted( aPos );
   709         delete entry;
   733         delete entry;
   710         iCount--;
   734         iCount--;
   711         }
   735         }
   712     }
   736     }
   824             if (aRfs.Att(newEntry->Filename(), att) == KErrNone)
   848             if (aRfs.Att(newEntry->Filename(), att) == KErrNone)
   825                 {
   849                 {
   826                 CHttpCacheEntry* myEntry = InsertL(newEntry->Url());
   850                 CHttpCacheEntry* myEntry = InsertL(newEntry->Url());
   827                 myEntry->SetState( CHttpCacheEntry::ECacheComplete );
   851                 myEntry->SetState( CHttpCacheEntry::ECacheComplete );
   828                 myEntry->Accessed(newEntry->LastAccessed(), newEntry->Ref());
   852                 myEntry->Accessed(newEntry->LastAccessed(), newEntry->Ref());
   829                 }          
   853                 }
   830             aHttpCacheLookupTable->SetDeleted(pos);
   854             aHttpCacheLookupTable->SetDeleted(pos);
   831             delete newEntry;
   855             delete newEntry;
   832             aHttpCacheLookupTable->iCount--;
   856             aHttpCacheLookupTable->iCount--;
   833             }
   857             }
   834         }
   858         }
   835     }
   859     }
   836 
   860 
   837 // -----------------------------------------------------------------------------
   861 // -----------------------------------------------------------------------------
   838 // CHttpCacheLookupTable::FindCacheEntryIndex
   862 // CHttpCacheLookupTable::BeginEntryIteration
   839 //
   863 //
   840 // -----------------------------------------------------------------------------
   864 // -----------------------------------------------------------------------------
   841 //
   865 //
   842 void CHttpCacheLookupTable::FindCacheEntryIndex(
   866 void CHttpCacheLookupTable::BeginEntryIteration(THttpCacheLookupTableEntryIterator& aIter)
   843     const CHttpCacheEntry& aCacheEntry,
   867     {
   844     TInt* aIndex )
   868     aIter.iPos = 0;
   845     {
   869     aIter.iCount = iCount;
   846     *aIndex = -1;
   870     }
   847     for ( TInt i = 0; i < iEntries->Count(); i++ )
   871 
   848         {
   872 // -----------------------------------------------------------------------------
   849         CHttpCacheEntry* entry = iEntries->At( i );
   873 // CHttpCacheLookupTable::NextEntry
   850 
   874 //
   851         if ( entry == &aCacheEntry )
   875 // -----------------------------------------------------------------------------
   852             {
   876 //
   853             if ( aIndex )
   877 const CHttpCacheEntry* CHttpCacheLookupTable::NextEntry(THttpCacheLookupTableEntryIterator& aIter)
   854                 {
   878     {
   855                 *aIndex = i;
   879     const CHttpCacheEntry *entry = NULL;
   856                 }
   880 
   857             break;
   881     while ( !entry && aIter.iPos < iEntries->Count() )
   858             }
   882         {
   859         }
   883         entry = Valid(aIter.iPos) ? iEntries->At(aIter.iPos) : NULL;
       
   884         aIter.iPos++;
       
   885         }
       
   886 
       
   887     return entry;
   860     }
   888     }
   861 
   889 
   862 //  End of File
   890 //  End of File