summaryrefslogtreecommitdiff
path: root/MobileCydia.mm
diff options
context:
space:
mode:
Diffstat (limited to 'MobileCydia.mm')
-rw-r--r--MobileCydia.mm226
1 files changed, 114 insertions, 112 deletions
diff --git a/MobileCydia.mm b/MobileCydia.mm
index 50fcb6f..6e9497a 100644
--- a/MobileCydia.mm
+++ b/MobileCydia.mm
@@ -213,7 +213,6 @@ extern NSString *Cydia_;
#define ManualRefresh (1 && !ForRelease)
#define ShowInternals (0 && !ForRelease)
#define AlwaysReload (0 && !ForRelease)
-#define TryIndexedCollation (0 && !ForRelease)
#if !TraceLogging
#undef _trace
@@ -314,7 +313,7 @@ static CGFloat CYStatusBarHeight() {
/* NSForcedOrderingSearch doesn't work on the iPhone */
static const NSStringCompareOptions MatchCompareOptions_ = NSLiteralSearch | NSCaseInsensitiveSearch;
static const NSStringCompareOptions LaxCompareOptions_ = NSNumericSearch | NSDiacriticInsensitiveSearch | NSWidthInsensitiveSearch | NSCaseInsensitiveSearch;
-static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareCaseInsensitive | kCFCompareNonliteral | kCFCompareLocalized | kCFCompareNumerically | kCFCompareWidthInsensitive | kCFCompareForcedOrdering;
+static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareNumerically | kCFCompareWidthInsensitive | kCFCompareForcedOrdering;
/* Insertion Sort {{{ */
@@ -720,6 +719,13 @@ static _H<NSString> UserAgent_;
static _H<NSString> Product_;
static _H<NSString> Safari_;
+static _H<NSLocale> CollationLocale_;
+static _H<NSArray> CollationThumbs_;
+static std::vector<NSInteger> CollationOffset_;
+static _H<NSArray> CollationTitles_;
+static _H<NSArray> CollationStarts_;
+static Function<NSString *, NSString *> CollationModify_;
+
static CFLocaleRef Locale_;
static NSArray *Languages_;
static CGColorSpaceRef space_;
@@ -2095,9 +2101,11 @@ uint32_t PackageChangesRadix(Package *self, void *) {
return _not(uint32_t) - value.key;
}
+CYString &(*PackageName)(Package *self, SEL sel);
+
uint32_t PackagePrefixRadix(Package *self, void *context) {
size_t offset(reinterpret_cast<size_t>(context));
- CYString &name([self cyname]);
+ CYString &name(PackageName(self, @selector(cyname)));
size_t size(name.size());
if (size == 0)
@@ -2150,21 +2158,17 @@ uint32_t PackagePrefixRadix(Package *self, void *context) {
return OSSwapInt32(*reinterpret_cast<uint32_t *>(data));
}
-CYString &(*PackageName)(Package *self, SEL sel);
-
-CFComparisonResult PackageNameCompare(Package *lhs, Package *rhs, void *arg) {
+CFComparisonResult StringNameCompare(CFStringRef lhn, CFStringRef rhn, void *arg) {
_profile(PackageNameCompare)
- CYString &lhi(PackageName(lhs, @selector(cyname)));
- CYString &rhi(PackageName(rhs, @selector(cyname)));
- CFStringRef lhn(lhi), rhn(rhi);
-
if (lhn == NULL)
return rhn == NULL ? kCFCompareEqualTo : kCFCompareLessThan;
else if (rhn == NULL)
return kCFCompareGreaterThan;
+ CFIndex lhl(CFStringGetLength(lhn));
+
_profile(PackageNameCompare$NumbersLast)
- if (!lhi.empty() && !rhi.empty()) {
+ if (lhl != 0 && CFStringGetLength(rhn) != 0) {
UniChar lhc(CFStringGetCharacterAtIndex(lhn, 0));
UniChar rhc(CFStringGetCharacterAtIndex(rhn, 0));
bool lha(CFUniCharIsMemberOf(lhc, kCFUniCharLetterCharacterSet));
@@ -2173,16 +2177,21 @@ CFComparisonResult PackageNameCompare(Package *lhs, Package *rhs, void *arg) {
}
_end
- CFIndex length = CFStringGetLength(lhn);
-
_profile(PackageNameCompare$Compare)
- return CFStringCompareWithOptionsAndLocale(lhn, rhn, CFRangeMake(0, length), LaxCompareFlags_, Locale_);
+ return CFStringCompareWithOptionsAndLocale(lhn, rhn, CFRangeMake(0, lhl), LaxCompareFlags_, (CFLocaleRef) (id) CollationLocale_);
_end
_end
}
-CFComparisonResult PackageNameCompare_(Package **lhs, Package **rhs, void *context) {
- return PackageNameCompare(*lhs, *rhs, context);
+CFComparisonResult PackageNameCompare(Package *lhs, Package *rhs, void *arg) {
+ CYString &lhi(PackageName(lhs, @selector(cyname)));
+ CYString &rhi(PackageName(rhs, @selector(cyname)));
+ CFStringRef lhn(lhi), rhn(rhi);
+ return StringNameCompare(lhn, rhn, arg);
+}
+
+CFComparisonResult PackageNameCompare_(Package **lhs, Package **rhs, void *arg) {
+ return PackageNameCompare(*lhs, *rhs, arg);
}
struct PackageNameOrdering :
@@ -3158,7 +3167,6 @@ struct PackageNameOrdering :
/* Section Class {{{ */
@interface Section : NSObject {
_H<NSString> name_;
- unichar index_;
size_t row_;
size_t count_;
_H<NSString> localized_;
@@ -3168,9 +3176,9 @@ struct PackageNameOrdering :
- (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;
+- (void) setName:(NSString *)name;
- (size_t) row;
- (size_t) count;
@@ -3216,28 +3224,18 @@ struct PackageNameOrdering :
- (Section *) initWithName:(NSString *)name row:(size_t)row localize:(BOOL)localize {
if ((self = [super init]) != nil) {
name_ = name;
- index_ = '\0';
row_ = row;
if (localize)
localized_ = LocalizeSection(name_);
} return self;
}
-/* XXX: localize the index thingees */
-- (Section *) initWithIndex:(unichar)index row:(size_t)row {
- if ((self = [super init]) != nil) {
- name_ = [NSString stringWithCharacters:&index length:1];
- index_ = index;
- row_ = row;
- } return self;
-}
-
- (NSString *) name {
return name_;
}
-- (unichar) index {
- return index_;
+- (void) setName:(NSString *)name {
+ name_ = name;
}
- (size_t) row {
@@ -6210,7 +6208,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
_H<NSArray> packages_;
_H<NSArray> sections_;
_H<UITableView, 2> list_;
- _H<NSMutableArray> index_;
+
+ _H<NSArray> thumbs_;
+ std::vector<NSInteger> offset_;
+
_H<NSString> title_;
unsigned reloading_;
}
@@ -6333,12 +6334,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
[[self navigationController] pushViewController:view animated:YES];
}
-#if TryIndexedCollation
-+ (BOOL) hasIndexedCollation {
- return NO; // XXX: objc_getClass("UILocalizedIndexedCollation") != nil;
-}
-#endif
-
- (NSInteger) numberOfSectionsInTableView:(UITableView *)list {
NSInteger count([sections_ count]);
return count == 0 ? 1 : count;
@@ -6384,20 +6379,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
}
- (NSArray *) sectionIndexTitlesForTableView:(UITableView *)tableView {
- if (![self showsSections])
- return nil;
-
- return index_;
+ return thumbs_;
}
- (NSInteger) tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
-#if TryIndexedCollation
- if ([[self class] hasIndexedCollation]) {
- return [[objc_getClass("UILocalizedIndexedCollation") currentCollation] sectionForSectionIndexTitleAtIndex:index];
- }
-#endif
-
- return index;
+ return offset_[index];
}
- (void) updateHeight {
@@ -6435,7 +6421,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
packages_ = nil;
sections_ = nil;
- index_ = nil;
+
+ thumbs_ = nil;
+ offset_.clear();
[super releaseSubviews];
}
@@ -6495,8 +6483,18 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
goto reload;
reloading_ = 0;
+ thumbs_ = nil;
+ offset_.clear();
+
packages_ = packages;
- sections_ = [self sectionsForPackages:packages];
+
+ if ([self showsSections])
+ sections_ = [self sectionsForPackages:packages];
+ else {
+ Section *section([[[Section alloc] initWithName:nil row:0 localize:NO] autorelease]);
+ [section setCount:[packages_ count]];
+ sections_ = [NSArray arrayWithObject:section];
+ }
[self updateHeight];
@@ -6510,79 +6508,53 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
}
- (NSArray *) sectionsForPackages:(NSMutableArray *)packages {
- NSMutableArray *sections([NSMutableArray arrayWithCapacity:16]);
-
- Section *section = nil;
+ Section *prefix([[[Section alloc] initWithName:nil row:0 localize:NO] autorelease]);
+ size_t end([packages count]);
-#if TryIndexedCollation
- if ([[self class] hasIndexedCollation]) {
- index_ = [[objc_getClass("UILocalizedIndexedCollation") currentCollation] sectionIndexTitles];
-
- id collation = [objc_getClass("UILocalizedIndexedCollation") currentCollation];
- NSArray *titles = [collation sectionIndexTitles];
- int secidx = -1;
+ NSMutableArray *sections([NSMutableArray arrayWithCapacity:16]);
+ Section *section(prefix);
- _profile(PackageTable$reloadData$Section)
- for (size_t offset(0), end([packages count]); offset != end; ++offset) {
- Package *package;
- int index;
+ thumbs_ = CollationThumbs_;
+ offset_ = CollationOffset_;
- _profile(PackageTable$reloadData$Section$Package)
- package = [packages objectAtIndex:offset];
- index = [collation sectionForObject:package collationStringSelector:@selector(name)];
- _end
+ size_t offset(0);
+ size_t offsets([CollationStarts_ count]);
- while (secidx < index) {
- secidx += 1;
+ NSString *start([CollationStarts_ objectAtIndex:offset]);
+ size_t length([start length]);
- _profile(PackageTable$reloadData$Section$Allocate)
- section = [[[Section alloc] initWithName:[titles objectAtIndex:secidx] row:offset localize:NO] autorelease];
- _end
+ for (size_t index(0); index != end; ++index) {
+ if (start != nil) {
+ Package *package([packages objectAtIndex:index]);
+ NSString *name([package name]);
- _profile(PackageTable$reloadData$Section$Add)
- [sections addObject:section];
- _end
- }
+ //while ([start compare:name options:NSNumericSearch range:NSMakeRange(0, length) locale:CollationLocale_] != NSOrderedDescending) {
+ while (StringNameCompare((CFStringRef) start, (CFStringRef) name, NULL) != kCFCompareGreaterThan) {
+ NSString *title([CollationTitles_ objectAtIndex:offset]);
+ section = [[[Section alloc] initWithName:title row:index localize:NO] autorelease];
+ [sections addObject:section];
- [section addToCount];
+ start = ++offset == offsets ? nil : [CollationStarts_ objectAtIndex:offset];
+ if (start == nil)
+ break;
+ length = [start length];
}
- _end
- } else
-#endif
- {
- index_ = [NSMutableArray arrayWithCapacity:32];
-
- bool sectioned([self showsSections]);
- if (!sectioned) {
- section = [[[Section alloc] initWithName:nil localize:false] autorelease];
- [sections addObject:section];
}
- _profile(PackageTable$reloadData$Section)
- for (size_t offset(0), end([packages count]); offset != end; ++offset) {
- Package *package;
- unichar index;
-
- _profile(PackageTable$reloadData$Section$Package)
- package = [packages objectAtIndex:offset];
- index = [package index];
- _end
-
- if (sectioned && (section == nil || [section index] != index)) {
- _profile(PackageTable$reloadData$Section$Allocate)
- section = [[[Section alloc] initWithIndex:index row:offset] autorelease];
- _end
-
- [index_ addObject:[section name]];
+ [section addToCount];
+ }
- _profile(PackageTable$reloadData$Section$Add)
- [sections addObject:section];
- _end
- }
+ for (; offset != offsets; ++offset) {
+ NSString *title([CollationTitles_ objectAtIndex:offset]);
+ Section *section([[[Section alloc] initWithName:title row:end localize:NO] autorelease]);
+ [sections addObject:section];
+ }
- [section addToCount];
- }
- _end
+ if ([prefix count] != 0) {
+ Section *suffix([sections lastObject]);
+ [prefix setName:[suffix name]];
+ [suffix setName:nil];
+ [sections insertObject:prefix atIndex:(offsets - 1)];
}
return sections;
@@ -10004,6 +9976,36 @@ int main(int argc, char *argv[]) {
std::setlocale(LC_ALL, lang);
}
/* }}} */
+ /* Index Collation {{{ */
+ if (Class $UILocalizedIndexedCollation = objc_getClass("UILocalizedIndexedCollation")) {
+ NSBundle *bundle([NSBundle bundleForClass:$UILocalizedIndexedCollation]);
+ NSString *path([bundle pathForResource:@"UITableViewLocalizedSectionIndex" ofType:@"plist"]);
+ //path = @"/System/Library/Frameworks/UIKit.framework/.lproj/UITableViewLocalizedSectionIndex.plist";
+ NSDictionary *dictionary([NSDictionary dictionaryWithContentsOfFile:path]);
+ _H<UILocalizedIndexedCollation> collation([[[UILocalizedIndexedCollation alloc] initWithDictionary:dictionary] autorelease]);
+
+ CollationLocale_ = MSHookIvar<NSLocale *>(collation, "_locale");
+
+ CollationThumbs_ = [collation sectionIndexTitles];
+ for (size_t index(0), end([CollationThumbs_ count]); index != end; ++index)
+ CollationOffset_.push_back([collation sectionForSectionIndexTitleAtIndex:index]);
+
+ CollationTitles_ = [collation sectionTitles];
+ CollationStarts_ = MSHookIvar<NSArray *>(collation, "_sectionStartStrings");
+
+ if ([collation respondsToSelector:@selector(transformedCollationStringForString:)])
+ CollationModify_ = [=](NSString *value) { return [collation transformedCollationStringForString:value]; };
+ } else {
+ CollationLocale_ = [[[NSLocale alloc] initWithLocaleIdentifier:@"en@collation=dictionary"] autorelease];
+
+ CollationThumbs_ = [NSArray arrayWithObjects:@"A",@"B",@"C",@"D",@"E",@"F",@"G",@"H",@"I",@"J",@"K",@"L",@"M",@"N",@"O",@"P",@"Q",@"R",@"S",@"T",@"U",@"V",@"W",@"X",@"Y",@"Z",@"#",nil];
+ for (NSInteger offset(0); offset != 28; ++offset)
+ CollationOffset_.push_back(offset);
+
+ CollationTitles_ = [NSArray arrayWithObjects:@"A",@"B",@"C",@"D",@"E",@"F",@"G",@"H",@"I",@"J",@"K",@"L",@"M",@"N",@"O",@"P",@"Q",@"R",@"S",@"T",@"U",@"V",@"W",@"X",@"Y",@"Z",@"#",nil];
+ CollationStarts_ = [NSArray arrayWithObjects:@"a",@"b",@"c",@"d",@"e",@"f",@"g",@"h",@"i",@"j",@"k",@"l",@"m",@"n",@"o",@"p",@"q",@"r",@"s",@"t",@"u",@"v",@"w",@"x",@"y",@"z",@"ʒ",nil];
+ }
+ /* }}} */
apr_app_initialize(&argc, const_cast<const char * const **>(&argv), NULL);