]> git.saurik.com Git - cydia.git/blobdiff - MobileCydia.mm
CyteKit/Application.mm has to have its @interface.
[cydia.git] / MobileCydia.mm
index 3dec86e2dee8bf9499698d36c398d32355c47cff..95bbca774d3273d3cc1e25d541da91a9a45292ff 100644 (file)
@@ -329,53 +329,47 @@ static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareNumerically | kCF
 
 /* Insertion Sort {{{ */
 
-CFIndex SKBSearch_(const void *element, CFIndex elementSize, const void *list, CFIndex count, CFComparatorFunction comparator, void *context) {
+template <typename Type_>
+size_t CFBSearch_(const Type_ &element, const void *list, size_t count, CFComparisonResult (*comparator)(Type_, Type_, void *), 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;
+        size_t half = count / 2;
+        const char *probe = ptr + sizeof(Type_) * half;
+        CFComparisonResult cr = comparator(element, * (const Type_ *) probe, context);
+        if (0 == cr) return (probe - (const char *)list) / sizeof(Type_);
+        ptr = (cr < 0) ? ptr : probe + sizeof(Type_);
         count = (cr < 0) ? half : (half + (count & 1) - 1);
     }
-    return (ptr - (const char *)list) / elementSize;
+    return (ptr - (const char *)list) / sizeof(Type_);
 }
 
