1*f0e491d3SAndrew Lindesay /* 2*f0e491d3SAndrew Lindesay * Copyright 2020, Andrew Lindesay <apl@lindesay.co.nz>. 3*f0e491d3SAndrew Lindesay * All rights reserved. Distributed under the terms of the MIT License. 4*f0e491d3SAndrew Lindesay */ 5*f0e491d3SAndrew Lindesay #include "PackageIconTarRepository.h" 6*f0e491d3SAndrew Lindesay 7*f0e491d3SAndrew Lindesay #include <Autolock.h> 8*f0e491d3SAndrew Lindesay #include <AutoDeleter.h> 9*f0e491d3SAndrew Lindesay #include <File.h> 10*f0e491d3SAndrew Lindesay #include <support/StopWatch.h> 11*f0e491d3SAndrew Lindesay 12*f0e491d3SAndrew Lindesay #include "Logger.h" 13*f0e491d3SAndrew Lindesay #include "TarArchiveService.h" 14*f0e491d3SAndrew Lindesay 15*f0e491d3SAndrew Lindesay 16*f0e491d3SAndrew Lindesay BitmapRef 17*f0e491d3SAndrew Lindesay PackageIconTarRepository::sDefaultIcon(new(std::nothrow) SharedBitmap( 18*f0e491d3SAndrew Lindesay "application/x-vnd.haiku-package"), true); 19*f0e491d3SAndrew Lindesay 20*f0e491d3SAndrew Lindesay 21*f0e491d3SAndrew Lindesay /*! An instance of this class can be provided to the TarArchiveService to 22*f0e491d3SAndrew Lindesay be called each time a tar entry is found. This way it is able to capture 23*f0e491d3SAndrew Lindesay the offsets of the icons in the tar file against the package names. 24*f0e491d3SAndrew Lindesay */ 25*f0e491d3SAndrew Lindesay 26*f0e491d3SAndrew Lindesay class IconTarPtrEntryListener : public TarEntryListener 27*f0e491d3SAndrew Lindesay { 28*f0e491d3SAndrew Lindesay public: 29*f0e491d3SAndrew Lindesay IconTarPtrEntryListener( 30*f0e491d3SAndrew Lindesay PackageIconTarRepository* 31*f0e491d3SAndrew Lindesay fPackageIconTarRepository); 32*f0e491d3SAndrew Lindesay virtual ~IconTarPtrEntryListener(); 33*f0e491d3SAndrew Lindesay 34*f0e491d3SAndrew Lindesay virtual status_t Handle( 35*f0e491d3SAndrew Lindesay const TarArchiveHeader& header, 36*f0e491d3SAndrew Lindesay size_t offset, 37*f0e491d3SAndrew Lindesay BDataIO *data); 38*f0e491d3SAndrew Lindesay private: 39*f0e491d3SAndrew Lindesay status_t _LeafNameToBitmapSize(BString& leafName, 40*f0e491d3SAndrew Lindesay BitmapSize* bitmapSize); 41*f0e491d3SAndrew Lindesay 42*f0e491d3SAndrew Lindesay private: 43*f0e491d3SAndrew Lindesay PackageIconTarRepository* 44*f0e491d3SAndrew Lindesay fPackageIconTarRepository; 45*f0e491d3SAndrew Lindesay }; 46*f0e491d3SAndrew Lindesay 47*f0e491d3SAndrew Lindesay 48*f0e491d3SAndrew Lindesay IconTarPtrEntryListener::IconTarPtrEntryListener( 49*f0e491d3SAndrew Lindesay PackageIconTarRepository* packageIconTarRepository) 50*f0e491d3SAndrew Lindesay : 51*f0e491d3SAndrew Lindesay fPackageIconTarRepository(packageIconTarRepository) 52*f0e491d3SAndrew Lindesay { 53*f0e491d3SAndrew Lindesay } 54*f0e491d3SAndrew Lindesay 55*f0e491d3SAndrew Lindesay 56*f0e491d3SAndrew Lindesay IconTarPtrEntryListener::~IconTarPtrEntryListener() 57*f0e491d3SAndrew Lindesay { 58*f0e491d3SAndrew Lindesay } 59*f0e491d3SAndrew Lindesay 60*f0e491d3SAndrew Lindesay 61*f0e491d3SAndrew Lindesay /*! The format of the filenames in the archive are of the format; 62*f0e491d3SAndrew Lindesay \code 63*f0e491d3SAndrew Lindesay hicn/ardino/icon.hvif 64*f0e491d3SAndrew Lindesay \endcode 65*f0e491d3SAndrew Lindesay The leafname (the last part of the path) determines the type of the file as 66*f0e491d3SAndrew Lindesay it could be either in HVIF format or a PNG of various sizes. 67*f0e491d3SAndrew Lindesay */ 68*f0e491d3SAndrew Lindesay 69*f0e491d3SAndrew Lindesay status_t 70*f0e491d3SAndrew Lindesay IconTarPtrEntryListener::Handle(const TarArchiveHeader& header, 71*f0e491d3SAndrew Lindesay size_t offset, BDataIO *data) 72*f0e491d3SAndrew Lindesay { 73*f0e491d3SAndrew Lindesay if (header.FileType() != TAR_FILE_TYPE_NORMAL) 74*f0e491d3SAndrew Lindesay return B_OK; 75*f0e491d3SAndrew Lindesay 76*f0e491d3SAndrew Lindesay BString fileName = header.FileName(); 77*f0e491d3SAndrew Lindesay if (!fileName.StartsWith("hicn/")) 78*f0e491d3SAndrew Lindesay return B_OK; 79*f0e491d3SAndrew Lindesay 80*f0e491d3SAndrew Lindesay int32 secondSlashIdx = fileName.FindFirst("/", 5); 81*f0e491d3SAndrew Lindesay if (secondSlashIdx == B_ERROR || secondSlashIdx == 5) 82*f0e491d3SAndrew Lindesay return B_OK; 83*f0e491d3SAndrew Lindesay 84*f0e491d3SAndrew Lindesay BString packageName; 85*f0e491d3SAndrew Lindesay BString leafName; 86*f0e491d3SAndrew Lindesay fileName.CopyInto(packageName, 5, secondSlashIdx - 5); 87*f0e491d3SAndrew Lindesay fileName.CopyInto(leafName, secondSlashIdx + 1, 88*f0e491d3SAndrew Lindesay fileName.Length() - (secondSlashIdx + 1)); 89*f0e491d3SAndrew Lindesay BitmapSize bitmapSize; 90*f0e491d3SAndrew Lindesay 91*f0e491d3SAndrew Lindesay if (_LeafNameToBitmapSize(leafName, &bitmapSize) == B_OK) { 92*f0e491d3SAndrew Lindesay fPackageIconTarRepository->AddIconTarPtr(packageName, bitmapSize, 93*f0e491d3SAndrew Lindesay offset); 94*f0e491d3SAndrew Lindesay } 95*f0e491d3SAndrew Lindesay 96*f0e491d3SAndrew Lindesay return B_OK; 97*f0e491d3SAndrew Lindesay } 98*f0e491d3SAndrew Lindesay 99*f0e491d3SAndrew Lindesay 100*f0e491d3SAndrew Lindesay status_t 101*f0e491d3SAndrew Lindesay IconTarPtrEntryListener::_LeafNameToBitmapSize(BString& leafName, 102*f0e491d3SAndrew Lindesay BitmapSize* bitmapSize) 103*f0e491d3SAndrew Lindesay { 104*f0e491d3SAndrew Lindesay if (leafName == "icon.hvif") { 105*f0e491d3SAndrew Lindesay *bitmapSize = BITMAP_SIZE_ANY; 106*f0e491d3SAndrew Lindesay return B_OK; 107*f0e491d3SAndrew Lindesay } 108*f0e491d3SAndrew Lindesay if (leafName == "64.png") { 109*f0e491d3SAndrew Lindesay *bitmapSize = BITMAP_SIZE_64; 110*f0e491d3SAndrew Lindesay return B_OK; 111*f0e491d3SAndrew Lindesay } 112*f0e491d3SAndrew Lindesay if (leafName == "32.png") { 113*f0e491d3SAndrew Lindesay *bitmapSize = BITMAP_SIZE_32; 114*f0e491d3SAndrew Lindesay return B_OK; 115*f0e491d3SAndrew Lindesay } 116*f0e491d3SAndrew Lindesay if (leafName == "16.png") { 117*f0e491d3SAndrew Lindesay *bitmapSize = BITMAP_SIZE_16; 118*f0e491d3SAndrew Lindesay return B_OK; 119*f0e491d3SAndrew Lindesay } 120*f0e491d3SAndrew Lindesay return B_BAD_VALUE; 121*f0e491d3SAndrew Lindesay } 122*f0e491d3SAndrew Lindesay 123*f0e491d3SAndrew Lindesay 124*f0e491d3SAndrew Lindesay PackageIconTarRepository::PackageIconTarRepository() 125*f0e491d3SAndrew Lindesay : 126*f0e491d3SAndrew Lindesay fTarIo(NULL) 127*f0e491d3SAndrew Lindesay { 128*f0e491d3SAndrew Lindesay } 129*f0e491d3SAndrew Lindesay 130*f0e491d3SAndrew Lindesay 131*f0e491d3SAndrew Lindesay PackageIconTarRepository::~PackageIconTarRepository() 132*f0e491d3SAndrew Lindesay { 133*f0e491d3SAndrew Lindesay } 134*f0e491d3SAndrew Lindesay 135*f0e491d3SAndrew Lindesay 136*f0e491d3SAndrew Lindesay /*! This method will reconfigure itself using the data in the tar file supplied. 137*f0e491d3SAndrew Lindesay Any existing data will be flushed and the new tar will be scanned for 138*f0e491d3SAndrew Lindesay offsets to usable files. 139*f0e491d3SAndrew Lindesay */ 140*f0e491d3SAndrew Lindesay 141*f0e491d3SAndrew Lindesay status_t 142*f0e491d3SAndrew Lindesay PackageIconTarRepository::Init(BPath& tarPath) 143*f0e491d3SAndrew Lindesay { 144*f0e491d3SAndrew Lindesay BAutolock locker(&fLock); 145*f0e491d3SAndrew Lindesay _Close(); 146*f0e491d3SAndrew Lindesay status_t result = B_OK; 147*f0e491d3SAndrew Lindesay 148*f0e491d3SAndrew Lindesay if (tarPath.Path() == NULL) { 149*f0e491d3SAndrew Lindesay HDINFO("empty path to tar-ball"); 150*f0e491d3SAndrew Lindesay result = B_BAD_VALUE; 151*f0e491d3SAndrew Lindesay } 152*f0e491d3SAndrew Lindesay 153*f0e491d3SAndrew Lindesay BFile *tarIo = NULL; 154*f0e491d3SAndrew Lindesay 155*f0e491d3SAndrew Lindesay if (result == B_OK) { 156*f0e491d3SAndrew Lindesay HDINFO("will init icon model from tar [%s]", tarPath.Path()); 157*f0e491d3SAndrew Lindesay tarIo = new BFile(tarPath.Path(), O_RDONLY); 158*f0e491d3SAndrew Lindesay 159*f0e491d3SAndrew Lindesay if (!tarIo->IsReadable()) { 160*f0e491d3SAndrew Lindesay HDERROR("unable to read the tar [%s]", tarPath.Path()); 161*f0e491d3SAndrew Lindesay result = B_IO_ERROR; 162*f0e491d3SAndrew Lindesay } 163*f0e491d3SAndrew Lindesay } 164*f0e491d3SAndrew Lindesay 165*f0e491d3SAndrew Lindesay // will fill the model up with records from the tar-ball. 166*f0e491d3SAndrew Lindesay 167*f0e491d3SAndrew Lindesay if (result == B_OK) { 168*f0e491d3SAndrew Lindesay BStopWatch watch("PackageIconTarRepository::Init", true); 169*f0e491d3SAndrew Lindesay HDINFO("will read [%s] and collect the tar pointers", tarPath.Path()); 170*f0e491d3SAndrew Lindesay 171*f0e491d3SAndrew Lindesay IconTarPtrEntryListener* listener = new IconTarPtrEntryListener(this); 172*f0e491d3SAndrew Lindesay ObjectDeleter<IconTarPtrEntryListener> listenerDeleter(listener); 173*f0e491d3SAndrew Lindesay TarArchiveService::ForEachEntry(*tarIo, listener); 174*f0e491d3SAndrew Lindesay 175*f0e491d3SAndrew Lindesay double secs = watch.ElapsedTime() / 1000000.0; 176*f0e491d3SAndrew Lindesay HDINFO("did collect %" B_PRIi32 " tar pointers (%6.3g secs)", 177*f0e491d3SAndrew Lindesay fIconTarPtrs.Size(), secs); 178*f0e491d3SAndrew Lindesay } 179*f0e491d3SAndrew Lindesay 180*f0e491d3SAndrew Lindesay if (result == B_OK) 181*f0e491d3SAndrew Lindesay fTarIo = tarIo; 182*f0e491d3SAndrew Lindesay else 183*f0e491d3SAndrew Lindesay delete tarIo; 184*f0e491d3SAndrew Lindesay 185*f0e491d3SAndrew Lindesay return result; 186*f0e491d3SAndrew Lindesay } 187*f0e491d3SAndrew Lindesay 188*f0e491d3SAndrew Lindesay 189*f0e491d3SAndrew Lindesay void 190*f0e491d3SAndrew Lindesay PackageIconTarRepository::_Close() 191*f0e491d3SAndrew Lindesay { 192*f0e491d3SAndrew Lindesay delete fTarIo; 193*f0e491d3SAndrew Lindesay fTarIo = NULL; 194*f0e491d3SAndrew Lindesay fIconTarPtrs.Clear(); 195*f0e491d3SAndrew Lindesay fIconCache.Clear(); 196*f0e491d3SAndrew Lindesay } 197*f0e491d3SAndrew Lindesay 198*f0e491d3SAndrew Lindesay 199*f0e491d3SAndrew Lindesay /*! This method should be treated private and only called from a situation 200*f0e491d3SAndrew Lindesay in which the class's lock is acquired. It is used to populate data from 201*f0e491d3SAndrew Lindesay the parsing of the tar headers. It is called from the listener above. 202*f0e491d3SAndrew Lindesay */ 203*f0e491d3SAndrew Lindesay 204*f0e491d3SAndrew Lindesay void 205*f0e491d3SAndrew Lindesay PackageIconTarRepository::AddIconTarPtr(const BString& packageName, 206*f0e491d3SAndrew Lindesay BitmapSize bitmapSize, off_t offset) 207*f0e491d3SAndrew Lindesay { 208*f0e491d3SAndrew Lindesay IconTarPtrRef tarPtrRef = _GetOrCreateIconTarPtr(packageName); 209*f0e491d3SAndrew Lindesay tarPtrRef->SetOffset(bitmapSize, offset); 210*f0e491d3SAndrew Lindesay } 211*f0e491d3SAndrew Lindesay 212*f0e491d3SAndrew Lindesay 213*f0e491d3SAndrew Lindesay bool 214*f0e491d3SAndrew Lindesay PackageIconTarRepository::HasAnyIcon(const BString& pkgName) 215*f0e491d3SAndrew Lindesay { 216*f0e491d3SAndrew Lindesay BAutolock locker(&fLock); 217*f0e491d3SAndrew Lindesay HashString key(pkgName); 218*f0e491d3SAndrew Lindesay return fIconTarPtrs.ContainsKey(key); 219*f0e491d3SAndrew Lindesay } 220*f0e491d3SAndrew Lindesay 221*f0e491d3SAndrew Lindesay 222*f0e491d3SAndrew Lindesay status_t 223*f0e491d3SAndrew Lindesay PackageIconTarRepository::GetIcon(const BString& pkgName, BitmapSize size, 224*f0e491d3SAndrew Lindesay BitmapRef& bitmap) 225*f0e491d3SAndrew Lindesay { 226*f0e491d3SAndrew Lindesay BAutolock locker(&fLock); 227*f0e491d3SAndrew Lindesay status_t result = B_OK; 228*f0e491d3SAndrew Lindesay BitmapSize actualSize; 229*f0e491d3SAndrew Lindesay off_t iconDataTarOffset = -1; 230*f0e491d3SAndrew Lindesay const IconTarPtrRef tarPtrRef = _GetIconTarPtr(pkgName); 231*f0e491d3SAndrew Lindesay 232*f0e491d3SAndrew Lindesay if (tarPtrRef.Get() != NULL) { 233*f0e491d3SAndrew Lindesay iconDataTarOffset = _OffsetToBestRepresentation(tarPtrRef, size, 234*f0e491d3SAndrew Lindesay &actualSize); 235*f0e491d3SAndrew Lindesay } 236*f0e491d3SAndrew Lindesay 237*f0e491d3SAndrew Lindesay if (iconDataTarOffset < 0) 238*f0e491d3SAndrew Lindesay bitmap.SetTo(sDefaultIcon); 239*f0e491d3SAndrew Lindesay else { 240*f0e491d3SAndrew Lindesay HashString key = _ToIconCacheKey(pkgName, actualSize); 241*f0e491d3SAndrew Lindesay 242*f0e491d3SAndrew Lindesay // TODO; need to implement an LRU cache so that not too many icons are 243*f0e491d3SAndrew Lindesay // in memory at the same time. 244*f0e491d3SAndrew Lindesay 245*f0e491d3SAndrew Lindesay if (!fIconCache.ContainsKey(key)) { 246*f0e491d3SAndrew Lindesay result = _CreateIconFromTarOffset(iconDataTarOffset, bitmap); 247*f0e491d3SAndrew Lindesay if (result == B_OK) 248*f0e491d3SAndrew Lindesay fIconCache.Put(key, bitmap); 249*f0e491d3SAndrew Lindesay else { 250*f0e491d3SAndrew Lindesay HDERROR("failure to read image for package [%s] at offset %" 251*f0e491d3SAndrew Lindesay B_PRIdSSIZE, pkgName.String(), iconDataTarOffset); 252*f0e491d3SAndrew Lindesay fIconCache.Put(key, sDefaultIcon); 253*f0e491d3SAndrew Lindesay } 254*f0e491d3SAndrew Lindesay } 255*f0e491d3SAndrew Lindesay bitmap.SetTo(fIconCache.Get(key).Get()); 256*f0e491d3SAndrew Lindesay } 257*f0e491d3SAndrew Lindesay return result; 258*f0e491d3SAndrew Lindesay } 259*f0e491d3SAndrew Lindesay 260*f0e491d3SAndrew Lindesay 261*f0e491d3SAndrew Lindesay IconTarPtrRef 262*f0e491d3SAndrew Lindesay PackageIconTarRepository::_GetIconTarPtr(const BString& pkgName) const 263*f0e491d3SAndrew Lindesay { 264*f0e491d3SAndrew Lindesay return fIconTarPtrs.Get(HashString(pkgName)); 265*f0e491d3SAndrew Lindesay } 266*f0e491d3SAndrew Lindesay 267*f0e491d3SAndrew Lindesay 268*f0e491d3SAndrew Lindesay const char* 269*f0e491d3SAndrew Lindesay PackageIconTarRepository::_ToIconCacheKeySuffix(BitmapSize size) 270*f0e491d3SAndrew Lindesay { 271*f0e491d3SAndrew Lindesay switch (size) 272*f0e491d3SAndrew Lindesay { 273*f0e491d3SAndrew Lindesay case BITMAP_SIZE_16: 274*f0e491d3SAndrew Lindesay return "16"; 275*f0e491d3SAndrew Lindesay // note that size 22 is not supported. 276*f0e491d3SAndrew Lindesay case BITMAP_SIZE_32: 277*f0e491d3SAndrew Lindesay return "32"; 278*f0e491d3SAndrew Lindesay case BITMAP_SIZE_64: 279*f0e491d3SAndrew Lindesay return "64"; 280*f0e491d3SAndrew Lindesay case BITMAP_SIZE_ANY: 281*f0e491d3SAndrew Lindesay return "any"; 282*f0e491d3SAndrew Lindesay default: 283*f0e491d3SAndrew Lindesay HDERROR("unsupported bitmap size"); 284*f0e491d3SAndrew Lindesay exit(1); 285*f0e491d3SAndrew Lindesay break; 286*f0e491d3SAndrew Lindesay } 287*f0e491d3SAndrew Lindesay } 288*f0e491d3SAndrew Lindesay 289*f0e491d3SAndrew Lindesay 290*f0e491d3SAndrew Lindesay const HashString 291*f0e491d3SAndrew Lindesay PackageIconTarRepository::_ToIconCacheKey(const BString& pkgName, 292*f0e491d3SAndrew Lindesay BitmapSize size) 293*f0e491d3SAndrew Lindesay { 294*f0e491d3SAndrew Lindesay return HashString(BString(pkgName) << "__x" << _ToIconCacheKeySuffix(size)); 295*f0e491d3SAndrew Lindesay } 296*f0e491d3SAndrew Lindesay 297*f0e491d3SAndrew Lindesay 298*f0e491d3SAndrew Lindesay status_t 299*f0e491d3SAndrew Lindesay PackageIconTarRepository::_CreateIconFromTarOffset(off_t offset, 300*f0e491d3SAndrew Lindesay BitmapRef& bitmap) 301*f0e491d3SAndrew Lindesay { 302*f0e491d3SAndrew Lindesay fTarIo->Seek(offset, SEEK_SET); 303*f0e491d3SAndrew Lindesay TarArchiveHeader header; 304*f0e491d3SAndrew Lindesay status_t result = TarArchiveService::GetEntry(*fTarIo, header); 305*f0e491d3SAndrew Lindesay 306*f0e491d3SAndrew Lindesay if (result == B_OK && header.Length() <= 0) 307*f0e491d3SAndrew Lindesay result = B_BAD_DATA; 308*f0e491d3SAndrew Lindesay 309*f0e491d3SAndrew Lindesay if (result == B_OK) 310*f0e491d3SAndrew Lindesay bitmap.SetTo(new(std::nothrow)SharedBitmap(*fTarIo, header.Length())); 311*f0e491d3SAndrew Lindesay 312*f0e491d3SAndrew Lindesay return result; 313*f0e491d3SAndrew Lindesay } 314*f0e491d3SAndrew Lindesay 315*f0e491d3SAndrew Lindesay 316*f0e491d3SAndrew Lindesay /*! If there is a vector representation (HVIF) then this will be the best 317*f0e491d3SAndrew Lindesay option. If there are only bitmap images to choose from then consider what 318*f0e491d3SAndrew Lindesay the target size is and choose the best image to match. 319*f0e491d3SAndrew Lindesay */ 320*f0e491d3SAndrew Lindesay 321*f0e491d3SAndrew Lindesay /*static*/ off_t 322*f0e491d3SAndrew Lindesay PackageIconTarRepository::_OffsetToBestRepresentation( 323*f0e491d3SAndrew Lindesay const IconTarPtrRef iconTarPtrRef, BitmapSize desiredSize, 324*f0e491d3SAndrew Lindesay BitmapSize* actualSize) 325*f0e491d3SAndrew Lindesay { 326*f0e491d3SAndrew Lindesay if (iconTarPtrRef->HasOffset(BITMAP_SIZE_ANY)) { 327*f0e491d3SAndrew Lindesay *actualSize = BITMAP_SIZE_ANY; 328*f0e491d3SAndrew Lindesay return iconTarPtrRef->Offset(BITMAP_SIZE_ANY); 329*f0e491d3SAndrew Lindesay } 330*f0e491d3SAndrew Lindesay if (iconTarPtrRef->HasOffset(BITMAP_SIZE_64) 331*f0e491d3SAndrew Lindesay && desiredSize >= BITMAP_SIZE_64) { 332*f0e491d3SAndrew Lindesay *actualSize = BITMAP_SIZE_64; 333*f0e491d3SAndrew Lindesay return iconTarPtrRef->Offset(BITMAP_SIZE_64); 334*f0e491d3SAndrew Lindesay } 335*f0e491d3SAndrew Lindesay if (iconTarPtrRef->HasOffset(BITMAP_SIZE_32) 336*f0e491d3SAndrew Lindesay && desiredSize >= BITMAP_SIZE_32) { 337*f0e491d3SAndrew Lindesay *actualSize = BITMAP_SIZE_32; 338*f0e491d3SAndrew Lindesay return iconTarPtrRef->Offset(BITMAP_SIZE_32); 339*f0e491d3SAndrew Lindesay } 340*f0e491d3SAndrew Lindesay if (iconTarPtrRef->HasOffset(BITMAP_SIZE_22) 341*f0e491d3SAndrew Lindesay && desiredSize >= BITMAP_SIZE_22) { 342*f0e491d3SAndrew Lindesay *actualSize = BITMAP_SIZE_22; 343*f0e491d3SAndrew Lindesay return iconTarPtrRef->Offset(BITMAP_SIZE_22); 344*f0e491d3SAndrew Lindesay } 345*f0e491d3SAndrew Lindesay if (iconTarPtrRef->HasOffset(BITMAP_SIZE_16)) { 346*f0e491d3SAndrew Lindesay *actualSize = BITMAP_SIZE_16; 347*f0e491d3SAndrew Lindesay return iconTarPtrRef->Offset(BITMAP_SIZE_16); 348*f0e491d3SAndrew Lindesay } 349*f0e491d3SAndrew Lindesay return -1; 350*f0e491d3SAndrew Lindesay } 351*f0e491d3SAndrew Lindesay 352*f0e491d3SAndrew Lindesay 353*f0e491d3SAndrew Lindesay IconTarPtrRef 354*f0e491d3SAndrew Lindesay PackageIconTarRepository::_GetOrCreateIconTarPtr(const BString& pkgName) 355*f0e491d3SAndrew Lindesay { 356*f0e491d3SAndrew Lindesay BAutolock locker(&fLock); 357*f0e491d3SAndrew Lindesay HashString key(pkgName); 358*f0e491d3SAndrew Lindesay if (!fIconTarPtrs.ContainsKey(key)) { 359*f0e491d3SAndrew Lindesay IconTarPtrRef value(new IconTarPtr(pkgName)); 360*f0e491d3SAndrew Lindesay fIconTarPtrs.Put(key, value); 361*f0e491d3SAndrew Lindesay return value; 362*f0e491d3SAndrew Lindesay } 363*f0e491d3SAndrew Lindesay return fIconTarPtrs.Get(key); 364*f0e491d3SAndrew Lindesay } 365*f0e491d3SAndrew Lindesay 366*f0e491d3SAndrew Lindesay 367*f0e491d3SAndrew Lindesay /*static*/ void 368*f0e491d3SAndrew Lindesay PackageIconTarRepository::CleanupDefaultIcon() 369*f0e491d3SAndrew Lindesay { 370*f0e491d3SAndrew Lindesay sDefaultIcon.Unset(); 371*f0e491d3SAndrew Lindesay } 372