X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/a93115162b319d3298a2b66fd7e023c14f62f41d..35ee854810ce90c8418e3072cfb28e246fdba013:/MobileCydia.mm diff --git a/MobileCydia.mm b/MobileCydia.mm index 0c07bbfe..d741ddaf 100644 --- a/MobileCydia.mm +++ b/MobileCydia.mm @@ -129,6 +129,8 @@ extern "C" { #include "CyteKit/WebViewController.h" #include "CyteKit/stringWithUTF8Bytes.h" +#include "Cydia/MIMEAddress.h" +#include "Cydia/LoadingViewController.h" #include "Cydia/ProgressEvent.h" #include "SDURLCache/SDURLCache.h" @@ -588,74 +590,6 @@ struct NSStringMapEqual : }; /* }}} */ -/* Mime Addresses {{{ */ -@interface Address : NSObject { - _H name_; - _H address_; -} - -- (NSString *) name; -- (NSString *) address; - -- (void) setAddress:(NSString *)address; - -+ (Address *) addressWithString:(NSString *)string; -- (Address *) initWithString:(NSString *)string; - -@end - -@implementation Address - -- (NSString *) name { - return name_; -} - -- (NSString *) address { - return address_; -} - -- (void) setAddress:(NSString *)address { - address_ = address; -} - -+ (Address *) addressWithString:(NSString *)string { - return [[[Address alloc] initWithString:string] autorelease]; -} - -+ (NSArray *) _attributeKeys { - return [NSArray arrayWithObjects: - @"address", - @"name", - nil]; -} - -- (NSArray *) attributeKeys { - return [[self class] _attributeKeys]; -} - -+ (BOOL) isKeyExcludedFromWebScript:(const char *)name { - return ![[self _attributeKeys] containsObject:[NSString stringWithUTF8String:name]] && [super isKeyExcludedFromWebScript:name]; -} - -- (Address *) initWithString:(NSString *)string { - if ((self = [super init]) != nil) { - const char *data = [string UTF8String]; - size_t size = [string length]; - - static Pcre address_r("^\"?(.*)\"? <([^>]*)>$"); - - if (address_r(data, size)) { - name_ = address_r[1]; - address_ = address_r[2]; - } else { - name_ = string; - address_ = nil; - } - } return self; -} - -@end -/* }}} */ /* CoreGraphics Primitives {{{ */ class CYColor { private: @@ -770,6 +704,7 @@ static _H SessionData_; static _H HostConfig_; static _H BridgedHosts_; static _H PipelinedHosts_; +static _H CachedURLs_; static NSString *kCydiaProgressEventTypeError = @"Error"; static NSString *kCydiaProgressEventTypeInformation = @"Information"; @@ -1328,6 +1263,7 @@ static void PackageImport(const void *key, const void *value, void *context) { CYString uri_; CYString distribution_; CYString type_; + CYString base_; CYString version_; _H host_; @@ -1352,6 +1288,9 @@ static void PackageImport(const void *key, const void *value, void *context) { - (NSString *) uri; - (NSString *) distribution; - (NSString *) type; + +- (NSString *) base; + - (NSString *) key; - (NSString *) host; @@ -1372,6 +1311,8 @@ static void PackageImport(const void *key, const void *value, void *context) { distribution_.clear(); type_.clear(); + base_.clear(); + description_.clear(); label_.clear(); origin_.clear(); @@ -1420,6 +1361,8 @@ static void PackageImport(const void *key, const void *value, void *context) { debReleaseIndex *dindex(dynamic_cast(index)); if (dindex != NULL) { + base_.set(pool, dindex->MetaIndexURI("")); + FileFd fd; if (!fd.Open(dindex->MetaIndexFile("Release"), FileFd::ReadOnly)) _error->Discard(); @@ -1524,6 +1467,10 @@ static void PackageImport(const void *key, const void *value, void *context) { return type_; } +- (NSString *) base { + return base_; +} + - (NSString *) key { return [NSString stringWithFormat:@"%@:%@:%@", (NSString *) type_, (NSString *) uri_, (NSString *) distribution_]; } @@ -1739,6 +1686,8 @@ struct ParsedPackage { apr_pool_t *pool_; + uint32_t rank_; + _transient Database *database_; pkgCache::VerIterator version_; @@ -1776,7 +1725,7 @@ struct ParsedPackage { - (NSString *) uri; -- (Address *) maintainer; +- (MIMEAddress *) maintainer; - (size_t) size; - (NSString *) longDescription; - (NSString *) shortDescription; @@ -1812,7 +1761,7 @@ struct ParsedPackage { - (UIImage *) icon; - (NSString *) homepage; - (NSString *) depiction; -- (Address *) author; +- (MIMEAddress *) author; - (NSString *) support; @@ -1822,7 +1771,8 @@ struct ParsedPackage { - (Source *) source; -- (BOOL) matches:(NSString *)text; +- (uint32_t) rank; +- (BOOL) matches:(NSArray *)query; - (bool) hasSupportingRole; - (BOOL) hasTag:(NSString *)tag; @@ -1839,7 +1789,7 @@ struct ParsedPackage { - (void) install; - (void) remove; -- (bool) isUnfilteredAndSearchedForBy:(NSString *)search; +- (bool) isUnfilteredAndSearchedForBy:(NSArray *)query; - (bool) isUnfilteredAndSelectedForBy:(NSString *)search; - (bool) isInstalledAndUnfiltered:(NSNumber *)number; - (bool) isVisibleInSection:(NSString *)section; @@ -2318,14 +2268,14 @@ struct PackageNameOrdering : #endif } -- (Address *) maintainer { +- (MIMEAddress *) maintainer { @synchronized (database_) { if ([database_ era] != era_ || file_.end()) return nil; pkgRecords::Parser *parser = &[database_ records]->Lookup(file_); const std::string &maintainer(parser->Maintainer()); - return maintainer.empty() ? nil : [Address addressWithString:[NSString stringWithUTF8String:maintainer.c_str()]]; + return maintainer.empty() ? nil : [MIMEAddress addressWithString:[NSString stringWithUTF8String:maintainer.c_str()]]; } } - (size_t) size { @@ -2553,12 +2503,12 @@ struct PackageNameOrdering : return parsed_ != NULL && !parsed_->depiction_.empty() ? parsed_->depiction_ : [[self source] depictionForPackage:id_]; } -- (Address *) sponsor { - return parsed_ == NULL || parsed_->sponsor_.empty() ? nil : [Address addressWithString:parsed_->sponsor_]; +- (MIMEAddress *) sponsor { + return parsed_ == NULL || parsed_->sponsor_.empty() ? nil : [MIMEAddress addressWithString:parsed_->sponsor_]; } -- (Address *) author { - return parsed_ == NULL || parsed_->author_.empty() ? nil : [Address addressWithString:parsed_->author_]; +- (MIMEAddress *) author { + return parsed_ == NULL || parsed_->author_.empty() ? nil : [MIMEAddress addressWithString:parsed_->author_]; } - (NSString *) support { @@ -2726,30 +2676,50 @@ struct PackageNameOrdering : return source_ == (Source *) [NSNull null] ? nil : source_; } -- (BOOL) matches:(NSString *)text { - if (text == nil) +- (uint32_t) rank { + return rank_; +} + +- (BOOL) matches:(NSArray *)query { + if (query == nil || [query count] == 0) return NO; + rank_ = 0; + + NSString *string; NSRange range; + NSUInteger length; - range = [[self id] rangeOfString:text options:MatchCompareOptions_]; - if (range.location != NSNotFound) - return YES; + [self parse]; - range = [[self name] rangeOfString:text options:MatchCompareOptions_]; - if (range.location != NSNotFound) - return YES; + string = [self id]; + length = [string length]; - [self parse]; + for (NSString *term in query) { + range = [string rangeOfString:term options:MatchCompareOptions_]; + if (range.location != NSNotFound) + rank_ -= 10 * 100000 / length; + } - NSString *description([self shortDescription]); - NSUInteger length([description length]); + string = [self name]; - range = [[self shortDescription] rangeOfString:text options:MatchCompareOptions_ range:NSMakeRange(0, std::min(length, 100))]; - if (range.location != NSNotFound) - return YES; + for (NSString *term in query) { + range = [string rangeOfString:term options:MatchCompareOptions_]; + if (range.location != NSNotFound) + rank_ -= 6 * 100000 / length; + } - return NO; + string = [self shortDescription]; + length = [string length]; + NSUInteger stop(std::min(length, 100)); + + for (NSString *term in query) { + range = [string rangeOfString:term options:MatchCompareOptions_ range:NSMakeRange(0, stop)]; + if (range.location != NSNotFound) + rank_ -= 2 * 100000 / length; + } + + return rank_ != 0; } - (bool) hasSupportingRole { @@ -2853,7 +2823,7 @@ struct PackageNameOrdering : cache->MarkDelete(iterator_, true); } } -- (bool) isUnfilteredAndSearchedForBy:(NSString *)search { +- (bool) isUnfilteredAndSearchedForBy:(NSArray *)query { _profile(Package$isUnfilteredAndSearchedForBy) bool value(true); @@ -2862,7 +2832,7 @@ struct PackageNameOrdering : _end _profile(Package$isUnfilteredAndSearchedForBy$Match) - value &= [self matches:search]; + value &= [self matches:query]; _end return value; @@ -3021,7 +2991,7 @@ struct PackageNameOrdering : /* }}} */ static NSString *Colon_; -static NSString *Elision_; +NSString *Elision_; static NSString *Error_; static NSString *Warning_; @@ -3935,6 +3905,8 @@ static _H Diversions_; return @"statfs"; else if (selector == @selector(supports:)) return @"supports"; + else if (selector == @selector(unload)) + return @"unload"; else return nil; } @@ -3947,6 +3919,10 @@ static _H Diversions_; return [feature isEqualToString:@"window.open"]; } +- (void) unload { + [delegate_ performSelectorOnMainThread:@selector(unloadData) withObject:nil waitUntilDone:NO]; +} + - (void) addInternalRedirect:(NSString *)from :(NSString *)to { [CydiaWebViewController performSelectorOnMainThread:@selector(addDiversion:) withObject:[[[Diversion alloc] initWithFrom:from to:to] autorelease] waitUntilDone:NO]; } @@ -4231,121 +4207,6 @@ static _H Diversions_; @end /* }}} */ -/* @ Loading... Indicator {{{ */ -@interface CYLoadingIndicator : UIView { - _H spinner_; - _H label_; - _H container_; -} - -@property (readonly, nonatomic) UILabel *label; -@property (readonly, nonatomic) UIActivityIndicatorView *activityIndicatorView; - -@end - -@implementation CYLoadingIndicator - -- (id) initWithFrame:(CGRect)frame { - if ((self = [super initWithFrame:frame]) != nil) { - container_ = [[[UIView alloc] init] autorelease]; - [container_ setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin]; - - spinner_ = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] autorelease]; - [spinner_ startAnimating]; - [container_ addSubview:spinner_]; - - label_ = [[[UILabel alloc] init] autorelease]; - [label_ setFont:[UIFont boldSystemFontOfSize:15.0f]]; - [label_ setBackgroundColor:[UIColor clearColor]]; - [label_ setTextColor:[UIColor blackColor]]; - [label_ setShadowColor:[UIColor whiteColor]]; - [label_ setShadowOffset:CGSizeMake(0, 1)]; - [label_ setText:[NSString stringWithFormat:Elision_, UCLocalize("LOADING"), nil]]; - [container_ addSubview:label_]; - - CGSize viewsize = frame.size; - CGSize spinnersize = [spinner_ bounds].size; - CGSize textsize = [[label_ text] sizeWithFont:[label_ font]]; - float bothwidth = spinnersize.width + textsize.width + 5.0f; - - CGRect containrect = { - CGPointMake(floorf((viewsize.width / 2) - (bothwidth / 2)), floorf((viewsize.height / 2) - (spinnersize.height / 2))), - CGSizeMake(bothwidth, spinnersize.height) - }; - CGRect textrect = { - CGPointMake(spinnersize.width + 5.0f, floorf((spinnersize.height / 2) - (textsize.height / 2))), - textsize - }; - CGRect spinrect = { - CGPointZero, - spinnersize - }; - - [container_ setFrame:containrect]; - [spinner_ setFrame:spinrect]; - [label_ setFrame:textrect]; - [self addSubview:container_]; - } return self; -} - -- (UILabel *) label { - return label_; -} - -- (UIActivityIndicatorView *) activityIndicatorView { - return spinner_; -} - -@end -/* }}} */ -/* Emulated Loading Controller {{{ */ -@interface CYEmulatedLoadingController : CyteViewController { - _transient Database *database_; - _H indicator_; - _H tabbar_; - _H navbar_; -} - -@end - -@implementation CYEmulatedLoadingController - -- (id) initWithDatabase:(Database *)database { - if ((self = [super init]) != nil) { - database_ = database; - } return self; -} - -- (void) loadView { - [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; - - UITableView *table([[[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStyleGrouped] autorelease]); - [table setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; - [[self view] addSubview:table]; - - indicator_ = [[[CYLoadingIndicator alloc] initWithFrame:[[self view] bounds]] autorelease]; - [indicator_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; - [[self view] addSubview:indicator_]; - - tabbar_ = [[[UITabBar alloc] initWithFrame:CGRectMake(0, 0, 0, 49.0f)] autorelease]; - [tabbar_ setFrame:CGRectMake(0.0f, [[self view] bounds].size.height - [tabbar_ bounds].size.height, [[self view] bounds].size.width, [tabbar_ bounds].size.height)]; - [tabbar_ setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth]; - [[self view] addSubview:tabbar_]; - - navbar_ = [[[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 0, 44.0f)] autorelease]; - [navbar_ setFrame:CGRectMake(0.0f, 0.0f, [[self view] bounds].size.width, [navbar_ bounds].size.height)]; - [navbar_ setAutoresizingMask:UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth]; - [[self view] addSubview:navbar_]; -} - -- (void) releaseSubviews { - indicator_ = nil; - tabbar_ = nil; - navbar_ = nil; -} - -@end -/* }}} */ /* Cydia Browser Controller {{{ */ @implementation CydiaWebViewController @@ -4384,6 +4245,13 @@ static _H Diversions_; [window setValue:cydia_ forKey:@"cydia"]; } +- (void) _setupMail:(MFMailComposeViewController *)controller { + [controller addAttachmentData:[NSData dataWithContentsOfFile:@"/tmp/cydia.log"] mimeType:@"text/plain" fileName:@"cydia.log"]; + + system("/usr/bin/dpkg -l >/tmp/dpkgl.log"); + [controller addAttachmentData:[NSData dataWithContentsOfFile:@"/tmp/dpkgl.log"] mimeType:@"text/plain" fileName:@"dpkgl.log"]; +} + - (NSURL *) URLWithURL:(NSURL *)url { return [Diversion divertURL:url]; } @@ -5816,6 +5684,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return false; } +- (bool) showsSections { + return true; +} + - (void) deselectWithAnimation:(BOOL)animated { [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated]; } @@ -5946,7 +5818,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (NSArray *) sectionIndexTitlesForTableView:(UITableView *)tableView { - if ([self isSummarized]) + if ([self showsSections]) return nil; return index_; @@ -6002,10 +5874,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { delegate_ = delegate; } -- (bool) hasPackage:(Package *)package { - return true; -} - - (bool) shouldYield { return false; } @@ -6014,17 +5882,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return false; } -- (NSArray *) _reloadPackages:(NSArray *)packages { - NSMutableArray *filtered([NSMutableArray arrayWithCapacity:[packages count]]); - - _profile(PackageTable$reloadData$Filter) - for (Package *package in packages) - if ([self hasPackage:package]) - [filtered addObject:package]; - _end +- (NSMutableArray *) _reloadPackages { +@synchronized (database_) { + era_ = [database_ era]; + NSArray *packages([database_ packages]); - return filtered; -} + return [NSMutableArray arrayWithArray:packages]; +} } - (void) _reloadData { if (reloading_ != 0) { @@ -6032,30 +5896,27 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return; } - era_ = [database_ era]; - NSArray *packages = [database_ packages]; - if ([self shouldYield]) { - UIProgressHUD *hud; + do { + UIProgressHUD *hud; - if (![self shouldBlock]) - hud = nil; - else { - hud = [delegate_ addProgressHUD]; - [hud setText:UCLocalize("LOADING")]; - } + if (![self shouldBlock]) + hud = nil; + else { + hud = [delegate_ addProgressHUD]; + [hud setText:UCLocalize("LOADING")]; + } - do { reloading_ = 1; - packages_ = [self yieldToSelector:@selector(_reloadPackages:) withObject:packages]; + packages_ = [self yieldToSelector:@selector(_reloadPackages)]; + + if (hud != nil) + [delegate_ removeProgressHUD:hud]; } while (reloading_ == 2); reloading_ = 0; - - if (hud != nil) - [delegate_ removeProgressHUD:hud]; } else { - packages_ = [self _reloadPackages:packages]; + packages_ = [self _reloadPackages]; } [indices_ removeAllObjects]; @@ -6099,8 +5960,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { { [index_ removeAllObjects]; - bool summary([self isSummarized]); - if (summary) { + bool sectioned([self showsSections]); + if (!sectioned) { section = [[[Section alloc] initWithName:nil localize:false] autorelease]; [sections_ addObject:section]; } @@ -6115,7 +5976,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { index = [package index]; _end - if (!summary && (section == nil || [section index] != index)) { + if (sectioned && (section == nil || [section index] != index)) { _profile(PackageTable$reloadData$Section$Allocate) section = [[[Section alloc] initWithIndex:index row:offset] autorelease]; _end @@ -6185,6 +6046,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) setFilter:(SEL)filter { +@synchronized (self) { filter_ = filter; /* XXX: this is an unsafe optimization of doomy hell */ @@ -6192,22 +6054,44 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { _assert(method != NULL); imp_ = method_getImplementation(method); _assert(imp_ != NULL); -} +} } - (void) setObject:(id)object { +@synchronized (self) { object_ = object; -} +} } - (void) setObject:(id)object forFilter:(SEL)filter { +@synchronized (self) { [self setFilter:filter]; [self setObject:object]; -} +} } + +- (NSMutableArray *) _reloadPackages { +@synchronized (database_) { + era_ = [database_ era]; + NSArray *packages([database_ packages]); + + NSMutableArray *filtered([NSMutableArray arrayWithCapacity:[packages count]]); + + IMP imp; + SEL filter; + _H object; + + @synchronized (self) { + imp = imp_; + filter = filter_; + object = object_; + } -- (bool) hasPackage:(Package *)package { - _profile(FilteredPackageTable$hasPackage) - return [package valid] && (*reinterpret_cast(imp_))(package, filter_, object_); + _profile(PackageTable$reloadData$Filter) + for (Package *package in packages) + if ([package valid] && (*reinterpret_cast(imp))(package, filter, object)) + [filtered addObject:package]; _end -} + + return filtered; +} } - (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object { if ((self = [super initWithDatabase:database title:title]) != nil) { @@ -6266,11 +6150,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { ] autorelease]; } -- (void) unloadData { - [super unloadData]; - [self reloadData]; -} - @end /* }}} */ /* Manage Controller {{{ */ @@ -7224,7 +7103,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } return self; } -- (NSArray *) _reloadPackages:(NSArray *)packages { +- (NSMutableArray *) _reloadPackages { +@synchronized (database_) { + era_ = [database_ era]; + NSArray *packages([database_ packages]); + NSMutableArray *filtered([NSMutableArray arrayWithCapacity:[packages count]]); _trace(); @@ -7240,22 +7123,23 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { _trace(); return filtered; -} +} } - (void) _reloadData { -@synchronized (database_) { - era_ = [database_ era]; - NSArray *packages = [database_ packages]; + reload: + if (true) { + UIProgressHUD *hud([delegate_ addProgressHUD]); + [hud setText:UCLocalize("LOADING")]; + //NSLog(@"HUD:%@::%@", delegate_, hud); + packages_ = [self yieldToSelector:@selector(_reloadPackages)]; + [delegate_ removeProgressHUD:hud]; + } else { + packages_ = [self _reloadPackages]; + } -#if 1 - UIProgressHUD *hud([delegate_ addProgressHUD]); - [hud setText:UCLocalize("LOADING")]; - //NSLog(@"HUD:%@::%@", delegate_, hud); - packages_ = [self yieldToSelector:@selector(_reloadPackages:) withObject:packages]; - [delegate_ removeProgressHUD:hud]; -#else - packages_ = [self _reloadPackages:packages]; -#endif +@synchronized (database_) { + if (era_ != [database_ era]) + goto reload; [sections_ removeAllObjects]; @@ -7370,7 +7254,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) useSearch { - [self setObject:[search_ text] forFilter:@selector(isUnfilteredAndSearchedForBy:)]; + [self setObject:[[search_ text] componentsSeparatedByString:@" "] forFilter:@selector(isUnfilteredAndSearchedForBy:)]; [self clearData]; [self reloadData]; } @@ -7419,8 +7303,19 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return [self filter] == @selector(isUnfilteredAndSelectedForBy:); } +- (bool) showsSections { + return false; +} + +- (NSMutableArray *) _reloadPackages { + NSMutableArray *packages([super _reloadPackages]); + if ([self filter] == @selector(isUnfilteredAndSearchedForBy:)) + [packages radixSortUsingSelector:@selector(rank)]; + return packages; +} + - (id) initWithDatabase:(Database *)database query:(NSString *)query { - if ((self = [super initWithDatabase:database title:UCLocalize("SEARCH") filter:@selector(isUnfilteredAndSearchedForBy:) with:query])) { + if ((self = [super initWithDatabase:database title:UCLocalize("SEARCH") filter:@selector(isUnfilteredAndSearchedForBy:) with:[query componentsSeparatedByString:@" "]])) { search_ = [[[UISearchBar alloc] init] autorelease]; [search_ setDelegate:self]; @@ -7451,7 +7346,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) reloadData { - [self setObject:[search_ text]]; + id object([search_ text]); + if ([self filter] == @selector(isUnfilteredAndSearchedForBy:)) + object = [object componentsSeparatedByString:@" "]; + + [self setObject:object]; [self resetCursor]; [super reloadData]; @@ -7728,17 +7627,44 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @implementation SourceCell +- (void) _setImage:(UIImage *)image { + icon_ = image; + [content_ setNeedsDisplay]; +} + +- (void) _setSource:(Source *)source { + NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]); + + if (NSString *base = [source base]) + if ([base length] != 0) { + NSURL *url([NSURL URLWithString:[base stringByAppendingString:@"CydiaIcon.png"]]); + + if (NSData *data = [NSURLConnection + sendSynchronousRequest:[NSURLRequest + requestWithURL:url + //cachePolicy:NSURLRequestUseProtocolCachePolicy + //timeoutInterval:5 + ] + + returningResponse:NULL + error:NULL + ]) + if (UIImage *image = [UIImage imageWithData:data]) + [self performSelectorOnMainThread:@selector(_setImage:) withObject:image waitUntilDone:NO]; + } + + [pool release]; +} + - (void) setSource:(Source *)source { - icon_ = nil; - if (icon_ == nil) - icon_ = [UIImage applicationImageNamed:[NSString stringWithFormat:@"Sources/%@.png", [source host]]]; - if (icon_ == nil) - icon_ = [UIImage applicationImageNamed:@"unknown.png"]; + icon_ = [UIImage applicationImageNamed:@"unknown.png"]; origin_ = [source name]; label_ = [source uri]; [content_ setNeedsDisplay]; + + [NSThread detachNewThreadSelector:@selector(_setSource:) toTarget:self withObject:source]; } - (SourceCell *) initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier { @@ -8529,6 +8455,24 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { #endif } +- (void) storeCachedResponse:(NSCachedURLResponse *)cached forRequest:(NSURLRequest *)request { + if (NSURLResponse *response = [cached response]) + if (NSString *mime = [response MIMEType]) + if ([mime isEqualToString:@"text/cache-manifest"]) { + NSURL *url([response URL]); + +#if !ForRelease + NSLog(@"###: %@", [url absoluteString]); +#endif + + @synchronized (HostConfig_) { + [CachedURLs_ addObject:url]; + } + } + + [super storeCachedResponse:cached forRequest:request]; +} + @end @interface Cydia : UIApplication < @@ -8540,7 +8484,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { > { _H window_; _H tabbar_; - _H emulated_; + _H emulated_; _H essential_; _H broken_; @@ -9416,7 +9360,7 @@ _trace(); [window_ setUserInteractionEnabled:NO]; [self setupViewControllers]; - emulated_ = [[[CYEmulatedLoadingController alloc] initWithDatabase:database_] autorelease]; + emulated_ = [[[CydiaLoadingViewController alloc] init] autorelease]; [window_ addSubview:[emulated_ view]]; [self performSelector:@selector(loadData) withObject:nil afterDelay:0]; @@ -9612,6 +9556,8 @@ MSHook(id, NSURLConnection$init$, NSURLConnection *self, SEL _cmd, NSURLRequest NSMutableURLRequest *copy([request mutableCopy]); NSURL *url([copy URL]); + + NSString *href([url absoluteString]); NSString *host([url host]); NSString *scheme([[url scheme] lowercaseString]); @@ -9621,6 +9567,20 @@ MSHook(id, NSURLConnection$init$, NSURLConnection *self, SEL _cmd, NSURLRequest if ([copy respondsToSelector:@selector(setHTTPShouldUsePipelining:)]) if ([PipelinedHosts_ containsObject:host] || [PipelinedHosts_ containsObject:compound]) [copy setHTTPShouldUsePipelining:YES]; + + if (NSString *control = [copy valueForHTTPHeaderField:@"Cache-Control"]) + if ([control isEqualToString:@"max-age=0"]) + if ([CachedURLs_ containsObject:href]) { +#if !ForRelease + NSLog(@"~~~: %@", href); +#endif + + [copy setCachePolicy:NSURLRequestReturnCacheDataDontLoad]; + + [copy setValue:nil forHTTPHeaderField:@"Cache-Control"]; + [copy setValue:nil forHTTPHeaderField:@"If-Modified-Since"]; + [copy setValue:nil forHTTPHeaderField:@"If-None-Match"]; + } } if ((self = _NSURLConnection$init$(self, _cmd, copy, delegate, usesCache, maxContentLength, startImmediately, connectionProperties)) != nil) { @@ -9665,6 +9625,7 @@ int main(int argc, char *argv[]) { @synchronized (HostConfig_) { BridgedHosts_ = [NSMutableSet setWithCapacity:4]; PipelinedHosts_ = [NSMutableSet setWithCapacity:4]; + CachedURLs_ = [NSMutableSet setWithCapacity:32]; } UI_ = CydiaURL([NSString stringWithFormat:@"ui/ios~%@", Idiom_]);