/* Cydia - iPhone UIKit Front-End for Debian APT
- * Copyright (C) 2008 Jay Freeman (saurik)
+ * Copyright (C) 2008-2009 Jay Freeman (saurik)
*/
/*
#include <GraphicsServices/GraphicsServices.h>
#include <Foundation/Foundation.h>
+#if 0
+#define DEPLOYMENT_TARGET_MACOSX 1
+#define CF_BUILDING_CF 1
+#include <CoreFoundation/CFInternal.h>
+#endif
+
+#include <CoreFoundation/CFPriv.h>
+#include <CoreFoundation/CFUniChar.h>
+
#import <QuartzCore/CALayer.h>
#import <UIKit/UIKit.h>
#include <WebCore/WebCoreThread.h>
#import <WebKit/WebDefaultUIKitDelegate.h>
+#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <apt-pkg/cachefile.h>
#include <apt-pkg/clean.h>
#include <apt-pkg/configuration.h>
+#include <apt-pkg/debindexfile.h>
#include <apt-pkg/debmetaindex.h>
#include <apt-pkg/error.h>
#include <apt-pkg/init.h>
#include <apt-pkg/sourcelist.h>
#include <apt-pkg/sptr.h>
#include <apt-pkg/strutl.h>
+#include <apt-pkg/tagfile.h>
#include <apr-1/apr_pools.h>
}
public:
+ _finline _H(const This_ &rhs) :
+ value_(rhs.value_ == nil ? nil : [rhs.value_ retain])
+ {
+ }
+
_finline _H(Type_ *value = NULL, bool mended = false) :
value_(value)
{
Clear_();
}
+ _finline operator Type_ *() const {
+ return value_;
+ }
+
_finline This_ &operator =(Type_ *value) {
if (value_ != value) {
- Clear_();
+ Type_ *old(value_);
value_ = value;
Retain_();
- } return this;
+ if (old != nil)
+ [old release];
+ } return *this;
}
};
/* }}} */
/* 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;
/* 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__
#define lprintf(args...) fprintf(stderr, args)
-#define ForRelease 0
+#define ForRelease 1
+#define TraceLogging (1 && !ForRelease)
+#define HistogramInsertionSort (0 && !ForRelease)
+#define ProfileTimes (0 && !ForRelease)
#define ForSaurik (0 && !ForRelease)
#define LogBrowser (1 && !ForRelease)
+#define TrackResize (0 && !ForRelease)
#define ManualRefresh (1 && !ForRelease)
#define ShowInternals (0 && !ForRelease)
#define IgnoreInstall (0 && !ForRelease)
#define RecycleWebViews 0
#define AlwaysReload (1 && !ForRelease)
-#if ForRelease
+#if !TraceLogging
#undef _trace
#define _trace(args...)
+#endif
+
+#if !ProfileTimes
#undef _profile
#define _profile(name) {
#undef _end
#endif
/* Radix Sort {{{ */
+typedef uint32_t (*SKRadixFunction)(id, void *);
+
@interface NSMutableArray (Radix)
- (void) radixSortUsingSelector:(SEL)selector withObject:(id)object;
-- (void) radixSortUsingFunction:(uint32_t (*)(id, void *))function withArgument:(void *)argument;
+- (void) radixSortUsingFunction:(SKRadixFunction)function withContext:(void *)argument;
@end
struct RadixItem_ {
@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<uint32_t (*)(id, SEL, id)>(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) {
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);
}
-- (void) radixSortUsingFunction:(uint32_t (*)(id, void *))function withArgument:(void *)argument {
+- (void) radixSortUsingFunction:(SKRadixFunction)function withContext:(void *)argument {
size_t count([self count]);
struct RadixItem_ *swap(new RadixItem_[count * 2]);
}
@end
+/* }}} */
+/* Insertion Sort {{{ */
+
+CFIndex SKBSearch_(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;
+}
+
+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);
+
+#if HistogramInsertionSort
+ uint32_t total(0), *offsets(new uint32_t[range.length]);
+#endif
+
+ for (CFIndex index(1); index != range.length; ++index) {
+ const void *value(values[index]);
+ //CFIndex correct(SKBSearch_(&value, sizeof(const void *), values, index, comparator, context));
+ CFIndex correct(index);
+ while (comparator(value, values[correct - 1], context) == kCFCompareLessThan)
+ if (--correct == 0)
+ break;
+ if (correct != index) {
+ size_t offset(index - correct);
+#if HistogramInsertionSort
+ total += offset;
+ ++offsets[offset];
+ if (offset > 10)
+ NSLog(@"Heavy Insertion Displacement: %u = %@", offset, value);
+#endif
+ memmove(values + correct + 1, values + correct, sizeof(const void *) * offset);
+ values[correct] = value;
+ }
+ }
+
+ CFArrayReplaceValues(array, range, values, range.length);
+ delete [] values;
+
+#if HistogramInsertionSort
+ for (CFIndex index(0); index != range.length; ++index)
+ if (offsets[index] != 0)
+ NSLog(@"Insertion Displacement [%u]: %u", index, offsets[index]);
+ NSLog(@"Average Insertion Displacement: %f", double(total) / range.length);
+ delete [] offsets;
+#endif
+}
+
/* }}} */
/* Apple Bug Fixes {{{ */
CFStringRef cache_;
_finline void clear_() {
- if (cache_ != nil)
+ if (cache_ != NULL) {
CFRelease(cache_);
+ cache_ = NULL;
+ }
}
public:
_finline CYString() :
data_(0),
size_(0),
- cache_(nil)
+ cache_(NULL)
{
}
else {
clear_();
- char *temp(reinterpret_cast<char *>(apr_palloc(pool, size)));
+ char *temp(reinterpret_cast<char *>(apr_palloc(pool, size + 1)));
memcpy(temp, data, size);
+ temp[size] = '\0';
data_ = temp;
size_ = size;
}
return size_ == rhs.size_ && memcmp(data_, rhs.data_, size_) == 0;
}
- operator id() {
+ operator CFStringRef() {
if (cache_ == NULL) {
if (size_ == 0)
return nil;
cache_ = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<uint8_t *>(data_), size_, kCFStringEncodingUTF8, NO, kCFAllocatorNull);
- } return (id) cache_;
+ } return cache_;
+ }
+
+ _finline operator id() {
+ return (NSString *) static_cast<CFStringRef>(*this);
}
};
static const float KeyboardTime_ = 0.3f;
#define SpringBoard_ "/System/Library/LaunchDaemons/com.apple.SpringBoard.plist"
-#define SandboxTemplate_ "/usr/share/sandbox/SandboxTemplate.sb"
#define NotifyConfig_ "/etc/notify.conf"
static bool Queuing_;
static const NSString *Safari_ = nil;
CFLocaleRef Locale_;
+NSArray *Languages_;
CGColorSpaceRef space_;
bool bootstrap_;
return [NSString stringWithFormat:@"%s%.1f %s", (negative ? "-" : ""), size, powers_[power]];
}
-NSString *StripVersion(NSString *version) {
- NSRange colon = [version rangeOfString:@":"];
- if (colon.location != NSNotFound)
- version = [version substringFromIndex:(colon.location + 1)];
+static _finline CFStringRef CFCString(const char *value) {
+ return CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const uint8_t *>(value), strlen(value), kCFStringEncodingUTF8, NO, kCFAllocatorNull);
+}
+
+const char *StripVersion_(const char *version) {
+ const char *colon(strchr(version, ':'));
+ if (colon != NULL)
+ version = colon + 1;
return version;
}
+CFStringRef StripVersion(const char *version) {
+ const char *colon(strchr(version, ':'));
+ if (colon != NULL)
+ version = colon + 1;
+ return CFStringCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const uint8_t *>(version), strlen(version), kCFStringEncodingUTF8, NO);
+ // XXX: performance
+ return CFCString(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) {
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]);
/* }}} */
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];
}
/* }}} */
/* Database Interface {{{ */
+typedef std::map< unsigned long, _H<Source> > SourceMap;
+
@interface Database : NSObject {
NSZone *zone_;
apr_pool_t *pool_;
SPtr<pkgPackageManager> manager_;
pkgSourceList *list_;
- NSMutableDictionary *sources_;
+ SourceMap sources_;
NSMutableArray *packages_;
_transient NSObject<ConfigurationDelegate, ProgressDelegate> *delegate_;
- (void) upgrade;
- (void) update;
-- (void) updateWithStatus:(Status &)status;
+- (NSString *) updateWithStatus:(Status &)status;
- (void) setDelegate:(id)delegate;
-- (Source *) getSource:(const pkgCache::PkgFileIterator &)file;
+- (Source *) getSource:(pkgCache::PkgFileIterator)file;
@end
/* }}} */
/* Source Class {{{ */
@interface Source : NSObject {
- NSString *description_;
- NSString *label_;
- NSString *origin_;
- NSString *support_;
+ CYString depiction_;
+ CYString description_;
+ CYString label_;
+ CYString origin_;
+ CYString support_;
- NSString *uri_;
- NSString *distribution_;
- NSString *type_;
- NSString *version_;
+ CYString uri_;
+ CYString distribution_;
+ CYString type_;
+ CYString version_;
- NSString *defaultIcon_;
+ NSString *host_;
+
+ CYString defaultIcon_;
NSDictionary *record_;
BOOL trusted_;
}
-- (Source *) initWithMetaIndex:(metaIndex *)index;
+- (Source *) initWithMetaIndex:(metaIndex *)index inPool:(apr_pool_t *)pool;
- (NSComparisonResult) compareByNameAndType:(Source *)source;
+- (NSString *) depictionForPackage:(NSString *)package;
- (NSString *) supportForPackage:(NSString *)package;
- (NSDictionary *) record;
@implementation Source
-#define _clear(field) \
- if (field != nil) \
- [field release]; \
- field = nil;
-
- (void) _clear {
- _clear(uri_)
- _clear(distribution_)
- _clear(type_)
+ uri_.clear();
+ distribution_.clear();
+ type_.clear();
- _clear(description_)
- _clear(label_)
- _clear(origin_)
- _clear(support_)
- _clear(version_)
- _clear(defaultIcon_)
- _clear(record_)
+ description_.clear();
+ label_.clear();
+ origin_.clear();
+ depiction_.clear();
+ support_.clear();
+ version_.clear();
+ defaultIcon_.clear();
+
+ if (record_ != nil) {
+ [record_ release];
+ record_ = nil;
+ }
+
+ if (host_ != nil) {
+ [host_ release];
+ host_ = nil;
+ }
}
- (void) dealloc {
return ![[self _attributeKeys] containsObject:[NSString stringWithUTF8String:name]] && [super isKeyExcludedFromWebScript:name];
}
-- (void) setMetaIndex:(metaIndex *)index {
+- (void) setMetaIndex:(metaIndex *)index inPool:(apr_pool_t *)pool {
[self _clear];
trusted_ = index->IsTrusted();
- uri_ = [[NSString stringWithUTF8String:index->GetURI().c_str()] retain];
- distribution_ = [[NSString stringWithUTF8String:index->GetDist().c_str()] retain];
- type_ = [[NSString stringWithUTF8String:index->GetType()] retain];
+ uri_.set(pool, index->GetURI());
+ distribution_.set(pool, index->GetDist());
+ type_.set(pool, index->GetType());
debReleaseIndex *dindex(dynamic_cast<debReleaseIndex *>(index));
if (dindex != NULL) {
- std::ifstream release(dindex->MetaIndexFile("Release").c_str());
- std::string line;
- while (std::getline(release, line)) {
- std::string::size_type colon(line.find(':'));
- if (colon == std::string::npos)
- continue;
-
- std::string name(line.substr(0, colon));
- std::string value(line.substr(colon + 1));
- while (!value.empty() && value[0] == ' ')
- value = value.substr(1);
-
- if (name == "Default-Icon")
- defaultIcon_ = [[NSString stringWithUTF8String:value.c_str()] retain];
- else if (name == "Description")
- description_ = [[NSString stringWithUTF8String:value.c_str()] retain];
- else if (name == "Label")
- label_ = [[NSString stringWithUTF8String:value.c_str()] retain];
- else if (name == "Origin")
- origin_ = [[NSString stringWithUTF8String:value.c_str()] retain];
- else if (name == "Support")
- support_ = [[NSString stringWithUTF8String:value.c_str()] retain];
- else if (name == "Version")
- version_ = [[NSString stringWithUTF8String:value.c_str()] retain];
+ FileFd fd;
+ if (!fd.Open(dindex->MetaIndexFile("Release"), FileFd::ReadOnly))
+ _error->Discard();
+ else {
+ pkgTagFile tags(&fd);
+
+ pkgTagSection section;
+ tags.Step(section);
+
+ struct {
+ const char *name_;
+ CYString *value_;
+ } names[] = {
+ {"default-icon", &defaultIcon_},
+ {"depiction", &depiction_},
+ {"description", &description_},
+ {"label", &label_},
+ {"origin", &origin_},
+ {"support", &support_},
+ {"version", &version_},
+ };
+
+ for (size_t i(0); i != sizeof(names) / sizeof(names[0]); ++i) {
+ const char *start, *end;
+
+ if (section.Find(names[i].name_, start, end)) {
+ CYString &value(*names[i].value_);
+ value.set(pool, start, end - start);
+ }
+ }
}
}
record_ = [Sources_ objectForKey:[self key]];
if (record_ != nil)
record_ = [record_ retain];
+
+ host_ = [[[[NSURL URLWithString:uri_] host] lowercaseString] retain];
}
-- (Source *) initWithMetaIndex:(metaIndex *)index {
+- (Source *) initWithMetaIndex:(metaIndex *)index inPool:(apr_pool_t *)pool {
if ((self = [super init]) != nil) {
- [self setMetaIndex:index];
+ [self setMetaIndex:index inPool:pool];
} return self;
}
return [lhs compare:rhs options:LaxCompareOptions_];
}
+- (NSString *) depictionForPackage:(NSString *)package {
+ return depiction_.empty() ? nil : [depiction_ stringByReplacingOccurrencesOfString:@"*" withString:package];
+}
+
- (NSString *) supportForPackage:(NSString *)package {
- return support_ == nil ? nil : [support_ stringByReplacingOccurrencesOfString:@"*" withString:package];
+ return support_.empty() ? nil : [support_ stringByReplacingOccurrencesOfString:@"*" withString:package];
}
- (NSDictionary *) record {
}
- (NSString *) key {
- return [NSString stringWithFormat:@"%@:%@:%@", type_, uri_, distribution_];
+ return [NSString stringWithFormat:@"%@:%@:%@", (NSString *) type_, (NSString *) uri_, (NSString *) distribution_];
}
- (NSString *) host {
- return [[[NSURL URLWithString:[self uri]] host] lowercaseString];
+ return host_;
}
- (NSString *) name {
- return origin_ == nil ? [self host] : origin_;
+ return origin_.empty() ? host_ : origin_;
}
- (NSString *) description {
}
- (NSString *) label {
- return label_ == nil ? [self host] : label_;
+ return label_.empty() ? host_ : label_;
}
- (NSString *) origin {
/* Package Class {{{ */
@interface Package : NSObject {
unsigned era_;
+ apr_pool_t *pool_;
+ pkgCache::VerIterator version_;
pkgCache::PkgIterator iterator_;
_transient Database *database_;
- pkgCache::VerIterator version_;
pkgCache::VerFileIterator file_;
Source *source_;
bool cached_;
+ bool parsed_;
CYString section_;
NSString *section$_;
bool essential_;
+ bool visible_;
NSString *latest_;
- NSString *installed_;
+ CYString installed_;
- NSString *id_;
+ CYString id_;
CYString name_;
CYString tagline_;
CYString icon_;
Address *author$_;
CYString support_;
- NSArray *tags_;
+ NSMutableArray *tags_;
NSString *role_;
NSArray *relationships_;
+
NSMutableDictionary *metadata_;
+ _transient NSDate *firstSeen_;
+ _transient NSDate *lastSeen_;
+ bool subscribed_;
}
-- (Package *) initWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database;
+- (Package *) initWithVersion:(pkgCache::VerIterator)version withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database;
+ (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database;
- (pkgCache::PkgIterator) iterator;
+- (void) parse;
- (NSString *) section;
- (NSString *) simpleSection;
- (Address *) maintainer;
- (size_t) size;
-- (NSString *) description;
+- (NSString *) longDescription;
+- (NSString *) shortDescription;
- (unichar) index;
- (NSMutableDictionary *) metadata;
- (NSString *) latest;
- (NSString *) installed;
+- (BOOL) uninstalled;
- (BOOL) valid;
- (BOOL) upgradableAndEssential:(BOOL)essential;
- (NSString *) id;
- (NSString *) name;
-- (NSString *) tagline;
- (UIImage *) icon;
- (NSString *) homepage;
- (NSString *) depiction;
- (NSArray *) purposes;
- (bool) isCommercial;
-- (uint32_t) compareByPrefix;
-- (NSComparisonResult) compareByName:(Package *)package;
+- (CYString &) cyname;
+
- (uint32_t) compareBySection:(NSArray *)sections;
- (uint32_t) compareForChanges;
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<size_t>(context));
+ CYString &name([self cyname]);
+
+ size_t size(name.size());
+ if (size == 0)
+ return 0;
+ char *text(name.data());
+
+ size_t zeros;
+ if (!isdigit(text[0]))
+ zeros = 0;
+ else {
+ size_t digits(1);
+ while (size != digits && isdigit(text[digits]))
+ if (++digits == 4)
+ break;
+ zeros = 4 - digits;
+ }
+
+ uint8_t data[4];
+
+ // 0.607997
+
+ if (offset == 0 && zeros != 0) {
+ memset(data, '0', zeros);
+ memcpy(data + zeros, text, 4 - zeros);
+ } else {
+ /* XXX: there's some danger here if you request a non-zero offset < 4 and it gets zero padded */
+ if (size <= offset - zeros)
+ return 0;
+
+ text += offset - zeros;
+ size -= offset - zeros;
+
+ if (size >= 4)
+ memcpy(data, text, 4);
+ else {
+ memcpy(data, text, size);
+ memset(data + size, 0, 4 - size);
+ }
+
+ for (size_t i(0); i != 4; ++i)
+ if (isalpha(data[i]))
+ data[i] &= 0xdf;
+ }
+
+ if (offset == 0)
+ data[0] = (data[0] & 0x3f) | "\x80\x00\xc0\x40"[data[0] >> 6];
+
+ /* XXX: ntohl may be more honest */
+ return OSSwapInt32(*reinterpret_cast<uint32_t *>(data));
+}
+
+CYString &(*PackageName)(Package *self, SEL sel);
+
+CFComparisonResult PackageNameCompare(Package *lhs, Package *rhs, void *arg) {
+ _profile(PackageNameCompare)
+ CYString &lhi(PackageName(lhs, @selector(cyname)));
+ CYString &rhi(PackageName(rhs, @selector(cyname)));
+ CFStringRef lhn(lhi), rhn(rhi);
+
+ _profile(PackageNameCompare$NumbersLast)
+ if (!lhi.empty() && !rhi.empty()) {
+ 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
+
+ CFIndex length = CFStringGetLength(lhn);
+
+ _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<Package *, Package *, bool>
+{
+ _finline bool operator ()(Package *lhs, Package *rhs) const {
+ return PackageNameCompare(lhs, rhs, NULL) == NSOrderedAscending;
+ }
+};
+
@implementation Package
+- (NSString *) description {
+ return [NSString stringWithFormat:@"<Package:%@>", static_cast<NSString *>(name_)];
+}
+
- (void) dealloc {
if (source_ != nil)
[source_ release];
if (section$_ != nil)
[section$_ release];
- [latest_ release];
- if (installed_ != nil)
- [installed_ release];
+ if (latest_ != nil)
+ [latest_ release];
- [id_ release];
if (sponsor$_ != nil)
[sponsor$_ release];
if (author$_ != nil)
}
+ (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 {
return ![[self _attributeKeys] containsObject:[NSString stringWithUTF8String:name]] && [super isKeyExcludedFromWebScript:name];
}
-- (Package *) initWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database {
- if ((self = [super init]) != nil) {
- _profile(Package$initWithIterator)
- @synchronized (database) {
- era_ = [database era];
+- (void) parse {
+ if (parsed_)
+ return;
+ parsed_ = true;
+ if (file_.end())
+ return;
- iterator_ = iterator;
- database_ = database;
+ _profile(Package$parse)
+ pkgRecords::Parser *parser;
- _profile(Package$initWithIterator$Control)
+ _profile(Package$parse$Lookup)
+ parser = &[database_ records]->Lookup(file_);
_end
- _profile(Package$initWithIterator$Version)
- version_ = [database_ policy]->GetCandidateVer(iterator_);
+ CYString website;
+
+ _profile(Package$parse$Find)
+ struct {
+ const char *name_;
+ CYString *value_;
+ } names[] = {
+ {"icon", &icon_},
+ {"depiction", &depiction_},
+ {"homepage", &homepage_},
+ {"website", &website},
+ {"support", &support_},
+ {"sponsor", &sponsor_},
+ {"author", &author_},
+ };
+
+ 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$parse$Value)
+ value.set(pool_, start, end - start);
+ _end
+ }
+ }
_end
- NSString *latest = version_.end() ? nil : [NSString stringWithUTF8String:version_.VerStr()];
+ _profile(Package$parse$Tagline)
+ const char *start, *end;
+ if (parser->ShortDesc(start, end)) {
+ const char *stop(reinterpret_cast<const char *>(memchr(start, '\n', end - start)));
+ if (stop == NULL)
+ stop = end;
+ while (stop != start && stop[-1] == '\r')
+ --stop;
+ tagline_.set(pool_, start, stop - start);
+ }
+ _end
- _profile(Package$initWithIterator$Latest)
- latest_ = latest == nil ? nil : [StripVersion(latest) retain];
+ _profile(Package$parse$Retain)
+ if (!homepage_.empty())
+ homepage_ = website;
+ if (homepage_ == depiction_)
+ homepage_.clear();
_end
+ _end
+}
- pkgCache::VerIterator current;
- NSString *installed;
+- (Package *) initWithVersion:(pkgCache::VerIterator)version withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database {
+ if ((self = [super init]) != nil) {
+ _profile(Package$initWithVersion)
+ @synchronized (database) {
+ era_ = [database era];
+ pool_ = pool;
- _profile(Package$initWithIterator$Current)
- current = iterator_.CurrentVer();
- installed = current.end() ? nil : [NSString stringWithUTF8String:current.VerStr()];
- _end
+ version_ = version;
+ iterator_ = version.ParentPkg();
+ database_ = database;
- _profile(Package$initWithIterator$Installed)
- installed_ = [StripVersion(installed) retain];
+ _profile(Package$initWithVersion$Latest)
+ latest_ = (NSString *) StripVersion(version_.VerStr());
_end
- _profile(Package$initWithIterator$File)
+ pkgCache::VerIterator current;
+ _profile(Package$initWithVersion$Versions)
+ current = iterator_.CurrentVer();
+ if (!current.end())
+ installed_.set(pool_, StripVersion_(current.VerStr()));
+
if (!version_.end())
file_ = version_.FileList();
else {
}
_end
- _profile(Package$initWithIterator$Name)
- id_ = [[NSString stringWithUTF8String:iterator_.Name()] retain];
+ _profile(Package$initWithVersion$Name)
+ id_.set(pool_, iterator_.Name());
+ name_.set(pool, iterator_.Display());
_end
- if (!file_.end())
- _profile(Package$initWithIterator$Parse)
- pkgRecords::Parser *parser;
-
- _profile(Package$initWithIterator$Parse$Lookup)
- 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<char *>(memchr(begin + 1, '\n', end - begin - 1));
- if (begin == NULL)
- break;
- } else if (const char *colon = static_cast<char *>(memchr(begin, ':', end - begin))) {
- const char *name(begin);
- size_t size(colon - begin);
-
- begin = static_cast<char *>(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$initWithIterator$Parse$Value)
- value.set(pool, colon, stop - colon);
- _end
-
- break;
- }
- }
-
- if (begin == NULL)
- break;
- ++begin;
- } else goto next;
-
- _profile(Package$initWithIterator$Parse$Tagline)
- tagline_.set(pool, parser->ShortDesc());
- _end
-
- _profile(Package$initWithIterator$Parse$Retain)
- if (!homepage_.empty())
- homepage_ = website;
- if (homepage_ == depiction_)
- homepage_.clear();
- if (!tag.empty())
- tags_ = [[tag componentsSeparatedByString:@", "] retain];
- _end
+ if (!file_.end()) {
+ _profile(Package$initWithVersion$Source)
+ source_ = [database_ getSource:file_.File()];
+ if (source_ != nil)
+ [source_ retain];
+ cached_ = true;
_end
+ }
- _profile(Package$initWithIterator$Tags)
- if (tags_ != nil)
- for (NSString *tag in tags_)
- if ([tag hasPrefix:@"role::"]) {
- role_ = [[tag substringFromIndex:6] retain];
- break;
- }
+ visible_ = true;
+
+ _profile(Package$initWithVersion$Tags)
+ pkgCache::TagIterator tag(iterator_.TagList());
+ if (!tag.end()) {
+ tags_ = [[NSMutableArray alloc] initWithCapacity:8];
+ do {
+ const char *name(tag.Name());
+ [tags_ addObject:(NSString *)CFCString(name)];
+ if (role_ == nil && strncmp(name, "role::", 6) == 0 /*&& strcmp(name, "role::leaper") != 0*/)
+ role_ = (NSString *) CFCString(name + 6);
+ if (visible_ && strncmp(name, "require::", 9) == 0 && (
+ true
+ ))
+ visible_ = false;
+ ++tag;
+ } while (!tag.end());
+ }
_end
- NSString *solid(latest == nil ? installed : latest);
bool changed(false);
-
NSString *key([id_ lowercaseString]);
- _profile(Package$initWithIterator$Metadata)
+ _profile(Package$initWithVersion$Metadata)
metadata_ = [Packages_ objectForKey:key];
+
if (metadata_ == nil) {
+ firstSeen_ = now_;
+
metadata_ = [[NSMutableDictionary dictionaryWithObjectsAndKeys:
- now_, @"FirstSeen",
+ firstSeen_, @"FirstSeen",
+ latest_, @"LastVersion",
nil] mutableCopy];
- if (solid != nil)
- [metadata_ setObject:solid 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;
}
- if (solid != nil)
- if (version == nil) {
- [metadata_ setObject:solid forKey:@"LastVersion"];
- changed = true;
- } else if (![version isEqualToString:solid]) {
- [metadata_ setObject:solid forKey:@"LastVersion"];
- last = now_;
- [metadata_ setObject:last forKey:@"LastSeen"];
- changed = true;
- }
+ if (version == nil) {
+ [metadata_ setObject:latest_ forKey:@"LastVersion"];
+ changed = true;
+ } else {
+ if (![version isEqualToString:latest_]) {
+ [metadata_ setObject:latest_ forKey:@"LastVersion"];
+ lastSeen_ = now_;
+ [metadata_ setObject:lastSeen_ forKey:@"LastSeen"];
+ changed = true;
+ } }
}
metadata_ = [metadata_ retain];
}
_end
- _profile(Package$initWithIterator$Section)
- section_.set(pool, iterator_.Section());
+ _profile(Package$initWithVersion$Section)
+ section_.set(pool_, iterator_.Section());
_end
essential_ = ((iterator_->Flags & pkgCache::Flag::Essential) == 0 ? NO : YES) || [self hasTag:@"cydia::essential"];
+ visible_ = 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;
+
+ _profile(Package$packageWithIterator$GetCandidateVer)
+ version = [database policy]->GetCandidateVer(iterator);
+ _end
+
+ if (version.end())
+ return nil;
+
return [[[Package alloc]
- initWithIterator:iterator
+ initWithVersion:version
withZone:zone
inPool:pool
database:database
}
- (NSString *) longSection {
- return LocalizeSection(section_);
+ return LocalizeSection([self section]);
}
- (NSString *) shortSection {
return version_.end() ? 0 : version_->InstalledSize;
}
-- (NSString *) description {
+- (NSString *) longDescription {
if (file_.end())
return nil;
pkgRecords::Parser *parser = &[database_ records]->Lookup(file_);
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 {
return installed_;
}
+- (BOOL) uninstalled {
+ return installed_.empty();
+}
+
- (BOOL) valid {
return !version_.end();
}
- (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 {
}
- (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;
}
}
- (NSString *) name {
- return name_ == nil ? id_ : name_;
-}
-
-- (NSString *) tagline {
- return tagline_;
+ return name_.empty() ? id_ : name_;
}
- (UIImage *) icon {
NSString *section = [self simpleSection];
UIImage *icon(nil);
- if (icon_ != nil)
+ if (!icon_.empty())
if ([icon_ hasPrefix:@"file:///"])
icon = [UIImage imageAtPath:[icon_ substringFromIndex:7]];
if (icon == nil) if (section != nil)
}
- (NSString *) depiction {
- return depiction_;
+ return !depiction_.empty() ? depiction_ : [[self source] depictionForPackage:id_];
}
- (Address *) sponsor {
}
- (NSString *) support {
- return support_ != nil ? support_ : [[self source] supportForPackage:id_];
+ return !support_.empty() ? support_ : [[self source] supportForPackage:id_];
}
- (NSArray *) files {
- NSString *path = [NSString stringWithFormat:@"/var/lib/dpkg/info/%@.list", id_];
+ NSString *path = [NSString stringWithFormat:@"/var/lib/dpkg/info/%@.list", static_cast<NSString *>(id_)];
NSMutableArray *files = [NSMutableArray arrayWithCapacity:128];
std::ifstream fin;
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;
return [self hasTag:@"cydia::commercial"];
}
-- (uint32_t) compareByPrefix {
- return 0;
-}
-
-- (NSComparisonResult) compareByName:(Package *)package {
- NSString *lhs = [self name];
- NSString *rhs = [package name];
-
- /*if ([lhs length] != 0 && [rhs length] != 0) {
- unichar lhc = [lhs characterAtIndex:0];
- unichar rhc = [rhs characterAtIndex:0];
-
- if (isalpha(lhc) && !isalpha(rhc))
- return NSOrderedAscending;
- else if (!isalpha(lhc) && isalpha(rhc))
- return NSOrderedDescending;
- }
-
- return [lhs compare:rhs options:LaxCompareOptions_];*/
-
- return [lhs compare:rhs];
+- (CYString &) cyname {
+ return name_.empty() ? id_ : name_;
}
- (uint32_t) compareBySection:(NSArray *)sections {
}
- (bool) isInstalledAndVisible:(NSNumber *)number {
- return (![number boolValue] || [self visible]) && [self installed] != nil;
+ return (![number boolValue] || [self visible]) && ![self uninstalled];
}
- (bool) isVisiblyUninstalledInSection:(NSString *)name {
return
[self visible] &&
- [self installed] == nil && (
+ [self uninstalled] && (
name == nil ||
section == nil && [name length] == 0 ||
[name isEqualToString:section]
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;
- (void) addToCount;
- (void) setCount:(size_t)count;
+- (NSString *) localized;
@end
[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];
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;
}
zone_ = NSCreateZone(1024 * 1024, 256 * 1024, NO);
apr_pool_create(&pool_, NULL);
- sources_ = [[NSMutableDictionary dictionaryWithCapacity:16] retain];
- packages_ = [[NSMutableArray arrayWithCapacity:16] retain];
+ packages_ = [[NSMutableArray alloc] init];
int fds[2];
}
- (NSArray *) sources {
- return [sources_ allValues];
+ NSMutableArray *sources([NSMutableArray arrayWithCapacity:sources_.size()]);
+ for (SourceMap::const_iterator i(sources_.begin()); i != sources_.end(); ++i)
+ [sources addObject:i->second];
+ return sources;
}
- (NSArray *) issues {
++era_;
}
+ [packages_ removeAllObjects];
+ sources_.clear();
+
_error->Discard();
delete list_;
delete policy_;
policy_ = NULL;
+ if (now_ != nil) {
+ [now_ release];
+ now_ = nil;
+ }
+
cache_.Close();
apr_pool_clear(pool_);
NSRecycleZone(zone_);
+ int chk(creat("/tmp/cydia.chk", 0644));
+ if (chk != -1)
+ close(chk);
+
_trace();
if (!cache_.Open(progress_, true)) {
std::string error;
}
_trace();
+ unlink("/tmp/cydia.chk");
+
now_ = [[NSDate date] retain];
policy_ = new pkgDepCache::Policy();
_assert(pkgMinimizeUpgrade(cache_));
}
- [sources_ removeAllObjects];
+ _trace();
+
for (pkgSourceList::const_iterator source = list_->begin(); source != list_->end(); ++source) {
std::vector<pkgIndexFile *> *indices = (*source)->GetIndexFiles();
for (std::vector<pkgIndexFile *>::const_iterator index = indices->begin(); index != indices->end(); ++index)
- [sources_
- setObject:[[[Source alloc] initWithMetaIndex:*source] autorelease]
- forKey:[NSNumber numberWithLong:reinterpret_cast<uintptr_t>(*index)]
- ];
+ // XXX: this could be more intelligent
+ if (dynamic_cast<debPackagesIndex *>(*index) != NULL) {
+ pkgCache::PkgFileIterator cached((*index)->FindInCache(cache_));
+ if (!cached.end())
+ sources_[cached->ID] = [[[Source alloc] initWithMetaIndex:*source inPool:pool_] autorelease];
+ }
}
- [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();
- _config->Set("Acquire::http::Timeout", 15);
- _config->Set("Acquire::http::MaxParallel", 4);
+ {
+ /*std::vector<Package *> packages;
+ packages.reserve(std::max(10000U, [packages_ count] + 1000));
+ [packages_ release];
+ packages_ = nil;*/
+
+ _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_ radixSortUsingFunction:reinterpret_cast<SKRadixFunction>(&PackagePrefixRadix) withContext:reinterpret_cast<void *>(16)];
+ [packages_ radixSortUsingFunction:reinterpret_cast<SKRadixFunction>(&PackagePrefixRadix) withContext:reinterpret_cast<void *>(4)];
+ [packages_ radixSortUsingFunction:reinterpret_cast<SKRadixFunction>(&PackagePrefixRadix) withContext:reinterpret_cast<void *>(0)];
+
+ /*_trace();
+ PrintTimes();
+ _trace();*/
+
+ _trace();
+
+ /*if (!packages.empty())
+ CFQSortArray(&packages.front(), packages.size(), sizeof(packages.front()), reinterpret_cast<CFComparatorFunction>(&PackageNameCompare_), NULL);*/
+ //std::sort(packages.begin(), packages.end(), PackageNameOrdering());
+
+ //CFArraySortValues((CFMutableArrayRef) packages_, CFRangeMake(0, [packages_ count]), reinterpret_cast<CFComparatorFunction>(&PackageNameCompare), NULL);
+
+ CFArrayInsertionSortValues((CFMutableArrayRef) packages_, CFRangeMake(0, [packages_ count]), reinterpret_cast<CFComparatorFunction>(&PackageNameCompare), NULL);
+
+ //[packages_ sortUsingFunction:reinterpret_cast<NSComparisonResult (*)(id, id, void *)>(&PackageNameCompare) context:NULL];
+
+ _trace();
+ }
}
- (void) configure {
for (pkgAcquire::ItemIterator item = fetcher_->ItemsBegin(); item != fetcher_->ItemsEnd(); item++) {
if ((*item)->Status == pkgAcquire::Item::StatDone && (*item)->Complete)
continue;
+ if ((*item)->Status == pkgAcquire::Item::StatIdle)
+ continue;
std::string uri = (*item)->DescURI();
std::string error = (*item)->ErrorText;
[self updateWithStatus:status_];
}
-- (void) updateWithStatus:(Status &)status {
+- (NSString *) updateWithStatus:(Status &)status {
pkgSourceList list;
_assert(list.ReadMainList());
FileFd lock;
lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
- _assert(!_error->PendingError());
+
+ if (_error->PendingError()) {
+ std::string error;
+ if (!_error->PopMessage(error))
+ _assert(false);
+ _error->Discard();
+ return [NSString stringWithUTF8String:error.c_str()];
+ }
pkgAcquire fetcher(&status);
_assert(list.GetIndexes(&fetcher));
[Metadata_ setObject:[NSDate date] forKey:@"LastUpdate"];
Changed_ = true;
}
+
+ return nil;
}
- (void) setDelegate:(id)delegate {
progress_.setDelegate(delegate);
}
-- (Source *) getSource:(const pkgCache::PkgFileIterator &)file {
- pkgIndexFile *index(NULL);
- list_->FindIndex(file, index);
- return [sources_ objectForKey:[NSNumber numberWithLong:reinterpret_cast<uintptr_t>(index)]];
+- (Source *) getSource:(pkgCache::PkgFileIterator)file {
+ SourceMap::const_iterator i(sources_.find(file->ID));
+ return i == sources_.end() ? nil : i->second;
}
@end
[transition_ transition:6 toView:view_];
}
-- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
- NSString *context([sheet context]);
-
- if ([context isEqualToString:@"error"])
- [sheet dismiss];
- else if ([context isEqualToString:@"conffile"]) {
- FILE *input = [database_ input];
-
- switch (button) {
- case 1:
- fprintf(input, "N\n");
- fflush(input);
- break;
- case 2:
- fprintf(input, "Y\n");
- fflush(input);
- break;
- default:
- _assert(false);
- }
-
- [sheet dismiss];
- }
-}
-
-- (void) closeButtonPushed {
- running_ = NO;
-
- switch (Finish_) {
- case 0:
- [self resetView];
- break;
-
- case 1:
- [delegate_ suspendWithAnimation:YES];
- break;
+- (void) _checkError {
+ if (_error->PendingError()) {
+ std::string error;
+ if (!_error->PopMessage(error))
+ _assert(false);
- case 2:
- system("launchctl stop com.apple.SpringBoard");
- break;
+ UIActionSheet *sheet = [[[UIActionSheet alloc]
+ initWithTitle:CYLocalize("ERROR")
+ buttons:[NSArray arrayWithObjects:CYLocalize("OKAY"), nil]
+ defaultButtonIndex:0
+ delegate:self
+ context:@"_error"
+ ] autorelease];
- case 3:
- system("launchctl unload "SpringBoard_"; launchctl load "SpringBoard_);
- break;
+ [sheet setBodyText:[NSString stringWithUTF8String:error.c_str()]];
+ [sheet popupAlertAnimated:YES];
- case 4:
- system("reboot");
- break;
+ return;
}
-}
-
-- (void) _retachThread {
- UINavigationItem *item = [navbar_ topItem];
- [item setTitle:CYLocalize("COMPLETE")];
-
- [overlay_ addSubview:close_];
- [progress_ removeFromSuperview];
- [status_ removeFromSuperview];
[delegate_ progressViewIsComplete:self];
if (Finish_ < 4) {
- FileFd file(SandboxTemplate_, FileFd::ReadOnly);
- MMap mmap(file, MMap::ReadOnly);
- SHA1Summation sha1;
- sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
- if (!(sandplate_ == sha1.Result()))
- Finish_ = 4;
- }
-
- if (Finish_ < 4) {
- FileFd file(NotifyConfig_, FileFd::ReadOnly);
- MMap mmap(file, MMap::ReadOnly);
- SHA1Summation sha1;
- sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
- if (!(notifyconf_ == sha1.Result()))
- Finish_ = 4;
+ FileFd file;
+ if (!file.Open(NotifyConfig_, FileFd::ReadOnly))
+ _error->Discard();
+ else {
+ MMap mmap(file, MMap::ReadOnly);
+ SHA1Summation sha1;
+ sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
+ if (!(notifyconf_ == sha1.Result()))
+ Finish_ = 4;
+ }
}
if (Finish_ < 3) {
- FileFd file(SpringBoard_, FileFd::ReadOnly);
- MMap mmap(file, MMap::ReadOnly);
- SHA1Summation sha1;
- sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
- if (!(springlist_ == sha1.Result()))
- Finish_ = 3;
+ FileFd file;
+ if (!file.Open(SpringBoard_, FileFd::ReadOnly))
+ _error->Discard();
+ else {
+ MMap mmap(file, MMap::ReadOnly);
+ SHA1Summation sha1;
+ sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
+ if (!(springlist_ == sha1.Result()))
+ Finish_ = 3;
+ }
}
switch (Finish_) {
[delegate_ setStatusBarShowsProgress:NO];
}
+- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
+ NSString *context([sheet context]);
+
+ if ([context isEqualToString:@"error"])
+ [sheet dismiss];
+ else if ([context isEqualToString:@"_error"]) {
+ [sheet dismiss];
+ [self _checkError];
+ } else if ([context isEqualToString:@"conffile"]) {
+ FILE *input = [database_ input];
+
+ switch (button) {
+ case 1:
+ fprintf(input, "N\n");
+ fflush(input);
+ break;
+ case 2:
+ fprintf(input, "Y\n");
+ fflush(input);
+ break;
+ default:
+ _assert(false);
+ }
+
+ [sheet dismiss];
+ }
+}
+
+- (void) closeButtonPushed {
+ running_ = NO;
+
+ switch (Finish_) {
+ case 0:
+ [self resetView];
+ break;
+
+ case 1:
+ [delegate_ suspendWithAnimation:YES];
+ break;
+
+ case 2:
+ system("launchctl stop com.apple.SpringBoard");
+ break;
+
+ case 3:
+ system("launchctl unload "SpringBoard_"; launchctl load "SpringBoard_);
+ break;
+
+ case 4:
+ system("reboot");
+ break;
+ }
+}
+
+- (void) _retachThread {
+ UINavigationItem *item = [navbar_ topItem];
+ [item setTitle:CYLocalize("COMPLETE")];
+
+ [overlay_ addSubview:close_];
+ [progress_ removeFromSuperview];
+ [status_ removeFromSuperview];
+
+ [self _checkError];
+}
+
- (void) _detachNewThreadData:(ProgressData *)data { _pooled
[[data target] performSelector:[data selector] withObject:[data object]];
[data release];
running_ = YES;
{
- FileFd file(SandboxTemplate_, FileFd::ReadOnly);
- MMap mmap(file, MMap::ReadOnly);
- SHA1Summation sha1;
- sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
- sandplate_ = sha1.Result();
- }
-
- {
- FileFd file(NotifyConfig_, FileFd::ReadOnly);
- MMap mmap(file, MMap::ReadOnly);
- SHA1Summation sha1;
- sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
- notifyconf_ = sha1.Result();
+ FileFd file;
+ if (!file.Open(NotifyConfig_, FileFd::ReadOnly))
+ _error->Discard();
+ else {
+ MMap mmap(file, MMap::ReadOnly);
+ SHA1Summation sha1;
+ sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
+ notifyconf_ = sha1.Result();
+ }
}
{
- FileFd file(SpringBoard_, FileFd::ReadOnly);
- MMap mmap(file, MMap::ReadOnly);
- SHA1Summation sha1;
- sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
- springlist_ = sha1.Result();
+ FileFd file;
+ if (!file.Open(SpringBoard_, FileFd::ReadOnly))
+ _error->Discard();
+ else {
+ MMap mmap(file, MMap::ReadOnly);
+ SHA1Summation sha1;
+ sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
+ springlist_ = sha1.Result();
+ }
}
[transition_ transition:6 toView:overlay_];
- (void) setPackage:(Package *)package {
[self clearPackage];
+ [package parse];
Source *source = [package source];
icon_ = [[package icon] retain];
name_ = [[package name] retain];
- description_ = [[package tagline] retain];
+ description_ = [[package shortDescription] retain];
commercial_ = [package isCommercial];
package_ = [package retain];
from = [NSString stringWithFormat:CYLocalize("PARENTHETICAL"), from, section];
}
- from = [NSString stringWithFormat:CYLocalize("FROM"), label];
+ from = [NSString stringWithFormat:CYLocalize("FROM"), from];
source_ = [from retain];
if (NSString *purpose = [package primaryPurpose])
}
+ (int) heightForPackage:(Package *)package {
- NSString *tagline([package tagline]);
- int height = tagline == nil || [tagline length] == 0 ? -17 : 0;
-#ifdef USE_BADGES
- if ([package hasMode] || [package half])
- return height + 96;
- else
-#endif
- return height + 73;
+ return 73;
}
@end
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];
+ name_ = [(section_ == nil || [section_ length] == 0 ? CYLocalize("NO_SECTION") : section_) retain];
count_ = [[NSString stringWithFormat:@"%d", [section count]] retain];
if (editing_)
[buttons_ removeAllObjects];
if (package != nil) {
+ [package parse];
+
package_ = [package retain];
name_ = [[package id] retain];
commercial_ = [package isCommercial];
if ([package_ source] == nil);
else if ([package_ upgradableAndEssential:NO])
[buttons_ addObject:CYLocalize("UPGRADE")];
- else if ([package_ installed] == nil)
+ else if ([package_ uninstalled])
[buttons_ addObject:CYLocalize("INSTALL")];
else
[buttons_ addObject:CYLocalize("REINSTALL")];
- if ([package_ installed] != nil)
+ if (![package_ uninstalled])
[buttons_ addObject:CYLocalize("REMOVE")];
if (special_ != NULL) {
[self setPopupHook:nil];
WebThreadUnlock();
+ //[self yieldToSelector:@selector(callFunction:) withObject:special_];
[super callFunction:special_];
}
}
/* 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);
];
}
-- (void) _update_ {
+- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
+ NSString *context([sheet context]);
+
+ if ([context isEqualToString:@"refresh"])
+ [sheet dismiss];
+}
+
+- (void) _update_:(NSString *)error {
updating_ = false;
[indicator_ stopAnimation];
[UIView commitAnimations];
- [delegate_ performSelector:@selector(reloadData) withObject:nil afterDelay:0];
+ if (error == nil)
+ [delegate_ performSelector:@selector(reloadData) withObject:nil afterDelay:0];
+ else {
+ UIActionSheet *sheet = [[[UIActionSheet alloc]
+ initWithTitle:[NSString stringWithFormat:CYLocalize("COLON_DELIMITED"), CYLocalize("ERROR"), CYLocalize("REFRESH")]
+ buttons:[NSArray arrayWithObjects:
+ CYLocalize("OK"),
+ nil]
+ defaultButtonIndex:0
+ delegate:self
+ context:@"refresh"
+ ] autorelease];
+
+ [sheet setBodyText:error];
+ [sheet popupAlertAnimated:YES];
+
+ [self reloadButtons];
+ }
}
- (id) initWithFrame:(CGRect)frame database:(Database *)database {
[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];
Status status;
status.setDelegate(self);
- [database_ updateWithStatus:status];
+ NSString *error([database_ updateWithStatus:status]);
[self
- performSelectorOnMainThread:@selector(_update_)
- withObject:nil
+ performSelectorOnMainThread:@selector(_update_:)
+ withObject:error
waitUntilDone:NO
];
}
- (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 {
return !updating_;
}
-- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
- [sheet dismiss];
-}
-
- (void) _setProgressTitle:(NSString *)title {
[prompt_ setText:title];
}
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
[*section addToCount];
_profile(SectionsView$reloadData$Filter)
- if (![package valid] || [package installed] != nil || ![package visible])
+ if (![package valid] || ![package uninstalled] || ![package visible])
continue;
_end
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
}
[section addToCount];
_profile(SectionsView$reloadData$Filter)
- if (![package valid] || [package installed] != nil || ![package visible])
+ if (![package valid] || ![package uninstalled] || ![package visible])
continue;
_end
[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];
}
}
- (NSString *) sectionList:(UISectionList *)list titleForSection:(int)section {
- NSLog(@"titleForSection:%u", section);
return [[sections_ objectAtIndex:section] name];
}
_trace();
for (Package *package in packages)
if (
- [package installed] == nil && [package valid] && [package visible] ||
+ [package uninstalled] && [package valid] && [package visible] ||
[package upgradableAndEssential:YES]
)
[packages_ addObject:package];
_trace();
- [packages_ radixSortUsingFunction:reinterpret_cast<uint32_t (*)(id, void *)>(&PackageChangesRadix) withArgument:NULL];
+ [packages_ radixSortUsingFunction:reinterpret_cast<SKRadixFunction>(&PackageChangesRadix) withContext: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;
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
}
ManageView *manage_;
SearchView *search_;
- PackageView *package_;
+ NSMutableArray *details_;
}
@end
}
- (void) setPackageView:(PackageView *)view {
- if (package_ == nil)
- package_ = [view retain];
+ WebThreadLock();
+ [view setPackage:nil];
+ if ([details_ count] < 3)
+ [details_ addObject:view];
+ WebThreadUnlock();
+}
+
+- (PackageView *) _packageView {
+ return [[[PackageView alloc] initWithBook:book_ database:database_] autorelease];
}
- (PackageView *) packageView {
PackageView *view;
+ size_t count([details_ count]);
- if (package_ == nil)
- view = [[[PackageView alloc] initWithBook:book_ database:database_] autorelease];
- else {
- return package_;
- view = [package_ autorelease];
- package_ = nil;
+ if (count == 0) {
+ view = [self _packageView];
+ renew:
+ [details_ addObject:[self _packageView]];
+ } else {
+ view = [[[details_ lastObject] retain] autorelease];
+ [details_ removeLastObject];
+ if (count == 1)
+ goto renew;
}
return view;
@"home-dn.png", kUIButtonBarButtonSelectedInfo,
[NSNumber numberWithInt:1], kUIButtonBarButtonTag,
self, kUIButtonBarButtonTarget,
- CYLocalize("HOME"), kUIButtonBarButtonTitle,
+ @"Cydia", kUIButtonBarButtonTitle,
@"0", kUIButtonBarButtonType,
nil],
withClass:[ManageView class]
] retain];
- [self setPackageView:[self packageView]];
+ details_ = [[NSMutableArray alloc] initWithCapacity:4];
+ [details_ addObject:[self _packageView]];
+ [details_ addObject:[self _packageView]];
PrintTimes();
Changed_ = true;
+ [sheet dismiss];
+
if (reset)
[self updateData];
else
[self finish];
-
- [sheet dismiss];
} else if ([context isEqualToString:@"upgrade"]) {
switch (button) {
case 1:
Font18Bold_ = [[UIFont boldSystemFontOfSize:18] retain];
Font22Bold_ = [[UIFont boldSystemFontOfSize:22] retain];
- _assert(pkgInitConfig(*_config));
- _assert(pkgInitSystem(*_config, _system));
-
tag_ = 1;
essential_ = [[NSMutableArray alloc] initWithCapacity:4];
if (
readlink("/Applications", NULL, 0) == -1 && errno == EINVAL ||
readlink("/Library/Ringtones", NULL, 0) == -1 && errno == EINVAL ||
- readlink("/Library/Wallpaper", NULL, 0) == -1 && errno == EINVAL ||
+ readlink("/Library/Wallpaper", NULL, 0) == -1 && errno == EINVAL /*||
+ readlink("/usr/bin", NULL, 0) == -1 && errno == EINVAL*/ ||
readlink("/usr/include", NULL, 0) == -1 && errno == EINVAL ||
+ readlink("/usr/lib/pam", NULL, 0) == -1 && errno == EINVAL ||
readlink("/usr/libexec", NULL, 0) == -1 && errno == EINVAL ||
readlink("/usr/share", NULL, 0) == -1 && errno == EINVAL /*||
readlink("/var/lib", NULL, 0) == -1 && errno == EINVAL*/
int main(int argc, char *argv[]) { _pooled
_trace();
- Locale_ = CFLocaleCopyCurrent();
+ PackageName = reinterpret_cast<CYString &(*)(Package *, SEL)>(method_getImplementation(class_getInstanceMethod([Package class], @selector(cyname))));
- CFStringRef locale(CFLocaleGetIdentifier(Locale_));
- setenv("LANG", [(NSString *) locale UTF8String], true);
+ /* Library Hacks {{{ */
+ class_addMethod(objc_getClass("DOMNodeList"), @selector(countByEnumeratingWithState:objects:count:), (IMP) &DOMNodeList$countByEnumeratingWithState$objects$count$, "I20@0:4^{NSFastEnumerationState}8^@12I16");
+
+ $WebDefaultUIKitDelegate = objc_getClass("WebDefaultUIKitDelegate");
+ Method UIWebDocumentView$_setUIKitDelegate$(class_getInstanceMethod([WebView class], @selector(_setUIKitDelegate:)));
+ if (UIWebDocumentView$_setUIKitDelegate$ != NULL) {
+ _UIWebDocumentView$_setUIKitDelegate$ = reinterpret_cast<void (*)(UIWebDocumentView *, SEL, id)>(method_getImplementation(UIWebDocumentView$_setUIKitDelegate$));
+ method_setImplementation(UIWebDocumentView$_setUIKitDelegate$, reinterpret_cast<IMP>(&$UIWebDocumentView$_setUIKitDelegate$));
+ }
+ /* }}} */
+ /* Set Locale {{{ */
+ Locale_ = CFLocaleCopyCurrent();
+ 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?
apr_initialize();
- class_addMethod(objc_getClass("DOMNodeList"), @selector(countByEnumeratingWithState:objects:count:), (IMP) &DOMNodeList$countByEnumeratingWithState$objects$count$, "I20@0:4^{NSFastEnumerationState}8^@12I16");
-
+ /* Parse Arguments {{{ */
bool substrate(false);
if (argc != 0) {
else
fprintf(stderr, "unknown argument: %s\n", args[argi]);
}
-
- App_ = [[NSBundle mainBundle] bundlePath];
- Home_ = NSHomeDirectory();
+ /* }}} */
{
NSString *plist = [Home_ stringByAppendingString:@"/Library/Preferences/com.apple.preferences.sounds.plist"];
Sounds_Keyboard_ = [keyboard boolValue];
}
+ App_ = [[NSBundle mainBundle] bundlePath];
+ Home_ = NSHomeDirectory();
+
setuid(0);
setgid(0);
-#if 1 /* XXX: this costs 1.4s of startup performance */
- if (unlink("/var/cache/apt/pkgcache.bin") == -1)
- _assert(errno == ENOENT);
- if (unlink("/var/cache/apt/srcpkgcache.bin") == -1)
- _assert(errno == ENOENT);
-#endif
-
- $WebDefaultUIKitDelegate = objc_getClass("WebDefaultUIKitDelegate");
- Method UIWebDocumentView$_setUIKitDelegate$(class_getInstanceMethod([WebView class], @selector(_setUIKitDelegate:)));
- if (UIWebDocumentView$_setUIKitDelegate$ != NULL) {
- _UIWebDocumentView$_setUIKitDelegate$ = reinterpret_cast<void (*)(UIWebDocumentView *, SEL, id)>(method_getImplementation(UIWebDocumentView$_setUIKitDelegate$));
- method_setImplementation(UIWebDocumentView$_setUIKitDelegate$, reinterpret_cast<IMP>(&$UIWebDocumentView$_setUIKitDelegate$));
- }
-
/*Method alloc = class_getClassMethod([NSObject class], @selector(alloc));
alloc_ = alloc->method_imp;
alloc->method_imp = (IMP) &Alloc_;*/
/*AddPreferences(@"/Applications/Preferences.app/Settings-iPhone.plist");
AddPreferences(@"/Applications/Preferences.app/Settings-iPod.plist");*/
+ /* Load Database {{{ */
_trace();
Metadata_ = [[[NSMutableDictionary alloc] initWithContentsOfFile:@"/var/lib/cydia/metadata.plist"] autorelease];
_trace();
Sources_ = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease];
[Metadata_ setObject:Sources_ forKey:@"Sources"];
}
+ /* }}} */
#if RecycleWebViews
Documents_ = [[[NSMutableArray alloc] initWithCapacity:4] autorelease];
error:NULL
]);
+ if (access("/tmp/cydia.chk", F_OK) == 0) {
+ if (unlink("/var/cache/apt/pkgcache.bin") == -1)
+ _assert(errno == ENOENT);
+ if (unlink("/var/cache/apt/srcpkgcache.bin") == -1)
+ _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();
Blue_.Set(space_, 0.2, 0.2, 1.0, 1.0);
//.93
InstallingColor_ = [UIColor colorWithRed:0.88f green:1.00f blue:0.88f alpha:1.00f];
RemovingColor_ = [UIColor colorWithRed:1.00f green:0.88f blue:0.88f alpha:1.00f];
+ /* }}}*/
Finishes_ = [NSArray arrayWithObjects:@"return", @"reopen", @"restart", @"reload", @"reboot", nil];
+ /* UIKit Configuration {{{ */
void (*$GSFontSetUseLegacyFontMetrics)(BOOL)(reinterpret_cast<void (*)(BOOL)>(dlsym(RTLD_DEFAULT, "GSFontSetUseLegacyFontMetrics")));
if ($GSFontSetUseLegacyFontMetrics != NULL)
$GSFontSetUseLegacyFontMetrics(YES);
UIKeyboardDisableAutomaticAppearance();
+ /* }}} */
_trace();
int value = UIApplicationMain(argc, argv, @"Cydia", @"Cydia");