X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/3e3977a2813ade57f892e24ec8b9da0e8bfdf69c..c807624525897db9d730b2fa5c92bec1e939f3b2:/Cydia.mm diff --git a/Cydia.mm b/Cydia.mm index 3daeb454..60067ebe 100644 --- a/Cydia.mm +++ b/Cydia.mm @@ -49,12 +49,22 @@ #include #include +#if 0 +#define DEPLOYMENT_TARGET_MACOSX 1 +#define CF_BUILDING_CF 1 +#include +#endif + +#include +#include + #import #import #include #import +#include #include #include #include @@ -254,8 +264,9 @@ void NSLogRect(const char *fix, const CGRect &rect) { /* XXX: deal with exceptions */ id value([self performSelector:selector withObject:object]); + NSMethodSignature *signature([self methodSignatureForSelector:selector]); [context removeAllObjects]; - if (value != nil) + if ([signature methodReturnLength] != 0 && value != nil) [context addObject:value]; stopped = true; @@ -302,9 +313,8 @@ void NSLogRect(const char *fix, const CGRect &rect) { /* NSForcedOrderingSearch doesn't work on the iPhone */ static const NSStringCompareOptions MatchCompareOptions_ = NSLiteralSearch | NSCaseInsensitiveSearch; -static const NSStringCompareOptions BaseCompareOptions_ = NSNumericSearch | NSDiacriticInsensitiveSearch | NSWidthInsensitiveSearch; -static const NSStringCompareOptions ForcedCompareOptions_ = BaseCompareOptions_; -static const NSStringCompareOptions LaxCompareOptions_ = BaseCompareOptions_ | NSCaseInsensitiveSearch; +static const NSStringCompareOptions LaxCompareOptions_ = NSNumericSearch | NSDiacriticInsensitiveSearch | NSWidthInsensitiveSearch | NSCaseInsensitiveSearch; +static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareCaseInsensitive | kCFCompareNonliteral | kCFCompareLocalized | kCFCompareNumerically | kCFCompareWidthInsensitive | kCFCompareForcedOrdering; /* iPhoneOS 2.0 Compatibility {{{ */ #ifdef __OBJC2__ @@ -388,7 +398,8 @@ extern NSString * const kCAFilterNearest; #define ForRelease 0 #define ForSaurik (0 && !ForRelease) -#define LogBrowser (1 && !ForRelease) +#define LogBrowser (0 && !ForRelease) +#define TrackResize (0 && !ForRelease) #define ManualRefresh (1 && !ForRelease) #define ShowInternals (0 && !ForRelease) #define IgnoreInstall (0 && !ForRelease) @@ -468,11 +479,22 @@ static void RadixSort_(NSMutableArray *self, size_t count, struct RadixItem_ *sw @implementation NSMutableArray (Radix) - (void) radixSortUsingSelector:(SEL)selector withObject:(id)object { + size_t count([self count]); + if (count == 0) + return; + +#if 0 NSInvocation *invocation([NSInvocation invocationWithMethodSignature:[NSMethodSignature signatureWithObjCTypes:"L12@0:4@8"]]); [invocation setSelector:selector]; [invocation setArgument:&object atIndex:2]; +#else + /* XXX: this is an unsafe optimization of doomy hell */ + Method method(class_getInstanceMethod([[self objectAtIndex:0] class], selector)); + _assert(method != NULL); + uint32_t (*imp)(id, SEL, id) = reinterpret_cast(method_getImplementation(method)); + _assert(imp != NULL); +#endif - size_t count([self count]); struct RadixItem_ *swap(new RadixItem_[count * 2]); for (size_t i(0); i != count; ++i) { @@ -480,10 +502,14 @@ static void RadixSort_(NSMutableArray *self, size_t count, struct RadixItem_ *sw item.index = i; id object([self objectAtIndex:i]); - [invocation setTarget:object]; +#if 0 + [invocation setTarget:object]; [invocation invoke]; [invocation getReturnValue:&item.key]; +#else + item.key = imp(object, selector, object); +#endif } RadixSort_(self, count, swap); @@ -505,6 +531,42 @@ static void RadixSort_(NSMutableArray *self, size_t count, struct RadixItem_ *sw } @end +/* }}} */ +/* Insertion Sort {{{ */ + +CFIndex CFBSearch_(const void *element, CFIndex elementSize, const void *list, CFIndex count, CFComparatorFunction comparator, void *context) { + const char *ptr = (const char *)list; + while (0 < count) { + CFIndex half = count / 2; + const char *probe = ptr + elementSize * half; + CFComparisonResult cr = comparator(element, probe, context); + if (0 == cr) return (probe - (const char *)list) / elementSize; + ptr = (cr < 0) ? ptr : probe + elementSize; + count = (cr < 0) ? half : (half + (count & 1) - 1); + } + return (ptr - (const char *)list) / elementSize; +} + +void CFArrayInsertionSortValues(CFMutableArrayRef array, CFRange range, CFComparatorFunction comparator, void *context) { + if (range.length == 0) + return; + const void **values(new const void *[range.length]); + CFArrayGetValues(array, range, values); + + for (CFIndex index(1); index != range.length; ++index) { + const void *value(values[index]); + CFIndex correct(CFBSearch_(&value, sizeof(const void *), values, index, comparator, context)); + //NSLog(@"%u %u", index, correct); + if (correct != index) { + memmove(values + correct + 1, values + correct, sizeof(const void *) * (index - correct)); + values[correct] = value; + } + } + + CFArrayReplaceValues(array, range, values, range.length); + delete [] values; +} + /* }}} */ /* Apple Bug Fixes {{{ */ @@ -701,8 +763,9 @@ class CYString { else { clear_(); - char *temp(reinterpret_cast(apr_palloc(pool, size))); + char *temp(reinterpret_cast(apr_palloc(pool, size + 1))); memcpy(temp, data, size); + temp[size] = '\0'; data_ = temp; size_ = size; } @@ -966,6 +1029,7 @@ static const NSString *Product_ = nil; static const NSString *Safari_ = nil; CFLocaleRef Locale_; +NSArray *Languages_; CGColorSpaceRef space_; bool bootstrap_; @@ -1021,6 +1085,13 @@ NSString *SizeString(double size) { return [NSString stringWithFormat:@"%s%.1f %s", (negative ? "-" : ""), size, powers_[power]]; } +NSString *StripVersion(const char *version) { + const char *colon(strchr(version, ':')); + if (colon != NULL) + version = colon + 1; + return [NSString stringWithUTF8String:version]; +} + NSString *StripVersion(NSString *version) { NSRange colon = [version rangeOfString:@":"]; if (colon.location != NSNotFound) @@ -1029,7 +1100,18 @@ NSString *StripVersion(NSString *version) { } NSString *LocalizeSection(NSString *section) { - return section; + static Pcre title_r("^(.*?) \\((.*)\\)$"); + if (title_r(section)) { + NSString *parent(title_r[1]); + NSString *child(title_r[2]); + + return [NSString stringWithFormat:CYLocalize("PARENTHETICAL"), + LocalizeSection(parent), + LocalizeSection(child) + ]; + } + + return [[NSBundle mainBundle] localizedStringForKey:section value:nil table:@"Sections"]; } NSString *Simplify(NSString *title) { @@ -1044,17 +1126,21 @@ NSString *Simplify(NSString *title) { if (paren_r(data, size)) return Simplify(paren_r[1]); - static Pcre title_r("^(.*?) \\(.*\\)$"); + static Pcre title_r("^(.*?) \\((.*)\\)$"); if (title_r(data, size)) return Simplify(title_r[1]); return title; } + +_finline static void Stifle(char &value) { + value = (value & 0xdf) ^ 0x40; +} /* }}} */ bool isSectionVisible(NSString *section) { - NSDictionary *metadata = [Sections_ objectForKey:section]; - NSNumber *hidden = metadata == nil ? nil : [metadata objectForKey:@"Hidden"]; + NSDictionary *metadata([Sections_ objectForKey:section]); + NSNumber *hidden(metadata == nil ? nil : [metadata objectForKey:@"Hidden"]); return hidden == nil || ![hidden boolValue]; } @@ -1540,11 +1626,12 @@ class Progress : CYString section_; NSString *section$_; bool essential_; + bool visible_; NSString *latest_; NSString *installed_; - NSString *id_; + CYString id_; CYString name_; CYString tagline_; CYString icon_; @@ -1562,7 +1649,11 @@ class Progress : NSString *role_; NSArray *relationships_; + NSMutableDictionary *metadata_; + _transient NSDate *firstSeen_; + _transient NSDate *lastSeen_; + bool subscribed_; } - (Package *) initWithVersion:(pkgCache::VerIterator)version withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database; @@ -1580,7 +1671,8 @@ class Progress : - (Address *) maintainer; - (size_t) size; -- (NSString *) description; +- (NSString *) longDescription; +- (NSString *) shortDescription; - (unichar) index; - (NSMutableDictionary *) metadata; @@ -1606,7 +1698,6 @@ class Progress : - (NSString *) id; - (NSString *) name; -- (NSString *) tagline; - (UIImage *) icon; - (NSString *) homepage; - (NSString *) depiction; @@ -1631,7 +1722,6 @@ class Progress : - (bool) isCommercial; - (uint32_t) compareByPrefix; -- (NSComparisonResult) compareByName:(Package *)package; - (uint32_t) compareBySection:(NSArray *)sections; - (uint32_t) compareForChanges; @@ -1673,6 +1763,53 @@ uint32_t PackageChangesRadix(Package *self, void *) { return _not(uint32_t) - value.key; } +CFStringRef (*PackageName)(Package *self, SEL sel); + +CFComparisonResult PackageNameCompare(Package *lhs, Package *rhs, void *arg) { + _profile(PackageNameCompare) + CFStringRef lhn, rhn; + CFIndex length; + + _profile(PackageNameCompare$Setup) + lhn = PackageName(lhs, @selector(name)); + rhn = PackageName(rhs, @selector(name)); + _end + + _profile(PackageNameCompare$Nothing) + _end + + _profile(PackageNameCompare$Length) + length = CFStringGetLength(lhn); + _end + + _profile(PackageNameCompare$NumbersLast) + if (length != 0 && CFStringGetLength(rhn) != 0) { + UniChar lhc(CFStringGetCharacterAtIndex(lhn, 0)); + UniChar rhc(CFStringGetCharacterAtIndex(rhn, 0)); + bool lha(CFUniCharIsMemberOf(lhc, kCFUniCharLetterCharacterSet)); + if (lha != CFUniCharIsMemberOf(rhc, kCFUniCharLetterCharacterSet)) + return lha ? NSOrderedAscending : NSOrderedDescending; + } + _end + + _profile(PackageNameCompare$Compare) + return CFStringCompareWithOptionsAndLocale(lhn, rhn, CFRangeMake(0, length), LaxCompareFlags_, Locale_); + _end + _end +} + +CFComparisonResult PackageNameCompare_(Package **lhs, Package **rhs, void *context) { + return PackageNameCompare(*lhs, *rhs, context); +} + +struct PackageNameOrdering : + std::binary_function +{ + _finline bool operator ()(Package *lhs, Package *rhs) const { + return PackageNameCompare(lhs, rhs, NULL) == NSOrderedAscending; + } +}; + @implementation Package - (void) dealloc { @@ -1686,8 +1823,6 @@ uint32_t PackageChangesRadix(Package *self, void *) { if (installed_ != nil) [installed_ release]; - if (id_ != nil) - [id_ release]; if (sponsor$_ != nil) [sponsor$_ release]; if (author$_ != nil) @@ -1717,7 +1852,7 @@ uint32_t PackageChangesRadix(Package *self, void *) { } + (NSArray *) _attributeKeys { - return [NSArray arrayWithObjects:@"applications", @"author", @"depiction", @"description", @"essential", @"homepage", @"icon", @"id", @"installed", @"latest", @"longSection", @"maintainer", @"mode", @"name", @"purposes", @"section", @"shortSection", @"simpleSection", @"size", @"source", @"sponsor", @"support", @"tagline", @"warnings", nil]; + return [NSArray arrayWithObjects:@"applications", @"author", @"depiction", @"longDescription", @"essential", @"homepage", @"icon", @"id", @"installed", @"latest", @"longSection", @"maintainer", @"mode", @"name", @"purposes", @"section", @"shortDescription", @"shortSection", @"simpleSection", @"size", @"source", @"sponsor", @"support", @"warnings", nil]; } - (NSArray *) attributeKeys { @@ -1739,32 +1874,22 @@ uint32_t PackageChangesRadix(Package *self, void *) { database_ = database; _profile(Package$initWithVersion$Latest) - latest_ = [StripVersion([NSString stringWithUTF8String:version_.VerStr()]) retain]; + latest_ = [StripVersion(version_.VerStr()) retain]; _end - pkgCache::VerIterator current; - NSString *installed; - - _profile(Package$initWithVersion$Current) - current = iterator_.CurrentVer(); - installed = current.end() ? nil : [NSString stringWithUTF8String:current.VerStr()]; - _end - - _profile(Package$initWithVersion$Installed) - installed_ = [StripVersion(installed) retain]; - _end + pkgCache::VerIterator current(iterator_.CurrentVer()); + if (!current.end()) + installed_ = [StripVersion(current.VerStr()) retain]; - _profile(Package$initWithVersion$File) - if (!version_.end()) - file_ = version_.FileList(); - else { - pkgCache &cache([database_ cache]); - file_ = pkgCache::VerFileIterator(cache, cache.VerFileP); - } - _end + if (!version_.end()) + file_ = version_.FileList(); + else { + pkgCache &cache([database_ cache]); + file_ = pkgCache::VerFileIterator(cache, cache.VerFileP); + } _profile(Package$initWithVersion$Name) - id_ = [[NSString stringWithUTF8String:iterator_.Name()] retain]; + id_.set(pool, iterator_.Name()); _end if (!file_.end()) @@ -1780,63 +1905,36 @@ uint32_t PackageChangesRadix(Package *self, void *) { parser = &[database_ records]->Lookup(file_); _end - const char *begin, *end; - parser->GetRec(begin, end); - CYString website; CYString tag; - struct { - const char *name_; - CYString *value_; - } names[] = { - {"name", &name_}, - {"icon", &icon_}, - {"depiction", &depiction_}, - {"homepage", &homepage_}, - {"website", &website}, - {"support", &support_}, - {"sponsor", &sponsor_}, - {"author", &author_}, - {"tag", &tag}, - }; - - while (begin != end) - if (*begin == '\n') { - ++begin; - continue; - } else if (isblank(*begin)) next: { - begin = static_cast(memchr(begin + 1, '\n', end - begin - 1)); - if (begin == NULL) - break; - } else if (const char *colon = static_cast(memchr(begin, ':', end - begin))) { - const char *name(begin); - size_t size(colon - begin); - - begin = static_cast(memchr(begin, '\n', end - begin)); - - { - const char *stop(begin == NULL ? end : begin); - while (stop[-1] == '\r') - --stop; - while (++colon != stop && isblank(*colon)); - - for (size_t i(0); i != sizeof(names) / sizeof(names[0]); ++i) - if (strncasecmp(names[i].name_, name, size) == 0) { - CYString &value(*names[i].value_); - - _profile(Package$initWithVersion$Parse$Value) - value.set(pool, colon, stop - colon); - _end - - break; - } + _profile(Package$initWithVersion$Parse$Find) + struct { + const char *name_; + CYString *value_; + } names[] = { + {"name", &name_}, + {"icon", &icon_}, + {"depiction", &depiction_}, + {"homepage", &homepage_}, + {"website", &website}, + {"support", &support_}, + {"sponsor", &sponsor_}, + {"author", &author_}, + {"tag", &tag}, + }; + + for (size_t i(0); i != sizeof(names) / sizeof(names[0]); ++i) { + const char *start, *end; + + if (parser->Find(names[i].name_, start, end)) { + CYString &value(*names[i].value_); + _profile(Package$initWithVersion$Parse$Value) + value.set(pool, start, end - start); + _end } - - if (begin == NULL) - break; - ++begin; - } else goto next; + } + _end _profile(Package$initWithVersion$Parse$Tagline) tagline_.set(pool, parser->ShortDesc()); @@ -1866,21 +1964,28 @@ uint32_t PackageChangesRadix(Package *self, void *) { _profile(Package$initWithVersion$Metadata) metadata_ = [Packages_ objectForKey:key]; + if (metadata_ == nil) { + firstSeen_ = [now_ retain]; + metadata_ = [[NSMutableDictionary dictionaryWithObjectsAndKeys: - now_, @"FirstSeen", + firstSeen_, @"FirstSeen", + latest_, @"LastVersion", nil] mutableCopy]; - [metadata_ setObject:latest_ forKey:@"LastVersion"]; changed = true; } else { - NSDate *first([metadata_ objectForKey:@"FirstSeen"]); - NSDate *last([metadata_ objectForKey:@"LastSeen"]); + firstSeen_ = [metadata_ objectForKey:@"FirstSeen"]; + lastSeen_ = [metadata_ objectForKey:@"LastSeen"]; + + if (NSNumber *subscribed = [metadata_ objectForKey:@"IsSubscribed"]) + subscribed_ = [subscribed boolValue]; + NSString *version([metadata_ objectForKey:@"LastVersion"]); - if (first == nil) { - first = last == nil ? now_ : last; - [metadata_ setObject:first forKey:@"FirstSeen"]; + if (firstSeen_ == nil) { + firstSeen_ = lastSeen_ == nil ? now_ : lastSeen_; + [metadata_ setObject:firstSeen_ forKey:@"FirstSeen"]; changed = true; } @@ -1889,8 +1994,8 @@ uint32_t PackageChangesRadix(Package *self, void *) { changed = true; } else if (![version isEqualToString:latest_]) { [metadata_ setObject:latest_ forKey:@"LastVersion"]; - last = now_; - [metadata_ setObject:last forKey:@"LastSeen"]; + lastSeen_ = now_; + [metadata_ setObject:lastSeen_ forKey:@"LastSeen"]; changed = true; } } @@ -1908,13 +2013,20 @@ uint32_t PackageChangesRadix(Package *self, void *) { _end essential_ = ((iterator_->Flags & pkgCache::Flag::Essential) == 0 ? NO : YES) || [self hasTag:@"cydia::essential"]; + visible_ = [self hasSupportingRole] && [self unfiltered]; } _end } return self; } + (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database { - pkgCache::VerIterator version([database policy]->GetCandidateVer(iterator)); + pkgCache::VerIterator version; + + _profile(Package$packageWithIterator$GetCandidateVer) + version = [database policy]->GetCandidateVer(iterator); + _end + if (version.end()) return nil; + return [[[Package alloc] initWithVersion:version withZone:zone @@ -1986,7 +2098,7 @@ uint32_t PackageChangesRadix(Package *self, void *) { return version_.end() ? 0 : version_->InstalledSize; } -- (NSString *) description { +- (NSString *) longDescription { if (file_.end()) return nil; pkgRecords::Parser *parser = &[database_ records]->Lookup(file_); @@ -2006,38 +2118,34 @@ uint32_t PackageChangesRadix(Package *self, void *) { return [trimmed componentsJoinedByString:@"\n"]; } +- (NSString *) shortDescription { + return tagline_; +} + - (unichar) index { _profile(Package$index) - NSString *name([self name]); - if ([name length] == 0) + CFStringRef name((CFStringRef) [self name]); + if (CFStringGetLength(name) == 0) return '#'; - unichar character([name characterAtIndex:0]); - if (!isalpha(character)) + UniChar character(CFStringGetCharacterAtIndex(name, 0)); + if (!CFUniCharIsMemberOf(character, kCFUniCharLetterCharacterSet)) return '#'; return toupper(character); _end } - (NSMutableDictionary *) metadata { - if (metadata_ == nil) - metadata_ = [[Packages_ objectForKey:[id_ lowercaseString]] retain]; return metadata_; } - (NSDate *) seen { - NSDictionary *metadata([self metadata]); - if ([self subscribed]) - if (NSDate *last = [metadata objectForKey:@"LastSeen"]) - return last; - return [metadata objectForKey:@"FirstSeen"]; + if (subscribed_ && lastSeen_ != nil) + return lastSeen_; + return firstSeen_; } - (BOOL) subscribed { - NSDictionary *metadata([self metadata]); - if (NSNumber *subscribed = [metadata objectForKey:@"IsSubscribed"]) - return [subscribed boolValue]; - else - return false; + return subscribed_; } - (BOOL) ignored { @@ -2061,14 +2169,13 @@ uint32_t PackageChangesRadix(Package *self, void *) { } - (BOOL) upgradableAndEssential:(BOOL)essential { - pkgCache::VerIterator current = iterator_.CurrentVer(); - - bool value; - if (current.end()) - value = essential && [self essential] && [self visible]; - else - value = !version_.end() && version_ != current;// && (!essential || ![database_ cache][iterator_].Keep()); - return value; + _profile(Package$upgradableAndEssential) + pkgCache::VerIterator current(iterator_.CurrentVer()); + if (current.end()) + return essential && essential_ && visible_; + else + return !version_.end() && version_ != current;// && (!essential || ![database_ cache][iterator_].Keep()); + _end } - (BOOL) essential { @@ -2080,16 +2187,16 @@ uint32_t PackageChangesRadix(Package *self, void *) { } - (BOOL) unfiltered { - NSString *section = [self section]; + NSString *section([self section]); return section == nil || isSectionVisible(section); } - (BOOL) visible { - return [self hasSupportingRole] && [self unfiltered]; + return visible_; } - (BOOL) half { - unsigned char current = iterator_->CurrentState; + unsigned char current(iterator_->CurrentState); return current == pkgCache::State::HalfConfigured || current == pkgCache::State::HalfInstalled; } @@ -2147,11 +2254,7 @@ uint32_t PackageChangesRadix(Package *self, void *) { } - (NSString *) name { - return name_ == nil ? id_ : name_; -} - -- (NSString *) tagline { - return tagline_; + return name_.empty() ? id_ : name_; } - (UIImage *) icon { @@ -2200,7 +2303,7 @@ uint32_t PackageChangesRadix(Package *self, void *) { } - (NSArray *) files { - NSString *path = [NSString stringWithFormat:@"/var/lib/dpkg/info/%@.list", id_]; + NSString *path = [NSString stringWithFormat:@"/var/lib/dpkg/info/%@.list", static_cast(id_)]; NSMutableArray *files = [NSMutableArray arrayWithCapacity:128]; std::ifstream fin; @@ -2334,7 +2437,7 @@ uint32_t PackageChangesRadix(Package *self, void *) { if (range.location != NSNotFound) return YES; - range = [[self tagline] rangeOfString:text options:MatchCompareOptions_]; + range = [[self shortDescription] rangeOfString:text options:MatchCompareOptions_]; if (range.location != NSNotFound) return YES; @@ -2383,24 +2486,28 @@ uint32_t PackageChangesRadix(Package *self, void *) { } - (uint32_t) compareByPrefix { - return 0; -} - -- (NSComparisonResult) compareByName:(Package *)package { - NSString *lhs = [self name]; - NSString *rhs = [package name]; + size_t offset(0); - if ([lhs length] != 0 && [rhs length] != 0) { - unichar lhc = [lhs characterAtIndex:0]; - unichar rhc = [rhs characterAtIndex:0]; + CYString &name(name_.empty() ? id_ : name_); + if (name.size() <= offset) + return 0; + size_t size(name.size() - offset); - if (isalpha(lhc) && !isalpha(rhc)) - return NSOrderedAscending; - else if (!isalpha(lhc) && isalpha(rhc)) - return NSOrderedDescending; + char data[4]; + if (size >= 4) + memcpy(data, name.data() + offset, 4); + else { + memcpy(data, name.data() + offset, size); + memset(data + size, 0, 4 - size); } - return [lhs compare:rhs options:LaxCompareOptions_]; + Stifle(data[0]); + Stifle(data[1]); + Stifle(data[2]); + Stifle(data[3]); + + /* XXX: ntohl may be more honest */ + return OSSwapInt32(*reinterpret_cast(data)); } - (uint32_t) compareBySection:(NSArray *)sections { @@ -2512,9 +2619,10 @@ uint32_t PackageChangesRadix(Package *self, void *) { NSString *localized_; } -- (NSComparisonResult) compareByName:(Section *)section; -- (Section *) initWithName:(NSString *)name; -- (Section *) initWithName:(NSString *)name row:(size_t)row; +- (NSComparisonResult) compareByLocalized:(Section *)section; +- (Section *) initWithName:(NSString *)name localized:(NSString *)localized; +- (Section *) initWithName:(NSString *)name localize:(BOOL)localize; +- (Section *) initWithName:(NSString *)name row:(size_t)row localize:(BOOL)localize; - (Section *) initWithIndex:(unichar)index row:(size_t)row; - (NSString *) name; - (unichar) index; @@ -2526,6 +2634,7 @@ uint32_t PackageChangesRadix(Package *self, void *) { - (void) addToCount; - (void) setCount:(size_t)count; +- (NSString *) localized; @end @@ -2538,11 +2647,11 @@ uint32_t PackageChangesRadix(Package *self, void *) { [super dealloc]; } -- (NSComparisonResult) compareByName:(Section *)section { - NSString *lhs = [self name]; - NSString *rhs = [section name]; +- (NSComparisonResult) compareByLocalized:(Section *)section { + NSString *lhs(localized_); + NSString *rhs([section localized]); - if ([lhs length] != 0 && [rhs length] != 0) { + /*if ([lhs length] != 0 && [rhs length] != 0) { unichar lhc = [lhs characterAtIndex:0]; unichar rhc = [rhs characterAtIndex:0]; @@ -2550,21 +2659,29 @@ uint32_t PackageChangesRadix(Package *self, void *) { return NSOrderedAscending; else if (!isalpha(lhc) && isalpha(rhc)) return NSOrderedDescending; - } + }*/ return [lhs compare:rhs options:LaxCompareOptions_]; } -- (Section *) initWithName:(NSString *)name { - return [self initWithName:name row:0]; +- (Section *) initWithName:(NSString *)name localized:(NSString *)localized { + if ((self = [self initWithName:name localize:NO]) != nil) { + if (localized != nil) + localized_ = [localized retain]; + } return self; +} + +- (Section *) initWithName:(NSString *)name localize:(BOOL)localize { + return [self initWithName:name row:0 localize:localize]; } -- (Section *) initWithName:(NSString *)name row:(size_t)row { +- (Section *) initWithName:(NSString *)name row:(size_t)row localize:(BOOL)localize { if ((self = [super init]) != nil) { name_ = [name retain]; index_ = '\0'; row_ = row; - localized_ = [LocalizeSection(name_) retain]; + if (localize) + localized_ = [LocalizeSection(name_) retain]; } return self; } @@ -2739,7 +2856,7 @@ static NSArray *Finishes_; apr_pool_create(&pool_, NULL); sources_ = [[NSMutableDictionary dictionaryWithCapacity:16] retain]; - packages_ = [[NSMutableArray arrayWithCapacity:16] retain]; + packages_ = [[NSMutableArray alloc] init]; int fds[2]; @@ -2971,17 +3088,49 @@ static NSArray *Finishes_; } _trace(); - [packages_ removeAllObjects]; - _trace(); - for (pkgCache::PkgIterator iterator = cache_->PkgBegin(); !iterator.end(); ++iterator) - if (Package *package = [Package packageWithIterator:iterator withZone:zone_ inPool:pool_ database:self]) - [packages_ addObject:package]; - _trace(); - [packages_ sortUsingSelector:@selector(compareByName:)]; - _trace(); + { + /*std::vector packages; + packages.reserve(std::max(10000U, [packages_ count] + 1000)); + [packages_ release]; + packages_ = nil;*/ - _config->Set("Acquire::http::Timeout", 15); - _config->Set("Acquire::http::MaxParallel", 4); + [packages_ removeAllObjects]; + + _trace(); + + for (pkgCache::PkgIterator iterator = cache_->PkgBegin(); !iterator.end(); ++iterator) + if (Package *package = [Package packageWithIterator:iterator withZone:zone_ inPool:pool_ database:self]) + //packages.push_back(package); + [packages_ addObject:package]; + + _trace(); + + /*if (packages.empty()) + packages_ = [[NSArray alloc] init]; + else + packages_ = [[NSArray alloc] initWithObjects:&packages.front() count:packages.size()]; + _trace();*/ + + [packages_ radixSortUsingSelector:@selector(compareByPrefix) withObject:NULL]; + + /*_trace(); + PrintTimes(); + _trace();*/ + + _trace(); + + /*if (!packages.empty()) + CFQSortArray(&packages.front(), packages.size(), sizeof(packages.front()), reinterpret_cast(&PackageNameCompare_), NULL);*/ + //std::sort(packages.begin(), packages.end(), PackageNameOrdering()); + + //CFArraySortValues((CFMutableArrayRef) packages_, CFRangeMake(0, [packages_ count]), reinterpret_cast(&PackageNameCompare), NULL); + + CFArrayInsertionSortValues((CFMutableArrayRef) packages_, CFRangeMake(0, [packages_ count]), reinterpret_cast(&PackageNameCompare_), NULL); + + //[packages_ sortUsingFunction:reinterpret_cast(&PackageNameCompare) context:NULL]; + + _trace(); + } } - (void) configure { @@ -4102,7 +4251,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { icon_ = [[package icon] retain]; name_ = [[package name] retain]; - description_ = [[package tagline] retain]; + description_ = [[package shortDescription] retain]; commercial_ = [package isCommercial]; package_ = [package retain]; @@ -4227,7 +4376,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } + (int) heightForPackage:(Package *)package { - NSString *tagline([package tagline]); + NSString *tagline([package shortDescription]); int height = tagline == nil || [tagline length] == 0 ? -17 : 0; #ifdef USE_BADGES if ([package hasMode] || [package half]) @@ -4315,7 +4464,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { name_ = [CYLocalize("ALL_PACKAGES") retain]; count_ = nil; } else { - section_ = [section name]; + section_ = [section localized]; if (section_ != nil) section_ = [section_ retain]; name_ = [(section_ == nil ? CYLocalize("NO_SECTION") : section_) retain]; @@ -4652,6 +4801,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [self setPopupHook:nil]; WebThreadUnlock(); + //[self yieldToSelector:@selector(callFunction:) withObject:special_]; [super callFunction:special_]; } } @@ -4893,6 +5043,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { /* XXX: this is an unsafe optimization of doomy hell */ Method method = class_getInstanceMethod([Package class], filter); + _assert(method != NULL); imp_ = method_getImplementation(method); _assert(imp_ != NULL); @@ -5767,7 +5918,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [cancel_ addTarget:self action:@selector(_onCancel) forControlEvents:UIControlEventTouchUpInside]; CGRect frame = [cancel_ frame]; - frame.size.width = 65; frame.origin.x = ovrrect.size.width - frame.size.width - 5; frame.origin.y = (ovrrect.size.height - frame.size.height) / 2; [cancel_ setFrame:frame]; @@ -5795,7 +5945,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) setProgressError:(NSString *)error forPackage:(NSString *)id { - [prompt_ setText:[NSString stringWithFormat:CYLocalize("ERROR_MESSAGE"), error]]; + [prompt_ setText:[NSString stringWithFormat:CYLocalize("COLON_DELIMITED"), CYLocalize("ERROR"), error]]; } - (void) setProgressTitle:(NSString *)title { @@ -6100,7 +6250,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { section = §ions[key]; if (*section == nil) { _profile(SectionsView$reloadData$Section$Allocate) - *section = [[[Section alloc] initWithName:name] autorelease]; + *section = [[[Section alloc] initWithName:name localize:YES] autorelease]; _end } _end @@ -6120,7 +6270,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { section = [sections objectForKey:key]; if (section == nil) { _profile(SectionsView$reloadData$Section$Allocate) - section = [[[Section alloc] initWithName:name] autorelease]; + section = [[[Section alloc] initWithName:name localize:YES] autorelease]; [sections setObject:section forKey:key]; _end } @@ -6145,14 +6295,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [sections_ addObjectsFromArray:[sections allValues]]; #endif - [sections_ sortUsingSelector:@selector(compareByName:)]; + [sections_ sortUsingSelector:@selector(compareByLocalized:)]; for (Section *section in sections_) { size_t count([section row]); - if ([section row] == 0) + if (count == 0) continue; - section = [[[Section alloc] initWithName:[section name]] autorelease]; + section = [[[Section alloc] initWithName:[section name] localized:[section localized]] autorelease]; [section setCount:count]; [filtered_ addObject:section]; } @@ -6329,24 +6479,20 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [packages_ radixSortUsingFunction:reinterpret_cast(&PackageChangesRadix) withArgument:NULL]; _trace(); - Section *upgradable = [[[Section alloc] initWithName:CYLocalize("AVAILABLE_UPGRADES")] autorelease]; - Section *ignored = [[[Section alloc] initWithName:CYLocalize("IGNORED_UPGRADES")] autorelease]; + Section *upgradable = [[[Section alloc] initWithName:CYLocalize("AVAILABLE_UPGRADES") localize:NO] autorelease]; + Section *ignored = [[[Section alloc] initWithName:CYLocalize("IGNORED_UPGRADES") localize:NO] autorelease]; Section *section = nil; NSDate *last = nil; upgrades_ = 0; bool unseens = false; - CFDateFormatterRef formatter = CFDateFormatterCreate(NULL, Locale_, kCFDateFormatterMediumStyle, kCFDateFormatterMediumStyle); + CFDateFormatterRef formatter(CFDateFormatterCreate(NULL, Locale_, kCFDateFormatterMediumStyle, kCFDateFormatterMediumStyle)); - _trace(); for (size_t offset = 0, count = [packages_ count]; offset != count; ++offset) { Package *package = [packages_ objectAtIndex:offset]; - BOOL uae; - _profile(ChangesView$reloadData$Upgrade) - uae = [package upgradableAndEssential:YES]; - _end + BOOL uae = [package upgradableAndEssential:YES]; if (!uae) { unseens = true; @@ -6356,28 +6502,20 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { seen = [package seen]; _end - bool different; - _profile(ChangesView$reloadData$Compare) - different = section == nil || last != seen && (seen == nil || [seen compare:last] != NSOrderedSame); - _end - - if (different) { + if (section == nil || last != seen && (seen == nil || [seen compare:last] != NSOrderedSame)) { last = seen; NSString *name; if (seen == nil) name = CYLocalize("UNKNOWN"); else { - _profile(ChangesView$reloadData$Format) - name = (NSString *) CFDateFormatterCreateStringWithDate(NULL, formatter, (CFDateRef) seen); - _end - + name = (NSString *) CFDateFormatterCreateStringWithDate(NULL, formatter, (CFDateRef) seen); [name autorelease]; } _profile(ChangesView$reloadData$Allocate) name = [NSString stringWithFormat:CYLocalize("NEW_AT"), name]; - section = [[[Section alloc] initWithName:name row:offset] autorelease]; + section = [[[Section alloc] initWithName:name row:offset localize:NO] autorelease]; [sections_ addObject:section]; _end } @@ -7390,7 +7528,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @"home-dn.png", kUIButtonBarButtonSelectedInfo, [NSNumber numberWithInt:1], kUIButtonBarButtonTag, self, kUIButtonBarButtonTarget, - CYLocalize("HOME"), kUIButtonBarButtonTitle, + @"Cydia", kUIButtonBarButtonTitle, @"0", kUIButtonBarButtonType, nil], @@ -7744,9 +7882,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { Font18Bold_ = [[UIFont boldSystemFontOfSize:18] retain]; Font22Bold_ = [[UIFont boldSystemFontOfSize:22] retain]; - _assert(pkgInitConfig(*_config)); - _assert(pkgInitSystem(*_config, _system)); - tag_ = 1; essential_ = [[NSMutableArray alloc] initWithCapacity:4]; @@ -7894,6 +8029,8 @@ void $UIWebDocumentView$_setUIKitDelegate$(UIWebDocumentView *self, SEL sel, id int main(int argc, char *argv[]) { _pooled _trace(); + PackageName = reinterpret_cast(method_getImplementation(class_getInstanceMethod([Package class], @selector(name)))); + /* Library Hacks {{{ */ class_addMethod(objc_getClass("DOMNodeList"), @selector(countByEnumeratingWithState:objects:count:), (IMP) &DOMNodeList$countByEnumeratingWithState$objects$count$, "I20@0:4^{NSFastEnumerationState}8^@12I16"); @@ -7906,9 +8043,17 @@ int main(int argc, char *argv[]) { _pooled /* }}} */ /* Set Locale {{{ */ Locale_ = CFLocaleCopyCurrent(); - - CFStringRef locale(CFLocaleGetIdentifier(Locale_)); - setenv("LANG", [(NSString *) locale UTF8String], true); + Languages_ = [NSLocale preferredLanguages]; + //CFStringRef locale(CFLocaleGetIdentifier(Locale_)); + //NSLog(@"%@", [Languages_ description]); + const char *lang; + if (Languages_ == nil || [Languages_ count] == 0) + lang = NULL; + else + lang = [[Languages_ objectAtIndex:0] UTF8String]; + setenv("LANG", lang, true); + //std::setlocale(LC_ALL, lang); + NSLog(@"Setting Language: %s", lang); /* }}} */ // XXX: apr_app_initialize? @@ -8057,6 +8202,14 @@ int main(int argc, char *argv[]) { _pooled _assert(errno == ENOENT); } + _assert(pkgInitConfig(*_config)); + _assert(pkgInitSystem(*_config, _system)); + + if (lang != NULL) + _config->Set("APT::Acquire::Translation", lang); + _config->Set("Acquire::http::Timeout", 15); + _config->Set("Acquire::http::MaxParallel", 4); + /* Color Choices {{{ */ space_ = CGColorSpaceCreateDeviceRGB();