+ RadixSort_(self, count, swap);
+}
+
+@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 {{{ */
+@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 WebScriptObject$countByEnumeratingWithState$objects$count$(WebScriptObject *self, SEL sel, NSFastEnumerationState *state, id *objects, NSUInteger count) {
+ size_t length([self count] - state->state);
+ if (length <= 0)
+ return 0;
+ else if (length > count)
+ length = count;
+ for (size_t i(0); i != length; ++i)
+ objects[i] = [self objectAtIndex:state->state++];
+ state->itemsPtr = objects;
+ state->mutationsPtr = (unsigned long *) self;
+ return length;
+}
+
+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;
+}