webengine/osswebengine/cache/src/HttpCacheHandler.cpp
changeset 11 c8a366e56285
parent 10 a359256acfc6
child 25 0ed94ceaa377
equal deleted inserted replaced
10:a359256acfc6 11:c8a366e56285
    61     }
    61     }
    62 
    62 
    63 // ============================ MEMBER FUNCTIONS ===============================
    63 // ============================ MEMBER FUNCTIONS ===============================
    64 THttpCachePostponeParameters::THttpCachePostponeParameters()
    64 THttpCachePostponeParameters::THttpCachePostponeParameters()
    65     {
    65     {
    66     iEnabled = EFalse;
    66     iEnabled = ETrue;               // Postpone enabled always
    67     iFreeRamThreshold = 0;
    67     iFreeRamThreshold = 6*1024*1024;    // 6MB free required
    68     iImmediateWriteThreshold = 0;
    68     iImmediateWriteThreshold = 0;   // Items below this size always written immediately
    69     iWriteTimeout = 0;
    69     iWriteTimeout = 30000000;        // 45s timeout
    70     }
    70     }
    71 
    71 
    72 // -----------------------------------------------------------------------------
    72 // -----------------------------------------------------------------------------
    73 // CHttpCacheHandler::CHttpCacheHandler
    73 // CHttpCacheHandler::CHttpCacheHandler
    74 // C++ default constructor can NOT contain any code, that
    74 // C++ default constructor can NOT contain any code, that
   125         User::Leave(err);
   125         User::Leave(err);
   126     }
   126     }
   127 
   127 
   128     // set path for the entries
   128     // set path for the entries
   129     iRfs.SetSessionPath( aDirectory );
   129     iRfs.SetSessionPath( aDirectory );
   130 #ifdef __USE_VALIDATION_FILES__
       
   131     // create validation file
       
   132     TFileName validateFile;
       
   133     GenerateValidationFilename(validateFile, aIndexFile);
       
   134 
       
   135     TBool validateCacheEntries( EFalse );
       
   136     RFile validate;
       
   137     TInt validateErr = validate.Create(iRfs, validateFile, EFileShareExclusive | EFileWrite);
       
   138     if ( validateErr != KErrNone )
       
   139         {
       
   140         if ( validateErr == KErrAlreadyExists )
       
   141             {
       
   142             validateCacheEntries = ETrue;
       
   143             }
       
   144 #ifdef _DEBUG
       
   145         else
       
   146             {
       
   147             // oh dear, we failed to create the file for some other reason, something must have gone properly wrong...
       
   148             User::Panic(_L("CacheHandler"), -9999);
       
   149             }
       
   150 #endif
       
   151         }
       
   152     validate.Close();
       
   153 #endif
       
   154     //
   130     //
   155     iEvictionHandler = CHttpCacheEvictionHandler::NewL();
   131     iEvictionHandler = CHttpCacheEvictionHandler::NewL();
   156     //
   132     //
   157     iStreamHandler = CHttpCacheStreamHandler::NewL( iDirectory->Des(), aCriticalLevel, iRfs );
   133     iStreamHandler = CHttpCacheStreamHandler::NewL( iDirectory->Des(), aCriticalLevel, iRfs );
   158     //
   134     //
   159     if ( aPostpone.iEnabled )
   135     if ( aPostpone.iEnabled )
   160         {
   136         {
   161         iPostponeHandler = CHttpCacheFileWriteHandler::NewL(this, iStreamHandler, iRfs, aPostpone.iWriteTimeout);
   137         iPostponeHandler = CHttpCacheFileWriteHandler::NewL(this, iStreamHandler, iRfs, aPostpone);
   162         }
   138         }
   163     //
   139     //
   164     iLookupTable = CHttpCacheLookupTable::NewL( *iEvictionHandler, *iStreamHandler );
   140     iLookupTable = CHttpCacheLookupTable::NewL( *iEvictionHandler, *iStreamHandler );
   165     TRAP( err, OpenLookupTableL() );
   141     TRAP( err, OpenLookupTableL() );
   166     if ( err != KErrNone )
   142     if ( err != KErrNone )
   168         // failed to open the lookup table, delete the old one and start again.
   144         // failed to open the lookup table, delete the old one and start again.
   169         delete iLookupTable;
   145         delete iLookupTable;
   170         iLookupTable = NULL;
   146         iLookupTable = NULL;
   171         iLookupTable = CHttpCacheLookupTable::NewL( *iEvictionHandler, *iStreamHandler );
   147         iLookupTable = CHttpCacheLookupTable::NewL( *iEvictionHandler, *iStreamHandler );
   172         }
   148         }
   173 #ifdef __USE_VALIDATION_FILES__
       
   174     if ( validateCacheEntries )
       
   175 #endif
       
   176         // ensure that the disk content matches the cache content
       
   177         ValidateCacheEntriesL();
       
   178 
       
   179     //
   149     //
   180     iHttpCacheObserver = CHttpCacheObserver::NewL(iDirectory, iIndexFile, this);
   150     iHttpCacheObserver = CHttpCacheObserver::NewL(iDirectory, iIndexFile, this);
   181     iHttpCacheObserver->StartObserver();
   151     iHttpCacheObserver->StartObserver();
   182     }
   152     }
   183 
   153 
  1441 // -----------------------------------------------------------------------------
  1411 // -----------------------------------------------------------------------------
  1442 //
  1412 //
  1443 void CHttpCacheHandler::UpdateLookupTable()
  1413 void CHttpCacheHandler::UpdateLookupTable()
  1444     {
  1414     {
  1445     TRAP_IGNORE(UpdateLookupTableL());
  1415     TRAP_IGNORE(UpdateLookupTableL());
  1446     iHttpCacheObserver->StartObserver();
       
  1447     }
  1416     }
  1448 
  1417 
  1449 // -----------------------------------------------------------------------------
  1418 // -----------------------------------------------------------------------------
  1450 // CHttpCacheHandler::UpdateLookupTableL
  1419 // CHttpCacheHandler::UpdateLookupTableL
  1451 // Slow method due to much file-system interaction. Don't call it from performance critical code.
  1420 // Slow method due to much file-system interaction. Don't call it from performance critical code.
  1456     CHttpCacheEvictionHandler* evictionHandler = CHttpCacheEvictionHandler::NewL();
  1425     CHttpCacheEvictionHandler* evictionHandler = CHttpCacheEvictionHandler::NewL();
  1457     CleanupStack::PushL(evictionHandler);
  1426     CleanupStack::PushL(evictionHandler);
  1458     CHttpCacheLookupTable* lookupTable = CHttpCacheLookupTable::NewL( *evictionHandler, *iStreamHandler );
  1427     CHttpCacheLookupTable* lookupTable = CHttpCacheLookupTable::NewL( *evictionHandler, *iStreamHandler );
  1459     CleanupStack::PushL(lookupTable);
  1428     CleanupStack::PushL(lookupTable);
  1460     OpenLookupTableL(lookupTable);
  1429     OpenLookupTableL(lookupTable);
  1461     iLookupTable->MergeL(lookupTable, iRfs);
  1430     iLookupTable->MergeL(lookupTable, iRfs, iDirectory->Des() );
  1462     CleanupStack::PopAndDestroy(2); // lookupTable, evictionHandler
  1431     CleanupStack::PopAndDestroy(2); // lookupTable, evictionHandler
  1463     }
       
  1464 
       
  1465 // -----------------------------------------------------------------------------
       
  1466 // CHttpCacheHandler::GenerateValidationFilename
       
  1467 // -----------------------------------------------------------------------------
       
  1468 //
       
  1469 #ifdef __USE_VALIDATION_FILES__
       
  1470     void CHttpCacheHandler::GenerateValidationFilename(TDes& aFilename, const TDesC& aIndexFilename) const
       
  1471 #else
       
  1472     void CHttpCacheHandler::GenerateValidationFilename(TDes& /*aFilename*/, const TDesC& /*aIndexFilename*/) const
       
  1473 #endif
       
  1474     {
       
  1475 #ifdef __USE_VALIDATION_FILES__
       
  1476     _LIT(KValidationExtension, ".val");
       
  1477     TParse filenameParser;
       
  1478     filenameParser.Set(aIndexFilename, NULL, NULL);
       
  1479     aFilename.Copy(filenameParser.DriveAndPath());
       
  1480     aFilename.Append(filenameParser.Name());
       
  1481     aFilename.Append(KValidationExtension);
       
  1482 #else
       
  1483     PanicCacheHandler(KErrNotSupported);
       
  1484 #endif
       
  1485     }
  1432     }
  1486 
  1433 
  1487 // -----------------------------------------------------------------------------
  1434 // -----------------------------------------------------------------------------
  1488 // DestroyBadUrlArray
  1435 // DestroyBadUrlArray
  1489 // -----------------------------------------------------------------------------
  1436 // -----------------------------------------------------------------------------
  1496 
  1443 
  1497 // -----------------------------------------------------------------------------
  1444 // -----------------------------------------------------------------------------
  1498 // CHttpCacheHandler::ValidateCacheEntriesL
  1445 // CHttpCacheHandler::ValidateCacheEntriesL
  1499 // -----------------------------------------------------------------------------
  1446 // -----------------------------------------------------------------------------
  1500 //
  1447 //
  1501 void CHttpCacheHandler::ValidateCacheEntriesL()
  1448 void CHttpCacheHandler::ValidateCacheEntriesL(CHttpCacheFileHash *aDiskContent)
  1502     {
  1449     {
  1503     // iterate through entries and check if file is present.
  1450     // iterate through entries and check if file is present.
  1504     // if not, add URL to a list of bad ones otherwise remove directory entry from list
  1451     // if not, add URL to a list of bad ones otherwise remove directory entry from list
  1505     // at the end, go through list of bad entries and remove them from cache,
  1452     // at the end, go through list of bad entries and remove them from cache,
  1506     // go through list of unreferenced files and delete them too.
       
  1507     THttpCacheLookupTableEntryIterator iter;
  1453     THttpCacheLookupTableEntryIterator iter;
  1508     iLookupTable->BeginEntryIteration(iter);
  1454     iLookupTable->BeginEntryIteration(iter);
  1509 #ifdef __CACHELOG__
  1455 #ifdef __CACHELOG__
  1510     HttpCacheUtil::WriteLog(0, _L("CHttpCacheHandler::ValidateCacheEntriesL"));
  1456     HttpCacheUtil::WriteLog(0, _L("CHttpCacheHandler::ValidateCacheEntriesL"));
  1511 #endif
  1457 #endif
  1512     // if the cache contains no items, we should still do this so we detect other files.
  1458 
  1513 
  1459     // mark our index file as 'no delete'
  1514     // get list of files on disk
  1460     RHttpCacheFileHashMap& hashmap = aDiskContent->HashMap();
  1515     CCacheDirectoryFiles *dirFiles = CCacheDirectoryFiles::NewLC(iRfs, *iDirectory);
  1461     TFileName indexFile;
  1516 
  1462     indexFile.Copy( iDirectory->Des() );
       
  1463     indexFile.Append( iIndexFile->Des() );
       
  1464     TFileInfo *info = hashmap.Find( indexFile );
       
  1465     if( info )
       
  1466         {
       
  1467         info->iUserInt = KCacheFileNoDelete;  
       
  1468         }
       
  1469     
  1517     // look for bad entries
  1470     // look for bad entries
  1518     RPointerArray<HBufC8> badEntries;
  1471     RPointerArray<HBufC8> badEntries;
  1519     CleanupStack::PushL(TCleanupItem(DestroyBadUrlArray, &badEntries));
  1472     CleanupStack::PushL(TCleanupItem(DestroyBadUrlArray, &badEntries));
  1520     const CHttpCacheEntry *tmpEntry;
  1473     const CHttpCacheEntry *tmpEntry;
  1521     while(tmpEntry = iLookupTable->NextEntry(iter), tmpEntry)
  1474     while(tmpEntry = iLookupTable->NextEntry(iter), tmpEntry)
  1522         {
  1475         {
  1523         if(!dirFiles->ValidateEntryL(*tmpEntry))
  1476         // check the files associated with the cache entry are present where they should be
       
  1477         // if the file is present AND the size matches the entry, mark the hashmap value with noDelete.
       
  1478         // otherwise, mark the hash map with delete and remove the entry.
       
  1479         info = hashmap.Find(tmpEntry->Filename());
       
  1480         if(info && info->iFileSize == tmpEntry->BodySize())
       
  1481             {
       
  1482             info->iUserInt = KCacheFileNoDelete; // noDelete
       
  1483             }
       
  1484         else
  1524             {
  1485             {
  1525 #ifdef __CACHELOG__
  1486 #ifdef __CACHELOG__
  1526             HttpCacheUtil::WriteUrlToLog(0, _L("Bad Entry: "), tmpEntry->Url() );
  1487             HttpCacheUtil::WriteUrlToLog(0, _L("Bad Entry: "), tmpEntry->Url() );
  1527 #endif
  1488 #endif
  1528             badEntries.AppendL(tmpEntry->Url().AllocL());
  1489             badEntries.AppendL(tmpEntry->Url().AllocL());
  1529             }
  1490             if(info)
  1530         }
  1491                 info->iUserInt = KCacheFileNeedsDelete; // needs delete
  1531 
  1492             }
  1532     // remove bad entries
  1493         }
       
  1494 
       
  1495     // remove entries from cache where files don't match content on disk, either file is missing or size is incorrect.
       
  1496     // needed to save URIs because that's the only interface we have here.
  1533     for(TInt i=0; i < badEntries.Count(); i++)
  1497     for(TInt i=0; i < badEntries.Count(); i++)
  1534         {
  1498         {
  1535         iLookupTable->Remove(badEntries[i]->Des());
  1499         iLookupTable->Remove(badEntries[i]->Des());
  1536         }
  1500         }
  1537     CleanupStack::PopAndDestroy(1); // bad entry list
  1501     CleanupStack::PopAndDestroy(1); // bad entry list
  1538 
  1502     }
  1539     // remove orphan files
  1503 
  1540     dirFiles->RemoveLeftoverFilesL();
       
  1541     CleanupStack::PopAndDestroy(dirFiles);
       
  1542     }
       
  1543 
       
  1544 // -----------------------------------------------------------------------------
       
  1545 // CCacheDirectoryFiles::NewL
       
  1546 // -----------------------------------------------------------------------------
       
  1547 //
       
  1548 CCacheDirectoryFiles* CCacheDirectoryFiles::NewL(RFs aRfs, const TDesC& aDir)
       
  1549     {
       
  1550     CCacheDirectoryFiles* me = CCacheDirectoryFiles::NewLC(aRfs, aDir);
       
  1551     CleanupStack::Pop(me);
       
  1552     return me;
       
  1553     }
       
  1554 
       
  1555 // -----------------------------------------------------------------------------
       
  1556 // CCacheDirectoryFiles::NewLC
       
  1557 // -----------------------------------------------------------------------------
       
  1558 //
       
  1559 CCacheDirectoryFiles* CCacheDirectoryFiles::NewLC(RFs aRfs, const TDesC& aDir)
       
  1560     {
       
  1561     CCacheDirectoryFiles *me = new (ELeave) CCacheDirectoryFiles(aRfs, aDir);
       
  1562     CleanupStack::PushL(me);
       
  1563     me->ConstructL();
       
  1564     return me;
       
  1565     }
       
  1566 
       
  1567 // -----------------------------------------------------------------------------
       
  1568 // CCacheDirectoryFiles::ValidateEntryL
       
  1569 // -----------------------------------------------------------------------------
       
  1570 //
       
  1571 TBool CCacheDirectoryFiles::ValidateEntryL(const CHttpCacheEntry& aEntry)
       
  1572     {
       
  1573     // check the files associated with the cache entry are present where they should be
       
  1574     // if the file is present, then remove it from the dir list
       
  1575     // if the file is present AND the size matches the entry, then return ETrue in aPresentAndValid
       
  1576     // otherwise, return EFalse there.
       
  1577     TBool presentAndValid = EFalse;
       
  1578 
       
  1579     TParse tmpParse;
       
  1580     tmpParse.Set(aEntry.Filename(), NULL, NULL);
       
  1581     // for this file to be part of the cache it must meet the following rules..
       
  1582     // length of name is 8 chars
       
  1583     if(tmpParse.Name().Length() != 8)
       
  1584         return presentAndValid;
       
  1585 
       
  1586     // this filename has a chance of existing and we can assume correct format from now on
       
  1587     TUint32 cacheUintName;
       
  1588     if(TCompressedEntry::ConvertANameToUint32(tmpParse.Name(), cacheUintName))
       
  1589         {
       
  1590         TInt arrayIndex = cacheUintName & 0x0000000F;
       
  1591         presentAndValid = iDirContent[arrayIndex]->ValidateCacheEntryL( aEntry );
       
  1592         }
       
  1593     // after all cache entries have been checked against the list, it should only contain orphaned files
       
  1594     // files which match but are corrupt will have been removed from this list
       
  1595     // however they should be cleaned up when the 'corrupt' entries are removed at a later date.
       
  1596     return presentAndValid;
       
  1597     }
       
  1598 
       
  1599 // -----------------------------------------------------------------------------
       
  1600 // CCacheDirectoryFiles::RemoveLeftoverFilesL
       
  1601 // -----------------------------------------------------------------------------
       
  1602 //
       
  1603 void CCacheDirectoryFiles::RemoveLeftoverFilesL()
       
  1604     {
       
  1605     // delete all the files which are still listed.
       
  1606     TFileName tempFilename;
       
  1607     for (TInt subDir=0; subDir < 16; subDir++)
       
  1608         {
       
  1609         for (TInt fileIdx = 0; fileIdx < iDirContent[subDir]->Count(); fileIdx++ )
       
  1610             {
       
  1611             // each file needs to have the full path prepended in order to delete
       
  1612             HBufC *name = iDirContent[subDir]->NameAtL(fileIdx);
       
  1613             tempFilename.Format(_L("%S%x\\%S"), &iDir, subDir, name);
       
  1614 #ifdef __CACHELOG__
       
  1615             HttpCacheUtil::WriteFormatLog(0, _L("Deleting file %S"), &tempFilename);
       
  1616 #endif
       
  1617             iRfs.Delete(tempFilename);
       
  1618             delete name;
       
  1619             }
       
  1620         }
       
  1621     }
       
  1622 
       
  1623 // -----------------------------------------------------------------------------
       
  1624 // CCacheDirectoryFiles::~CCacheDirectoryFiles
       
  1625 // -----------------------------------------------------------------------------
       
  1626 //
       
  1627 CCacheDirectoryFiles::~CCacheDirectoryFiles()
       
  1628     {
       
  1629     iDirContent.ResetAndDestroy();
       
  1630     }
       
  1631 
       
  1632 // -----------------------------------------------------------------------------
       
  1633 // CCacheDirectoryFiles::ConstructL
       
  1634 // -----------------------------------------------------------------------------
       
  1635 //
       
  1636 void CCacheDirectoryFiles::ConstructL()
       
  1637     {
       
  1638     CDir* baseDirs;
       
  1639     User::LeaveIfError(iRfs.GetDir(iDir,KEntryAttDir,ESortByName,baseDirs));
       
  1640     CleanupStack::PushL(baseDirs);
       
  1641 
       
  1642     // we know that the cache format is a single letter directory from 0-f
       
  1643     // so we ignore any other directories - they might belong to other caches
       
  1644     // and our cache will not have written any files out into anywhere except the
       
  1645     // 0-f dirs, even if we lost track of something.
       
  1646     // See HttpCacheUtil::GenerateNameLC
       
  1647     iDirContent.ReserveL(16);
       
  1648 
       
  1649     TInt numdirs = baseDirs->Count();
       
  1650     // storage for <c:/system/cache/> + '0/'
       
  1651     HBufC* currentDir = HBufC::NewLC( iDir.Length() + KSubdirNameLength );
       
  1652     for(TInt i=0; i < numdirs; i++)
       
  1653         {
       
  1654         TInt arrayIndex = -1;
       
  1655         const TEntry& entry = (*baseDirs)[i];
       
  1656         if(entry.IsDir() && entry.iName.Length()==1)
       
  1657             {
       
  1658             TUint16 chr = *(entry.iName.Right(1).Ptr());
       
  1659             arrayIndex = TCompressedEntry::ConvertAsciiToIntSingleHexDigit(chr);
       
  1660             }
       
  1661 
       
  1662         if(arrayIndex >=0 && arrayIndex <= 15)
       
  1663             {
       
  1664             // initialise subdir name to base directory
       
  1665             currentDir->Des().Copy(iDir);
       
  1666             currentDir->Des().AppendFormat(_L("%x\\"), arrayIndex); // if base path wasn't terminated with trailing / we would have blown up at creation time.
       
  1667 
       
  1668             // get subdirectory content
       
  1669             CDir *dir;
       
  1670             iRfs.GetDir(currentDir->Des(), KEntryAttMatchExclude | KEntryAttDir, ESortByName, dir); // only files this time...
       
  1671             if(dir)
       
  1672                 {
       
  1673                 iDirContent.Insert( CCustomCacheDirList::NewL( dir ), arrayIndex );
       
  1674                 }
       
  1675             delete dir;
       
  1676             }
       
  1677         }
       
  1678         CleanupStack::PopAndDestroy(2); // baseDirs & currentDir
       
  1679     }
       
  1680 
       
  1681 // -----------------------------------------------------------------------------
       
  1682 // CCustomCacheDirList::NewL
       
  1683 // -----------------------------------------------------------------------------
       
  1684 //
       
  1685 CCustomCacheDirList* CCustomCacheDirList::NewL(CDir *aSrc)
       
  1686     {
       
  1687     CCustomCacheDirList *me = new (ELeave) CCustomCacheDirList;
       
  1688     CleanupStack::PushL( me );
       
  1689     me->ConstructL( aSrc );
       
  1690     CleanupStack::Pop( me );
       
  1691     return me;
       
  1692     }
       
  1693 
       
  1694 // -----------------------------------------------------------------------------
       
  1695 // CCustomCacheDirList::ValidateCacheEntryL
       
  1696 // -----------------------------------------------------------------------------
       
  1697 //
       
  1698 TBool CCustomCacheDirList::ValidateCacheEntryL( const CHttpCacheEntry& aEntry )
       
  1699     {
       
  1700     TBool presentAndValid = EFalse;
       
  1701     TUint32 shortName;
       
  1702     if( TCompressedEntry::ConvertANameToUint32( aEntry.Filename().Right(8), shortName) )
       
  1703         {
       
  1704         for(TInt i=0; i<iDirList.Count(); i++)
       
  1705             {
       
  1706             if(iDirList[i]->IsCompressed() &&
       
  1707                     (iDirList[i]->GetCompressedName() == shortName) &&
       
  1708                     (iDirList[i]->GetSize() == aEntry.BodySize()))
       
  1709                 {
       
  1710                 presentAndValid = ETrue;
       
  1711                 iDirList.Remove(i);
       
  1712                 break;
       
  1713                 }
       
  1714             }
       
  1715         }
       
  1716     return presentAndValid;
       
  1717     }
       
  1718 
       
  1719 // -----------------------------------------------------------------------------
       
  1720 // CCustomCacheDirList::Count
       
  1721 // -----------------------------------------------------------------------------
       
  1722 //
       
  1723 TInt CCustomCacheDirList::Count()
       
  1724     {
       
  1725     return iDirList.Count();
       
  1726     }
       
  1727 
       
  1728 // -----------------------------------------------------------------------------
       
  1729 // CCustomCacheDirList::NameAtL
       
  1730 // -----------------------------------------------------------------------------
       
  1731 //
       
  1732 HBufC* CCustomCacheDirList::NameAtL( TInt aIndex )
       
  1733     {
       
  1734     return iDirList[aIndex]->GetNameL();
       
  1735     }
       
  1736 
       
  1737 // -----------------------------------------------------------------------------
       
  1738 // CCustomCacheDirList::CCustomCacheDirList
       
  1739 // -----------------------------------------------------------------------------
       
  1740 //
       
  1741 CCustomCacheDirList::CCustomCacheDirList()
       
  1742     {
       
  1743     }
       
  1744 
       
  1745 // -----------------------------------------------------------------------------
       
  1746 // CCustomCacheDirList::ConstructL
       
  1747 // -----------------------------------------------------------------------------
       
  1748 //
       
  1749 void CCustomCacheDirList::ConstructL(CDir *aSrc)
       
  1750     {
       
  1751     TInt items = aSrc->Count();
       
  1752     if(items)
       
  1753         {
       
  1754         iDirList.ReserveL(items);
       
  1755         for(TInt i=0; i < items; i++)
       
  1756             {
       
  1757             TCompressedEntry *newDirEntry = TCompressedEntry::NewL( (*aSrc)[i] );
       
  1758             iDirList.AppendL( newDirEntry );
       
  1759             }
       
  1760         }
       
  1761     }
       
  1762 
       
  1763 // -----------------------------------------------------------------------------
       
  1764 // TCompressedEntry::NewL
       
  1765 // -----------------------------------------------------------------------------
       
  1766 //
       
  1767 TCompressedEntry *TCompressedEntry::NewL( const TEntry& aEntry )
       
  1768     {
       
  1769     TCompressedEntry *newEntry = new (ELeave) TCompressedEntry;
       
  1770     CleanupStack::PushL( newEntry );
       
  1771     newEntry->ConstructL( aEntry );
       
  1772     CleanupStack::Pop( newEntry );
       
  1773 
       
  1774     return newEntry;
       
  1775     }
       
  1776 
       
  1777 // -----------------------------------------------------------------------------
       
  1778 // TCompressedEntry::ConstructL
       
  1779 // -----------------------------------------------------------------------------
       
  1780 //
       
  1781 void TCompressedEntry::ConstructL( const TEntry& aEntry )
       
  1782     {
       
  1783     TUint32 compressedName;
       
  1784     if ( ConvertANameToUint32(aEntry.iName, compressedName) )
       
  1785         {
       
  1786         iFlags |= EFilenameStoredAsUint32;
       
  1787         iName.iNameAsUint32 = compressedName;
       
  1788         }
       
  1789     else
       
  1790         {
       
  1791         iName.iNameAsHBuf = aEntry.iName.AllocL();
       
  1792         }
       
  1793     iSize = aEntry.iSize;
       
  1794     }
       
  1795 
       
  1796 // -----------------------------------------------------------------------------
       
  1797 // TCompressedEntry::ConvertANameToUint32
       
  1798 // -----------------------------------------------------------------------------
       
  1799 //
       
  1800 TBool TCompressedEntry::ConvertANameToUint32( const TDesC& aName, TUint32& aConverted)
       
  1801     {
       
  1802     TBool success = EFalse;
       
  1803     aConverted = 0;
       
  1804 
       
  1805     if ( aName.Length() == 8 )
       
  1806         {
       
  1807         TUint32 scratch = 0;
       
  1808         for ( TInt i=0; i < 8; i++ )
       
  1809             {
       
  1810             scratch <<= 4;
       
  1811             TInt val = TCompressedEntry::ConvertAsciiToIntSingleHexDigit(aName[i]);
       
  1812             if ( val >= 0 )
       
  1813                 {
       
  1814                 scratch += val & 0x0F;
       
  1815                 }
       
  1816             else
       
  1817                 break;
       
  1818 
       
  1819             if ( i==7 )
       
  1820                 {
       
  1821                 aConverted = scratch;
       
  1822                 success = ETrue;
       
  1823                 }
       
  1824             }
       
  1825         }
       
  1826 
       
  1827     return success;
       
  1828     }
       
  1829 
       
  1830 // -----------------------------------------------------------------------------
       
  1831 // TCompressedEntry::ConvertAsciiToIntSingleHexDigit
       
  1832 // -----------------------------------------------------------------------------
       
  1833 //
       
  1834 TInt TCompressedEntry::ConvertAsciiToIntSingleHexDigit(const TUint16& aDigitChar)
       
  1835     {
       
  1836     if ( aDigitChar >=48 && aDigitChar <=57 )
       
  1837         {
       
  1838         return (aDigitChar - 48); //numerals
       
  1839         }
       
  1840     else if ( aDigitChar >= 65 && aDigitChar <= 70 )
       
  1841         {
       
  1842         return (aDigitChar - 55); // uppercase hex letters
       
  1843         }
       
  1844     else if ( aDigitChar >= 97 && aDigitChar <= 102 )
       
  1845         {
       
  1846         return (aDigitChar - 87); // lowercase hex letters
       
  1847         }
       
  1848 
       
  1849     return -1;
       
  1850     }
       
  1851 
       
  1852 // -----------------------------------------------------------------------------
       
  1853 // TCompressedEntry::GetNameL
       
  1854 // -----------------------------------------------------------------------------
       
  1855 //
       
  1856 HBufC* TCompressedEntry::GetNameL()
       
  1857     {
       
  1858     if ( !IsCompressed() )
       
  1859         {
       
  1860         return iName.iNameAsHBuf->AllocL();
       
  1861         }
       
  1862 
       
  1863     HBufC* name = HBufC::NewL(8);
       
  1864     name->Des().Format(_L("%08x"), iName.iNameAsUint32);
       
  1865 
       
  1866     return name;
       
  1867     }
       
  1868 //  End of File
  1504 //  End of File