#include "Substrate.hpp"
#include "Menes/Menes.h"
-#include "CyteKit/Application.h"
-#include "CyteKit/NavigationController.h"
+#include "CyteKit/CyteKit.h"
#include "CyteKit/RegEx.hpp"
-#include "CyteKit/TableViewCell.h"
-#include "CyteKit/TabBarController.h"
-#include "CyteKit/WebScriptObject-Cyte.h"
-#include "CyteKit/WebViewController.h"
-#include "CyteKit/WebViewTableViewCell.h"
-#include "CyteKit/stringWithUTF8Bytes.h"
#include "Cydia/MIMEAddress.h"
#include "Cydia/LoadingViewController.h"
#include "Cydia/ProgressEvent.h"
-
-#include "SDURLCache/SDURLCache.h"
/* }}} */
/* Profiler {{{ */
#define _end }
/* }}} */
-// XXX: I hate clang. Apple: please get over your petty hatred of GPL and fix your gcc fork
-#define synchronized(lock) \
- synchronized(static_cast<NSObject *>(lock))
-
extern NSString *Cydia_;
#define lprintf(args...) fprintf(stderr, args)
/* }}} */
-/* Apple Bug Fixes {{{ */
-@implementation UIWebDocumentView (Cydia)
-
-- (void) _setScrollerOffset:(CGPoint)offset {
- UIScroller *scroller([self _scroller]);
-
- CGSize size([scroller contentSize]);
- CGSize bounds([scroller bounds].size);
-
- CGPoint max;
- max.x = size.width - bounds.width;
- max.y = size.height - bounds.height;
-
- // wtf Apple?!
- if (max.x < 0)
- max.x = 0;
- if (max.y < 0)
- max.y = 0;
-
- offset.x = offset.x < 0 ? 0 : offset.x > max.x ? max.x : offset.x;
- offset.y = offset.y < 0 ? 0 : offset.y > max.y ? max.y : offset.y;
-
- [scroller setOffset:offset];
-}
-
-@end
-/* }}} */
-
-NSUInteger DOMNodeList$countByEnumeratingWithState$objects$count$(DOMNodeList *self, SEL sel, NSFastEnumerationState *state, id *objects, NSUInteger count) {
- size_t length([self length] - state->state);
- if (length <= 0)
- return 0;
- else if (length > count)
- length = count;
- for (size_t i(0); i != length; ++i)
- objects[i] = [self item:state->state++];
- state->itemsPtr = objects;
- state->mutationsPtr = (unsigned long *) self;
- return length;
-}
-
/* Cydia NSString Additions {{{ */
@interface NSString (Cydia)
- (NSComparisonResult) compareByPath:(NSString *)other;
static _transient NSNumber *Version_;
static time_t now_;
-bool IsWildcat_;
-CGFloat ScreenScale_;
static NSString *Idiom_;
static _H<NSString> Firmware_;
static NSString *Major_;
static _H<NSObject> HostConfig_;
static _H<NSMutableSet> BridgedHosts_;
static _H<NSMutableSet> InsecureHosts_;
-static _H<NSMutableSet> PipelinedHosts_;
-static _H<NSMutableSet> CachedURLs_;
static NSString *kCydiaProgressEventTypeError = @"Error";
static NSString *kCydiaProgressEventTypeInformation = @"Information";
}
//printf("Set(%s, %s)\n", fetch ? "true" : "false", uri.c_str());
- [database_ setFetch:fetch forURI:uri.c_str()];
+
+ auto slash(uri.rfind('/'));
+ if (slash != std::string::npos)
+ [database_ setFetch:fetch forURI:uri.substr(0, slash).c_str()];
}
_finline void Set(bool fetch, pkgAcquire::Item *item) {
_profile(Source$setMetaIndex$DescURI)
for (pkgAcquire::ItemIterator item(acquire.ItemsBegin()); item != acquire.ItemsEnd(); item++) {
std::string file((*item)->DescURI());
- files_.insert(file);
- if (file.length() < sizeof("Packages.bz2") || file.substr(file.length() - sizeof("Packages.bz2")) != "/Packages.bz2")
+ auto slash(file.rfind('/'));
+ if (slash == std::string::npos)
continue;
- file = file.substr(0, file.length() - 4);
- files_.insert(file);
- files_.insert(file + ".gz");
- files_.insert(file + "Index");
+ files_.insert(file.substr(0, slash));
}
_end
continue;
} else {
std::swap(package, packages[index]);
- if (package != nil)
+ if (package != nil) {
+ if (package.metadata->index_ == index + 1)
+ ++lost;
goto lost;
+ }
if (last != index)
continue;
}
- } else lost: {
+ } else {
++lost;
- if (last == packages.size()) {
+ lost: if (last == packages.size())
packages.push_back(package);
- ++last;
- } else {
+ else
packages[last] = package;
- ++last;
- }
+ ++last;
}
for (; last != packages.size(); ++last)
return @"addInsecureHost";
else if (selector == @selector(addInternalRedirect::))
return @"addInternalRedirect";
- else if (selector == @selector(addPipelinedHost:scheme:))
- return @"addPipelinedHost";
else if (selector == @selector(addSource:::))
return @"addSource";
else if (selector == @selector(addTrivialSource:))
}
- (void) unload {
- [delegate_ performSelectorOnMainThread:@selector(unloadData) withObject:nil waitUntilDone:NO];
+ [[indirect_ rootViewController] performSelectorOnMainThread:@selector(unloadData) withObject:nil waitUntilDone:NO];
}
- (void) setScrollAlwaysBounceVertical:(NSNumber *)value {
[InsecureHosts_ addObject:host];
} }
-- (void) addPipelinedHost:(NSString *)host scheme:(NSString *)scheme {
-@synchronized (HostConfig_) {
- if (scheme != (id) [WebUndefined undefined])
- host = [NSString stringWithFormat:@"%@:%@", [scheme lowercaseString], host];
-
- [PipelinedHosts_ addObject:host];
-} }
-
- (void) popViewController:(NSNumber *)value {
if (value == (id) [WebUndefined undefined])
value = [NSNumber numberWithBool:YES];
@end
/* }}} */
-// CydiaScript {{{
-@interface NSObject (CydiaScript)
-- (id) Cydia$webScriptObjectInContext:(WebScriptObject *)context;
-@end
-
-@implementation NSObject (CydiaScript)
-
-- (id) Cydia$webScriptObjectInContext:(WebScriptObject *)context {
- return self;
-}
-
-@end
-
-@implementation NSArray (CydiaScript)
-
-- (id) Cydia$webScriptObjectInContext:(WebScriptObject *)context {
- WebScriptObject *object([context evaluateWebScript:@"[]"]);
- for (size_t i(0), e([self count]); i != e; ++i)
- [object setWebScriptValueAtIndex:i value:[[self objectAtIndex:i] Cydia$webScriptObjectInContext:context]];
- return object;
-}
-
-@end
-
-@implementation NSDictionary (CydiaScript)
-
-- (id) Cydia$webScriptObjectInContext:(WebScriptObject *)context {
- WebScriptObject *object([context evaluateWebScript:@"({})"]);
- for (id i in self)
- [object setValue:[[self objectForKey:i] Cydia$webScriptObjectInContext:context] forKey:i];
- return object;
-}
-
-@end
-// }}}
-
/* Confirmation Controller {{{ */
bool DepSubstrate(const pkgCache::VerIterator &iterator) {
if (!iterator.end())
#if !AlwaysReload
- (void) _customButtonClicked {
- if (commercial_ && [package_ uninstalled])
+ if (commercial_ && self.isLoading && [package_ uninstalled])
return [self reloadURLWithCache:NO];
size_t count(buttons_.size());
[self getKeyboardCurve:&curve duration:&duration forNotification:notification];
CGRect kbframe = CGRectMake(Retina(center.x - bounds.size.width / 2), Retina(center.y - bounds.size.height / 2), bounds.size.width, bounds.size.height);
- UIViewController *base = self;
- while ([base parentOrPresentingViewController] != nil)
- base = [base parentOrPresentingViewController];
+ UIViewController *base([self rootViewController]);
CGRect viewframe = [[base view] convertRect:[list_ frame] fromView:[list_ superview]];
CGRect intersection = CGRectIntersection(viewframe, kbframe);
@end
/* }}} */
-@interface CYURLCache : SDURLCache {
-}
-
-@end
-
-@implementation CYURLCache
-
-- (void) logEvent:(NSString *)event forRequest:(NSURLRequest *)request {
-#if !ForRelease
- if (false);
- else if ([event isEqualToString:@"no-cache"])
- event = @"!!!";
- else if ([event isEqualToString:@"store"])
- event = @">>>";
- else if ([event isEqualToString:@"invalid"])
- event = @"???";
- else if ([event isEqualToString:@"memory"])
- event = @"mem";
- else if ([event isEqualToString:@"disk"])
- event = @"ssd";
- else if ([event isEqualToString:@"miss"])
- event = @"---";
-
- NSLog(@"%@: %@", event, [[request URL] absoluteString]);
-#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];
-}
-
-- (void) createDiskCachePath {
- [super createDiskCachePath];
-}
-
-@end
-
@interface Cydia : CyteApplication <
ConfirmationControllerDelegate,
DatabaseDelegate,
CydiaDelegate
> {
- _H<UIWindow> window_;
+ _H<CyteWindow> window_;
_H<CydiaTabBarController> tabbar_;
_H<CyteTabBarController> emulated_;
_H<AppCacheController> appcache_;
return [controllers objectAtIndex:3];
}
-- (void) unloadData {
- [tabbar_ unloadData];
-}
-
- (void) _updateData {
[self _saveConfig];
- [self unloadData];
+ [window_ unloadData];
UINavigationController *navigation = [self queueNavigationController];
if (emulated_ == nil)
return;
- if ([window_ respondsToSelector:@selector(setRootViewController:)])
- [window_ setRootViewController:tabbar_];
- else {
- [window_ addSubview:[tabbar_ view]];
- [[emulated_ view] removeFromSuperview];
- }
-
+ [window_ setRootViewController:tabbar_];
emulated_ = nil;
+
[window_ setUserInteractionEnabled:YES];
}
[self reloadSpringBoard];
}
-- (void) setupViewControllers {
- tabbar_ = [[[CydiaTabBarController alloc] initWithDatabase:database_] autorelease];
-
- NSMutableArray *items;
- if (kCFCoreFoundationVersionNumber < 800) {
- items = [NSMutableArray arrayWithObjects:
- [[[UITabBarItem alloc] initWithTitle:@"Cydia" image:[UIImage imageNamed:@"home.png"] tag:0] autorelease],
- [[[UITabBarItem alloc] initWithTitle:UCLocalize("SOURCES") image:[UIImage imageNamed:@"install.png"] tag:0] autorelease],
- [[[UITabBarItem alloc] initWithTitle:UCLocalize("CHANGES") image:[UIImage imageNamed:@"changes.png"] tag:0] autorelease],
- [[[UITabBarItem alloc] initWithTitle:UCLocalize("INSTALLED") image:[UIImage imageNamed:@"manage.png"] tag:0] autorelease],
- [[[UITabBarItem alloc] initWithTitle:UCLocalize("SEARCH") image:[UIImage imageNamed:@"search.png"] tag:0] autorelease],
- nil];
- } else {
- items = [NSMutableArray arrayWithObjects:
- [[[UITabBarItem alloc] initWithTitle:@"Cydia" image:[UIImage imageNamed:@"home7.png"] selectedImage:[UIImage imageNamed:@"home7s.png"]] autorelease],
- [[[UITabBarItem alloc] initWithTitle:UCLocalize("SOURCES") image:[UIImage imageNamed:@"install7.png"] selectedImage:[UIImage imageNamed:@"install7s.png"]] autorelease],
- [[[UITabBarItem alloc] initWithTitle:UCLocalize("CHANGES") image:[UIImage imageNamed:@"changes7.png"] selectedImage:[UIImage imageNamed:@"changes7s.png"]] autorelease],
- [[[UITabBarItem alloc] initWithTitle:UCLocalize("INSTALLED") image:[UIImage imageNamed:@"manage7.png"] selectedImage:[UIImage imageNamed:@"manage7s.png"]] autorelease],
- [[[UITabBarItem alloc] initWithTitle:UCLocalize("SEARCH") image:[UIImage imageNamed:@"search7.png"] selectedImage:[UIImage imageNamed:@"search7s.png"]] autorelease],
- nil];
- }
-
- NSMutableArray *controllers([NSMutableArray array]);
- for (UITabBarItem *item in items) {
- UINavigationController *controller([[[UINavigationController alloc] init] autorelease]);
- [controller setTabBarItem:item];
- [controllers addObject:controller];
- }
- [tabbar_ setViewControllers:controllers];
-
- [tabbar_ setUpdateDelegate:self];
-}
-
- (void) applicationDidFinishLaunching:(id)unused {
[super applicationDidFinishLaunching:unused];
_trace();
[BridgedHosts_ addObject:[[NSURL URLWithString:CydiaURL(@"")] host]];
}
- [NSURLCache setSharedURLCache:[[[CYURLCache alloc]
- initWithMemoryCapacity:524288
- diskCapacity:10485760
- diskPath:Cache("SDURLCache")
- ] autorelease]];
-
[CydiaWebViewController _initialize];
[NSURLProtocol registerClass:[CydiaURLProtocol class]];
appcache_ = [[[AppCacheController alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/appcache/", UI_]]] autorelease];
[appcache_ reloadData];
- window_ = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
+ window_ = [[[CyteWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
[window_ orderFront:self];
[window_ makeKey:self];
[window_ setHidden:NO];
[database_ setDelegate:self];
[window_ setUserInteractionEnabled:NO];
- [self setupViewControllers];
+
+ tabbar_ = [[[CydiaTabBarController alloc] initWithDatabase:database_] autorelease];
+
+ [tabbar_ addViewControllers:nil,
+ @"Cydia", @"home.png", @"home7.png", @"home7s.png",
+ UCLocalize("SOURCES"), @"install.png", @"install7.png", @"install7s.png",
+ UCLocalize("CHANGES"), @"changes.png", @"changes7.png", @"changes7s.png",
+ UCLocalize("INSTALLED"), @"manage.png", @"manage7.png", @"manage7s.png",
+ UCLocalize("SEARCH"), @"search.png", @"search7.png", @"search7s.png",
+ nil];
+
+ [tabbar_ setUpdateDelegate:self];
CydiaLoadingViewController *loading([[[CydiaLoadingViewController alloc] init] autorelease]);
UINavigationController *navigation([[[UINavigationController alloc] init] autorelease]);
if ([emulated_ respondsToSelector:@selector(concealTabBarSelection)])
[emulated_ concealTabBarSelection];
- if ([window_ respondsToSelector:@selector(setRootViewController:)])
- [window_ setRootViewController:emulated_];
- else
- [window_ addSubview:[emulated_ view]];
+ [window_ setRootViewController:emulated_];
[self performSelector:@selector(loadData) withObject:nil afterDelay:0];
_trace();
return object;
}*/
-Class $NSURLConnection;
-
-MSHook(id, NSURLConnection$init$, NSURLConnection *self, SEL _cmd, NSURLRequest *request, id delegate, BOOL usesCache, int64_t maxContentLength, BOOL startImmediately, NSDictionary *connectionProperties) {
- NSMutableURLRequest *copy([[request mutableCopy] autorelease]);
-
- NSURL *url([copy URL]);
-
- NSString *host([url host]);
- NSString *scheme([[url scheme] lowercaseString]);
-
- NSString *compound([NSString stringWithFormat:@"%@:%@", scheme, host]);
-
- @synchronized (HostConfig_) {
- 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:url]) {
-#if !ForRelease
- NSLog(@"~~~: %@", url);
-#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) {
- } return self;
-}
-
-Class $WAKWindow;
-
-static CGSize $WAKWindow$screenSize(WAKWindow *self, SEL _cmd) {
- CGSize size([[UIScreen mainScreen] bounds].size);
- /*if ([$WAKWindow respondsToSelector:@selector(hasLandscapeOrientation)])
- if ([$WAKWindow hasLandscapeOrientation])
- std::swap(size.width, size.height);*/
- return size;
-}
-
-Class $NSUserDefaults;
-
-MSHook(id, NSUserDefaults$objectForKey$, NSUserDefaults *self, SEL _cmd, NSString *key) {
- if ([key respondsToSelector:@selector(isEqualToString:)] && [key isEqualToString:@"WebKitLocalStorageDatabasePathPreferenceKey"])
- return Cache("LocalStorage");
- return _NSUserDefaults$objectForKey$(self, _cmd, key);
-}
-
static NSMutableDictionary *AutoreleaseDeepMutableCopyOfDictionary(CFTypeRef type) {
if (type == NULL)
return nil;
UpdateExternalStatus(0);
- UIScreen *screen([UIScreen mainScreen]);
- if ([screen respondsToSelector:@selector(scale)])
- ScreenScale_ = [screen scale];
- else
- ScreenScale_ = 1;
-
- UIDevice *device([UIDevice currentDevice]);
- if ([device respondsToSelector:@selector(userInterfaceIdiom)]) {
- UIUserInterfaceIdiom idiom([device userInterfaceIdiom]);
- if (idiom == UIUserInterfaceIdiomPad)
- IsWildcat_ = true;
- }
-
Idiom_ = IsWildcat_ ? @"ipad" : @"iphone";
RegEx pattern("([0-9]+\\.[0-9]+).*");
+ UIDevice *device([UIDevice currentDevice]);
if (pattern([device systemVersion]))
Firmware_ = pattern[1];
+
if (pattern(Cydia_))
Major_ = pattern[1];
@synchronized (HostConfig_) {
BridgedHosts_ = [NSMutableSet setWithCapacity:4];
InsecureHosts_ = [NSMutableSet setWithCapacity:4];
- PipelinedHosts_ = [NSMutableSet setWithCapacity:4];
- CachedURLs_ = [NSMutableSet setWithCapacity:32];
}
NSString *ui(@"ui/ios");
PackageName = reinterpret_cast<CYString &(*)(Package *, SEL)>(method_getImplementation(class_getInstanceMethod([Package class], @selector(cyname))));
- /* Library Hacks {{{ */
- class_addMethod(objc_getClass("DOMNodeList"), @selector(countByEnumeratingWithState:objects:count:), (IMP) &DOMNodeList$countByEnumeratingWithState$objects$count$, "I20@0:4^{NSFastEnumerationState}8^@12I16");
-
- $WAKWindow = objc_getClass("WAKWindow");
- if ($WAKWindow != NULL)
- if (Method method = class_getInstanceMethod($WAKWindow, @selector(screenSize)))
- method_setImplementation(method, (IMP) &$WAKWindow$screenSize);
-
- $NSURLConnection = objc_getClass("NSURLConnection");
- Method NSURLConnection$init$(class_getInstanceMethod($NSURLConnection, @selector(_initWithRequest:delegate:usesCache:maxContentLength:startImmediately:connectionProperties:)));
- if (NSURLConnection$init$ != NULL) {
- _NSURLConnection$init$ = reinterpret_cast<id (*)(NSURLConnection *, SEL, NSURLRequest *, id, BOOL, int64_t, BOOL, NSDictionary *)>(method_getImplementation(NSURLConnection$init$));
- method_setImplementation(NSURLConnection$init$, reinterpret_cast<IMP>(&$NSURLConnection$init$));
- }
-
- $NSUserDefaults = objc_getClass("NSUserDefaults");
- Method NSUserDefaults$objectForKey$(class_getInstanceMethod($NSUserDefaults, @selector(objectForKey:)));
- if (NSUserDefaults$objectForKey$ != NULL) {
- _NSUserDefaults$objectForKey$ = reinterpret_cast<id (*)(NSUserDefaults *, SEL, NSString *)>(method_getImplementation(NSUserDefaults$objectForKey$));
- method_setImplementation(NSUserDefaults$objectForKey$, reinterpret_cast<IMP>(&$NSUserDefaults$objectForKey$));
- }
- /* }}} */
/* Set Locale {{{ */
Locale_ = CFLocaleCopyCurrent();
Languages_ = [NSLocale preferredLanguages];
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];
}
/* }}} */
- /* Parse Arguments {{{ */
- bool substrate(false);
-
- if (argc != 0) {
- char **args(argv);
- int arge(1);
-
- for (int argi(1); argi != argc; ++argi)
- if (strcmp(argv[argi], "--") == 0) {
- arge = argi;
- argv[argi] = argv[0];
- argv += argi;
- argc -= argi;
- break;
- }
-
- for (int argi(1); argi != arge; ++argi)
- if (strcmp(args[argi], "--substrate") == 0)
- substrate = true;
- else
- fprintf(stderr, "unknown argument: %s\n", args[argi]);
- }
- /* }}} */
App_ = [[NSBundle mainBundle] bundlePath];
Advanced_ = YES;