X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/05467b1e69dcb6ab49f5bc5d880529ab22551bce..15580453fc31f5e09669f7a24f74da6dcdf948b0:/MobileCydia.mm diff --git a/MobileCydia.mm b/MobileCydia.mm index 40176ccd..8212c6cb 100644 --- a/MobileCydia.mm +++ b/MobileCydia.mm @@ -276,8 +276,6 @@ static _finline void UpdateExternalStatus(uint64_t newStatus) { } - (id) yieldToSelector:(SEL)selector withObject:(id)object { - /*return [self performSelector:selector withObject:object];*/ - volatile bool stopped(false); NSMutableArray *context([NSMutableArray arrayWithObjects: @@ -766,23 +764,24 @@ class CYString { cache_ = reinterpret_cast(CFRetain(rhs.cache_)); } + void copy(apr_pool_t *pool) { + char *temp(reinterpret_cast(apr_palloc(pool, size_ + 1))); + memcpy(temp, data_, size_); + temp[size_] = '\0'; + data_ = temp; + } + void set(apr_pool_t *pool, const char *data, size_t size) { if (size == 0) clear(); else { clear_(); - if (pool == NULL) - data_ = const_cast(data); - else { - char *temp(reinterpret_cast(apr_palloc(pool, size + 1))); - memcpy(temp, data, size); - temp[size] = '\0'; - - data_ = temp; - } - + data_ = const_cast(data); size_ = size; + + if (pool != NULL) + copy(pool); } } @@ -1100,9 +1099,7 @@ NSString *SizeString(double size) { static _finline const char *StripVersion_(const char *version) { const char *colon(strchr(version, ':')); - if (colon != NULL) - version = colon + 1; - return version; + return colon == NULL ? version : colon + 1; } NSString *LocalizeSection(NSString *section) { @@ -1431,7 +1428,6 @@ typedef std::map< unsigned long, _H > SourceMap; struct PackageValue : Cytore::Block { - Cytore::Offset reserved_; Cytore::Offset next_; uint32_t index_ : 23; @@ -1451,14 +1447,13 @@ struct PackageValue : struct MetaValue : Cytore::Block { - Cytore::Offset reserved_; Cytore::Offset packages_[1 << 16]; }; static Cytore::File MetaFile_; // }}} // Cytore Helper Functions {{{ -static PackageValue *PackageFind(const char *name, size_t length, Cytore::Offset *cache = NULL) { +static PackageValue *PackageFind(const char *name, size_t length) { SplitHash nhash = { hashlittle(name, length) }; PackageValue *metadata; @@ -1479,9 +1474,6 @@ static PackageValue *PackageFind(const char *name, size_t length, Cytore::Offset } } - if (cache != NULL) - *cache = *offset; - return metadata; } @@ -1505,25 +1497,32 @@ static void PackageImport(const void *key, const void *value, void *context) { metadata->first_ = time; } + bool versioned(false); + if (NSDate *date = [package objectForKey:@"LastSeen"]) { time_t time([date timeIntervalSince1970]); if (metadata->last_ < time || metadata->last_ == 0) { metadata->last_ = time; - goto last; + versioned = true; } - } else if (metadata->last_ == 0) last: { - NSString *version([package objectForKey:@"LastVersion"]); - if (CFStringGetCString((CFStringRef) version, buffer, sizeof(buffer), kCFStringEncodingUTF8)) { - size_t length(strlen(buffer)); - uint16_t vhash(hashlittle(buffer, length)); + } else if (metadata->last_ == 0) { + metadata->last_ = metadata->first_; + if (metadata->version_[0] == '\0') + versioned = true; + } - size_t capped(std::min(8, length)); - char *latest(buffer + length - capped); + if (versioned) + if (NSString *version = [package objectForKey:@"LastVersion"]) + if (CFStringGetCString((CFStringRef) version, buffer, sizeof(buffer), kCFStringEncodingUTF8)) { + size_t length(strlen(buffer)); + uint16_t vhash(hashlittle(buffer, length)); - strncpy(metadata->version_, latest, sizeof(metadata->version_)); - metadata->vhash_ = vhash; - } - } + size_t capped(std::min(8, length)); + char *latest(buffer + length - capped); + + strncpy(metadata->version_, latest, sizeof(metadata->version_)); + metadata->vhash_ = vhash; + } } // }}} @@ -1830,34 +1829,35 @@ struct ParsedPackage { }; @interface Package : NSObject { - unsigned era_; + uint32_t era_ : 29; + uint32_t essential_ : 1; + uint32_t obsolete_ : 1; + uint32_t ignored_ : 1; + apr_pool_t *pool_; + _transient Database *database_; + pkgCache::VerIterator version_; pkgCache::PkgIterator iterator_; - _transient Database *database_; pkgCache::VerFileIterator file_; - Source *source_; - ParsedPackage *parsed_; + CYString id_; + CYString name_; + + CYString latest_; + CYString installed_; CYString section_; _transient NSString *section$_; - bool essential_; - bool obsolete_; - CYString latest_; - CYString installed_; + Source *source_; - CYString id_; - CYString name_; + PackageValue *metadata_; + ParsedPackage *parsed_; NSMutableArray *tags_; NSString *role_; - - Cytore::Offset metadata_; - - bool ignored_; } - (Package *) initWithVersion:(pkgCache::VerIterator)version withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database; @@ -1929,6 +1929,8 @@ struct ParsedPackage { - (NSArray *) purposes; - (bool) isCommercial; +- (void) setIndex:(size_t)index; + - (CYString &) cyname; - (uint32_t) compareBySection:(NSArray *)sections; @@ -1971,9 +1973,6 @@ uint32_t PackageChangesRadix(Package *self, void *) { return _not(uint32_t) - value.key; } -_finline static void Stifle(uint8_t &value) { -} - uint32_t PackagePrefixRadix(Package *self, void *context) { size_t offset(reinterpret_cast(context)); CYString &name([self cyname]); @@ -1996,8 +1995,6 @@ uint32_t PackagePrefixRadix(Package *self, void *context) { uint8_t data[4]; - // 0.607997 - if (offset == 0 && zeros != 0) { memset(data, '0', zeros); memcpy(data + zeros, text, 4 - zeros); @@ -2188,27 +2185,17 @@ struct PackageNameOrdering : - (Package *) initWithVersion:(pkgCache::VerIterator)version withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database { if ((self = [super init]) != nil) { _profile(Package$initWithVersion) - era_ = [database era]; pool_ = pool; - version_ = version; - - _profile(Package$initWithVersion$ParentPkg) - iterator_ = version.ParentPkg(); - _end - database_ = database; + era_ = [database era]; - _profile(Package$initWithVersion$Latest) - latest_.set(NULL, StripVersion_(version_.VerStr())); - _end + version_ = version; - pkgCache::VerIterator current; - _profile(Package$initWithVersion$Versions) - current = iterator_.CurrentVer(); - if (!current.end()) - installed_.set(NULL, StripVersion_(current.VerStr())); + pkgCache::PkgIterator iterator(version.ParentPkg()); + iterator_ = iterator; + _profile(Package$initWithVersion$Version) if (!version_.end()) file_ = version_.FileList(); else { @@ -2217,34 +2204,56 @@ struct PackageNameOrdering : } _end - _profile(Package$initWithVersion$Name) - id_.set(pool_, iterator_.Name()); - name_.set(NULL, iterator_.Display()); + _profile(Package$initWithVersion$Cache) + id_.set(NULL, iterator.Name()); + name_.set(NULL, iterator.Display()); + + latest_.set(NULL, StripVersion_(version_.VerStr())); + + pkgCache::VerIterator current(iterator.CurrentVer()); + if (!current.end()) + installed_.set(NULL, StripVersion_(current.VerStr())); _end - _profile(Package$initWithVersion$lowercaseString) + _profile(Package$initWithVersion$Lower) + // XXX: do not use tolower() as this is not locale-specific? :( char *data(id_.data()); for (size_t i(0), e(id_.size()); i != e; ++i) - // XXX: do not use tolower() as this is not locale-specific? :( - data[i] |= 0x20; + if ((data[i] & 0x20) == 0) { + id_.copy(pool); + data = id_.data(); + for (; i != e; ++i) + data[i] |= 0x20; + break; + } _end _profile(Package$initWithVersion$Tags) - pkgCache::TagIterator tag(iterator_.TagList()); + pkgCache::TagIterator tag(iterator.TagList()); if (!tag.end()) { tags_ = [[NSMutableArray alloc] initWithCapacity:8]; do { const char *name(tag.Name()); [tags_ addObject:[(NSString *)CYStringCreate(name) autorelease]]; + if (role_ == nil && strncmp(name, "role::", 6) == 0 /*&& strcmp(name, "role::leaper") != 0*/) role_ = (NSString *) CYStringCreate(name + 6); + + if (strncmp(name, "cydia::", 7) == 0) { + if (strcmp(name + 7, "essential") == 0) + essential_ = true; + else if (strcmp(name + 7, "obsolete") == 0) + obsolete_ = true; + } + ++tag; } while (!tag.end()); } _end _profile(Package$initWithVersion$Metadata) - PackageValue *metadata(PackageFind(id_.data(), id_.size(), &metadata_)); + PackageValue *metadata(PackageFind(id_.data(), id_.size())); + metadata_ = metadata; const char *latest(version_.VerStr()); size_t length(strlen(latest)); @@ -2257,24 +2266,25 @@ struct PackageNameOrdering : if (metadata->first_ == 0) metadata->first_ = now_; + if (metadata->last_ == 0) + metadata->last_ = metadata->first_; + if (metadata->vhash_ != vhash || strncmp(metadata->version_, latest, sizeof(metadata->version_)) != 0) { - metadata->last_ = now_; + if (metadata->version_[0] != '\0') + metadata->last_ = now_; strncpy(metadata->version_, latest, sizeof(metadata->version_)); metadata->vhash_ = vhash; - } else if (metadata->last_ == 0) - metadata->last_ = metadata->first_; + } _end _profile(Package$initWithVersion$Section) - section_.set(NULL, iterator_.Section()); + section_.set(NULL, iterator.Section()); _end - _profile(Package$initWithVersion$hasTag) - obsolete_ = [self hasTag:@"cydia::obsolete"]; - essential_ = ((iterator_->Flags & pkgCache::Flag::Essential) == 0 ? NO : YES) || [self hasTag:@"cydia::essential"]; + _profile(Package$initWithVersion$Flags) + essential_ |= ((iterator->Flags & pkgCache::Flag::Essential) == 0 ? NO : YES); + ignored_ = iterator->SelectedState == pkgCache::State::Hold; _end - - ignored_ = iterator_->SelectedState == pkgCache::State::Hold; _end } return self; } @@ -2288,12 +2298,26 @@ struct PackageNameOrdering : if (version.end()) return nil; - return [[[Package alloc] - initWithVersion:version - withZone:zone - inPool:pool - database:database - ] autorelease]; + Package *package; + + _profile(Package$packageWithIterator$Allocate) + package = [Package allocWithZone:zone]; + _end + + _profile(Package$packageWithIterator$Initialize) + package = [package + initWithVersion:version + withZone:zone + inPool:pool + database:database + ]; + _end + + _profile(Package$packageWithIterator$Autorelease) + package = [package autorelease]; + _end + + return package; } - (pkgCache::PkgIterator) iterator { @@ -2398,7 +2422,7 @@ struct PackageNameOrdering : } - (PackageValue *) metadata { - return &MetaFile_.Get(metadata_); + return metadata_; } - (time_t) seen { @@ -2763,6 +2787,11 @@ struct PackageNameOrdering : return [self hasTag:@"cydia::commercial"]; } +- (void) setIndex:(size_t)index { + if (metadata_->index_ != index) + metadata_->index_ = index; +} + - (CYString &) cyname { return name_.empty() ? id_ : name_; } @@ -3446,6 +3475,12 @@ static NSString *Warning_; //[packages_ sortUsingFunction:reinterpret_cast(&PackageNameCompare) context:NULL]; _trace(); + + size_t count(CFArrayGetCount(packages_)); + for (size_t index(0); index != count; ++index) + [(Package *) CFArrayGetValueAtIndex(packages_, index) setIndex:index]; + + _trace(); } } } CYPoolEnd() _trace(); } @@ -4967,14 +5002,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) onSwitch:(id)sender { - NSMutableDictionary *metadata = [Sections_ objectForKey:basic_]; + NSMutableDictionary *metadata([Sections_ objectForKey:basic_]); if (metadata == nil) { metadata = [NSMutableDictionary dictionaryWithCapacity:2]; [Sections_ setObject:metadata forKey:basic_]; } - Changed_ = true; [metadata setObject:[NSNumber numberWithBool:([switch_ isOn] == NO)] forKey:@"Hidden"]; + Changed_ = true; } - (void) setSection:(Section *)section editing:(BOOL)editing { @@ -7526,7 +7561,6 @@ freeing the view controllers on tab change */ nil]; [Metadata_ setObject:Settings_ forKey:@"Settings"]; - Changed_ = true; if (rolling) @@ -7978,6 +8012,9 @@ typedef enum { - (void) setPage:(CYViewController *)page; - (void) loadData; +// XXX: I hate prototypes +- (id) queueBadgeController; + @end static _finline void _setHomePage(Cydia *self) { @@ -8029,21 +8066,24 @@ static _finline void _setHomePage(Cydia *self) { } - (void) _saveConfig { + _trace(); + MetaFile_.Sync(); + _trace(); + if (Changed_) { - _trace(); NSString *error(nil); + if (NSData *data = [NSPropertyListSerialization dataFromPropertyList:Metadata_ format:NSPropertyListBinaryFormat_v1_0 errorDescription:&error]) { _trace(); NSError *error(nil); if (![data writeToFile:@"/var/lib/cydia/metadata.plist" options:NSAtomicWrite error:&error]) NSLog(@"failure to save metadata data: %@", error); _trace(); + + Changed_ = false; } else { NSLog(@"failure to serialize metadata: %@", error); - return; } - - Changed_ = false; } } @@ -8059,6 +8099,9 @@ static _finline void _setHomePage(Cydia *self) { [search_ reloadData]; [(CYNavigationController *)[tabbar_ selectedViewController] reloadData]; + + [queueDelegate_ queueStatusDidChange]; + [[[self queueBadgeController] tabBarItem] setBadgeValue:(Queuing_ ? UCLocalize("Q_D") : nil)]; } - (int)indexOfTabWithTag:(int)tag { @@ -8306,6 +8349,8 @@ static _finline void _setHomePage(Cydia *self) { } - (void) confirmWithNavigationController:(UINavigationController *)navigation { + Queuing_ = false; + ProgressController *progress = [[[ProgressController alloc] initWithDatabase:database_ delegate:self] autorelease]; if (navigation != nil) { @@ -8450,18 +8495,12 @@ static _finline void _setHomePage(Cydia *self) { @synchronized (self) { if (clear) { [database_ clear]; - - // Stop queuing. Queuing_ = false; - [[[self queueBadgeController] tabBarItem] setBadgeValue:nil]; } else { - // Start queuing. Queuing_ = true; - [[[self queueBadgeController] tabBarItem] setBadgeValue:UCLocalize("Q_D")]; } [self _updateData]; - [queueDelegate_ queueStatusDidChange]; } } @@ -8720,6 +8759,7 @@ static _finline void _setHomePage(Cydia *self) { } - (void) applicationDidFinishLaunching:(id)unused { +_trace(); [CYBrowserController _initialize]; [NSURLProtocol registerClass:[CydiaURLProtocol class]];