first commit

This commit is contained in:
Victor Bodinaud
2025-03-03 13:59:05 +01:00
commit 954e43aa2f
166 changed files with 15834 additions and 0 deletions

124
UICaboodle/BrowserView.h Normal file
View File

@@ -0,0 +1,124 @@
#import "ResetView.h"
#include <WebKit/DOMCSSPrimitiveValue.h>
#include <WebKit/DOMCSSStyleDeclaration.h>
#include <WebKit/DOMDocument.h>
#include <WebKit/DOMHTMLBodyElement.h>
#include <WebKit/DOMNodeList.h>
#include <WebKit/DOMRGBColor.h>
#include <WebKit/WebFrame.h>
#include <WebKit/WebPolicyDelegate.h>
#include <WebKit/WebPreferences.h>
#include <WebKit/WebScriptObject.h>
#import <WebKit/WebView.h>
#import <WebKit/WebView-WebPrivate.h>
#include <WebCore/Page.h>
#include <WebCore/Settings.h>
#import <JavaScriptCore/JavaScriptCore.h>
@class NSMutableArray;
@class NSString;
@class NSURL;
@class NSURLRequest;
@class UIProgressIndicator;
@class UIScroller;
@class UIDocumentWebView;
@class WebView;
@class Database;
@class IndirectDelegate;
@interface WebScriptObject (UICaboodle)
- (unsigned) count;
- (id) objectAtIndex:(unsigned)index;
@end
@protocol BrowserViewDelegate
- (RVPage *) pageForURL:(NSURL *)url hasTag:(int *)tag;
@end
@interface BrowserView : RVPage <
RVBookHook
> {
UIScroller *scroller_;
UIWebDocumentView *document_;
UIProgressIndicator *indicator_;
IndirectDelegate *indirect_;
NSURLAuthenticationChallenge *challenge_;
bool error_;
NSURLRequest *request_;
NSNumber *confirm_;
NSNumber *sensitive_;
NSString *title_;
NSMutableSet *loading_;
bool reloading_;
NSString *button_;
NSString *style_;
WebScriptObject *function_;
WebScriptObject *closer_;
WebScriptObject *special_;
WebScriptObject *finish_;
bool pushed_;
float width_;
bool popup_;
CGSize size_;
bool editing_;
Class class_;
}
+ (void) _initialize;
- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button;
- (void) loadURL:(NSURL *)url cachePolicy:(NSURLRequestCachePolicy)policy;
- (void) loadURL:(NSURL *)url;
- (void) loadRequest:(NSURLRequest *)request;
- (void) reloadURL;
- (bool) isLoading;
- (void) fixScroller;
- (WebView *) webView;
- (UIWebDocumentView *) documentView;
- (id) initWithBook:(RVBook *)book;
- (id) initWithBook:(RVBook *)book forWidth:(float)width;
- (id) initWithBook:(RVBook *)book forWidth:(float)width ofClass:(Class)_class;
- (NSString *) stringByEvaluatingJavaScriptFromString:(NSString *)script;
- (void) callFunction:(WebScriptObject *)function;
- (void) webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame;
- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame;
- (NSURLRequest *) webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)source;
+ (float) defaultWidth;
- (void) setViewportWidth:(float)width;
- (void) setButtonImage:(NSString *)button withStyle:(NSString *)style toFunction:(id)function;
- (void) setButtonTitle:(NSString *)button withStyle:(NSString *)style toFunction:(id)function;
- (void) setFinishHook:(id)function;
- (void) setPopupHook:(id)function;
- (id) _rightButtonTitle;
- (bool) promptForSensitive:(NSString *)name;
- (bool) allowSensitiveRequests;
@end

1527
UICaboodle/BrowserView.mm Normal file

File diff suppressed because it is too large Load Diff

81
UICaboodle/RVBook.h Normal file
View File