-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)
+template <typename Type_>
+void CYArrayInsertionSortValues(Type_ *values, size_t length, CFComparisonResult (*comparator)(Type_, Type_, void *), void *context) {
+    if (length == 0)
         return;
-    const void **values(new const void *[range.length]);
-    CFArrayGetValues(array, range, values);
 
 #if HistogramInsertionSort > 0
-    uint32_t total(0), *offsets(new uint32_t[range.length]);
+    uint32_t total(0), *offsets(new uint32_t[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);
+    for (size_t index(1); index != length; ++index) {
+        Type_ value(values[index]);
+#if 0
+        size_t correct(CFBSearch_(value, values, index, comparator, context));
+#else
+        size_t correct(index);
         while (comparator(value, values[correct - 1], context) == kCFCompareLessThan) {
 #if HistogramInsertionSort > 1
             NSLog(@"%@ < %@", value, values[correct - 1]);
 #endif
             if (--correct == 0)
                 break;
+            if (index - correct >= 8) {
+                correct = CFBSearch_(value, values, correct, comparator, context);
+                break;
+            }
         }
+#endif
         if (correct != index) {
             size_t offset(index - correct);
 #if HistogramInsertionSort
@@ -389,11 +383,8 @@ void CFArrayInsertionSortValues(CFMutableArrayRef array, CFRange range, CFCompar
         }
     }
 
-    CFArrayReplaceValues(array, range, values, range.length);
-    delete [] values;
-
 #if HistogramInsertionSort > 0
-    for (CFIndex index(0); index != range.length; ++index)
+    for (size_t 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);
@@ -1119,7 +1110,7 @@ typedef std::map< unsigned long, _H<Source> > SourceMap;
     SourceMap sourceMap_;
     _H<NSMutableArray> sourceList_;
 
-    CFMutableArrayRef packages_;
+    _H<NSArray> packages_;
 
     _transient NSObject<DatabaseDelegate> *delegate_;
     _transient NSObject<ProgressDelegate> *progress_;
@@ -1203,7 +1194,10 @@ class SourceStatus :
         }
 
         //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) {
@@ -1668,13 +1662,10 @@ static void SaveConfig(NSObject *lock) {
         _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
 
@@ -2143,6 +2134,8 @@ struct ParsedPackage {
 }
 
 - (Package *) initWithVersion:(pkgCache::VerIterator)version withZone:(NSZone *)zone inPool:(CYPool *)pool database:(Database *)database;
++ (Package *) newPackageWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(CYPool *)pool database:(Database *)database;
+
 + (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(CYPool *)pool database:(Database *)database;
 
 - (pkgCache::PkgIterator) iterator;
@@ -2712,7 +2705,7 @@ struct PackageNameOrdering :
     _end } return self;
 }
 
-+ (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(CYPool *)pool database:(Database *)database {
++ (Package *) newPackageWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(CYPool *)pool database:(Database *)database {
     pkgCache::VerIterator version;
 
     _profile(Package$packageWithIterator$GetCandidateVer)
@@ -2737,13 +2730,14 @@ struct PackageNameOrdering :
         ];
     _end
 
-    _profile(Package$packageWithIterator$Autorelease)
-        package = [package autorelease];
-    _end
-
     return package;
 }
 
+// XXX: just in case a Cydia extension is using this (I bet this is unlikely, though, due to CYPool?)
++ (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(CYPool *)pool database:(Database *)database {
+    return [[self newPackageWithIterator:iterator withZone:zone inPool:pool database:database] autorelease];
+}
+
 - (pkgCache::PkgIterator) iterator {
     return iterator_;
 }
@@ -3328,8 +3322,8 @@ struct PackageNameOrdering :
 }
 
 - (void) setIndex:(size_t)index {
-    if (metadata_->index_ != index)
-        metadata_->index_ = index;
+    if (metadata_->index_ != index + 1)
+        metadata_->index_ = index + 1;
 }
 
 - (CYString &) cyname {
@@ -3520,12 +3514,11 @@ class CydiaLogCleaner :
 }
 
 - (void) releasePackages {
-    CFArrayApplyFunction(packages_, CFRangeMake(0, CFArrayGetCount(packages_)), reinterpret_cast<CFArrayApplierFunction>(&CFRelease), NULL);
-    CFArrayRemoveAllValues(packages_);
+    packages_ = nil;
 }
 
 - (bool) hasPackages {
-    return CFArrayGetCount(packages_) != 0;
+    return [packages_ count] != 0;
 }
 
 - (void) dealloc {
@@ -3651,7 +3644,7 @@ class CydiaLogCleaner :
         , "any"
 #endif
     ));
-    return iterator.end() ? nil : [Package packageWithIterator:iterator withZone:NULL inPool:NULL database:self];
+    return iterator.end() ? nil : [[Package newPackageWithIterator:iterator withZone:NULL inPool:NULL database:self] autorelease];
 } }
 
 - (id) init {
@@ -3664,13 +3657,6 @@ class CydiaLogCleaner :
 
         zone_ = NSCreateZone(1024 * 1024, 256 * 1024, NO);
 
-        size_t capacity(MetaFile_->active_);
-        if (capacity == 0)
-            capacity = 16384;
-        else
-            capacity += 1024;
-
-        packages_ = CFArrayCreateMutable(kCFAllocatorDefault, capacity, NULL);
         sourceList_ = [NSMutableArray arrayWithCapacity:16];
 
         int fds[2];
@@ -3739,7 +3725,7 @@ class CydiaLogCleaner :
 }
 
 - (NSArray *) packages {
-    return (NSArray *) packages_;
+    return packages_;
 }
 
 - (NSArray *) sources {
@@ -3956,40 +3942,88 @@ class CydiaLogCleaner :
     }
 
     {
-        /*std::vector<Package *> packages;
-        packages.reserve(std::max(10000U, [packages_ count] + 1000));
-        packages_ = nil;*/
+        size_t capacity(MetaFile_->active_);
+        if (capacity == 0)
+            capacity = 128*1024;
+        else
+            capacity += 1024;
 
+        std::vector<Package *> packages;
+        packages.reserve(capacity);
+        size_t lost(0);
+
+        size_t last(0);
         _profile(reloadDataWithInvocation$packageWithIterator)
         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);
-                CFArrayAppendValue(packages_, CFRetain(package));
+            if (Package *package = [Package newPackageWithIterator:iterator withZone:zone_ inPool:&pool_ database:self]) {
+                if (unsigned index = package.metadata->index_) {
+                    --index;
+                    if (packages.size() == index) {
+                        packages.push_back(package);
+                    } else if (packages.size() <= index) {
+                        packages.resize(index + 1, nil);
+                        packages[index] = package;
+                        continue;
+                    } else {
+                        std::swap(package, packages[index]);
+                        if (package != nil)
+                            goto lost;
+                        if (last != index)
+                            continue;
+                    }
+                } else lost: {
+                    ++lost;
+                    if (last == packages.size()) {
+                        packages.push_back(package);
+                        ++last;
+                    } else {
+                        packages[last] = package;
+                        ++last;
+                    }
+                }
+
+                for (; last != packages.size(); ++last)
+                    if (packages[last] == nil)
+                        break;
+            }
         _end
 
+        for (size_t next(last + 1); last != packages.size(); ++last, ++next) {
+            while (true) {
+                if (next == packages.size())
+                    goto done;
+                if (packages[next] != nil)
+                    break;
+                ++next;
+            }
+
+            std::swap(packages[last], packages[next]);
+        } done:;
 
-        /*if (packages.empty())
-            packages_ = [[NSArray alloc] init];
-        else
-            packages_ = [[NSArray alloc] initWithObjects:&packages.front() count:packages.size()];
-        _trace();*/
+        packages.resize(last);
 
-        _profile(reloadDataWithInvocation$radix$8)
-        [(NSMutableArray *) packages_ radixSortUsingFunction:reinterpret_cast<MenesRadixSortFunction>(&PackagePrefixRadix) withContext:reinterpret_cast<void *>(8)];
-        _end
+        if (lost > 128) {
+            NSLog(@"lost = %zu", lost);
 
-        _profile(reloadDataWithInvocation$radix$4)
-        [(NSMutableArray *) packages_ radixSortUsingFunction:reinterpret_cast<MenesRadixSortFunction>(&PackagePrefixRadix) withContext:reinterpret_cast<void *>(4)];
-        _end
+            _profile(reloadDataWithInvocation$radix$8)
+            CYRadixSortUsingFunction(packages.data(), packages.size(), reinterpret_cast<MenesRadixSortFunction>(&PackagePrefixRadix), reinterpret_cast<void *>(8));
+            _end
 
-        _profile(reloadDataWithInvocation$radix$0)
-        [(NSMutableArray *) packages_ radixSortUsingFunction:reinterpret_cast<MenesRadixSortFunction>(&PackagePrefixRadix) withContext:reinterpret_cast<void *>(0)];
-        _end
+            _profile(reloadDataWithInvocation$radix$4)
+            CYRadixSortUsingFunction(packages.data(), packages.size(), reinterpret_cast<MenesRadixSortFunction>(&PackagePrefixRadix), reinterpret_cast<void *>(4));
+            _end
+
+            _profile(reloadDataWithInvocation$radix$0)
+            CYRadixSortUsingFunction(packages.data(), packages.size(), reinterpret_cast<MenesRadixSortFunction>(&PackagePrefixRadix), reinterpret_cast<void *>(0));
+            _end
+        }
 
         _profile(reloadDataWithInvocation$insertion)
-        CFArrayInsertionSortValues(packages_, CFRangeMake(0, CFArrayGetCount(packages_)), reinterpret_cast<CFComparatorFunction>(&PackageNameCompare), NULL);
+        CYArrayInsertionSortValues(packages.data(), packages.size(), &PackageNameCompare, NULL);
         _end
 
+        packages_ = [[[NSArray alloc] initWithObjects:packages.data() count:packages.size()] autorelease];
+
         /*_profile(reloadDataWithInvocation$CFQSortArray)
         CFQSortArray(&packages.front(), packages.size(), sizeof(packages.front()), reinterpret_cast<CFComparatorFunction>(&PackageNameCompare_), NULL);
         _end*/
@@ -4006,11 +4040,12 @@ class CydiaLogCleaner :
         [packages_ sortUsingFunction:reinterpret_cast<NSComparisonResult (*)(id, id, void *)>(&PackageNameCompare) context:NULL];
         _end*/
 
-
-        size_t count(CFArrayGetCount(packages_));
-        MetaFile_->active_ = count;
-        for (size_t index(0); index != count; ++index)
-            [(Package *) CFArrayGetValueAtIndex(packages_, index) setIndex:index];
+        MetaFile_->active_ = packages.size();
+        for (size_t index(0), count(packages.size()); index != count; ++index) {
+            auto package(packages[index]);
+            [package setIndex:index];
+            [package release];
+        }
     }
 } }
 
@@ -6402,7 +6437,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 #if !AlwaysReload
 - (void) _customButtonClicked {
-    if (commercial_ && [package_ uninstalled])
+    if (commercial_ && self.isLoading && [package_ uninstalled])
         return [self reloadURLWithCache:NO];
 
     size_t count(buttons_.size());
@@ -10238,7 +10273,11 @@ int main(int argc, char *argv[]) {
         }
 
     if (Languages_ != nil)
-        for (NSString *language : Languages_) {
+        for (NSString *locale : Languages_) {
+            auto components([NSLocale componentsFromLocaleIdentifier:locale]);
+            NSString *language([components objectForKey:(id)kCFLocaleLanguageCode]);
+            if (NSString *script = [components objectForKey:(id)kCFLocaleScriptCode])
+                language = [NSString stringWithFormat:@"%@-%@", language, script];
             languages += [language UTF8String];
             languages += ",";
         }