@@ -0,0 +1,81 @@
#import <UICaboodle/UCPlatform.h>
#import <UIKit/UIKit.h>
@class NSMutableArray;
@class RVBook;
@class RVPage;
@class UINavigationBar;
@class UITransitionView;
@interface UIView (PopUpView)
- (void) popFromSuperviewAnimated:(BOOL)animated;
- (void) popSubview:(UIView *)view;
@end
@protocol RVNavigationBarDelegate
@end
@protocol RVDelegate
- (void) setPageActive:(BOOL)active with:(id)object;
- (void) resetViewAnimated:(BOOL)animated with:(id)object;
- (void) reloadDataWith:(id)object;
- (void) popUpBook:(RVBook *)book;
- (CGRect) popUpBounds;
@end
@protocol RVBookHook
- (void) didCloseBook:(RVBook *)book;
@end
@interface RVBook : UIView <
RVNavigationBarDelegate
> {
NSMutableArray *pages_;
UINavigationBar *navbar_;
UITransitionView *transition_;
BOOL resetting_;
_transient id delegate_;
_transient id hook_;
UIToolbar *toolbar_;
}
- (UINavigationBar *) navigationBar;
- (id) initWithFrame:(CGRect)frame;
- (void) setDelegate:(id)delegate;
- (void) setHook:(id)hook;
- (void) setPage:(RVPage *)page;
- (void) swapPage:(RVPage *)page;
- (void) pushPage:(RVPage *)page animated:(BOOL)animated;
- (void) pushPage:(RVPage *)page;
- (void) popPages:(unsigned)pages;
- (void) pushBook:(RVBook *)book;
- (void) resetViewAnimated:(BOOL)animated;
- (void) resetViewAnimated:(BOOL)animated toPage:(RVPage *)page;
- (void) setBackButtonTitle:(NSString *)title forPage:(RVPage *)page;
- (void) reloadTitleForPage:(RVPage *)page;
- (void) reloadButtonsForPage:(RVPage *)page;
- (NSString *) getTitleForPage:(RVPage *)page;
- (void) reloadButtons;
- (void) reloadData;
- (CGRect) pageBounds;
- (void) close;
@end
@interface RVPopUpBook : RVBook {
_transient RVBook *parent_;
bool cancel_;
}
@end

338
UICaboodle/RVBook.mm Normal file
View File

@@ -0,0 +1,338 @@
#import "RVBook.h"
#import <UIKit/UINavigationBar.h>
#import <UIKit/UINavigationItem.h>
#import <UIKit/UITransitionView.h>
#import <UIKit/UIView-Geometry.h>
#import <UIKit/UIView-Hierarchy.h>
#import <Foundation/Foundation.h>
#import <CoreGraphics/CGGeometry.h>
#include <cstdio>
#include <cstdlib>
#include <errno.h>
#import "RVPage.h"
@interface NSObject (UICaboodleRVBook)
- (float) widthForButtonContents:(float)width;
@end
@implementation NSObject (UICaboodleRVBook)
- (float) widthForButtonContents:(float)width {
return width;
}
@end
@interface UIImage (UICaboodleRVBook)
- (float) widthForButtonContents:(float)width;
@end
@implementation UIImage (UICaboodleRVBook)
- (float) widthForButtonContents:(float)width {
return [self size].width + 8;
}
@end
@interface RVNavigationBar : UINavigationBar {
}
- (id) createButtonWithContents:(id)contents width:(float)width barStyle:(int)barStyle buttonStyle:(int)style isRight:(BOOL)right;
@end
@implementation RVNavigationBar
- (id) createButtonWithContents:(id)contents width:(float)width barStyle:(int)barStyle buttonStyle:(int)style isRight:(BOOL)right {
float adjust = [contents widthForButtonContents:width];
width = adjust;
return [super createButtonWithContents:contents width:width barStyle:barStyle buttonStyle:style isRight:right];
}
@end
@implementation RVBook
- (void) dealloc {
[navbar_ setDelegate:nil];
if (toolbar_ != nil)
[toolbar_ setDelegate:nil];
for (RVPage *page in pages_)
[page setBook:nil];
[pages_ release];
[navbar_ release];
[transition_ release];
if (toolbar_ != nil)
[toolbar_ release];
[super dealloc];
}
- (UINavigationBar *) navigationBar {
return navbar_;
}
- (void) navigationBar:(UINavigationBar *)navbar buttonClicked:(int)button {
_assert([pages_ count] != 0);
RVPage *page = [pages_ lastObject];
switch (button) {
case 0: [page _rightButtonClicked]; break;
case 1: [page _leftButtonClicked]; break;
}
}
- (void) navigationBar:(UINavigationBar *)navbar poppedItem:(UINavigationItem *)item {
_assert([pages_ count] != 0);
if (!resetting_)
[[pages_ lastObject] setPageActive:NO];
[pages_ removeLastObject];
if (!resetting_)
[self resetViewAnimated:YES toPage:[pages_ lastObject]];
}
- (id) initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame]) != nil) {
pages_ = [[NSMutableArray arrayWithCapacity:4] retain];
struct CGRect bounds = [self bounds];
CGSize navsize = [UINavigationBar defaultSize];
CGRect navrect = {{0, 0}, {bounds.size.width, navsize.height}};
navbar_ = [[RVNavigationBar alloc] initWithFrame:navrect];
[navbar_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
[self addSubview:navbar_];
[navbar_ setBarStyle:0];
[navbar_ setDelegate:self];
transition_ = [[UITransitionView alloc] initWithFrame:CGRectMake(
bounds.origin.x, bounds.origin.y + navsize.height, bounds.size.width, bounds.size.height - navsize.height
)];
[transition_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
[self addSubview:transition_];
} return self;
}
- (void) setDelegate:(id)delegate {
delegate_ = delegate;
}
- (void) setHook:(id)hook {
hook_ = hook;
}
- (void) setPage:(RVPage *)page {
if ([pages_ count] != 0)
[[pages_ lastObject] setPageActive:NO];
[navbar_ disableAnimation];
resetting_ = true;
for (unsigned i(0), pages([pages_ count]); i != pages; ++i)
[navbar_ popNavigationItem];
resetting_ = false;
[self pushPage:page];
[navbar_ enableAnimation];
}
- (void) swapPage:(RVPage *)page {
if ([pages_ count] == 0)
return [self pushPage:page];
[[pages_ lastObject] setPageActive:NO];
[navbar_ disableAnimation];
resetting_ = true;
[navbar_ popNavigationItem];
resetting_ = false;
[self pushPage:page animated:NO];
[navbar_ enableAnimation];
}
- (void) pushPage:(RVPage *)page animated:(BOOL)animated {
NSString *title = [self getTitleForPage:page];
NSString *backButtonTitle = [page backButtonTitle];
if (backButtonTitle == nil)
backButtonTitle = title;
UINavigationItem *navitem = [[[UINavigationItem alloc] initWithTitle:title] autorelease];
[navitem setBackButtonTitle:backButtonTitle];
[navbar_ pushNavigationItem:navitem];
[page setFrame:[transition_ bounds]];
[transition_ transition:(animated ? 1 : 0) toView:page];
[page setPageActive:YES];
[pages_ addObject:page];
[self reloadButtonsForPage:page];
if ([navbar_ respondsToSelector:@selector(setAccessoryView:animate:removeOnPop:)])
[navbar_ setAccessoryView:[page accessoryView] animate:animated removeOnPop:NO];
else
[navbar_ setAccessoryView:[page accessoryView] animate:animated];
}
- (void) pushPage:(RVPage *)page {
if ([pages_ count] != 0)
[[pages_ lastObject] setPageActive:NO];
[self pushPage:page animated:([pages_ count] == 0 ? NO : YES)];
}
- (void) pushBook:(RVBook *)book {
[delegate_ popUpBook:book];
}
- (void) popPages:(unsigned)pages {
if (pages == 0)
return;
[[pages_ lastObject] setPageActive:NO];
resetting_ = true;
for (unsigned i(0); i != pages; ++i)
[navbar_ popNavigationItem];
resetting_ = false;
[self resetViewAnimated:YES toPage:[pages_ lastObject]];
}
- (void) resetViewAnimated:(BOOL)animated {
resetting_ = true;
if ([pages_ count] > 1) {
[navbar_ disableAnimation];
while ([pages_ count] != (animated ? 2 : 1))
[navbar_ popNavigationItem];
[navbar_ enableAnimation];
if (animated)
[navbar_ popNavigationItem];
}
resetting_ = false;
[self resetViewAnimated:animated toPage:[pages_ lastObject]];
}
- (void) resetViewAnimated:(BOOL)animated toPage:(RVPage *)page {
[page resetViewAnimated:animated];
[page setFrame:[transition_ bounds]];
[transition_ transition:(animated ? 2 : 0) toView:page];
[page setPageActive:YES];
[self reloadButtonsForPage:page];
if ([navbar_ respondsToSelector:@selector(setAccessoryView:animate:removeOnPop:)])
[navbar_ setAccessoryView:[page accessoryView] animate:animated removeOnPop:NO];
else
[navbar_ setAccessoryView:[page accessoryView] animate:animated];
}
- (void) setBackButtonTitle:(NSString *)title forPage:(RVPage *)page {
if ([pages_ count] == 0 || page != [pages_ lastObject])
return;
UINavigationItem *navitem = [navbar_ topItem];
[navitem setBackButtonTitle:title];
}
- (void) reloadTitleForPage:(RVPage *)page {
if ([pages_ count] == 0 || page != [pages_ lastObject])
return;
UINavigationItem *navitem = [navbar_ topItem];
NSString *title = [self getTitleForPage:page];
[navitem setTitle:title];
}
- (void) _leftButtonTitle:(NSString *&)leftButtonTitle style:(UINavigationButtonStyle &)leftButtonStyle forPage:(RVPage *)page {
leftButtonTitle = [page leftButtonTitle];
leftButtonStyle = [page leftButtonStyle];
}
- (void) reloadButtonsForPage:(RVPage *)page {
if ([pages_ count] == 0 || page != [pages_ lastObject])
return;
NSString *leftButtonTitle;
UINavigationButtonStyle leftButtonStyle;
[self _leftButtonTitle:leftButtonTitle style:leftButtonStyle forPage:page];
UINavigationButtonStyle rightButtonStyle = [page rightButtonStyle];
//[navbar_ showButtonsWithLeftTitle:leftButtonTitle rightTitle:[page rightButtonTitle] leftBack:(leftButtonTitle == nil)];
[navbar_
showLeftButton:leftButtonTitle
withStyle:leftButtonStyle
rightButton:[page rightButtonTitle]
withStyle:rightButtonStyle
];
}
- (NSString *) getTitleForPage:(RVPage *)page {
return [page title];
}
- (void) reloadData {
size_t count([pages_ count]);
for (size_t i(0); i != count; ++i) {
RVPage *page([pages_ objectAtIndex:(count - i - 1)]);
[page reloadData];
}
if (count != 0) {
RVPage *page([pages_ lastObject]);
[self reloadButtonsForPage:page];
}
}
- (void) reloadButtons {
size_t count([pages_ count]);
if (count != 0) {
RVPage *page([pages_ lastObject]);
[self reloadButtonsForPage:page];
}
}
- (CGRect) pageBounds {
return [transition_ bounds];
}
- (void) close {
if (hook_ != nil)
[hook_ didCloseBook:self];
}
@end
@implementation RVPopUpBook
- (void) _leftButtonTitle:(NSString *&)leftButtonTitle style:(UINavigationButtonStyle &)leftButtonStyle forPage:(RVPage *)page {
[super _leftButtonTitle:leftButtonTitle style:leftButtonStyle forPage:page];
if ((cancel_ = leftButtonTitle == nil && [pages_ count] == 1)) {
leftButtonTitle = [[NSBundle mainBundle] localizedStringForKey:@"CANCEL" value:nil table:nil];
leftButtonStyle = UINavigationButtonStyleNormal;
}
}
- (void) navigationBar:(UINavigationBar *)navbar buttonClicked:(int)button {
if (button == 1 && cancel_)
[self close];
else
[super navigationBar:navbar buttonClicked:button];
}
- (void) close {
[self popFromSuperviewAnimated:YES];
[super close];
}
@end

42
UICaboodle/RVPage.h Normal file
View File

@@ -0,0 +1,42 @@
#import <UICaboodle/UCPlatform.h>
#import <UIKit/UIKit.h>
@class NSString;
@class RVBook;
@interface RVPage : UIView {
_transient RVBook *book_;
_transient id delegate_;
}
- (bool) splitView;
- (NSString *) title;
- (NSString *) backButtonTitle;
- (id) rightButtonTitle;
- (NSString *) leftButtonTitle;
- (UIView *) accessoryView;
- (UIImage *) rightButtonImage;
- (UINavigationButtonStyle) leftButtonStyle;
- (UINavigationButtonStyle) rightButtonStyle;
- (void) _rightButtonClicked;
- (void) _leftButtonClicked;
- (void) setPageActive:(BOOL)active;
- (void) resetViewAnimated:(BOOL)animated;
- (void) setBackButtonTitle:(NSString *)title;
- (void) reloadButtons;
- (void) reloadData;
- (id) initWithBook:(RVBook *)book;
- (void) setDelegate:(id)delegate;
- (void) setBook:(RVBook *)book;
@end

87
UICaboodle/RVPage.mm Normal file
View File

@@ -0,0 +1,87 @@
#import "RVPage.h"
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "RVBook.h"
@implementation RVPage
- (bool) splitView {
return false;
}
- (NSString *) title {
[self doesNotRecognizeSelector:_cmd];
return nil;
}
- (NSString *) backButtonTitle {
return nil;
}
- (NSString *) leftButtonTitle {
return nil;
}
- (id) rightButtonTitle {
return nil;
}
- (UINavigationButtonStyle) leftButtonStyle {
return [self leftButtonTitle] == nil ? UINavigationButtonStyleBack : UINavigationButtonStyleNormal;
}
- (UINavigationButtonStyle) rightButtonStyle {
return UINavigationButtonStyleNormal;
}
- (void) _rightButtonClicked {
[self doesNotRecognizeSelector:_cmd];
}
- (void) _leftButtonClicked {
[self doesNotRecognizeSelector:_cmd];
}
- (UIView *) accessoryView {
return nil;
}
- (UIImage *) rightButtonImage {
return nil;
}
- (void) setPageActive:(BOOL)active {
}
- (void) resetViewAnimated:(BOOL)animated {
[self doesNotRecognizeSelector:_cmd];
}
- (void) setBackButtonTitle:(NSString *)title {
[book_ setBackButtonTitle:title forPage:self];
}
- (void) reloadButtons {
[book_ reloadButtonsForPage:self];
}
- (void) reloadData {
}
- (id) initWithBook:(RVBook *)book {
if ((self = [super initWithFrame:[book pageBounds]]) != nil) {
book_ = book;
} return self;
}
- (void) setDelegate:(id)delegate {
delegate_ = delegate;
}
- (void) setBook:(RVBook *)book {
book_ = book;
}
@end

24
UICaboodle/ResetView.h Normal file
View File

@@ -0,0 +1,24 @@
#import <UICaboodle/RVPage.h>
#import <UICaboodle/RVBook.h>
#import <UIKit/UIKit.h>
@interface UIView (RVBook)
- (void) resetViewAnimated:(BOOL)animated;
- (void) clearView;
@end
@interface UITable (RVBook)
- (void) resetViewAnimated:(BOOL)animated;
- (void) clearView;
@end
@interface UITableView (RVBook)
- (void) resetViewAnimated:(BOOL)animated;
- (void) clearView;
@end
@interface UISectionList (RVBook)
- (void) resetViewAnimated:(BOOL)animated;
- (void) clearView;
@end

61
UICaboodle/ResetView.mm Normal file
View File

@@ -0,0 +1,61 @@
#import "ResetView.h"
#include <objc/objc.h>
#include <objc/runtime.h>
#include <errno.h>
#include <cstdio>
#include <cstdlib>
@implementation UIView (RVBook)
- (void) resetViewAnimated:(BOOL)animated {
fprintf(stderr, "%s\n", class_getName(self->isa));
_assert(false);
}
- (void) clearView {
fprintf(stderr, "%s\n", class_getName(self->isa));
_assert(false);
}
@end
@implementation UITable (RVBook)
- (void) resetViewAnimated:(BOOL)animated {
[self selectRow:-1 byExtendingSelection:NO withFade:animated];
}
- (void) clearView {
[self clearAllData];
}
@end
@implementation UITableView (RVBook)
- (void) resetViewAnimated:(BOOL)animated {
//[self selectRowAtIndexPath:nil animated:animated scrollPosition:UITableViewScrollPositionNone];
if (NSIndexPath *path = [self indexPathForSelectedRow])
[self deselectRowAtIndexPath:path animated:animated];
}
- (void) clearView {
//XXX:[[self table] clearView];
}
@end
@implementation UISectionList (RVBook)
- (void) resetViewAnimated:(BOOL)animated {
[[self table] resetViewAnimated:animated];
}
- (void) clearView {
[[self table] clearView];
}
@end

10
UICaboodle/UCInternal.h Normal file
View File

@@ -0,0 +1,10 @@
- (NSMethodSignature *) methodSignatureForSelector:(SEL)selector {
fprintf(stderr, "[%s]S-%s\n", class_getName(self->isa), sel_getName(selector));
return [super methodSignatureForSelector:selector];
}
- (BOOL) respondsToSelector:(SEL)selector {
BOOL responds = [super respondsToSelector:selector];
fprintf(stderr, "[%s]R%c%s\n", class_getName(self->isa), (responds ? '+' : '-'), sel_getName(selector));
return responds;
}

12
UICaboodle/UCLocalize.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef UICABOODLE_UCLOCALIZE_H
#define UICABOODLE_UCLOCALIZE_H
#import <Foundation/Foundation.h>
static inline NSString *UCLocalizeEx(NSString *key, NSString *value = nil) {
return [[NSBundle mainBundle] localizedStringForKey:key value:value table:nil];
}
#define UCLocalize(key) UCLocalizeEx(@ key)
#endif/*UICABOODLE_UCLOCALIZE_H*/

56
UICaboodle/UCPlatform.h Normal file
View File

@@ -0,0 +1,56 @@
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#include <objc/objc.h>
#include <sys/time.h>
#include <time.h>
#define _forever \
for (;;)
extern struct timeval _ltv;
extern bool _itv;
#define _trace() do { \
struct timeval _ctv; \
gettimeofday(&_ctv, NULL); \
if (!_itv) { \
_itv = true; \
_ltv = _ctv; \
} \
fprintf(stderr, "%lu.%.6u[%f]:_trace()@%s:%u[%s]\n", \
_ctv.tv_sec, _ctv.tv_usec, \
(_ctv.tv_sec - _ltv.tv_sec) + (_ctv.tv_usec - _ltv.tv_usec) / 1000000.0, \
__FILE__, __LINE__, __FUNCTION__\
); \
_ltv = _ctv; \
} while (false)
#define _assert(test) do \
if (!(test)) { \
fprintf(stderr, "_assert(%d:%s)@%s:%u[%s]\n", errno, #test, __FILE__, __LINE__, __FUNCTION__); \
exit(-1); \
} \
while (false)
#define _not(type) ((type) ~ (type) 0)
#define _transient
#define _label__(x) _label ## x
#define _label_(y) _label__(y)
#define _label _label_(__LINE__)
#define _packed \
__attribute__((__packed__))
#define _finline \
inline __attribute__((__always_inline__))
#define _assume(e) \
_assert(e)
#define _nodefault \
default: \
_assume(false); \
throw;

42
UICaboodle/UCString.h Normal file
View File

@@ -0,0 +1,42 @@
#ifndef UICABOODLE_UCSTRING_H
#define UICABOODLE_UCSTRING_H
#import <Foundation/NSString.h>
@interface NSString (UIKit)
- (NSString *) stringByAddingPercentEscapes;
- (NSString *) stringByReplacingCharacter:(unsigned short)arg0 withCharacter:(unsigned short)arg1;
@end
@interface NSString (UICaboodle)
+ (NSString *) stringWithDataSize:(double)size;
- (NSString *) stringByAddingPercentEscapesIncludingReserved;
@end
@implementation NSString (UICaboodle)
+ (NSString *) stringWithDataSize:(double)size {
unsigned power = 0;
while (size > 1024) {
size /= 1024;
++power;
}
static const char *powers_[] = {"B", "KiB", "MiB", "GiB"};
return [NSString stringWithFormat:@"%.1f%s", size, powers_[power]];
}
- (NSString *) stringByAddingPercentEscapesIncludingReserved {
return [(id)CFURLCreateStringByAddingPercentEscapes(
kCFAllocatorDefault,
(CFStringRef) self,
NULL,
CFSTR(";/?:@&=+$,"),
kCFStringEncodingUTF8
) autorelease];
}
@end
#endif/*UICABOODLE_UCSTRING_H*/

64
UICaboodle/UCYield.h Normal file
View File

@@ -0,0 +1,64 @@
@interface NSObject (UICaboodle)
- (id) yieldToSelector:(SEL)selector withObject:(id)object;
- (id) yieldToSelector:(SEL)selector;
@end
@implementation NSObject (UICaboodle)
- (void) doNothing {
}
- (void) _yieldToContext:(NSMutableArray *)context { _pooled
SEL selector(reinterpret_cast<SEL>([[context objectAtIndex:0] pointerValue]));
id object([[context objectAtIndex:1] nonretainedObjectValue]);
volatile bool &stopped(*reinterpret_cast<bool *>([[context objectAtIndex:2] pointerValue]));
/* XXX: deal with exceptions */
id value([self performSelector:selector withObject:object]);
NSMethodSignature *signature([self methodSignatureForSelector:selector]);
[context removeAllObjects];
if ([signature methodReturnLength] != 0 && value != nil)
[context addObject:value];
stopped = true;
[self
performSelectorOnMainThread:@selector(doNothing)
withObject:nil
waitUntilDone:NO
];
}
- (id) yieldToSelector:(SEL)selector withObject:(id)object {
/*return [self performSelector:selector withObject:object];*/
volatile bool stopped(false);
NSMutableArray *context([NSMutableArray arrayWithObjects:
[NSValue valueWithPointer:selector],
[NSValue valueWithNonretainedObject:object],
[NSValue valueWithPointer:const_cast<bool *>(&stopped)],
nil]);
NSThread *thread([[[NSThread alloc]
initWithTarget:self
selector:@selector(_yieldToContext:)
object:context
] autorelease]);
[thread start];
NSRunLoop *loop([NSRunLoop currentRunLoop]);
NSDate *future([NSDate distantFuture]);
while (!stopped && [loop runMode:NSDefaultRunLoopMode beforeDate:future]);
return [context count] == 0 ? nil : [context objectAtIndex:0];
}
- (id) yieldToSelector:(SEL)selector {
return [self yieldToSelector:selector withObject:nil];
}
@end