Initial checkin.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/.hgignore Sat Mar 08 21:04:41 2008 -0800
1.3 @@ -0,0 +1,8 @@
1.4 +syntax: glob
1.5 +.DS_Store
1.6 +build
1.7 +.svn
1.8 +*.pbxuser
1.9 +*.perspectivev3
1.10 +*.mpkg
1.11 +*.framework
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/Base64.h Sat Mar 08 21:04:41 2008 -0800
2.3 @@ -0,0 +1,23 @@
2.4 +//
2.5 +// Base64.h
2.6 +// MYUtilities
2.7 +//
2.8 +// Created by Jens Alfke on 1/27/08.
2.9 +// Copyright 2008 Jens Alfke. All rights reserved.
2.10 +//
2.11 +
2.12 +#import <Cocoa/Cocoa.h>
2.13 +
2.14 +
2.15 +@interface NSData (Base64)
2.16 +
2.17 +- (NSString *)base64String;
2.18 +- (NSString *)base64StringWithNewlines:(BOOL)encodeWithNewlines;
2.19 +
2.20 +- (NSData *)decodeBase64;
2.21 +- (NSData *)decodeBase64WithNewLines:(BOOL)encodedWithNewlines;
2.22 +
2.23 +- (NSString *)hexString;
2.24 +- (NSString *)hexDump;
2.25 +
2.26 +@end
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/Base64.m Sat Mar 08 21:04:41 2008 -0800
3.3 @@ -0,0 +1,165 @@
3.4 +//
3.5 +// Base64.m
3.6 +// MYUtilities
3.7 +//
3.8 +// Created by Jens Alfke on 1/27/08.
3.9 +// Copyright 2008 Jens Alfke. All rights reserved.
3.10 +//
3.11 +// Adapted from SSCrypto.m by Ed Silva;
3.12 +// Copyright (c) 2003-2006 Septicus Software. All rights reserved.
3.13 +//
3.14 +
3.15 +#import "Base64.h"
3.16 +#import <openssl/bio.h>
3.17 +#import <openssl/evp.h>
3.18 +
3.19 +
3.20 +@implementation NSData (Base64)
3.21 +
3.22 +
3.23 +/**
3.24 + * Encodes the current data in base64, and creates and returns an NSString from the result.
3.25 + * This is the same as piping data through "... | openssl enc -base64" on the command line.
3.26 + *
3.27 + * Code courtesy of DaveDribin (http://www.dribin.org/dave/)
3.28 + * Taken from http://www.cocoadev.com/index.pl?BaseSixtyFour
3.29 + **/
3.30 +- (NSString *)base64String
3.31 +{
3.32 + return [self base64StringWithNewlines: YES];
3.33 +}
3.34 +
3.35 +/**
3.36 + * Encodes the current data in base64, and creates and returns an NSString from the result.
3.37 + * This is the same as piping data through "... | openssl enc -base64" on the command line.
3.38 + *
3.39 + * Code courtesy of DaveDribin (http://www.dribin.org/dave/)
3.40 + * Taken from http://www.cocoadev.com/index.pl?BaseSixtyFour
3.41 + **/
3.42 +- (NSString *)base64StringWithNewlines:(BOOL)encodeWithNewlines
3.43 +{
3.44 + // Create a memory buffer which will contain the Base64 encoded string
3.45 + BIO * mem = BIO_new(BIO_s_mem());
3.46 +
3.47 + // Push on a Base64 filter so that writing to the buffer encodes the data
3.48 + BIO * b64 = BIO_new(BIO_f_base64());
3.49 + if (!encodeWithNewlines)
3.50 + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
3.51 + mem = BIO_push(b64, mem);
3.52 +
3.53 + // Encode all the data
3.54 + BIO_write(mem, [self bytes], [self length]);
3.55 + BIO_flush(mem);
3.56 +
3.57 + // Create a new string from the data in the memory buffer
3.58 + char * base64Pointer;
3.59 + long base64Length = BIO_get_mem_data(mem, &base64Pointer);
3.60 + NSString * base64String = [NSString stringWithCString:base64Pointer length:base64Length];
3.61 +
3.62 + // Clean up and go home
3.63 + BIO_free_all(mem);
3.64 + return base64String;
3.65 +}
3.66 +
3.67 +- (NSData *)decodeBase64
3.68 +{
3.69 + return [self decodeBase64WithNewLines:YES];
3.70 +}
3.71 +
3.72 +- (NSData *)decodeBase64WithNewLines:(BOOL)encodedWithNewlines
3.73 +{
3.74 + // Create a memory buffer containing Base64 encoded string data
3.75 + BIO * mem = BIO_new_mem_buf((void *) [self bytes], [self length]);
3.76 +
3.77 + // Push a Base64 filter so that reading from the buffer decodes it
3.78 + BIO * b64 = BIO_new(BIO_f_base64());
3.79 + if (!encodedWithNewlines)
3.80 + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
3.81 + mem = BIO_push(b64, mem);
3.82 +
3.83 + // Decode into an NSMutableData
3.84 + NSMutableData * data = [NSMutableData data];
3.85 + char inbuf[512];
3.86 + int inlen;
3.87 + while ((inlen = BIO_read(mem, inbuf, sizeof(inbuf))) > 0)
3.88 + [data appendBytes: inbuf length: inlen];
3.89 +
3.90 + // Clean up and go home
3.91 + BIO_free_all(mem);
3.92 + return data;
3.93 +}
3.94 +
3.95 +
3.96 +- (NSString *)hexString
3.97 +{
3.98 + const UInt8 *bytes = self.bytes;
3.99 + NSUInteger length = self.length;
3.100 + char out[2*length+1];
3.101 + char *dst = &out[0];
3.102 + for( int i=0; i<length; i+=1 )
3.103 + dst += sprintf(dst,"%02X",*(bytes++));
3.104 + return [[[NSString alloc] initWithBytes: out length: 2*length encoding: NSASCIIStringEncoding]
3.105 + autorelease];
3.106 +}
3.107 +
3.108 +- (NSString *)hexDump
3.109 +{
3.110 + NSMutableString *ret=[NSMutableString stringWithCapacity:[self length]*2];
3.111 + /* dumps size bytes of *data to string. Looks like:
3.112 + * [0000] 75 6E 6B 6E 6F 77 6E 20
3.113 + * 30 FF 00 00 00 00 39 00 unknown 0.....9.
3.114 + * (in a single line of course)
3.115 + */
3.116 + unsigned int size= [self length];
3.117 + const unsigned char *p = [self bytes];
3.118 + unsigned char c;
3.119 + int n;
3.120 + char bytestr[4] = {0};
3.121 + char addrstr[10] = {0};
3.122 + char hexstr[ 16*3 + 5] = {0};
3.123 + char charstr[16*1 + 5] = {0};
3.124 + for(n=1;n<=size;n++) {
3.125 + if (n%16 == 1) {
3.126 + /* store address for this line */
3.127 + snprintf(addrstr, sizeof(addrstr), "%.4x",
3.128 + ((unsigned int)p-(unsigned int)self) );
3.129 + }
3.130 +
3.131 + c = *p;
3.132 + if (isalnum(c) == 0) {
3.133 + c = '.';
3.134 + }
3.135 +
3.136 + /* store hex str (for left side) */
3.137 + snprintf(bytestr, sizeof(bytestr), "%02X ", *p);
3.138 + strncat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1);
3.139 +
3.140 + /* store char str (for right side) */
3.141 + snprintf(bytestr, sizeof(bytestr), "%c", c);
3.142 + strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1);
3.143 +
3.144 + if(n%16 == 0) {
3.145 + /* line completed */
3.146 + //printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr);
3.147 + [ret appendString:[NSString stringWithFormat:@"[%4.4s] %-50.50s %s\n",
3.148 + addrstr, hexstr, charstr]];
3.149 + hexstr[0] = 0;
3.150 + charstr[0] = 0;
3.151 + } else if(n%8 == 0) {
3.152 + /* half line: add whitespaces */
3.153 + strncat(hexstr, " ", sizeof(hexstr)-strlen(hexstr)-1);
3.154 + strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1);
3.155 + }
3.156 + p++; /* next byte */
3.157 + }
3.158 +
3.159 + if (strlen(hexstr) > 0) {
3.160 + /* print rest of buffer if not empty */
3.161 + //printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr);
3.162 + [ret appendString:[NSString stringWithFormat:@"[%4.4s] %-50.50s %s\n",
3.163 + addrstr, hexstr, charstr]];
3.164 + }
3.165 + return ret;
3.166 +}
3.167 +
3.168 +@end
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/CollectionUtils.h Sat Mar 08 21:04:41 2008 -0800
4.3 @@ -0,0 +1,77 @@
4.4 +//
4.5 +// CollectionUtils.h
4.6 +// MYUtilities
4.7 +//
4.8 +// Created by Jens Alfke on 1/5/08.
4.9 +// Copyright 2008 Jens Alfke. All rights reserved.
4.10 +//
4.11 +
4.12 +#import <Cocoa/Cocoa.h>
4.13 +
4.14 +// Collection creation conveniences:
4.15 +
4.16 +#define $array(OBJS...) ({id objs[]={OBJS}; \
4.17 + [NSArray arrayWithObjects: objs count: sizeof(objs)/sizeof(id)];})
4.18 +#define $marray(OBJS...) ({id objs[]={OBJS}; \
4.19 + [NSMutableArray arrayWithObjects: objs count: sizeof(objs)/sizeof(id)];})
4.20 +
4.21 +#define $dict(PAIRS...) ({struct _dictpair pairs[]={PAIRS}; \
4.22 + _dictof(pairs,sizeof(pairs)/sizeof(struct _dictpair));})
4.23 +#define $mdict(PAIRS...) ({struct _dictpair pairs[]={PAIRS}; \
4.24 + _mdictof(pairs,sizeof(pairs)/sizeof(struct _dictpair));})
4.25 +
4.26 +#define $object(VAL) ({__typeof(VAL) v=(VAL); _box(&v,@encode(__typeof(v)));})
4.27 +
4.28 +
4.29 +// Object conveniences:
4.30 +
4.31 +BOOL $equal(id obj1, id obj2); // Like -isEqual: but works even if either/both are nil
4.32 +
4.33 +#define $sprintf(FORMAT, ARGS... ) [NSString stringWithFormat: (FORMAT), ARGS]
4.34 +
4.35 +#define $cast(CLASSNAME,OBJ) (CLASSNAME*)(_cast([CLASSNAME class],(OBJ)))
4.36 +#define $castNotNil(CLASSNAME,OBJ) (CLASSNAME*)(_castNotNil([CLASSNAME class],(OBJ)))
4.37 +#define $castIf(CLASSNAME,OBJ) (CLASSNAME*)(_castIf([CLASSNAME class],(OBJ)))
4.38 +#define $castArrayOf(ITEMCLASSNAME,OBJ) _castArrayOf([ITEMCLASSNAME class],(OBJ)))
4.39 +
4.40 +void setObj( id *var, id value );
4.41 +BOOL ifSetObj( id *var, id value );
4.42 +void setString( NSString **var, NSString *value );
4.43 +BOOL ifSetString( NSString **var, NSString *value );
4.44 +
4.45 +
4.46 +@interface NSArray (MYUtils)
4.47 +- (BOOL) my_containsObjectIdenticalTo: (id)object;
4.48 +@end
4.49 +
4.50 +
4.51 +#pragma mark -
4.52 +#pragma mark FOREACH:
4.53 +
4.54 +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
4.55 +#define foreach(VAR,ARR) for(VAR in ARR)
4.56 +
4.57 +#else
4.58 +struct foreachstate {NSArray *array; unsigned n, i;};
4.59 +static inline struct foreachstate _initforeach( NSArray *arr ) {
4.60 + struct foreachstate s;
4.61 + s.array = arr;
4.62 + s.n = [arr count];
4.63 + s.i = 0;
4.64 + return s;
4.65 +}
4.66 +#define foreach(VAR,ARR) for( struct foreachstate _s = _initforeach((ARR)); \
4.67 + _s.i<_s.n && ((VAR)=[_s.array objectAtIndex: _s.i], YES); \
4.68 + _s.i++ )
4.69 +#endif
4.70 +
4.71 +
4.72 +// Internals (don't use directly)
4.73 +struct _dictpair { id key; id value; };
4.74 +NSDictionary* _dictof(const struct _dictpair*, size_t count);
4.75 +NSMutableDictionary* _mdictof(const struct _dictpair*, size_t count);
4.76 +NSValue* _box(const void *value, const char *encoding);
4.77 +id _cast(Class,id);
4.78 +id _castNotNil(Class,id);
4.79 +id _castIf(Class,id);
4.80 +NSArray* _castArrayOf(Class,NSArray*);
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/CollectionUtils.m Sat Mar 08 21:04:41 2008 -0800
5.3 @@ -0,0 +1,192 @@
5.4 +//
5.5 +// CollectionUtils.m
5.6 +// MYUtilities
5.7 +//
5.8 +// Created by Jens Alfke on 1/5/08.
5.9 +// Copyright 2008 Jens Alfke. All rights reserved.
5.10 +//
5.11 +
5.12 +#import "CollectionUtils.h"
5.13 +#import "Test.h"
5.14 +
5.15 +
5.16 +NSDictionary* _dictof(const struct _dictpair* pairs, size_t count)
5.17 +{
5.18 + CAssert(count<10000);
5.19 + id objects[count], keys[count];
5.20 + size_t n = 0;
5.21 + for( size_t i=0; i<count; i++,pairs++ ) {
5.22 + if( pairs->value ) {
5.23 + objects[n] = pairs->value;
5.24 + keys[n] = pairs->key;
5.25 + n++;
5.26 + }
5.27 + }
5.28 + return [NSDictionary dictionaryWithObjects: objects forKeys: keys count: n];
5.29 +}
5.30 +
5.31 +
5.32 +NSMutableDictionary* _mdictof(const struct _dictpair* pairs, size_t count)
5.33 +{
5.34 + CAssert(count<10000);
5.35 + id objects[count], keys[count];
5.36 + size_t n = 0;
5.37 + for( size_t i=0; i<count; i++,pairs++ ) {
5.38 + if( pairs->value ) {
5.39 + objects[n] = pairs->value;
5.40 + keys[n] = pairs->key;
5.41 + n++;
5.42 + }
5.43 + }
5.44 + return [NSMutableDictionary dictionaryWithObjects: objects forKeys: keys count: n];
5.45 +}
5.46 +
5.47 +
5.48 +BOOL $equal(id obj1, id obj2) // Like -isEqual: but works even if either/both are nil
5.49 +{
5.50 + if( obj1 )
5.51 + return obj2 && [obj1 isEqual: obj2];
5.52 + else
5.53 + return obj2==nil;
5.54 +}
5.55 +
5.56 +
5.57 +NSValue* _box(const void *value, const char *encoding)
5.58 +{
5.59 + // file:///Developer/Documentation/DocSets/com.apple.ADC_Reference_Library.DeveloperTools.docset/Contents/Resources/Documents/documentation/DeveloperTools/gcc-4.0.1/gcc/Type-encoding.html
5.60 + char e = encoding[0];
5.61 + if( e=='r' ) // ignore 'const' modifier
5.62 + e = encoding[1];
5.63 + switch( e ) {
5.64 + case 'c': return [NSNumber numberWithChar: *(char*)value];
5.65 + case 'C': return [NSNumber numberWithUnsignedChar: *(char*)value];
5.66 + case 's': return [NSNumber numberWithShort: *(short*)value];
5.67 + case 'S': return [NSNumber numberWithUnsignedShort: *(unsigned short*)value];
5.68 + case 'i': return [NSNumber numberWithInt: *(int*)value];
5.69 + case 'I': return [NSNumber numberWithUnsignedInt: *(unsigned int*)value];
5.70 + case 'l': return [NSNumber numberWithLong: *(long*)value];
5.71 + case 'L': return [NSNumber numberWithUnsignedLong: *(unsigned long*)value];
5.72 + case 'q': return [NSNumber numberWithLongLong: *(long long*)value];
5.73 + case 'Q': return [NSNumber numberWithUnsignedLongLong: *(unsigned long long*)value];
5.74 + case 'f': return [NSNumber numberWithFloat: *(float*)value];
5.75 + case 'd': return [NSNumber numberWithDouble: *(double*)value];
5.76 + case '*': return [NSString stringWithUTF8String: *(char**)value];
5.77 + case '@': return *(id*)value;
5.78 + default: return [NSValue value: value withObjCType: encoding];
5.79 + }
5.80 +}
5.81 +
5.82 +
5.83 +id _cast( Class requiredClass, id object )
5.84 +{
5.85 + if( object && ! [object isKindOfClass: requiredClass] )
5.86 + [NSException raise: NSInvalidArgumentException format: @"%@ required, but got %@ %p",
5.87 + requiredClass,[object class],object];
5.88 + return object;
5.89 +}
5.90 +
5.91 +id _castNotNil( Class requiredClass, id object )
5.92 +{
5.93 + if( ! [object isKindOfClass: requiredClass] )
5.94 + [NSException raise: NSInvalidArgumentException format: @"%@ required, but got %@ %p",
5.95 + requiredClass,[object class],object];
5.96 + return object;
5.97 +}
5.98 +
5.99 +id _castIf( Class requiredClass, id object )
5.100 +{
5.101 + if( object && ! [object isKindOfClass: requiredClass] )
5.102 + object = nil;
5.103 + return object;
5.104 +}
5.105 +
5.106 +NSArray* _castArrayOf(Class itemClass, NSArray *a)
5.107 +{
5.108 + id item;
5.109 + foreach( item, $cast(NSArray,a) )
5.110 + _cast(itemClass,item);
5.111 + return a;
5.112 +}
5.113 +
5.114 +
5.115 +void setObj( id *var, id value )
5.116 +{
5.117 + if( value != *var ) {
5.118 + [*var release];
5.119 + *var = [value retain];
5.120 + }
5.121 +}
5.122 +
5.123 +BOOL ifSetObj( id *var, id value )
5.124 +{
5.125 + if( value != *var && ![value isEqual: *var] ) {
5.126 + [*var release];
5.127 + *var = [value retain];
5.128 + return YES;
5.129 + } else {
5.130 + return NO;
5.131 + }
5.132 +}
5.133 +
5.134 +
5.135 +void setString( NSString **var, NSString *value )
5.136 +{
5.137 + if( value != *var ) {
5.138 + [*var release];
5.139 + *var = [value copy];
5.140 + }
5.141 +}
5.142 +
5.143 +
5.144 +BOOL ifSetString( NSString **var, NSString *value )
5.145 +{
5.146 + if( value != *var && ![value isEqualToString: *var] ) {
5.147 + [*var release];
5.148 + *var = [value copy];
5.149 + return YES;
5.150 + } else {
5.151 + return NO;
5.152 + }
5.153 +}
5.154 +
5.155 +
5.156 +@implementation NSArray (MYUtils)
5.157 +
5.158 +- (BOOL) my_containsObjectIdenticalTo: (id)object
5.159 +{
5.160 + return [self indexOfObjectIdenticalTo: object] != NSNotFound;
5.161 +}
5.162 +
5.163 +@end
5.164 +
5.165 +
5.166 +#import "Test.h"
5.167 +
5.168 +TestCase(CollectionUtils) {
5.169 + NSArray *a = $array(@"foo",@"bar",@"baz");
5.170 + //Log(@"a = %@",a);
5.171 + NSArray *aa = [NSArray arrayWithObjects: @"foo",@"bar",@"baz",nil];
5.172 + CAssertEqual(a,aa);
5.173 +
5.174 + const char *cstr = "a C string";
5.175 + id o = $object(cstr);
5.176 + //Log(@"o = %@",o);
5.177 + CAssertEqual(o,@"a C string");
5.178 +
5.179 + NSDictionary *d = $dict({@"int", $object(1)},
5.180 + {@"double", $object(-1.1)},
5.181 + {@"char", $object('x')},
5.182 + {@"ulong", $object(1234567UL)},
5.183 + {@"longlong",$object(987654321LL)},
5.184 + {@"cstr", $object(cstr)});
5.185 + //Log(@"d = %@",d);
5.186 + NSDictionary *dd = [NSDictionary dictionaryWithObjectsAndKeys:
5.187 + [NSNumber numberWithInt: 1], @"int",
5.188 + [NSNumber numberWithDouble: -1.1], @"double",
5.189 + [NSNumber numberWithChar: 'x'], @"char",
5.190 + [NSNumber numberWithUnsignedLong: 1234567UL], @"ulong",
5.191 + [NSNumber numberWithDouble: 987654321LL], @"longlong",
5.192 + @"a C string", @"cstr",
5.193 + nil];
5.194 + CAssertEqual(d,dd);
5.195 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/ConcurrentOperation.h Sat Mar 08 21:04:41 2008 -0800
6.3 @@ -0,0 +1,19 @@
6.4 +//
6.5 +// ConcurrentOperation.h
6.6 +// MYUtilities
6.7 +//
6.8 +// Created by Jens Alfke on 2/5/08.
6.9 +// Copyright 2008 Jens Alfke. All rights reserved.
6.10 +//
6.11 +
6.12 +#import <Foundation/Foundation.h>
6.13 +
6.14 +
6.15 +@interface ConcurrentOperation : NSOperation
6.16 +{
6.17 + BOOL _isExecuting, _isFinished;
6.18 +}
6.19 +
6.20 +- (void) finish;
6.21 +
6.22 +@end
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/ConcurrentOperation.m Sat Mar 08 21:04:41 2008 -0800
7.3 @@ -0,0 +1,67 @@
7.4 +//
7.5 +// ConcurrentOperation.m
7.6 +// MYUtilities
7.7 +//
7.8 +// Created by Jens Alfke on 2/5/08.
7.9 +// Copyright 2008 Jens Alfke. All rights reserved.
7.10 +//
7.11 +
7.12 +#import "ConcurrentOperation.h"
7.13 +
7.14 +// See file:///Developer/Documentation/DocSets/com.apple.ADC_Reference_Library.CoreReference.docset/Contents/Resources/Documents/documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.html#//apple_ref/doc/uid/TP40004591-RH2-DontLinkElementID_4
7.15 +
7.16 +
7.17 +@implementation ConcurrentOperation
7.18 +
7.19 +
7.20 +- (BOOL) isConcurrent {return YES;}
7.21 +
7.22 +- (void) main
7.23 +{
7.24 + Assert(NO,@"Shouldn't call -main method of ConcurrentOperation");
7.25 +}
7.26 +
7.27 +- (BOOL) isExecuting
7.28 +{
7.29 + return _isExecuting;
7.30 +}
7.31 +
7.32 +- (BOOL) isFinished
7.33 +{
7.34 + return _isFinished;
7.35 +}
7.36 +
7.37 +- (void) start
7.38 +{
7.39 + // don't call super!
7.40 + Log(@"Starting %@",self);
7.41 + [self willChangeValueForKey: @"isExecuting"];
7.42 + _isExecuting = YES;
7.43 + [self didChangeValueForKey: @"isExecuting"];
7.44 +}
7.45 +
7.46 +- (void) finish
7.47 +{
7.48 + Log(@"Finished %@",self);
7.49 + [self willChangeValueForKey: @"isExecuting"];
7.50 + [self willChangeValueForKey: @"isFinished"];
7.51 + _isExecuting = NO;
7.52 + _isFinished = YES;
7.53 + [self didChangeValueForKey: @"isFinished"];
7.54 + [self didChangeValueForKey: @"isExecuting"];
7.55 +}
7.56 +
7.57 +
7.58 +- (void) cancel
7.59 +{
7.60 + Log(@"Canceling %@",self);
7.61 + [super cancel];
7.62 + if( _isExecuting ) {
7.63 + [self willChangeValueForKey: @"isExecuting"];
7.64 + _isExecuting = NO;
7.65 + [self didChangeValueForKey: @"isExecuting"];
7.66 + }
7.67 +}
7.68 +
7.69 +
7.70 +@end
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/FileAlias.h Sat Mar 08 21:04:41 2008 -0800
8.3 @@ -0,0 +1,39 @@
8.4 +//
8.5 +// FileAlias.h
8.6 +// MYUtilities
8.7 +//
8.8 +// Copyright 2008 Jens Alfke. All rights reserved.
8.9 +//
8.10 +
8.11 +#import <Foundation/Foundation.h>
8.12 +
8.13 +
8.14 +/** A wrapper around an AliasHandle: a persistent reference to a file, which works
8.15 + even if the file is moved or renamed, or its volume unmounted. */
8.16 +
8.17 +@interface FileAlias : NSObject <NSCoding>
8.18 +{
8.19 + AliasHandle _alias;
8.20 +}
8.21 +
8.22 +- (id) initWithFilePath: (NSString*)path
8.23 + error: (NSError**)error;
8.24 +
8.25 +- (id) initWithFilePath: (NSString*)path
8.26 + relativeToPath: (NSString*)fromPath
8.27 + error: (NSError**)error;
8.28 +
8.29 +- (NSString*) filePath: (NSError**)error;
8.30 +- (NSString*) filePathRelativeToPath: (NSString*)fromPath error: (NSError**)error;
8.31 +
8.32 +- (NSArray*) findMatchesRelativeToPath: (NSString*)fromPath
8.33 + withRules: (unsigned)rules // rules = kARMSearch etc.
8.34 + error: (NSError**)error;
8.35 +- (NSArray*) findMatches: (NSError**)error;
8.36 +
8.37 +- (NSString*) originalPath;
8.38 +- (NSString*) originalFilename;
8.39 +- (NSString*) originalVolumeName;
8.40 +- (void) dump;
8.41 +
8.42 +@end
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/FileAlias.m Sat Mar 08 21:04:41 2008 -0800
9.3 @@ -0,0 +1,231 @@
9.4 +//
9.5 +// FileAlias.m
9.6 +// MYUtilities
9.7 +//
9.8 +// Copyright 2008 Jens Alfke. All rights reserved.
9.9 +//
9.10 +
9.11 +#import "FileAlias.h"
9.12 +#import "FileUtils.h"
9.13 +
9.14 +
9.15 +@implementation FileAlias
9.16 +
9.17 +
9.18 +- (id) initWithFilePath: (NSString*)targetPath
9.19 + relativeToPath: (NSString*)fromPath
9.20 + error: (NSError**)error
9.21 +{
9.22 + NSParameterAssert(targetPath);
9.23 + self = [super init];
9.24 + if( self ) {
9.25 + OSStatus err;
9.26 + FSRef fromRef, targetRef;
9.27 + err = PathToFSRef(targetPath, &targetRef);
9.28 + if( ! err ) {
9.29 + if( fromPath ) {
9.30 + err = PathToFSRef(fromPath,&fromRef);
9.31 + if( ! err )
9.32 + err = FSNewAlias(&fromRef,&targetRef,&_alias);
9.33 + } else {
9.34 + err = FSNewAlias(NULL,&targetRef,&_alias);
9.35 + }
9.36 + }
9.37 +
9.38 + if( ! CheckOSErr(err,error) ) {
9.39 + Warn(@"FileAlias init failed with OSStatus %i",err);
9.40 + [self release];
9.41 + return nil;
9.42 + }
9.43 + }
9.44 + return self;
9.45 +}
9.46 +
9.47 +- (id) initWithFilePath: (NSString*)path
9.48 + error: (NSError**)error
9.49 +{
9.50 + return [self initWithFilePath: path relativeToPath: nil error: error];
9.51 +}
9.52 +
9.53 +
9.54 +- (void) dealloc
9.55 +{
9.56 + if( _alias )
9.57 + DisposeHandle((Handle)_alias);
9.58 + [super dealloc];
9.59 +}
9.60 +
9.61 +
9.62 +- (void)encodeWithCoder:(NSCoder *)coder
9.63 +{
9.64 + NSParameterAssert([coder allowsKeyedCoding]);
9.65 + NSKeyedArchiver *arch = (NSKeyedArchiver*)coder;
9.66 +
9.67 + [arch encodeBytes: (const uint8_t *) *_alias
9.68 + length: GetHandleSize((Handle)_alias)
9.69 + forKey: @"aliasHandle"];
9.70 +}
9.71 +
9.72 +
9.73 +- (id)initWithCoder:(NSCoder *)decoder
9.74 +{
9.75 + NSParameterAssert([decoder allowsKeyedCoding]);
9.76 + NSKeyedUnarchiver *arch = (NSKeyedUnarchiver*)decoder;
9.77 +
9.78 + self = [super init];
9.79 + if( self ) {
9.80 + Handle handle;
9.81 + unsigned length;
9.82 + const void *bytes = [arch decodeBytesForKey:@"aliasHandle" returnedLength: &length];
9.83 + if( bytes )
9.84 + PtrToHand(bytes,&handle,length);
9.85 + if( ! handle ) {
9.86 + [self release];
9.87 + return nil;
9.88 + }
9.89 + _alias = (AliasHandle) handle;
9.90 + }
9.91 + return self;
9.92 +}
9.93 +
9.94 +
9.95 +- (NSString*) description
9.96 +{
9.97 + return [NSString stringWithFormat: @"%@['%@']", [self class],[self originalFilename]];
9.98 +}
9.99 +
9.100 +
9.101 +- (NSString*) originalPath
9.102 +{
9.103 + CFStringRef path = NULL;
9.104 + OSStatus err = FSCopyAliasInfo(_alias,NULL,NULL,&path,NULL,NULL);
9.105 + if( err )
9.106 + return nil;
9.107 + else
9.108 + return [(id)path autorelease];
9.109 +}
9.110 +
9.111 +- (NSString*) originalFilename
9.112 +{
9.113 + HFSUniStr255 targetName;
9.114 + OSStatus err = FSCopyAliasInfo(_alias,&targetName,NULL,NULL,NULL,NULL);
9.115 + if( err )
9.116 + return nil;
9.117 + else
9.118 + return [(id)FSCreateStringFromHFSUniStr(NULL,&targetName) autorelease];
9.119 +}
9.120 +
9.121 +- (NSString*) originalVolumeName
9.122 +{
9.123 + HFSUniStr255 volName;
9.124 + OSStatus err = FSCopyAliasInfo(_alias,NULL,&volName,NULL,NULL,NULL);
9.125 + if( err )
9.126 + return nil;
9.127 + else
9.128 + return [(id)FSCreateStringFromHFSUniStr(NULL,&volName) autorelease];
9.129 +}
9.130 +
9.131 +- (void) dump
9.132 +{
9.133 + HFSUniStr255 targetName,volName;
9.134 + CFStringRef path;
9.135 + FSAliasInfoBitmap whichInfo = 0;
9.136 + FSAliasInfo info;
9.137 + OSStatus err = FSCopyAliasInfo(_alias,&targetName,&volName,&path,&whichInfo,&info);
9.138 + if( err ) {
9.139 + NSLog(@"FSCopyAliasInfo returned error %i",err);
9.140 + return;
9.141 + }
9.142 + NSString *str = (id)FSCreateStringFromHFSUniStr(NULL,&targetName);
9.143 + NSLog(@"Target name = '%@'",str);
9.144 + [str release];
9.145 + str = (id)FSCreateStringFromHFSUniStr(NULL,&volName);
9.146 + NSLog(@"Volume name = '%@'",str);
9.147 + [str release];
9.148 + NSLog(@"Path = %@",path);
9.149 + if( path ) CFRelease(path);
9.150 + NSLog(@"Info bitmap = %08X", whichInfo);
9.151 +}
9.152 +
9.153 +
9.154 +#pragma mark -
9.155 +#pragma mark RESOLVING:
9.156 +
9.157 +
9.158 +- (NSString*) filePathRelativeToPath: (NSString*)fromPath error: (NSError**)error
9.159 +{
9.160 + FSRef fromRef, targetRef, *fromRefPtr;
9.161 + if( fromPath ) {
9.162 + if( ! CheckOSErr( PathToFSRef(fromPath,&fromRef), error ) )
9.163 + return NO;
9.164 + fromRefPtr = &fromRef;
9.165 + } else {
9.166 + fromRefPtr = NULL;
9.167 + }
9.168 +
9.169 + Boolean wasChanged;
9.170 + NSString *targetPath;
9.171 + if( CheckOSErr( FSResolveAlias(fromRefPtr,_alias,&targetRef,&wasChanged), error)
9.172 + && CheckOSErr( FSRefToPath(&targetRef,&targetPath), error ) )
9.173 + return targetPath;
9.174 + else {
9.175 + NSLog(@"%@: Couldn't resolve alias!",self);
9.176 + [self dump];
9.177 + return nil;
9.178 + }
9.179 +}
9.180 +
9.181 +- (NSString*) filePath: (NSError**)error
9.182 +{
9.183 + return [self filePathRelativeToPath: nil error: error];
9.184 +}
9.185 +
9.186 +
9.187 +- (NSArray*) findMatchesRelativeToPath: (NSString*)fromPath
9.188 + withRules: (unsigned)rules
9.189 + error: (NSError**)error
9.190 +{
9.191 + FSRef fromRef, *fromRefPtr;
9.192 + if( fromPath ) {
9.193 + if( ! CheckOSErr( PathToFSRef(fromPath,&fromRef), error ) )
9.194 + return nil;
9.195 + fromRefPtr = &fromRef;
9.196 + } else {
9.197 + fromRefPtr = NULL;
9.198 + }
9.199 +
9.200 + Boolean wasChanged;
9.201 + short count = 10;
9.202 + FSRef matches[count];
9.203 +
9.204 +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
9.205 + if( ! FSMatchAliasBulk(fromRefPtr, rules, _alias, &count, matches, &wasChanged, NULL, NULL), error ) {
9.206 + NSLog(@"%@: FSMatchAliasBulk failed!",self);
9.207 + return nil;
9.208 + }
9.209 +#else
9.210 + if( ! CheckOSErr( FSMatchAlias(fromRefPtr,rules,_alias,&count,matches,&wasChanged,NULL,NULL), error) ) {
9.211 + NSLog(@"%@: FSMatchAlias failed!",self);
9.212 + return nil;
9.213 + }
9.214 +#endif
9.215 +
9.216 + NSMutableArray *paths = [NSMutableArray arrayWithCapacity: count];
9.217 + for( short i=0; i<count; i++ ) {
9.218 + NSString *path;
9.219 + if( FSRefToPath(&matches[i],&path) == noErr )
9.220 + [paths addObject: path];
9.221 + }
9.222 + return paths;
9.223 +}
9.224 +
9.225 +
9.226 +- (NSArray*) findMatches: (NSError**)error
9.227 +{
9.228 + return [self findMatchesRelativeToPath: nil
9.229 + withRules: kARMMultVols | kARMSearch | kARMSearchMore | kARMTryFileIDFirst
9.230 + error: error];
9.231 +}
9.232 +
9.233 +
9.234 +@end
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/FileUtils.h Sat Mar 08 21:04:41 2008 -0800
10.3 @@ -0,0 +1,17 @@
10.4 +//
10.5 +// FileUtils.h
10.6 +// MYUtilities
10.7 +//
10.8 +// Created by Jens Alfke on 1/14/08.
10.9 +// Copyright 2008 Jens Alfke. All rights reserved.
10.10 +//
10.11 +
10.12 +#import <Foundation/Foundation.h>
10.13 +
10.14 +
10.15 +FOUNDATION_EXPORT OSStatus PathToFSRef( NSString *path, FSRef *outFSRef );
10.16 +FOUNDATION_EXPORT OSStatus FSRefToPath( const FSRef *fsRef, NSString **outPath );
10.17 +
10.18 +FOUNDATION_EXPORT BOOL CheckOSErr( OSStatus err, NSError **error );
10.19 +
10.20 +FOUNDATION_EXPORT NSString* AppSupportDirectory(void);
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/FileUtils.m Sat Mar 08 21:04:41 2008 -0800
11.3 @@ -0,0 +1,55 @@
11.4 +//
11.5 +// FileUtils.m
11.6 +// MYUtilities
11.7 +//
11.8 +// Created by Jens Alfke on 1/14/08.
11.9 +// Copyright 2008 Jens Alfke. All rights reserved.
11.10 +//
11.11 +
11.12 +#import "FileUtils.h"
11.13 +
11.14 +
11.15 +OSStatus PathToFSRef( NSString *path, FSRef *fsRef )
11.16 +{
11.17 + NSCParameterAssert(path);
11.18 + return FSPathMakeRef((const UInt8 *)[path UTF8String],fsRef,NULL);
11.19 +}
11.20 +
11.21 +OSStatus FSRefToPath( const FSRef *fsRef, NSString **outPath )
11.22 +{
11.23 + NSURL *url = (id) CFURLCreateFromFSRef(NULL,fsRef);
11.24 + if( ! url )
11.25 + return paramErr;
11.26 + *outPath = [url path];
11.27 + [url release];
11.28 + return noErr;
11.29 +}
11.30 +
11.31 +
11.32 +BOOL CheckOSErr( OSStatus err, NSError **error )
11.33 +{
11.34 + if( err ) {
11.35 + if( error )
11.36 + *error = [NSError errorWithDomain: NSOSStatusErrorDomain code: err userInfo: nil];
11.37 + return NO;
11.38 + } else {
11.39 + return YES;
11.40 + }
11.41 +}
11.42 +
11.43 +
11.44 +NSString* AppSupportDirectory()
11.45 +{
11.46 + static NSString *sPath;
11.47 + if( ! sPath ) {
11.48 + NSString *dir = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory,
11.49 + NSUserDomainMask, YES)
11.50 + objectAtIndex: 0];
11.51 + dir = [dir stringByAppendingPathComponent: [[NSBundle mainBundle] bundleIdentifier]];
11.52 + if( ! [[NSFileManager defaultManager] fileExistsAtPath: dir]
11.53 + && ! [[NSFileManager defaultManager] createDirectoryAtPath: dir attributes: nil] )
11.54 + [NSException raise: NSGenericException format: @"Unable to create app support dir %@",dir];
11.55 + sPath = [dir copy];
11.56 + }
11.57 + return sPath;
11.58 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/GraphicsUtils.h Sat Mar 08 21:04:41 2008 -0800
12.3 @@ -0,0 +1,21 @@
12.4 +//
12.5 +// GraphicsUtils.h
12.6 +// MYUtilities
12.7 +//
12.8 +// Copyright 2008 Jens Alfke. All rights reserved.
12.9 +//
12.10 +
12.11 +#import <Cocoa/Cocoa.h>
12.12 +
12.13 +
12.14 +@interface NSImage (MYUtilities)
12.15 +- (NSImage*) my_shrunkToFitIn: (NSSize) maxSize;
12.16 +- (NSSize) my_sizeOfLargestRep;
12.17 +- (NSData*) my_JPEGData;
12.18 +//- (NSData*) my)_PICTData;
12.19 +@end
12.20 +
12.21 +
12.22 +@interface NSBezierPath (MYUtilities)
12.23 ++ (NSBezierPath*) my_bezierPathWithRoundRect: (NSRect)rect radius: (float)radius;
12.24 +@end
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/GraphicsUtils.m Sat Mar 08 21:04:41 2008 -0800
13.3 @@ -0,0 +1,190 @@
13.4 +//
13.5 +// GraphicsUtils.m
13.6 +// MYUtilities
13.7 +//
13.8 +// Copyright 2008 Jens Alfke. All rights reserved.
13.9 +//
13.10 +
13.11 +#import "GraphicsUtils.h"
13.12 +
13.13 +
13.14 +@implementation NSImage (MYUtilities)
13.15 +
13.16 +
13.17 +- (NSSize) my_sizeOfLargestRep
13.18 +{
13.19 + NSArray *reps = [self representations];
13.20 + NSSize max = {0,0};
13.21 + int i;
13.22 + for( i=[reps count]-1; i>=0; i-- ) {
13.23 + NSImageRep *rep = [reps objectAtIndex: i];
13.24 + NSSize size = [rep size];
13.25 + if( size.width > max.width || size.height > max.height ) {
13.26 + max = size;
13.27 + }
13.28 + }
13.29 + return max;
13.30 +}
13.31 +
13.32 +
13.33 +- (NSImage*) my_shrunkToFitIn: (NSSize) maxSize
13.34 +{
13.35 + NSSize size = self.size;
13.36 + float scale = MIN( size.width/maxSize.width, size.height/maxSize.height );
13.37 + if( scale >= 1.0 )
13.38 + return self;
13.39 +
13.40 + NSSize newSize = {roundf(size.width*scale), roundf(size.height*scale)};
13.41 + NSImage *newImage = [[NSImage alloc] initWithSize: newSize];
13.42 + [newImage lockFocus];
13.43 + NSGraphicsContext *context = [NSGraphicsContext currentContext];
13.44 + [context saveGraphicsState];
13.45 + [context setImageInterpolation: NSImageInterpolationHigh];
13.46 + [self drawInRect: NSMakeRect(0,0,newSize.width,newSize.height)
13.47 + fromRect: NSMakeRect(0,0,size.width,size.height)
13.48 + operation: NSCompositeCopy fraction: 1.0f];
13.49 + [context restoreGraphicsState];
13.50 + [newImage unlockFocus];
13.51 + return [newImage autorelease];
13.52 +}
13.53 +
13.54 +
13.55 +- (NSData*) my_JPEGData
13.56 +{
13.57 + NSImage *tiffImage = [[NSImage alloc] initWithData:[self TIFFRepresentation]];
13.58 + NSBitmapImageRep *rep = [[tiffImage representations] objectAtIndex:0];
13.59 + NSDictionary *props = [NSDictionary dictionaryWithObjectsAndKeys:
13.60 + [NSNumber numberWithFloat: 0.75f], NSImageCompressionFactor, nil];
13.61 + NSData *jpeg = [rep representationUsingType: NSJPEGFileType properties: props];
13.62 + [tiffImage release];
13.63 + return jpeg;
13.64 +}
13.65 +
13.66 +
13.67 +#if 0
13.68 +
13.69 +// Adapted from Apple's CocoaCreateMovie sample
13.70 +// <http://developer.apple.com/samplecode/Sample_Code/QuickTime/Basics/CocoaCreateMovie/MyController.m.htm>
13.71 +static void CopyNSImageRepToGWorld(NSBitmapImageRep *imageRepresentation, GWorldPtr gWorldPtr)
13.72 +{
13.73 + PixMapHandle pixMapHandle;
13.74 + unsigned char* pixBaseAddr;
13.75 +
13.76 + // Lock the pixels
13.77 + pixMapHandle = GetGWorldPixMap(gWorldPtr);
13.78 + LockPixels (pixMapHandle);
13.79 + pixBaseAddr = (unsigned char*) GetPixBaseAddr(pixMapHandle);
13.80 +
13.81 + const unsigned char* bitMapDataPtr = [imageRepresentation bitmapData];
13.82 +
13.83 + if ((bitMapDataPtr != nil) && (pixBaseAddr != nil))
13.84 + {
13.85 + int i,j;
13.86 + int pixmapRowBytes = GetPixRowBytes(pixMapHandle);
13.87 + NSSize imageSize = [imageRepresentation size];
13.88 + for (i=0; i< imageSize.height; i++)
13.89 + {
13.90 + const unsigned char *src = bitMapDataPtr + i * [imageRepresentation bytesPerRow];
13.91 + unsigned char *dst = pixBaseAddr + i * pixmapRowBytes;
13.92 + for (j = 0; j < imageSize.width; j++)
13.93 + {
13.94 + *dst++ = 0; // X - our src is 24-bit only
13.95 + *dst++ = *src++; // Red component
13.96 + *dst++ = *src++; // Green component
13.97 + *dst++ = *src++; // Blue component
13.98 + }
13.99 + }
13.100 + }
13.101 + UnlockPixels(pixMapHandle);
13.102 +}
13.103 +
13.104 +
13.105 +- (NSData*) my_PICTData
13.106 +{
13.107 + // Locate the bitmap image rep:
13.108 + NSBitmapImageRep *rep;
13.109 + NSEnumerator *e = [[self representations] objectEnumerator];
13.110 + while( (rep=[e nextObject]) != nil ) {
13.111 + if( [rep isKindOfClass: [NSBitmapImageRep class]] )
13.112 + break;
13.113 + }
13.114 + if( ! rep ) {
13.115 + Warn(@"No bitmap image rep in image");
13.116 + return nil;
13.117 + }
13.118 +
13.119 + // Copy the image data into a GWorld:
13.120 + Rect bounds;
13.121 + SetRect(&bounds, 0,0,[rep pixelsWide],[rep pixelsHigh]);
13.122 + GWorldPtr gworld;
13.123 + OSStatus err = NewGWorld(&gworld, 32, &bounds, NULL, NULL, 0);
13.124 + if( err ) {
13.125 + Warn(@"NewGWorld failed with err %i",err);
13.126 + return nil;
13.127 + }
13.128 + CopyNSImageRepToGWorld(rep,gworld);
13.129 +
13.130 + // Draw the GWorld into a PicHandle:
13.131 + CGrafPtr oldPort;
13.132 + GDHandle oldDevice;
13.133 + GetGWorld(&oldPort,&oldDevice);
13.134 + SetGWorld(gworld,NULL);
13.135 + ClipRect(&bounds);
13.136 + PicHandle pic = OpenPicture(&bounds);
13.137 + CopyBits(GetPortBitMapForCopyBits(gworld),
13.138 + GetPortBitMapForCopyBits(gworld),
13.139 + &bounds,&bounds,srcCopy,NULL);
13.140 + ClosePicture();
13.141 + err = QDError();
13.142 + SetGWorld(oldPort,oldDevice);
13.143 + DisposeGWorld(gworld);
13.144 +
13.145 + if( err ) {
13.146 + Warn(@"Couldn't convert to PICT: error %i",err);
13.147 + return nil;
13.148 + }
13.149 +
13.150 + // Copy the PicHandle into an NSData:
13.151 + HLock((Handle)pic);
13.152 + //Test to put PICT on clipboard:
13.153 + /*ScrapRef scrap;
13.154 + GetCurrentScrap(&scrap);
13.155 + ClearScrap(&scrap);
13.156 + PutScrapFlavor(scrap,'PICT',0,GetHandleSize((Handle)pic),*pic);*/
13.157 + NSData *data = [NSData dataWithBytes: *pic length: GetHandleSize((Handle)pic)];
13.158 + DisposeHandle((Handle)pic);
13.159 + Log(@"Converted image to %i bytes of PICT data",[data length]);
13.160 + return data;
13.161 +}
13.162 +#endif
13.163 +
13.164 +
13.165 +@end
13.166 +
13.167 +
13.168 +
13.169 +
13.170 +@implementation NSBezierPath (MYUtilities)
13.171 +
13.172 ++ (NSBezierPath*) my_bezierPathWithRoundRect: (NSRect)rect radius: (float)radius
13.173 +{
13.174 + radius = MIN(radius, floorf(rect.size.width/2));
13.175 + float x0 = NSMinX(rect), y0 = NSMinY(rect),
13.176 + x1 = NSMaxX(rect), y1 = NSMaxY(rect);
13.177 + NSBezierPath *path = [NSBezierPath bezierPath];
13.178 +
13.179 + [path moveToPoint: NSMakePoint(x0+radius,y0)];
13.180 +
13.181 + [path appendBezierPathWithArcFromPoint: NSMakePoint(x1,y0)
13.182 + toPoint: NSMakePoint(x1,y1) radius: radius];
13.183 + [path appendBezierPathWithArcFromPoint: NSMakePoint(x1,y1)
13.184 + toPoint: NSMakePoint(x0,y1) radius: radius];
13.185 + [path appendBezierPathWithArcFromPoint: NSMakePoint(x0,y1)
13.186 + toPoint: NSMakePoint(x0,y0) radius: radius];
13.187 + [path appendBezierPathWithArcFromPoint: NSMakePoint(x0,y0)
13.188 + toPoint: NSMakePoint(x1,y0) radius: radius];
13.189 + [path closePath];
13.190 + return path;
13.191 +}
13.192 +
13.193 +@end
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/IChatUtils.h Sat Mar 08 21:04:41 2008 -0800
14.3 @@ -0,0 +1,21 @@
14.4 +//
14.5 +// IChatUtils.h
14.6 +// MYUtilities
14.7 +//
14.8 +// Created by Jens Alfke on 3/3/08.
14.9 +// Copyright 2008 Jens Alfke. All rights reserved.
14.10 +//
14.11 +
14.12 +#import <Cocoa/Cocoa.h>
14.13 +@class SBApplication;
14.14 +
14.15 +
14.16 +@interface IChatUtils : NSObject
14.17 +
14.18 ++ (SBApplication*) app;
14.19 ++ (BOOL) isRunning;
14.20 ++ (void) activate;
14.21 ++ (NSString*) activeChatPartner;
14.22 ++ (BOOL) sendMessage: (NSString*)msg;
14.23 +
14.24 +@end
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/IChatUtils.m Sat Mar 08 21:04:41 2008 -0800
15.3 @@ -0,0 +1,65 @@
15.4 +//
15.5 +// IChatUtils.m
15.6 +// MYUtilities
15.7 +//
15.8 +// Created by Jens Alfke on 3/3/08.
15.9 +// Copyright 2008 Jens Alfke. All rights reserved.
15.10 +//
15.11 +
15.12 +#import "IChatUtils.h"
15.13 +#import "iChatBridge.h"
15.14 +
15.15 +@implementation IChatUtils
15.16 +
15.17 +
15.18 +static iChatApplication *sIChatApp;
15.19 +
15.20 ++ (void) initialize
15.21 +{
15.22 + if( ! sIChatApp ) {
15.23 + sIChatApp = [SBApplication applicationWithBundleIdentifier: @"com.apple.iChat"];
15.24 + sIChatApp.timeout = 5*60; // in ticks
15.25 + }
15.26 +}
15.27 +
15.28 +
15.29 ++ (SBApplication*) app {return sIChatApp;}
15.30 ++ (BOOL) isRunning {return sIChatApp.isRunning;}
15.31 ++ (void) activate {[sIChatApp activate];}
15.32 +
15.33 +
15.34 ++ (iChatTextChat*) activeChat
15.35 +{
15.36 + if( ! [sIChatApp isRunning] )
15.37 + return nil;
15.38 + SBElementArray *chats = sIChatApp.textChats;
15.39 + if( chats.count==0 )
15.40 + return nil;
15.41 + iChatTextChat *chat = [chats objectAtIndex: 0];
15.42 + if( ! chat.active )
15.43 + return nil;
15.44 + return chat;
15.45 +}
15.46 +
15.47 ++ (NSString*) activeChatPartner
15.48 +{
15.49 + iChatTextChat *chat = [self activeChat];
15.50 + if( ! chat )
15.51 + return nil;
15.52 + NSMutableArray *names = $marray();
15.53 + for( iChatBuddy *b in [chat participants] )
15.54 + [names addObject: (b.fullName ?: b.name)];
15.55 + return [names componentsJoinedByString: @", "];
15.56 +}
15.57 +
15.58 ++ (BOOL) sendMessage: (NSString*)msg
15.59 +{
15.60 + iChatTextChat *chat = [self activeChat];
15.61 + if( ! chat )
15.62 + return NO;
15.63 + [sIChatApp send: msg to: chat];
15.64 + return YES;
15.65 +}
15.66 +
15.67 +
15.68 +@end
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/KVUtils.h Sat Mar 08 21:04:41 2008 -0800
16.3 @@ -0,0 +1,66 @@
16.4 +//
16.5 +// KVUtils.h
16.6 +// MYUtilities
16.7 +//
16.8 +// Created by Jens Alfke on 2/25/08.
16.9 +// Copyright 2008 Jens Alfke. All rights reserved.
16.10 +//
16.11 +
16.12 +#import <Cocoa/Cocoa.h>
16.13 +
16.14 +
16.15 +enum {
16.16 + MYKeyValueObservingOptionOnce = 1<<31,
16.17 + MYKeyValueObservingOptionDelayed = 1<<30
16.18 +};
16.19 +
16.20 +
16.21 +
16.22 +@interface Observance : NSObject
16.23 +{
16.24 + id _target;
16.25 + id _observed;
16.26 + NSString *_keyPath;
16.27 + NSKeyValueObservingOptions _options;
16.28 + SEL _action;
16.29 +}
16.30 +
16.31 +- (id) initWithTarget: (id)target
16.32 + action: (SEL)action
16.33 + observed: (id)observed
16.34 + keyPath: (NSString*)keyPath
16.35 + options: (NSKeyValueObservingOptions)options;
16.36 +
16.37 +- (void) stopObserving;
16.38 +
16.39 +@property (readonly) id observed;
16.40 +@property (readonly) NSString* keyPath;
16.41 +
16.42 +@end
16.43 +
16.44 +
16.45 +
16.46 +@interface Observer : NSObject
16.47 +{
16.48 + id _target;
16.49 + NSMutableArray *_observances;
16.50 +}
16.51 +
16.52 +- (id) initWithTarget: (id)target;
16.53 +
16.54 +@property (readonly) id target;
16.55 +
16.56 +- (void) observe: (id)observed
16.57 + keyPath: (NSString*)keyPath
16.58 + options: (NSKeyValueObservingOptions)options
16.59 + action: (SEL)action;
16.60 +
16.61 +- (void) observe: (id)observed
16.62 + keyPath: (NSString*)keyPath
16.63 + action: (SEL)action;
16.64 +
16.65 +- (void) stopObserving: (id)observedOrNil keyPath: (NSString*)keyPathOrNil;
16.66 +
16.67 +- (void) stopObserving;
16.68 +
16.69 +@end
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/KVUtils.m Sat Mar 08 21:04:41 2008 -0800
17.3 @@ -0,0 +1,163 @@
17.4 +//
17.5 +// KVUtils.m
17.6 +// MYUtilities
17.7 +//
17.8 +// Created by Jens Alfke on 2/25/08.
17.9 +// Copyright 2008 Jens Alfke. All rights reserved.
17.10 +//
17.11 +
17.12 +#import "KVUtils.h"
17.13 +
17.14 +
17.15 +@implementation Observance
17.16 +
17.17 +- (id) initWithTarget: (id)target
17.18 + action: (SEL)action
17.19 + observed: (id)observed
17.20 + keyPath: (NSString*)keyPath
17.21 + options: (NSKeyValueObservingOptions)options
17.22 +{
17.23 + self = [super init];
17.24 + if (self != nil) {
17.25 + _target = target;
17.26 + _action = action;
17.27 + _observed = observed;
17.28 + _keyPath = [keyPath copy];
17.29 + _options = options;
17.30 +
17.31 + options &= ~(MYKeyValueObservingOptionOnce | MYKeyValueObservingOptionDelayed);
17.32 +
17.33 + [_observed addObserver: self forKeyPath: _keyPath options: options context: _action];
17.34 + }
17.35 + return self;
17.36 +}
17.37 +
17.38 +- (void) dealloc
17.39 +{
17.40 + [_observed removeObserver: self forKeyPath: _keyPath];
17.41 + [_keyPath release];
17.42 + [super dealloc];
17.43 +}
17.44 +
17.45 +
17.46 +@synthesize observed=_observed, keyPath=_keyPath;
17.47 +
17.48 +
17.49 +- (void) stopObserving
17.50 +{
17.51 + [_observed removeObserver: self forKeyPath: _keyPath];
17.52 + _observed = nil;
17.53 + _target = nil;
17.54 + _action = NULL;
17.55 +}
17.56 +
17.57 +
17.58 +- (void) _callTargetWithChange: (NSDictionary*)change
17.59 +{
17.60 + @try{
17.61 + [_target performSelector: _action withObject: _observed withObject: change];
17.62 + }@catch( NSException *x ) {
17.63 + Warn(@"Uncaught exception in -[%@<%p> %s] while observing change of key-path %@ in %@<%p>: %@",
17.64 + _target,_target, _action, _keyPath, _observed,_observed, x);
17.65 + }
17.66 +}
17.67 +
17.68 +
17.69 +- (void)observeValueForKeyPath:(NSString *)keyPath
17.70 + ofObject:(id)object
17.71 + change:(NSDictionary *)change
17.72 + context:(void *)context
17.73 +{
17.74 + if( object == _observed ) {
17.75 + if( _options & MYKeyValueObservingOptionDelayed )
17.76 + [self performSelector: @selector(_callTargetWithChange:) withObject: change
17.77 + afterDelay: 0.0];
17.78 + else
17.79 + [self _callTargetWithChange: change];
17.80 + if( _options & MYKeyValueObservingOptionOnce )
17.81 + [self stopObserving];
17.82 + }
17.83 +}
17.84 +
17.85 +
17.86 +@end
17.87 +
17.88 +
17.89 +
17.90 +
17.91 +@implementation Observer
17.92 +
17.93 +
17.94 +- (id) init
17.95 +{
17.96 + return [self initWithTarget: self];
17.97 +}
17.98 +
17.99 +
17.100 +
17.101 +- (id) initWithTarget: (id)target
17.102 +{
17.103 + Assert(target);
17.104 + self = [super init];
17.105 + if (self != nil) {
17.106 + _target = target;
17.107 + _observances = [[NSMutableArray alloc] init];
17.108 + }
17.109 + return self;
17.110 +}
17.111 +
17.112 +
17.113 +- (void) dealloc
17.114 +{
17.115 + [self stopObserving];
17.116 + [_observances release];
17.117 + [super dealloc];
17.118 +}
17.119 +
17.120 +
17.121 +@synthesize target=_target;
17.122 +
17.123 +
17.124 +- (void) observe: (id)observed
17.125 + keyPath: (NSString*)keyPath
17.126 + options: (NSKeyValueObservingOptions)options
17.127 + action: (SEL)action
17.128 +{
17.129 + Observance *o = [[Observance alloc] initWithTarget: _target
17.130 + action: action
17.131 + observed: observed
17.132 + keyPath: keyPath
17.133 + options: options];
17.134 + [_observances addObject: o];
17.135 + [o release];
17.136 +}
17.137 +
17.138 +
17.139 +- (void) observe: (id)observed
17.140 + keyPath: (NSString*)keyPath
17.141 + action: (SEL)action
17.142 +{
17.143 + [self observe: observed keyPath: keyPath options: 0 action: action];
17.144 +}
17.145 +
17.146 +
17.147 +- (void) stopObserving
17.148 +{
17.149 + [_observances makeObjectsPerformSelector: @selector(stopObserving)];
17.150 + [_observances removeAllObjects];
17.151 +}
17.152 +
17.153 +
17.154 +- (void) stopObserving: (id)observed keyPath: (NSString*)keyPath
17.155 +{
17.156 + // observed or keyPath may be nil
17.157 + for( int i=_observances.count-1; i>=0; i-- ) {
17.158 + Observance *o = [_observances objectAtIndex: i];
17.159 + if( (observed==nil || observed==o.observed) && (keyPath==nil || [keyPath isEqual: o.keyPath]) ) {
17.160 + [o stopObserving];
17.161 + [_observances removeObjectAtIndex: i];
17.162 + }
17.163 + }
17.164 +}
17.165 +
17.166 +@end
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/Logging.h Sat Mar 08 21:04:41 2008 -0800
18.3 @@ -0,0 +1,23 @@
18.4 +//
18.5 +// Logging.h
18.6 +// MYUtilities
18.7 +//
18.8 +// Created by Jens Alfke on 1/5/08.
18.9 +// Copyright 2008 Jens Alfke. All rights reserved.
18.10 +//
18.11 +
18.12 +#import <Cocoa/Cocoa.h>
18.13 +
18.14 +
18.15 +NSString* LOC( NSString *key ); // Localized string lookup
18.16 +
18.17 +
18.18 +#define Log(FMT,ARGS...) do{if(__builtin_expect(gShouldLog,0)) _Log(FMT,##ARGS);}while(0)
18.19 +#define Warn Warn
18.20 +
18.21 +void AlwaysLog( NSString *msg, ... ) __attribute__((format(__NSString__, 1, 2)));
18.22 +
18.23 +
18.24 +extern int gShouldLog;
18.25 +void _Log( NSString *msg, ... ) __attribute__((format(__NSString__, 1, 2)));
18.26 +void Warn( NSString *msg, ... ) __attribute__((format(__NSString__, 1, 2)));
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/Logging.m Sat Mar 08 21:04:41 2008 -0800
19.3 @@ -0,0 +1,96 @@
19.4 +//
19.5 +// Logging.m
19.6 +// MYUtilities
19.7 +//
19.8 +// Created by Jens Alfke on 1/5/08.
19.9 +// Copyright 2008 Jens Alfke. All rights reserved.
19.10 +//
19.11 +
19.12 +#import "Logging.h"
19.13 +#import <unistd.h>
19.14 +#include <fcntl.h>
19.15 +#include <sys/param.h>
19.16 +
19.17 +
19.18 +NSString* LOC( NSString *key ) // Localized string lookup
19.19 +{
19.20 + NSString *value = [[NSBundle mainBundle] localizedStringForKey:key value:nil table:nil];
19.21 + if( value == key ) {
19.22 + Warn(@"No localized string for '%@' in Localizable.strings!",key);
19.23 + value = [key uppercaseString];
19.24 + }
19.25 + return value;
19.26 +}
19.27 +
19.28 +
19.29 +int gShouldLog = -1;
19.30 +
19.31 +
19.32 +static BOOL isConsole( int fd )
19.33 +{
19.34 + if( isatty(fd) )
19.35 + return YES;
19.36 + char path[MAXPATHLEN];
19.37 + if( fcntl(fd, F_GETPATH, path) == -1 )
19.38 + return NO;
19.39 + return YES;
19.40 +}
19.41 +
19.42 +
19.43 +static void _Logv( NSString *msg, va_list args )
19.44 +{
19.45 + if( isConsole(STDERR_FILENO) ) {
19.46 + NSAutoreleasePool *pool = [NSAutoreleasePool new];
19.47 + static NSDateFormatter *sTimestampFormat;
19.48 + if( ! sTimestampFormat ) {
19.49 + sTimestampFormat = [[NSDateFormatter alloc] init];
19.50 + sTimestampFormat.dateFormat = @"HH:mm:ss.SSS";
19.51 + }
19.52 + NSDate *now = [[NSDate alloc] init];
19.53 + NSString *timestamp = [sTimestampFormat stringFromDate: now];
19.54 + [now release];
19.55 + msg = [[NSString alloc] initWithFormat: msg arguments: args];
19.56 + NSString *finalMsg = [[NSString alloc] initWithFormat: @"%@| %@\n", timestamp,msg];
19.57 + fputs([finalMsg UTF8String], stderr);
19.58 + [finalMsg release];
19.59 + [msg release];
19.60 + [pool drain];
19.61 + } else
19.62 + NSLogv(msg,args);
19.63 +}
19.64 +
19.65 +
19.66 +void AlwaysLog( NSString *msg, ... )
19.67 +{
19.68 + va_list args;
19.69 + va_start(args,msg);
19.70 + _Logv(msg,args);
19.71 + va_end(args);
19.72 +}
19.73 +
19.74 +
19.75 +void _Log( NSString *msg, ... )
19.76 +{
19.77 + if( gShouldLog == -1 )
19.78 + gShouldLog = [[NSUserDefaults standardUserDefaults] boolForKey: @"Log"];
19.79 +
19.80 + if( gShouldLog ) {
19.81 + va_list args;
19.82 + va_start(args,msg);
19.83 + _Logv(msg,args);
19.84 + va_end(args);
19.85 + }
19.86 +}
19.87 +
19.88 +
19.89 +void Warn( NSString *msg, ... )
19.90 +{
19.91 + msg = [@"WARNING*** " stringByAppendingString: msg];
19.92 +
19.93 + va_list args;
19.94 + va_start(args,msg);
19.95 + _Logv(msg,args);
19.96 + va_end(args);
19.97 +}
19.98 +
19.99 +
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/Target.h Sat Mar 08 21:04:41 2008 -0800
20.3 @@ -0,0 +1,17 @@
20.4 +//
20.5 +// Target.h
20.6 +// MYUtilities
20.7 +//
20.8 +// Created by Jens Alfke on 2/11/08.
20.9 +// Copyright 2008 Jens Alfke. All rights reserved.
20.10 +//
20.11 +
20.12 +#import <Cocoa/Cocoa.h>
20.13 +
20.14 +
20.15 +#define $target(RCVR,METHOD) _mktarget((RCVR),@selector(METHOD))
20.16 +
20.17 +id $calltarget( NSInvocation *target, id sender );
20.18 +
20.19 +
20.20 +NSInvocation* _mktarget( id rcvr, SEL action );
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/Target.m Sat Mar 08 21:04:41 2008 -0800
21.3 @@ -0,0 +1,53 @@
21.4 +//
21.5 +// Target.m
21.6 +// MYUtilities
21.7 +//
21.8 +// Created by Jens Alfke on 2/11/08.
21.9 +// Copyright 2008 Jens Alfke. All rights reserved.
21.10 +//
21.11 +
21.12 +#import "Target.h"
21.13 +
21.14 +
21.15 +NSInvocation* _mktarget( id rcvr, SEL action )
21.16 +{
21.17 + NSMethodSignature *sig = [rcvr methodSignatureForSelector: action];
21.18 + CAssert(sig,@"%@<%p> does not respond to %@",[rcvr class],rcvr,NSStringFromSelector(action));
21.19 + CAssert(sig.numberOfArguments==3,
21.20 + @"-[%@ %@] can't be used as a target because it takes >1 param",
21.21 + [rcvr class],NSStringFromSelector(action));
21.22 + CAssert(0==strcmp([sig getArgumentTypeAtIndex: 2],"@"),
21.23 + @"-[%@ %@] can't be used as a target because it takes a non-object param",
21.24 + [rcvr class],NSStringFromSelector(action));
21.25 + NSInvocation *inv = [NSInvocation invocationWithMethodSignature: sig];
21.26 + inv.target = rcvr;
21.27 + inv.selector = action;
21.28 + return inv;
21.29 +}
21.30 +
21.31 +
21.32 +id $calltarget( NSInvocation *target, id param )
21.33 +{
21.34 + if( target && target.target ) {
21.35 + [target setArgument: ¶m atIndex: 2];
21.36 + [target invoke];
21.37 +
21.38 + NSMethodSignature *sig = target.methodSignature;
21.39 + NSUInteger returnLength = sig.methodReturnLength;
21.40 + if( returnLength==0 )
21.41 + return nil; // void
21.42 + else {
21.43 + const char *returnType = sig.methodReturnType;
21.44 + if( returnType[0]=='@' ) {
21.45 + id returnObject;
21.46 + [target getReturnValue: &returnObject];
21.47 + return returnObject;
21.48 + } else {
21.49 + UInt8 returnBuffer[returnLength];
21.50 + [target getReturnValue: &returnBuffer];
21.51 + return [NSValue valueWithBytes: &returnBuffer objCType: returnType];
21.52 + }
21.53 + }
21.54 + } else
21.55 + return nil;
21.56 +}
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/Test.h Sat Mar 08 21:04:41 2008 -0800
22.3 @@ -0,0 +1,96 @@
22.4 +//
22.5 +// Test.h
22.6 +// MYUtilities
22.7 +//
22.8 +// Created by Jens Alfke on 1/5/08.
22.9 +// Copyright 2008 Jens Alfke. All rights reserved.
22.10 +//
22.11 +
22.12 +#import <Foundation/Foundation.h>
22.13 +#import "CollectionUtils.h"
22.14 +
22.15 +
22.16 +/** Call this first thing in main() to run tests.
22.17 + This function is a no-op if the DEBUG macro is not defined (i.e. in a release build).
22.18 + At runtime, to cause a particular test "X" to run, add a command-line argument "Test_X".
22.19 + To run all tests, add the argument "Test_All".
22.20 + To run only tests without starting the main program, add the argument "Test_Only". */
22.21 +#if DEBUG
22.22 +void RunTestCases( int argc, const char **argv );
22.23 +#else
22.24 +#define RunTestCases(ARGC,ARGV)
22.25 +#endif
22.26 +
22.27 +/** The TestCase() macro declares a test case.
22.28 + Its argument is a name for the test case (without quotes), and it's followed with a block
22.29 + of code implementing the test.
22.30 + The code should raise an exception if anything fails.
22.31 + The CAssert, CAssertEqual and CAssertEq macros, below, are the most useful way to do this.
22.32 + A test case can register a dependency on another test case by calling RequireTestCase().
22.33 + Example:
22.34 + TestCase(MyLib) {
22.35 + RequireTestCase("LibIDependOn");
22.36 + CAssertEq( myFunction(), 12345 );
22.37 + }
22.38 + Test cases are disabled if the DEBUG macro is not defined (i.e. in a release build). */
22.39 +#if DEBUG
22.40 +#define TestCase(NAME) void Test_##NAME(void); \
22.41 + struct TestCaseLink linkToTest##NAME = {&Test_##NAME,#NAME}; \
22.42 + __attribute__((constructor)) static void registerTestCase##NAME() \
22.43 + {linkToTest##NAME.next = gAllTestCases; gAllTestCases=&linkToTest##NAME; } \
22.44 + void Test_##NAME(void)
22.45 +#else
22.46 +#define TestCase(NAME) __attribute__((unused)) static void Test_##NAME(void)
22.47 +#endif
22.48 +
22.49 +/** Can call this in a test case to indicate a prerequisite.
22.50 + The prerequisite test will be run first, and if it fails, the current test case will be skipped. */
22.51 +#define RequireTestCase(NAME) _RequireTestCase(#NAME)
22.52 +void _RequireTestCase( const char *name );
22.53 +
22.54 +
22.55 +
22.56 +/** General-purpose assertions, replacing NSAssert etc.. You can use these outside test cases. */
22.57 +
22.58 +#define Assert(COND,MSG...) do{ if( __builtin_expect(!(COND),NO) ) \
22.59 + _AssertFailed(self,(const char*)_cmd, __FILE__, __LINE__,\
22.60 + #COND,##MSG,NULL); }while(0)
22.61 +#define CAssert(COND,MSG...) do{ if( __builtin_expect(!(COND),NO) ) \
22.62 + _AssertFailed(nil, __PRETTY_FUNCTION__, __FILE__, __LINE__,\
22.63 + #COND,##MSG,NULL); }while(0)
22.64 +
22.65 +#define AssertEqual(VAL,EXPECTED) do{ id _val = VAL, _expected = EXPECTED;\
22.66 + Assert(_val==_expected || [_val isEqual: _expected], @"Unexpected value for %s: %@ (expected %@)", #VAL,_val,_expected); \
22.67 + }while(0)
22.68 +#define CAssertEqual(VAL,EXPECTED) do{ id _val = (VAL), _expected = (EXPECTED);\
22.69 + CAssert(_val==_expected || [_val isEqual: _expected], @"Unexpected value for %s: %@ (expected %@)", #VAL,_val,_expected); \
22.70 + }while(0)
22.71 +
22.72 +// AssertEq is for scalars (int, float...)
22.73 +#define AssertEq(VAL,EXPECTED) do{ typeof(VAL) _val = VAL; typeof(EXPECTED) _expected = EXPECTED;\
22.74 + Assert(_val==_expected, @"Unexpected value for %s: %@ (expected %@)", #VAL,$object(_val),$object(_expected)); \
22.75 + }while(0)
22.76 +#define CAssertEq(VAL,EXPECTED) do{ typeof(VAL) _val = VAL; typeof(EXPECTED) _expected = EXPECTED;\
22.77 + CAssert(_val==_expected, @"Unexpected value for %s: %@ (expected %@)", #VAL,$object(_val),$object(_expected)); \
22.78 + }while(0)
22.79 +
22.80 +
22.81 +#pragma mark -
22.82 +#pragma mark EXCEPTION UTILITIES:
22.83 +
22.84 +@interface NSException (MooseyardUtil)
22.85 +/** Returns a textual, human-readable backtrace of the point where the exception was thrown. */
22.86 +- (NSString*) my_callStack;
22.87 +@end
22.88 +
22.89 +
22.90 +
22.91 +// Nasty internals ...
22.92 +#if DEBUG
22.93 +void _RunTestCase( void (*testptr)(), const char *name );
22.94 +
22.95 +struct TestCaseLink {void (*testptr)(); const char *name; BOOL passed; struct TestCaseLink *next;};
22.96 +extern struct TestCaseLink *gAllTestCases;
22.97 +#endif DEBUG
22.98 +void _AssertFailed( id rcvr, const char *selOrFn, const char *sourceFile, int sourceLine,
22.99 + const char *condString, NSString *message, ... ) __attribute__((noreturn));
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/Test.m Sat Mar 08 21:04:41 2008 -0800
23.3 @@ -0,0 +1,203 @@
23.4 +//
23.5 +// Test.m
23.6 +// MYUtilities
23.7 +//
23.8 +// Created by Jens Alfke on 1/5/08.
23.9 +// Copyright 2008 Jens Alfke. All rights reserved.
23.10 +//
23.11 +
23.12 +#import "Test.h"
23.13 +#import <unistd.h>
23.14 +
23.15 +#if DEBUG
23.16 +
23.17 +struct TestCaseLink *gAllTestCases;
23.18 +static int sPassed, sFailed;
23.19 +
23.20 +static BOOL RunTestCase( struct TestCaseLink *test )
23.21 +{
23.22 + if( test->testptr ) {
23.23 + NSAutoreleasePool *pool = [NSAutoreleasePool new];
23.24 + Log(@"=== Testing %s ...",test->name);
23.25 + @try{
23.26 + test->testptr();
23.27 + Log(@"√√√ %s passed\n\n",test->name);
23.28 + test->passed = YES;
23.29 + sPassed++;
23.30 + }@catch( NSException *x ) {
23.31 + if( [x.name isEqualToString: @"TestCaseSkipped"] )
23.32 + Log(@"... skipping test %s since %@\n\n", test->name, x.reason);
23.33 + else {
23.34 + Log(@"XXX FAILED test case '%s' due to:\nException: %@\n%@\n\n",
23.35 + test->name,x,x.my_callStack);
23.36 + sFailed++;
23.37 + }
23.38 + }@finally{
23.39 + [pool drain];
23.40 + test->testptr = NULL; // prevents test from being run again
23.41 + }
23.42 + }
23.43 + return test->passed;
23.44 +}
23.45 +
23.46 +
23.47 +static BOOL RunTestCaseNamed( const char *name )
23.48 +{
23.49 + for( struct TestCaseLink *test = gAllTestCases; test; test=test->next )
23.50 + if( strcmp(name,test->name)==0 ) {
23.51 + return RunTestCase(test);
23.52 + }
23.53 + Log(@"... WARNING: Could not find test case named '%s'\n\n",name);
23.54 + return NO;
23.55 +}
23.56 +
23.57 +
23.58 +void _RequireTestCase( const char *name )
23.59 +{
23.60 + if( ! RunTestCaseNamed(name) ) {
23.61 + [NSException raise: @"TestCaseSkipped"
23.62 + format: @"prerequisite %s failed", name];
23.63 + }
23.64 +}
23.65 +
23.66 +
23.67 +void RunTestCases( int argc, const char **argv )
23.68 +{
23.69 + gShouldLog = YES;
23.70 + sPassed = sFailed = 0;
23.71 + BOOL stopAfterTests = NO;
23.72 + for( int i=1; i<argc; i++ ) {
23.73 + const char *arg = argv[i];
23.74 + if( strncmp(arg,"Test_",5)==0 ) {
23.75 + arg += 5;
23.76 + if( strcmp(arg,"Only")==0 )
23.77 + stopAfterTests = YES;
23.78 + else if( strcmp(arg,"All") == 0 ) {
23.79 + for( struct TestCaseLink *link = gAllTestCases; link; link=link->next )
23.80 + RunTestCase(link);
23.81 + } else {
23.82 + RunTestCaseNamed(arg);
23.83 + }
23.84 + }
23.85 + }
23.86 + if( sPassed>0 || sFailed>0 || stopAfterTests ) {
23.87 + if( sFailed==0 )
23.88 + Log(@"√√√√√√ ALL %i TESTS PASSED √√√√√√", sPassed);
23.89 + else {
23.90 + Log(@"****** %i TESTS FAILED, %i PASSED ******", sFailed,sPassed);
23.91 + exit(1);
23.92 + }
23.93 + if( stopAfterTests ) {
23.94 + Log(@"Stopping after tests ('Test_Only' arg detected)");
23.95 + exit(0);
23.96 + }
23.97 + }
23.98 +}
23.99 +
23.100 +
23.101 +#endif DEBUG
23.102 +
23.103 +
23.104 +#pragma mark -
23.105 +#pragma mark ASSERTION FAILURE HANDLER:
23.106 +
23.107 +
23.108 +void _AssertFailed( id rcvr, const char *selOrFn, const char *sourceFile, int sourceLine,
23.109 + const char *condString, NSString *message, ... )
23.110 +{
23.111 + if( message ) {
23.112 + va_list args;
23.113 + va_start(args,message);
23.114 + message = [[[NSString alloc] initWithFormat: message arguments: args] autorelease];
23.115 + va_end(args);
23.116 + } else
23.117 + message = [NSString stringWithUTF8String: condString];
23.118 +
23.119 + if( rcvr )
23.120 + [[NSAssertionHandler currentHandler] handleFailureInMethod: (SEL)selOrFn
23.121 + object: rcvr
23.122 + file: [NSString stringWithUTF8String: sourceFile]
23.123 + lineNumber: sourceLine
23.124 + description: @"%@", message];
23.125 + else
23.126 + [[NSAssertionHandler currentHandler] handleFailureInFunction: [NSString stringWithUTF8String:selOrFn]
23.127 + file: [NSString stringWithUTF8String: sourceFile]
23.128 + lineNumber: sourceLine
23.129 + description: @"%@", message];
23.130 + abort(); // unreachable, but appeases compiler
23.131 +}
23.132 +
23.133 +
23.134 +#pragma mark -
23.135 +#pragma mark EXCEPTION BACKTRACES:
23.136 +
23.137 +
23.138 +@implementation NSException (MooseyardUtil)
23.139 +
23.140 +
23.141 +- (NSArray*) my_callStackReturnAddresses
23.142 +{
23.143 + // On 10.5 or later, can get the backtrace:
23.144 + if( [self respondsToSelector: @selector(callStackReturnAddresses)] )
23.145 + return [self valueForKey: @"callStackReturnAddresses"];
23.146 + else
23.147 + return nil;
23.148 +}
23.149 +
23.150 +- (NSArray*) my_callStackReturnAddressesSkipping: (unsigned)skip limit: (unsigned)limit
23.151 +{
23.152 + NSArray *addresses = [self my_callStackReturnAddresses];
23.153 + if( addresses ) {
23.154 + unsigned n = [addresses count];
23.155 + skip = MIN(skip,n);
23.156 + limit = MIN(limit,n-skip);
23.157 + addresses = [addresses subarrayWithRange: NSMakeRange(skip,limit)];
23.158 + }
23.159 + return addresses;
23.160 +}
23.161 +
23.162 +
23.163 +- (NSString*) my_callStack
23.164 +{
23.165 + NSArray *addresses = [self my_callStackReturnAddressesSkipping: 2 limit: 15];
23.166 + if (!addresses)
23.167 + return nil;
23.168 +
23.169 + // We pipe the hex return addresses through the 'atos' tool to get symbolic names:
23.170 + // Adapted from <http://paste.lisp.org/display/47196>:
23.171 + NSMutableString *cmd = [NSMutableString stringWithFormat: @"/usr/bin/atos -p %d", getpid()];
23.172 + NSValue *addr;
23.173 + foreach(addr,addresses) {
23.174 + [cmd appendFormat: @" %p", [addr pointerValue]];
23.175 + }
23.176 + FILE *file = popen( [cmd UTF8String], "r" );
23.177 + if( ! file )
23.178 + return nil;
23.179 +
23.180 + NSMutableData *output = [NSMutableData data];
23.181 + char buffer[512];
23.182 + size_t length;
23.183 + while ((length = fread( buffer, 1, sizeof( buffer ), file ) ))
23.184 + [output appendBytes: buffer length: length];
23.185 + pclose( file );
23.186 + NSString *outStr = [[[NSString alloc] initWithData: output encoding: NSUTF8StringEncoding] autorelease];
23.187 +
23.188 + NSMutableString *result = [NSMutableString string];
23.189 + NSString *line;
23.190 + foreach( line, [outStr componentsSeparatedByString: @"\n"] ) {
23.191 + // Skip frames that are part of the exception/assertion handling itself:
23.192 + if( [line hasPrefix: @"-[NSAssertionHandler"] || [line hasPrefix: @"+[NSException"]
23.193 + || [line hasPrefix: @"-[NSException"] || [line hasPrefix: @"_AssertFailed"] )
23.194 + continue;
23.195 + if( result.length )
23.196 + [result appendString: @"\n"];
23.197 + [result appendString: @"\t"];
23.198 + [result appendString: line];
23.199 + // Don't show the "__start" frame below "main":
23.200 + if( [line hasPrefix: @"main "] )
23.201 + break;
23.202 + }
23.203 + return result;
23.204 +}
23.205 +
23.206 +@end
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/TimeIntervalFormatter.h Sat Mar 08 21:04:41 2008 -0800
24.3 @@ -0,0 +1,19 @@
24.4 +//
24.5 +// TimeIntervalFormatter.h
24.6 +// MYUtilities
24.7 +//
24.8 +// Copyright 2008 Jens Alfke. All rights reserved.
24.9 +//
24.10 +
24.11 +#import <Cocoa/Cocoa.h>
24.12 +
24.13 +
24.14 +@interface TimeIntervalFormatter : NSFormatter
24.15 +{
24.16 + BOOL _showsMinutes, _showsFractionalSeconds;
24.17 +}
24.18 +
24.19 +- (void) setShowsMinutes: (BOOL)showsMinutes;
24.20 +- (void) setShowsFractionalSeconds: (BOOL)showsFractionalSeconds;
24.21 +
24.22 +@end
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/TimeIntervalFormatter.m Sat Mar 08 21:04:41 2008 -0800
25.3 @@ -0,0 +1,93 @@
25.4 +//
25.5 +// TimeIntervalFormatter.m
25.6 +// MYUtilities
25.7 +//
25.8 +// Copyright 2008 Jens Alfke. All rights reserved.
25.9 +//
25.10 +
25.11 +#import "TimeIntervalFormatter.h"
25.12 +
25.13 +
25.14 +@implementation TimeIntervalFormatter
25.15 +
25.16 +
25.17 +- (void) awakeFromNib
25.18 +{
25.19 + _showsMinutes = YES;
25.20 +}
25.21 +
25.22 +- (void) setShowsMinutes: (BOOL)show {_showsMinutes = show;}
25.23 +- (void) setShowsFractionalSeconds: (BOOL)show {_showsFractionalSeconds = show;}
25.24 +
25.25 +
25.26 +- (NSString*) stringForObjectValue: (id)object
25.27 +{
25.28 + if (![object isKindOfClass:[NSNumber class]])
25.29 + return nil;
25.30 + NSTimeInterval time = [object doubleValue];
25.31 + NSString *sign;
25.32 + if( time==0.0 )
25.33 + return nil;
25.34 + else if( time < 0.0 ) {
25.35 + sign = @"-";
25.36 + time = -time;
25.37 + } else
25.38 + sign = @"";
25.39 + if( ! _showsFractionalSeconds )
25.40 + time = floor(time);
25.41 + int minutes = (int)floor(time / 60.0);
25.42 + if( _showsMinutes || minutes>0 ) {
25.43 + double seconds = time - 60.0*minutes;
25.44 + return [NSString stringWithFormat: (_showsFractionalSeconds ?@"%@%d:%06.3lf" :@"%@%d:%02.0lf"),
25.45 + sign,minutes,seconds];
25.46 + } else {
25.47 + return [NSString stringWithFormat: (_showsFractionalSeconds ?@"%@%.3lf" :@"%@%.0lf"),
25.48 + sign,time];
25.49 + }
25.50 +}
25.51 +
25.52 +
25.53 +- (BOOL)getObjectValue:(id *)anObject
25.54 + forString:(NSString *)string
25.55 + errorDescription:(NSString **)error
25.56 +{
25.57 + NSScanner *scanner = [NSScanner scannerWithString: string];
25.58 + [scanner setCharactersToBeSkipped: [NSCharacterSet whitespaceCharacterSet]];
25.59 + double seconds;
25.60 + if( [scanner isAtEnd] ) {
25.61 + seconds = 0.0;
25.62 + } else {
25.63 + if( ! [scanner scanDouble: &seconds] || seconds<0.0 ) goto error;
25.64 + if( [scanner scanString: @":" intoString: NULL] ) {
25.65 + double minutes = seconds;
25.66 + if( ! [scanner scanDouble: &seconds] || seconds<0.0 ) goto error;
25.67 + seconds += 60*minutes;
25.68 + }
25.69 + if( ! [scanner isAtEnd] ) goto error;
25.70 + }
25.71 + *anObject = [NSNumber numberWithDouble: seconds];
25.72 + return YES;
25.73 +
25.74 +error:
25.75 + *anObject = nil;
25.76 + if( error )
25.77 + *error = @"Not a valid time interval";
25.78 + return NO;
25.79 +}
25.80 +
25.81 +
25.82 +- (BOOL)isPartialStringValid:(NSString **)partialStringPtr
25.83 + proposedSelectedRange:(NSRangePointer)proposedSelRangePtr
25.84 + originalString:(NSString *)origString
25.85 + originalSelectedRange:(NSRange)origSelRange
25.86 + errorDescription:(NSString **)error
25.87 +{
25.88 + static NSCharacterSet *sIllegalChars;
25.89 + if( ! sIllegalChars )
25.90 + sIllegalChars = [[[NSCharacterSet characterSetWithCharactersInString: @"0123456789.:"]
25.91 + invertedSet] retain];
25.92 + return [*partialStringPtr rangeOfCharacterFromSet: sIllegalChars].length == 0;
25.93 +}
25.94 +
25.95 +
25.96 +@end
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/ValueArray.h Sat Mar 08 21:04:41 2008 -0800
26.3 @@ -0,0 +1,49 @@
26.4 +//
26.5 +// ValueArray.h
26.6 +// MYUtilities
26.7 +//
26.8 +// Copyright 2008 Jens Alfke. All rights reserved.
26.9 +//
26.10 +
26.11 +#import <Cocoa/Cocoa.h>
26.12 +
26.13 +
26.14 +@interface ValueArray : NSObject <NSCoding>
26.15 +{
26.16 + unsigned _count;
26.17 + size_t _valueSize;
26.18 +}
26.19 +
26.20 ++ (ValueArray*) valueArrayWithCount: (unsigned)count valueSize: (size_t)valueSize;
26.21 +
26.22 +- (unsigned) count;
26.23 +- (size_t) valueSize;
26.24 +- (const void*) valueAtIndex: (unsigned)i;
26.25 +- (void) getValue: (void*)value atIndex: (unsigned)i;
26.26 +- (void) setValue: (const void*)value atIndex: (unsigned)i;
26.27 +
26.28 +@end
26.29 +
26.30 +
26.31 +#define DeclareValueArrayOf(CAPTYPE,TYPE) \
26.32 + @interface CAPTYPE##Array : ValueArray \
26.33 + + (CAPTYPE##Array*) TYPE##ArrayWithCount: (unsigned)count; \
26.34 + - (TYPE) TYPE##AtIndex: (unsigned)index; \
26.35 + - (void) set##CAPTYPE: (TYPE)value atIndex: (unsigned)index; \
26.36 + @end
26.37 +
26.38 +#define ImplementValueArrayOf(CAPTYPE,TYPE) \
26.39 + @implementation CAPTYPE##Array \
26.40 + + (CAPTYPE##Array*) TYPE##Array##WithCount: (unsigned)count \
26.41 + {return (id)[super valueArrayWithCount: count valueSize: sizeof(TYPE)];} \
26.42 + - (TYPE) TYPE##AtIndex: (unsigned)i; \
26.43 + {NSParameterAssert(i<_count); return ((const TYPE*)object_getIndexedIvars(self))[i];}\
26.44 + - (void) set##CAPTYPE: (TYPE)value atIndex: (unsigned)i \
26.45 + {NSParameterAssert(i<_count); ((TYPE*)object_getIndexedIvars(self))[i] = value;}\
26.46 + @end
26.47 +
26.48 +
26.49 +// Declares IntArray class
26.50 +DeclareValueArrayOf(Int,int)
26.51 +
26.52 +DeclareValueArrayOf(Double,double)
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/ValueArray.m Sat Mar 08 21:04:41 2008 -0800
27.3 @@ -0,0 +1,93 @@
27.4 +//
27.5 +// ValueArray.m
27.6 +// MYUtilities
27.7 +//
27.8 +// Copyright 2008 Jens Alfke. All rights reserved.
27.9 +//
27.10 +
27.11 +#import "ValueArray.h"
27.12 +
27.13 +
27.14 +@implementation ValueArray
27.15 +
27.16 +
27.17 +- (id) initWithCount: (unsigned)count valueSize: (size_t)valueSize
27.18 +{
27.19 + self = [super init];
27.20 + if( self ) {
27.21 + _count = count;
27.22 + _valueSize = valueSize;
27.23 + }
27.24 + return self;
27.25 +}
27.26 +
27.27 ++ (ValueArray*) valueArrayWithCount: (unsigned)count valueSize: (size_t)valueSize
27.28 +{
27.29 + return [[(ValueArray*)NSAllocateObject(self,count*valueSize,nil)
27.30 + initWithCount: count valueSize: valueSize]
27.31 + autorelease];
27.32 +}
27.33 +
27.34 +- (unsigned) count {return _count;}
27.35 +- (size_t) valueSize {return _valueSize;}
27.36 +
27.37 +- (const void*) valueAtIndex: (unsigned)i
27.38 +{
27.39 + NSParameterAssert(i<_count);
27.40 + return (const char*)object_getIndexedIvars(self) + i*_valueSize;
27.41 +}
27.42 +
27.43 +- (void) getValue: (void*)value atIndex: (unsigned)i
27.44 +{
27.45 + NSParameterAssert(i<_count);
27.46 + NSParameterAssert(value!=NULL);
27.47 + memcpy(value, object_getIndexedIvars(self) + i*_valueSize, _valueSize);
27.48 +}
27.49 +
27.50 +- (void) setValue: (const void*)value atIndex: (unsigned)i
27.51 +{
27.52 + NSParameterAssert(i<_count);
27.53 + NSParameterAssert(value!=NULL);
27.54 + memcpy(object_getIndexedIvars(self) + i*_valueSize, value, _valueSize);
27.55 +}
27.56 +
27.57 +
27.58 +
27.59 +- (id)initWithCoder:(NSCoder *)decoder
27.60 +{
27.61 + NSParameterAssert([decoder allowsKeyedCoding]);
27.62 + NSKeyedUnarchiver *arch = (NSKeyedUnarchiver*)decoder;
27.63 + unsigned count = [arch decodeIntForKey: @"count"];
27.64 + size_t valueSize = [arch decodeIntForKey: @"valueSize"];
27.65 +
27.66 + [super release];
27.67 + self = [[[self class] valueArrayWithCount: count valueSize: valueSize] retain];
27.68 + if( self ) {
27.69 + unsigned nBytes;
27.70 + const void *bytes = [arch decodeBytesForKey: @"values" returnedLength: &nBytes];
27.71 + NSAssert(nBytes==count*valueSize,@"Value size mismatch");
27.72 + memcpy( object_getIndexedIvars(self), bytes, nBytes );
27.73 + }
27.74 + return self;
27.75 +}
27.76 +
27.77 +
27.78 +- (void)encodeWithCoder:(NSCoder *)coder
27.79 +{
27.80 + NSParameterAssert([coder allowsKeyedCoding]);
27.81 + NSKeyedArchiver *arch = (NSKeyedArchiver*)coder;
27.82 +
27.83 + [arch encodeInt: _count forKey: @"count"];
27.84 + [arch encodeInt: _valueSize forKey: @"valueSize"];
27.85 + [arch encodeBytes: object_getIndexedIvars(self)
27.86 + length: _count*_valueSize
27.87 + forKey: @"values"];
27.88 +}
27.89 +
27.90 +
27.91 +@end
27.92 +
27.93 +
27.94 +ImplementValueArrayOf(Int,int)
27.95 +
27.96 +ImplementValueArrayOf(Double,double)
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/With.h Sat Mar 08 21:04:41 2008 -0800
28.3 @@ -0,0 +1,21 @@
28.4 +//
28.5 +// With.h
28.6 +// MYUtilities
28.7 +//
28.8 +// Copyright 2008 Jens Alfke. All rights reserved.
28.9 +//
28.10 +
28.11 +#import <Cocoa/Cocoa.h>
28.12 +
28.13 +
28.14 +#define WITH(OBJ) id __with=[OBJ beginWith]; @try
28.15 +
28.16 +#define ENDWITH @finally{[__with endWith];}
28.17 +#define CATCHWITH @catch(NSException *x){id w=__with; __with=nil; _catchWith(w,x);} @finally{[__with endWith];}
28.18 +
28.19 +void _catchWith( id with, NSException *x );
28.20 +
28.21 +@interface NSAutoreleasePool (With)
28.22 ++ (NSAutoreleasePool*) beginWith;
28.23 +- (void) endWith;
28.24 +@end
28.25 \ No newline at end of file
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/With.m Sat Mar 08 21:04:41 2008 -0800
29.3 @@ -0,0 +1,34 @@
29.4 +//
29.5 +// With.m
29.6 +// MYUtilities
29.7 +//
29.8 +// Copyright 2008 Jens Alfke. All rights reserved.
29.9 +//
29.10 +
29.11 +#import "With.h"
29.12 +#import "Logging.h"
29.13 +
29.14 +
29.15 +@interface NSObject (With)
29.16 +- (BOOL) endWith: (NSException*)x;
29.17 +@end
29.18 +
29.19 +
29.20 +void _catchWith( id with, NSException *x )
29.21 +{
29.22 + Warn(@"Exception thrown from WITH(%@) block: %@",[with class],x);
29.23 + if( [with respondsToSelector: @selector(endWith:)] ) {
29.24 + if( ! [with endWith: x] )
29.25 + @throw x; // propagate the exception if -endWith: returns NO
29.26 + } else {
29.27 + [with endWith];
29.28 + }
29.29 +}
29.30 +
29.31 +
29.32 +
29.33 +@implementation NSAutoreleasePool (With)
29.34 ++ (NSAutoreleasePool*) beginWith {return [self new];}
29.35 +- (void) endWith {[self drain];}
29.36 +- (BOOL) endWith: (NSException*)x {[self drain]; return YES;}
29.37 +@end
29.38 \ No newline at end of file
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/iChatBridge.h Sat Mar 08 21:04:41 2008 -0800
30.3 @@ -0,0 +1,460 @@
30.4 +/*
30.5 + * iChat.h
30.6 + */
30.7 +
30.8 +#import <AppKit/AppKit.h>
30.9 +#import <ScriptingBridge/ScriptingBridge.h>
30.10 +
30.11 +
30.12 +@class iChatItem, iChatApplication, iChatColor, iChatDocument, iChatWindow, iChatRichText, iChatCharacter, iChatParagraph, iChatWord, iChatAttributeRun, iChatAttachment, iChatApplication, iChatBuddy, iChatService, iChatChat, iChatTextChat, iChatAudioChat, iChatVideoChat, iChatFileTransfer;
30.13 +
30.14 +typedef enum {
30.15 + iChatSaveOptionsYes = 'yes ' /* Save the file. */,
30.16 + iChatSaveOptionsNo = 'no ' /* Do not save the file. */,
30.17 + iChatSaveOptionsAsk = 'ask ' /* Ask the user whether or not to save the file. */
30.18 +} iChatSaveOptions;
30.19 +
30.20 +typedef enum {
30.21 + iChatInviteTypeAudioInvitation = 'acon',
30.22 + iChatInviteTypeTextChatInvitation = 'tcon',
30.23 + iChatInviteTypeVideoInvitation = 'vcon'
30.24 +} iChatInviteType;
30.25 +
30.26 +typedef enum {
30.27 + iChatAccountStatusAvailable = 'aval',
30.28 + iChatAccountStatusAway = 'away',
30.29 + iChatAccountStatusOffline = 'offl',
30.30 + iChatAccountStatusInvisible = 'invs',
30.31 + iChatAccountStatusIdle = 'idle',
30.32 + iChatAccountStatusUnknown = 'unkn'
30.33 +} iChatAccountStatus;
30.34 +
30.35 +typedef enum {
30.36 + iChatMyStatusAway = 'away',
30.37 + iChatMyStatusAvailable = 'aval',
30.38 + iChatMyStatusOffline = 'offl',
30.39 + iChatMyStatusInvisible = 'invs'
30.40 +} iChatMyStatus;
30.41 +
30.42 +typedef enum {
30.43 + iChatConnectionStatusDisconnecting = 'dcng',
30.44 + iChatConnectionStatusConnected = 'conn',
30.45 + iChatConnectionStatusConnecting = 'cong',
30.46 + iChatConnectionStatusDisconnected = 'dcon'
30.47 +} iChatConnectionStatus;
30.48 +
30.49 +typedef enum {
30.50 + iChatCapabilitiesVideoChat = 'vcon',
30.51 + iChatCapabilitiesAudioChat = 'acon',
30.52 + iChatCapabilitiesMultipersonVideo = 'mwvc',
30.53 + iChatCapabilitiesMultipersonAudio = 'mwac'
30.54 +} iChatCapabilities;
30.55 +
30.56 +typedef enum {
30.57 + iChatScreenSharingNone = 'ssns',
30.58 + iChatScreenSharingLocalScreen = 'ssls',
30.59 + iChatScreenSharingRemoteScreen = 'ssrs'
30.60 +} iChatScreenSharing;
30.61 +
30.62 +typedef enum {
30.63 + iChatServiceTypeAIM = 'saim',
30.64 + iChatServiceTypeBonjour = 'ssub',
30.65 + iChatServiceTypeJabber = 'sjab'
30.66 +} iChatServiceType;
30.67 +
30.68 +typedef enum {
30.69 + iChatDirectionIncoming = 'FTic',
30.70 + iChatDirectionOutgoing = 'FTog'
30.71 +} iChatDirection;
30.72 +
30.73 +typedef enum {
30.74 + iChatTransferStatusPreparing = 'FTsp',
30.75 + iChatTransferStatusWaiting = 'FTsw',
30.76 + iChatTransferStatusTransferring = 'FTsg',
30.77 + iChatTransferStatusFinalizing = 'FTsz',
30.78 + iChatTransferStatusFinished = 'FTsf',
30.79 + iChatTransferStatusFailed = 'FTse'
30.80 +} iChatTransferStatus;
30.81 +
30.82 +typedef enum {
30.83 + iChatAvTypeAudio = 'ICAa',
30.84 + iChatAvTypeVideo = 'ICAv'
30.85 +} iChatAvType;
30.86 +
30.87 +typedef enum {
30.88 + iChatChatTypeInstantMessage = 'ICim',
30.89 + iChatChatTypeDirectInstantMessage = 'ICdi',
30.90 + iChatChatTypeChatRoom = 'ICcr'
30.91 +} iChatChatType;
30.92 +
30.93 +typedef enum {
30.94 + iChatJoinStateNotJoined = 'ICJc',
30.95 + iChatJoinStateJoining = 'ICJg',
30.96 + iChatJoinStateJoined = 'ICJj'
30.97 +} iChatJoinState;
30.98 +
30.99 +typedef enum {
30.100 + iChatAvConnectionStatusInvited = 'ICAi',
30.101 + iChatAvConnectionStatusWaiting = 'ICAw',
30.102 + iChatAvConnectionStatusConnecting = 'ICAx',
30.103 + iChatAvConnectionStatusConnected = 'ICAc',
30.104 + iChatAvConnectionStatusEnded = 'ICAn'
30.105 +} iChatAvConnectionStatus;
30.106 +
30.107 +
30.108 +
30.109 +/*
30.110 + * Standard Suite
30.111 + */
30.112 +
30.113 +// A scriptable object.
30.114 +@interface iChatItem : SBObject
30.115 +
30.116 +@property (copy) NSDictionary *properties; // All of the object's properties.
30.117 +
30.118 +- (void) closeSaving:(iChatSaveOptions)saving savingIn:(NSURL *)savingIn; // Close a document.
30.119 +- (void) saveIn:(NSURL *)in_ as:(NSString *)as; // Save a document.
30.120 +- (void) delete; // Delete an object.
30.121 +- (SBObject *) duplicateTo:(SBObject *)to withProperties:(NSDictionary *)withProperties; // Copy object(s) and put the copies at a new location.
30.122 +- (BOOL) exists; // Verify if an object exists.
30.123 +- (SBObject *) moveTo:(SBObject *)to; // Move object(s) to a new location.
30.124 +
30.125 +@end
30.126 +
30.127 +// The application's top-level scripting object.
30.128 +@interface iChatApplication : SBApplication
30.129 +
30.130 +- (SBElementArray *) documents;
30.131 +- (SBElementArray *) windows;
30.132 +
30.133 +@property (copy, readonly) NSString *name; // The name of the application.
30.134 +@property (readonly) BOOL frontmost; // Is this the frontmost (active) application?
30.135 +@property (copy, readonly) NSString *version; // The version of the application.
30.136 +
30.137 +- (void) open:(NSArray *)x; // Open a document.
30.138 +- (void) print:(NSURL *)x; // Print an object.
30.139 +- (void) quitSaving:(iChatSaveOptions)saving; // Quit the application.
30.140 +- (void) invite:(NSArray *)x to:(id)to withMessage:(NSString *)withMessage; // Invites a buddy to join an existing chat.
30.141 +- (void) logIn; // Log in to the specified service, or all services if none is specified. If the account password is not in the keychain the user will be prompted to enter one.
30.142 +- (void) logOut; // Logs out of a service, or all services if none is specified.
30.143 +- (void) send:(id)x to:(id)to; // Sends a message or file to a buddy or to a chat.
30.144 +- (void) storeRecentPicture; // Stores the currently set buddy picture into your recent pictures.
30.145 +- (void) showChatChooserFor:(iChatBuddy *)for_; // displays a dialog in iChat to start a new chat with the specified buddy
30.146 +
30.147 +@end
30.148 +
30.149 +// A color.
30.150 +@interface iChatColor : SBObject
30.151 +
30.152 +- (void) closeSaving:(iChatSaveOptions)saving savingIn:(NSURL *)savingIn; // Close a document.
30.153 +- (void) saveIn:(NSURL *)in_ as:(NSString *)as; // Save a document.
30.154 +- (void) delete; // Delete an object.
30.155 +- (SBObject *) duplicateTo:(SBObject *)to withProperties:(NSDictionary *)withProperties; // Copy object(s) and put the copies at a new location.
30.156 +- (BOOL) exists; // Verify if an object exists.
30.157 +- (SBObject *) moveTo:(SBObject *)to; // Move object(s) to a new location.
30.158 +
30.159 +@end
30.160 +
30.161 +// An iChat document.
30.162 +@interface iChatDocument : SBObject
30.163 +
30.164 +@property (copy, readonly) NSString *name; // The document's name.
30.165 +@property (readonly) BOOL modified; // Has the document been modified since the last save?
30.166 +@property (copy, readonly) NSURL *file; // The document's location on disk.
30.167 +
30.168 +- (void) closeSaving:(iChatSaveOptions)saving savingIn:(NSURL *)savingIn; // Close a document.
30.169 +- (void) saveIn:(NSURL *)in_ as:(NSString *)as; // Save a document.
30.170 +- (void) delete; // Delete an object.
30.171 +- (SBObject *) duplicateTo:(SBObject *)to withProperties:(NSDictionary *)withProperties; // Copy object(s) and put the copies at a new location.
30.172 +- (BOOL) exists; // Verify if an object exists.
30.173 +- (SBObject *) moveTo:(SBObject *)to; // Move object(s) to a new location.
30.174 +
30.175 +@end
30.176 +
30.177 +// A window.
30.178 +@interface iChatWindow : SBObject
30.179 +
30.180 +@property (copy, readonly) NSString *name; // The full title of the window.
30.181 +- (NSInteger) id; // The unique identifier of the window.
30.182 +@property NSInteger index; // The index of the window, ordered front to back.
30.183 +@property NSRect bounds; // The bounding rectangle of the window.
30.184 +@property (readonly) BOOL closeable; // Whether the window has a close box.
30.185 +@property (readonly) BOOL minimizable; // Whether the window can be minimized.
30.186 +@property BOOL minimized; // Whether the window is currently minimized.
30.187 +@property (readonly) BOOL resizable; // Whether the window can be resized.
30.188 +@property BOOL visible; // Whether the window is currently visible.
30.189 +@property (readonly) BOOL zoomable; // Whether the window can be zoomed.
30.190 +@property BOOL zoomed; // Whether the window is currently zoomed.
30.191 +@property (copy, readonly) iChatDocument *document; // The document whose contents are being displayed in the window.
30.192 +
30.193 +- (void) closeSaving:(iChatSaveOptions)saving savingIn:(NSURL *)savingIn; // Close a document.
30.194 +- (void) saveIn:(NSURL *)in_ as:(NSString *)as; // Save a document.
30.195 +- (void) delete; // Delete an object.
30.196 +- (SBObject *) duplicateTo:(SBObject *)to withProperties:(NSDictionary *)withProperties; // Copy object(s) and put the copies at a new location.
30.197 +- (BOOL) exists; // Verify if an object exists.
30.198 +- (SBObject *) moveTo:(SBObject *)to; // Move object(s) to a new location.
30.199 +
30.200 +@end
30.201 +
30.202 +
30.203 +
30.204 +/*
30.205 + * Text Suite
30.206 + */
30.207 +
30.208 +// Rich (styled) text
30.209 +@interface iChatRichText : SBObject
30.210 +
30.211 +- (SBElementArray *) characters;
30.212 +- (SBElementArray *) paragraphs;
30.213 +- (SBElementArray *) words;
30.214 +- (SBElementArray *) attributeRuns;
30.215 +- (SBElementArray *) attachments;
30.216 +
30.217 +@property (copy) NSColor *color; // The color of the first character.
30.218 +@property (copy) NSString *font; // The name of the font of the first character.
30.219 +@property double size; // The size in points of the first character.
30.220 +
30.221 +- (void) closeSaving:(iChatSaveOptions)saving savingIn:(NSURL *)savingIn; // Close a document.
30.222 +- (void) saveIn:(NSURL *)in_ as:(NSString *)as; // Save a document.
30.223 +- (void) delete; // Delete an object.
30.224 +- (SBObject *) duplicateTo:(SBObject *)to withProperties:(NSDictionary *)withProperties; // Copy object(s) and put the copies at a new location.
30.225 +- (BOOL) exists; // Verify if an object exists.
30.226 +- (SBObject *) moveTo:(SBObject *)to; // Move object(s) to a new location.
30.227 +
30.228 +@end
30.229 +
30.230 +// This subdivides the text into characters.
30.231 +@interface iChatCharacter : SBObject
30.232 +
30.233 +- (SBElementArray *) characters;
30.234 +- (SBElementArray *) paragraphs;
30.235 +- (SBElementArray *) words;
30.236 +- (SBElementArray *) attributeRuns;
30.237 +- (SBElementArray *) attachments;
30.238 +
30.239 +@property (copy) NSColor *color; // The color of the first character.
30.240 +@property (copy) NSString *font; // The name of the font of the first character.
30.241 +@property NSInteger size; // The size in points of the first character.
30.242 +
30.243 +- (void) closeSaving:(iChatSaveOptions)saving savingIn:(NSURL *)savingIn; // Close a document.
30.244 +- (void) saveIn:(NSURL *)in_ as:(NSString *)as; // Save a document.
30.245 +- (void) delete; // Delete an object.
30.246 +- (SBObject *) duplicateTo:(SBObject *)to withProperties:(NSDictionary *)withProperties; // Copy object(s) and put the copies at a new location.
30.247 +- (BOOL) exists; // Verify if an object exists.
30.248 +- (SBObject *) moveTo:(SBObject *)to; // Move object(s) to a new location.
30.249 +
30.250 +@end
30.251 +
30.252 +// This subdivides the text into paragraphs.
30.253 +@interface iChatParagraph : SBObject
30.254 +
30.255 +- (SBElementArray *) characters;
30.256 +- (SBElementArray *) paragraphs;
30.257 +- (SBElementArray *) words;
30.258 +- (SBElementArray *) attributeRuns;
30.259 +- (SBElementArray *) attachments;
30.260 +
30.261 +@property (copy) NSColor *color; // The color of the first character.
30.262 +@property (copy) NSString *font; // The name of the font of the first character.
30.263 +@property NSInteger size; // The size in points of the first character.
30.264 +
30.265 +- (void) closeSaving:(iChatSaveOptions)saving savingIn:(NSURL *)savingIn; // Close a document.
30.266 +- (void) saveIn:(NSURL *)in_ as:(NSString *)as; // Save a document.
30.267 +- (void) delete; // Delete an object.
30.268 +- (SBObject *) duplicateTo:(SBObject *)to withProperties:(NSDictionary *)withProperties; // Copy object(s) and put the copies at a new location.
30.269 +- (BOOL) exists; // Verify if an object exists.
30.270 +- (SBObject *) moveTo:(SBObject *)to; // Move object(s) to a new location.
30.271 +
30.272 +@end
30.273 +
30.274 +// This subdivides the text into words.
30.275 +@interface iChatWord : SBObject
30.276 +
30.277 +- (SBElementArray *) characters;
30.278 +- (SBElementArray *) paragraphs;
30.279 +- (SBElementArray *) words;
30.280 +- (SBElementArray *) attributeRuns;
30.281 +- (SBElementArray *) attachments;
30.282 +
30.283 +@property (copy) NSColor *color; // The color of the first character.
30.284 +@property (copy) NSString *font; // The name of the font of the first character.
30.285 +@property NSInteger size; // The size in points of the first character.
30.286 +
30.287 +- (void) closeSaving:(iChatSaveOptions)saving savingIn:(NSURL *)savingIn; // Close a document.
30.288 +- (void) saveIn:(NSURL *)in_ as:(NSString *)as; // Save a document.
30.289 +- (void) delete; // Delete an object.
30.290 +- (SBObject *) duplicateTo:(SBObject *)to withProperties:(NSDictionary *)withProperties; // Copy object(s) and put the copies at a new location.
30.291 +- (BOOL) exists; // Verify if an object exists.
30.292 +- (SBObject *) moveTo:(SBObject *)to; // Move object(s) to a new location.
30.293 +
30.294 +@end
30.295 +
30.296 +// This subdivides the text into chunks that all have the same attributes.
30.297 +@interface iChatAttributeRun : SBObject
30.298 +
30.299 +- (SBElementArray *) characters;
30.300 +- (SBElementArray *) paragraphs;
30.301 +- (SBElementArray *) words;
30.302 +- (SBElementArray *) attributeRuns;
30.303 +- (SBElementArray *) attachments;
30.304 +
30.305 +@property (copy) NSColor *color; // The color of the first character.
30.306 +@property (copy) NSString *font; // The name of the font of the first character.
30.307 +@property NSInteger size; // The size in points of the first character.
30.308 +
30.309 +- (void) closeSaving:(iChatSaveOptions)saving savingIn:(NSURL *)savingIn; // Close a document.
30.310 +- (void) saveIn:(NSURL *)in_ as:(NSString *)as; // Save a document.
30.311 +- (void) delete; // Delete an object.
30.312 +- (SBObject *) duplicateTo:(SBObject *)to withProperties:(NSDictionary *)withProperties; // Copy object(s) and put the copies at a new location.
30.313 +- (BOOL) exists; // Verify if an object exists.
30.314 +- (SBObject *) moveTo:(SBObject *)to; // Move object(s) to a new location.
30.315 +
30.316 +@end
30.317 +
30.318 +// Represents an inline text attachment. This class is used mainly for make commands.
30.319 +@interface iChatAttachment : iChatRichText
30.320 +
30.321 +@property (copy, readonly) NSURL *file; // The path to the file for the attachment
30.322 +
30.323 +
30.324 +@end
30.325 +
30.326 +
30.327 +
30.328 +/*
30.329 + * iChat Suite
30.330 + */
30.331 +
30.332 +// iChat application.
30.333 +@interface iChatApplication (IChatSuite)
30.334 +
30.335 +- (SBElementArray *) buddies;
30.336 +- (SBElementArray *) services;
30.337 +- (SBElementArray *) fileTransfers;
30.338 +- (SBElementArray *) chats;
30.339 +- (SBElementArray *) textChats;
30.340 +- (SBElementArray *) audioChats;
30.341 +- (SBElementArray *) videoChats;
30.342 +
30.343 +@property (readonly) NSInteger idleTime; // Time in seconds that I have been idle.
30.344 +@property (copy) NSImage *image; // My image as it appears in all services.
30.345 +@property (copy) NSString *statusMessage; // My status message, visible to other people while I am online.
30.346 +@property iChatMyStatus status; // My status on all services.
30.347 +@property (copy) iChatAudioChat *activeAvChat; // The currently active audio or video chat.
30.348 +
30.349 +@end
30.350 +
30.351 +// A buddy on a service.
30.352 +@interface iChatBuddy : iChatItem
30.353 +
30.354 +- (NSString *) id; // The buddy's service and handle. For example: AIM:JohnDoe007
30.355 +@property (copy, readonly) iChatService *service; // The service on which this buddy exists.
30.356 +@property (copy, readonly) NSString *name; // The buddy's name as it appears in the buddy list.
30.357 +@property (copy, readonly) NSString *handle; // The buddy's online account name.
30.358 +@property (readonly) iChatAccountStatus status; // The buddy's current status.
30.359 +@property (copy, readonly) NSString *statusMessage; // The buddy's current status message.
30.360 +@property (readonly) NSInteger idleTime; // The time in seconds the buddy has been idle.
30.361 +@property (copy, readonly) NSArray *capabilities; // The buddy's messaging capabilities.
30.362 +@property (copy, readonly) NSImage *image; // The buddy's custom image.
30.363 +@property (copy, readonly) NSString *firstName; // The first name from this buddy's Address Book card, if available
30.364 +@property (copy, readonly) NSString *lastName; // The last name from this buddy's Address Book card, if available
30.365 +@property (copy, readonly) NSString *fullName; // The full name from this buddy's Address Book card, if available
30.366 +
30.367 +
30.368 +@end
30.369 +
30.370 +// A service that can be logged in from this system
30.371 +@interface iChatService : iChatItem
30.372 +
30.373 +- (SBElementArray *) buddies;
30.374 +- (SBElementArray *) chats;
30.375 +
30.376 +- (NSString *) id; // A guid identifier for this service.
30.377 +@property (copy) NSString *name; // The name of this service as defined in Account preferences description field
30.378 +@property BOOL enabled; // Is the service enabled?
30.379 +@property (readonly) iChatConnectionStatus status; // The connection status for this account.
30.380 +@property (readonly) iChatServiceType serviceType; // The type of protocol for this service
30.381 +
30.382 +- (void) logIn; // Log in to the specified service, or all services if none is specified. If the account password is not in the keychain the user will be prompted to enter one.
30.383 +- (void) logOut; // Logs out of a service, or all services if none is specified.
30.384 +
30.385 +@end
30.386 +
30.387 +// An audio, video, or text chat.
30.388 +@interface iChatChat : SBObject
30.389 +
30.390 +- (NSString *) id; // A guid identifier for this chat.
30.391 +@property (copy, readonly) iChatService *service; // The service which is participating in this chat.
30.392 +@property (copy, readonly) NSArray *participants; // Other participants of this chat. This property may be specified at time of creation.
30.393 +@property (readonly) BOOL secure; // Is this chat secure?
30.394 +@property (readonly) BOOL invitation; // Is this an invitation to a chat?
30.395 +@property (readonly) BOOL active; // Is this chat currently active?
30.396 +@property (copy, readonly) NSDate *started; // The date on which this chat started.
30.397 +@property (copy, readonly) NSDate *updated; // The date when this chat was last updated.
30.398 +
30.399 +- (void) closeSaving:(iChatSaveOptions)saving savingIn:(NSURL *)savingIn; // Close a document.
30.400 +- (void) saveIn:(NSURL *)in_ as:(NSString *)as; // Save a document.
30.401 +- (void) delete; // Delete an object.
30.402 +- (SBObject *) duplicateTo:(SBObject *)to withProperties:(NSDictionary *)withProperties; // Copy object(s) and put the copies at a new location.
30.403 +- (BOOL) exists; // Verify if an object exists.
30.404 +- (SBObject *) moveTo:(SBObject *)to; // Move object(s) to a new location.
30.405 +- (void) accept; // Accepts an incoming text, audio, or video chat invitation, or file transfer
30.406 +- (void) decline; // Declines an incoming text, audio, or video chat invitation, or file transfer
30.407 +
30.408 +@end
30.409 +
30.410 +// A text chat.
30.411 +@interface iChatTextChat : iChatChat
30.412 +
30.413 +@property (copy, readonly) NSString *subject; // The subject of this chat, if available.
30.414 +@property (copy, readonly) NSString *invitationMessage; // An invitation message. This may only be specified at the time of creation. This message will be sent to chat participants when the chat is created.
30.415 +@property (readonly) iChatJoinState joinState; // How you are joined to this chat
30.416 +@property (copy, readonly) NSString *name; // The address or room name of this chat. This property may be specified at time of creation.
30.417 +@property (readonly) iChatChatType chatType; // The type of this chat.
30.418 +
30.419 +
30.420 +@end
30.421 +
30.422 +// An audio or video chat.
30.423 +@interface iChatAudioChat : iChatChat
30.424 +
30.425 +@property (readonly) iChatScreenSharing screenSharing; // Type of screen sharing session taking place within this chat.
30.426 +@property BOOL muted; // Is the chat muted?
30.427 +@property (readonly) iChatAvConnectionStatus avConnectionStatus; // The connection state for this av chat.
30.428 +
30.429 +- (void) requestRecording; // Sends a recording request to all participants of an audio or video chat. Recording will not start until all participants have agreed to allow recording.
30.430 +- (void) stopRecording; // Ends recording of an audio or video chat.
30.431 +
30.432 +@end
30.433 +
30.434 +@interface iChatVideoChat : iChatAudioChat
30.435 +
30.436 +@property BOOL paused; // Is the chat paused?
30.437 +@property BOOL showingFullScreen; // Is the chat being displayed in full screen mode?
30.438 +@property BOOL showingLocalVideo; // Is the local video preview being displayed?
30.439 +
30.440 +- (void) takeSnapshot; // Takes a snapshot of a video chat and saves it to a desktop.
30.441 +
30.442 +@end
30.443 +
30.444 +// A file being sent or received
30.445 +@interface iChatFileTransfer : iChatItem
30.446 +
30.447 +- (NSString *) id; // The guid for this file transfer
30.448 +@property (copy, readonly) NSString *name; // The name of this file
30.449 +@property (copy, readonly) NSURL *file; // The local path to this file transfer
30.450 +@property (readonly) iChatDirection direction; // The direction in which this file is being sent
30.451 +@property (copy, readonly) iChatService *service; // The service on which this file transfer is taking place
30.452 +@property (copy, readonly) iChatBuddy *buddy; // The account participating in this file transfer
30.453 +@property (readonly) BOOL secure; // Is this file transfer secure?
30.454 +@property (readonly) NSInteger fileSize; // The total size in bytes of the completed file transfer
30.455 +@property (readonly) NSInteger fileProgress; // The number of bytes that have been transferred
30.456 +@property (readonly) iChatTransferStatus transferStatus; // The current status of this file transfer
30.457 +@property (copy, readonly) NSDate *started; // The date that this file transfer started
30.458 +
30.459 +- (void) accept; // Accepts an incoming text, audio, or video chat invitation, or file transfer
30.460 +- (void) decline; // Declines an incoming text, audio, or video chat invitation, or file transfer
30.461 +
30.462 +@end
30.463 +
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/mnemonicode-0.73/Makefile Sat Mar 08 21:04:41 2008 -0800
31.3 @@ -0,0 +1,12 @@
31.4 +sample_programs: mnencode mndecode
31.5 +
31.6 +mnencode: mnencode.o mnemonic.o mn_wordlist.o
31.7 +
31.8 +mndecode: mndecode.o mnemonic.o mn_wordlist.o
31.9 +
31.10 +mn_wordlist.o: mn_wordlist.c mnemonic.h
31.11 +
31.12 +mnemonic.o: mnemonic.c mnemonic.h
31.13 +
31.14 +clean:
31.15 + rm -f *.o mnencode mndecode *~
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/mnemonicode-0.73/README Sat Mar 08 21:04:41 2008 -0800
32.3 @@ -0,0 +1,13 @@
32.4 +These routines implement a method for encoding binary data into a sequence
32.5 +of words which can be spoken over the phone, for example, and converted
32.6 +back to data on the other side.
32.7 +
32.8 +For more information see http://www.tothink.com/mnemonic
32.9 +
32.10 +mnemonic.h Header file
32.11 +mnemonic.c Encoding/decoding and associated routines
32.12 +mn_wordlist.c The word list itself
32.13 +mnencode.c Sample program - encode data from stdin to stdout
32.14 +mndecode.c Sample program - decode data from stdin to stdout
32.15 +
32.16 +Oren Tirosh <oren@hishome.net>
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/mnemonicode-0.73/TODO Sat Mar 08 21:04:41 2008 -0800
33.3 @@ -0,0 +1,10 @@
33.4 +Improve the wordlist
33.5 +
33.6 + I am looking for comments on the wordlist from you. Yes, you :-)
33.7 +
33.8 +Soundalike matching
33.9 +
33.10 + I have given up on standard soundex techniques for this purpose.
33.11 + I am working on an ad-hoc solution which is more-or-less tailored to
33.12 + this specific list.
33.13 +
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/mnemonicode-0.73/mn_wordlist.c Sat Mar 08 21:04:41 2008 -0800
34.3 @@ -0,0 +1,302 @@
34.4 +/* mn_wordlist.c
34.5 + Copyright (c) 2000 Oren Tirosh <oren@hishome.net>
34.6 +
34.7 + Permission is hereby granted, free of charge, to any person obtaining a copy
34.8 + of this software and associated documentation files (the "Software"), to deal
34.9 + in the Software without restriction, including without limitation the rights
34.10 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
34.11 + copies of the Software, and to permit persons to whom the Software is
34.12 + furnished to do so, subject to the following conditions:
34.13 +
34.14 + The above copyright notice and this permission notice shall be included in
34.15 + all copies or substantial portions of the Software.
34.16 +
34.17 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34.18 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34.19 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34.20 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34.21 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34.22 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
34.23 + THE SOFTWARE.
34.24 +*/
34.25 +
34.26 +#include "mnemonic.h"
34.27 +
34.28 +const char *mn_wordlist_version =
34.29 + " Wordlist ver 0.7 - EXPECT INCOMPATIBLE CHANGES";
34.30 +
34.31 +const char *mn_words[MN_WORDS + 1] = { 0,
34.32 + "academy", "acrobat", "active", "actor", "adam", "admiral",
34.33 + "adrian", "africa", "agenda", "agent", "airline", "airport",
34.34 + "aladdin", "alarm", "alaska", "albert", "albino", "album",
34.35 + "alcohol", "alex", "algebra", "alibi", "alice", "alien",
34.36 + "alpha", "alpine", "amadeus", "amanda", "amazon", "amber",
34.37 + "america", "amigo", "analog", "anatomy", "angel", "animal",
34.38 + "antenna", "antonio", "apollo", "april", "archive", "arctic",
34.39 + "arizona", "arnold", "aroma", "arthur", "artist", "asia",
34.40 + "aspect", "aspirin", "athena", "athlete", "atlas", "audio",
34.41 + "august", "austria", "axiom", "aztec", "balance", "ballad",
34.42 + "banana", "bandit", "banjo", "barcode", "baron", "basic",
34.43 + "battery", "belgium", "berlin", "bermuda", "bernard", "bikini",
34.44 + "binary", "bingo", "biology", "block", "blonde", "bonus",
34.45 + "boris", "boston", "boxer", "brandy", "bravo", "brazil",
34.46 + "bronze", "brown", "bruce", "bruno", "burger", "burma",
34.47 + "cabinet", "cactus", "cafe", "cairo", "cake", "calypso",
34.48 + "camel", "camera", "campus", "canada", "canal", "cannon",
34.49 + "canoe", "cantina", "canvas", "canyon", "capital", "caramel",
34.50 + "caravan", "carbon", "cargo", "carlo", "carol", "carpet",
34.51 + "cartel", "casino", "castle", "castro", "catalog", "caviar",
34.52 + "cecilia", "cement", "center", "century", "ceramic", "chamber",
34.53 + "chance", "change", "chaos", "charlie", "charm", "charter",
34.54 + "chef", "chemist", "cherry", "chess", "chicago", "chicken",
34.55 + "chief", "china", "cigar", "cinema", "circus", "citizen",
34.56 + "city", "clara", "classic", "claudia", "clean", "client",
34.57 + "climax", "clinic", "clock", "club", "cobra", "coconut",
34.58 + "cola", "collect", "colombo", "colony", "color", "combat",
34.59 + "comedy", "comet", "command", "compact", "company", "complex",
34.60 + "concept", "concert", "connect", "consul", "contact", "context",
34.61 + "contour", "control", "convert", "copy", "corner", "corona",
34.62 + "correct", "cosmos", "couple", "courage", "cowboy", "craft",
34.63 + "crash", "credit", "cricket", "critic", "crown", "crystal",
34.64 + "cuba", "culture", "dallas", "dance", "daniel", "david",
34.65 + "decade", "decimal", "deliver", "delta", "deluxe", "demand",
34.66 + "demo", "denmark", "derby", "design", "detect", "develop",
34.67 + "diagram", "dialog", "diamond", "diana", "diego", "diesel",
34.68 + "diet", "digital", "dilemma", "diploma", "direct", "disco",
34.69 + "disney", "distant", "doctor", "dollar", "dominic", "domino",
34.70 + "donald", "dragon", "drama", "dublin", "duet", "dynamic",
34.71 + "east", "ecology", "economy", "edgar", "egypt", "elastic",
34.72 + "elegant", "element", "elite", "elvis", "email", "energy",
34.73 + "engine", "english", "episode", "equator", "escort", "ethnic",
34.74 + "europe", "everest", "evident", "exact", "example", "exit",
34.75 + "exotic", "export", "express", "extra", "fabric", "factor",
34.76 + "falcon", "family", "fantasy", "fashion", "fiber", "fiction",
34.77 + "fidel", "fiesta", "figure", "film", "filter", "final",
34.78 + "finance", "finish", "finland", "flash", "florida", "flower",
34.79 + "fluid", "flute", "focus", "ford", "forest", "formal",
34.80 + "format", "formula", "fortune", "forum", "fragile", "france",
34.81 + "frank", "friend", "frozen", "future", "gabriel", "galaxy",
34.82 + "gallery", "gamma", "garage", "garden", "garlic", "gemini",
34.83 + "general", "genetic", "genius", "germany", "global", "gloria",
34.84 + "golf", "gondola", "gong", "good", "gordon", "gorilla",
34.85 + "grand", "granite", "graph", "green", "group", "guide",
34.86 + "guitar", "guru", "hand", "happy", "harbor", "harmony",
34.87 + "harvard", "havana", "hawaii", "helena", "hello", "henry",
34.88 + "hilton", "history", "horizon", "hotel", "human", "humor",
34.89 + "icon", "idea", "igloo", "igor", "image", "impact",
34.90 + "import", "index", "india", "indigo", "input", "insect",
34.91 + "instant", "iris", "italian", "jacket", "jacob", "jaguar",
34.92 + "janet", "japan", "jargon", "jazz", "jeep", "john",
34.93 + "joker", "jordan", "jumbo", "june", "jungle", "junior",
34.94 + "jupiter", "karate", "karma", "kayak", "kermit", "kilo",
34.95 + "king", "koala", "korea", "labor", "lady", "lagoon",
34.96 + "laptop", "laser", "latin", "lava", "lecture", "left",
34.97 + "legal", "lemon", "level", "lexicon", "liberal", "libra",
34.98 + "limbo", "limit", "linda", "linear", "lion", "liquid",
34.99 + "liter", "little", "llama", "lobby", "lobster", "local",
34.100 + "logic", "logo", "lola", "london", "lotus", "lucas",
34.101 + "lunar", "machine", "macro", "madam", "madonna", "madrid",
34.102 + "maestro", "magic", "magnet", "magnum", "major", "mama",
34.103 + "mambo", "manager", "mango", "manila", "marco", "marina",
34.104 + "market", "mars", "martin", "marvin", "master", "matrix",
34.105 + "maximum", "media", "medical", "mega", "melody", "melon",
34.106 + "memo", "mental", "mentor", "menu", "mercury", "message",
34.107 + "metal", "meteor", "meter", "method", "metro", "mexico",
34.108 + "miami", "micro", "million", "mineral", "minimum", "minus",
34.109 + "minute", "miracle", "mirage", "miranda", "mister", "mixer",
34.110 + "mobile", "model", "modem", "modern", "modular", "moment",
34.111 + "monaco", "monica", "monitor", "mono", "monster", "montana",
34.112 + "morgan", "motel", "motif", "motor", "mozart", "multi",
34.113 + "museum", "music", "mustang", "natural", "neon", "nepal",
34.114 + "neptune", "nerve", "neutral", "nevada", "news", "ninja",
34.115 + "nirvana", "normal", "nova", "novel", "nuclear", "numeric",
34.116 + "nylon", "oasis", "object", "observe", "ocean", "octopus",
34.117 + "olivia", "olympic", "omega", "opera", "optic", "optimal",
34.118 + "orange", "orbit", "organic", "orient", "origin", "orlando",
34.119 + "oscar", "oxford", "oxygen", "ozone", "pablo", "pacific",
34.120 + "pagoda", "palace", "pamela", "panama", "panda", "panel",
34.121 + "panic", "paradox", "pardon", "paris", "parker", "parking",
34.122 + "parody", "partner", "passage", "passive", "pasta", "pastel",
34.123 + "patent", "patriot", "patrol", "patron", "pegasus", "pelican",
34.124 + "penguin", "pepper", "percent", "perfect", "perfume", "period",
34.125 + "permit", "person", "peru", "phone", "photo", "piano",
34.126 + "picasso", "picnic", "picture", "pigment", "pilgrim", "pilot",
34.127 + "pirate", "pixel", "pizza", "planet", "plasma", "plaster",
34.128 + "plastic", "plaza", "pocket", "poem", "poetic", "poker",
34.129 + "polaris", "police", "politic", "polo", "polygon", "pony",
34.130 + "popcorn", "popular", "postage", "postal", "precise", "prefix",
34.131 + "premium", "present", "price", "prince", "printer", "prism",
34.132 + "private", "product", "profile", "program", "project", "protect",
34.133 + "proton", "public", "pulse", "puma", "pyramid", "queen",
34.134 + "radar", "radio", "random", "rapid", "rebel", "record",
34.135 + "recycle", "reflex", "reform", "regard", "regular", "relax",
34.136 + "report", "reptile", "reverse", "ricardo", "ringo", "ritual",
34.137 + "robert", "robot", "rocket", "rodeo", "romeo", "royal",
34.138 + "russian", "safari", "salad", "salami", "salmon", "salon",
34.139 + "salute", "samba", "sandra", "santana", "sardine", "school",
34.140 + "screen", "script", "second", "secret", "section", "segment",
34.141 + "select", "seminar", "senator", "senior", "sensor", "serial",
34.142 + "service", "sheriff", "shock", "sierra", "signal", "silicon",
34.143 + "silver", "similar", "simon", "single", "siren", "slogan",
34.144 + "social", "soda", "solar", "solid", "solo", "sonic",
34.145 + "soviet", "special", "speed", "spiral", "spirit", "sport",
34.146 + "static", "station", "status", "stereo", "stone", "stop",
34.147 + "street", "strong", "student", "studio", "style", "subject",
34.148 + "sultan", "super", "susan", "sushi", "suzuki", "switch",
34.149 + "symbol", "system", "tactic", "tahiti", "talent", "tango",
34.150 + "tarzan", "taxi", "telex", "tempo", "tennis", "texas",
34.151 + "textile", "theory", "thermos", "tiger", "titanic", "tokyo",
34.152 + "tomato", "topic", "tornado", "toronto", "torpedo", "total",
34.153 + "totem", "tourist", "tractor", "traffic", "transit", "trapeze",
34.154 + "travel", "tribal", "trick", "trident", "trilogy", "tripod",
34.155 + "tropic", "trumpet", "tulip", "tuna", "turbo", "twist",
34.156 + "ultra", "uniform", "union", "uranium", "vacuum", "valid",
34.157 + "vampire", "vanilla", "vatican", "velvet", "ventura", "venus",
34.158 + "vertigo", "veteran", "victor", "video", "vienna", "viking",
34.159 + "village", "vincent", "violet", "violin", "virtual", "virus",
34.160 + "visa", "vision", "visitor", "visual", "vitamin", "viva",
34.161 + "vocal", "vodka", "volcano", "voltage", "volume", "voyage",
34.162 + "water", "weekend", "welcome", "western", "window", "winter",
34.163 + "wizard", "wolf", "world", "xray", "yankee", "yoga",
34.164 + "yogurt", "yoyo", "zebra", "zero", "zigzag", "zipper",
34.165 + "zodiac", "zoom", "abraham", "action", "address", "alabama",
34.166 + "alfred", "almond", "ammonia", "analyze", "annual", "answer",
34.167 + "apple", "arena", "armada", "arsenal", "atlanta", "atomic",
34.168 + "avenue", "average", "bagel", "baker", "ballet", "bambino",
34.169 + "bamboo", "barbara", "basket", "bazaar", "benefit", "bicycle",
34.170 + "bishop", "blitz", "bonjour", "bottle", "bridge", "british",
34.171 + "brother", "brush", "budget", "cabaret", "cadet", "candle",
34.172 + "capitan", "capsule", "career", "cartoon", "channel", "chapter",
34.173 + "cheese", "circle", "cobalt", "cockpit", "college", "compass",
34.174 + "comrade", "condor", "crimson", "cyclone", "darwin", "declare",
34.175 + "degree", "delete", "delphi", "denver", "desert", "divide",
34.176 + "dolby", "domain", "domingo", "double", "drink", "driver",
34.177 + "eagle", "earth", "echo", "eclipse", "editor", "educate",
34.178 + "edward", "effect", "electra", "emerald", "emotion", "empire",
34.179 + "empty", "escape", "eternal", "evening", "exhibit", "expand",
34.180 + "explore", "extreme", "ferrari", "first", "flag", "folio",
34.181 + "forget", "forward", "freedom", "fresh", "friday", "fuji",
34.182 + "galileo", "garcia", "genesis", "gold", "gravity", "habitat",
34.183 + "hamlet", "harlem", "helium", "holiday", "house", "hunter",
34.184 + "ibiza", "iceberg", "imagine", "infant", "isotope", "jackson",
34.185 + "jamaica", "jasmine", "java", "jessica", "judo", "kitchen",
34.186 + "lazarus", "letter", "license", "lithium", "loyal", "lucky",
34.187 + "magenta", "mailbox", "manual", "marble", "mary", "maxwell",
34.188 + "mayor", "milk", "monarch", "monday", "money", "morning",
34.189 + "mother", "mystery", "native", "nectar", "nelson", "network",
34.190 + "next", "nikita", "nobel", "nobody", "nominal", "norway",
34.191 + "nothing", "number", "october", "office", "oliver", "opinion",
34.192 + "option", "order", "outside", "package", "pancake", "pandora",
34.193 + "panther", "papa", "patient", "pattern", "pedro", "pencil",
34.194 + "people", "phantom", "philips", "pioneer", "pluto", "podium",
34.195 + "portal", "potato", "prize", "process", "protein", "proxy",
34.196 + "pump", "pupil", "python", "quality", "quarter", "quiet",
34.197 + "rabbit", "radical", "radius", "rainbow", "ralph", "ramirez",
34.198 + "ravioli", "raymond", "respect", "respond", "result", "resume",
34.199 + "retro", "richard", "right", "risk", "river", "roger",
34.200 + "roman", "rondo", "sabrina", "salary", "salsa", "sample",
34.201 + "samuel", "saturn", "savage", "scarlet", "scoop", "scorpio",
34.202 + "scratch", "scroll", "sector", "serpent", "shadow", "shampoo",
34.203 + "sharon", "sharp", "short", "shrink", "silence", "silk",
34.204 + "simple", "slang", "smart", "smoke", "snake", "society",
34.205 + "sonar", "sonata", "soprano", "source", "sparta", "sphere",
34.206 + "spider", "sponsor", "spring", "acid", "adios", "agatha",
34.207 + "alamo", "alert", "almanac", "aloha", "andrea", "anita",
34.208 + "arcade", "aurora", "avalon", "baby", "baggage", "balloon",
34.209 + "bank", "basil", "begin", "biscuit", "blue", "bombay",
34.210 + "brain", "brenda", "brigade", "cable", "carmen", "cello",
34.211 + "celtic", "chariot", "chrome", "citrus", "civil", "cloud",
34.212 + "common", "compare", "cool", "copper", "coral", "crater",
34.213 + "cubic", "cupid", "cycle", "depend", "door", "dream",
34.214 + "dynasty", "edison", "edition", "enigma", "equal", "eric",
34.215 + "event", "evita", "exodus", "extend", "famous", "farmer",
34.216 + "food", "fossil", "frog", "fruit", "geneva", "gentle",
34.217 + "george", "giant", "gilbert", "gossip", "gram", "greek",
34.218 + "grille", "hammer", "harvest", "hazard", "heaven", "herbert",
34.219 + "heroic", "hexagon", "husband", "immune", "inca", "inch",
34.220 + "initial", "isabel", "ivory", "jason", "jerome", "joel",
34.221 + "joshua", "journal", "judge", "juliet", "jump", "justice",
34.222 + "kimono", "kinetic", "leonid", "lima", "maze", "medusa",
34.223 + "member", "memphis", "michael", "miguel", "milan", "mile",
34.224 + "miller", "mimic", "mimosa", "mission", "monkey", "moral",
34.225 + "moses", "mouse", "nancy", "natasha", "nebula", "nickel",
34.226 + "nina", "noise", "orchid", "oregano", "origami", "orinoco",
34.227 + "orion", "othello", "paper", "paprika", "prelude", "prepare",
34.228 + "pretend", "profit", "promise", "provide", "puzzle", "remote",
34.229 + "repair", "reply", "rival", "riviera", "robin", "rose",
34.230 + "rover", "rudolf", "saga", "sahara", "scholar", "shelter",
34.231 + "ship", "shoe", "sigma", "sister", "sleep", "smile",
34.232 + "spain", "spark", "split", "spray", "square", "stadium",
34.233 + "star", "storm", "story", "strange", "stretch", "stuart",
34.234 + "subway", "sugar", "sulfur", "summer", "survive", "sweet",
34.235 + "swim", "table", "taboo", "target", "teacher", "telecom",
34.236 + "temple", "tibet", "ticket", "tina", "today", "toga",
34.237 + "tommy", "tower", "trivial", "tunnel", "turtle", "twin",
34.238 + "uncle", "unicorn", "unique", "update", "valery", "vega",
34.239 + "version", "voodoo", "warning", "william", "wonder", "year",
34.240 + "yellow", "young", "absent", "absorb", "accent", "alfonso",
34.241 + "alias", "ambient", "andy", "anvil", "appear", "apropos",
34.242 + "archer", "ariel", "armor", "arrow", "austin", "avatar",
34.243 + "axis", "baboon", "bahama", "bali", "balsa", "bazooka",
34.244 + "beach", "beast", "beatles", "beauty", "before", "benny",
34.245 + "betty", "between", "beyond", "billy", "bison", "blast",
34.246 + "bless", "bogart", "bonanza", "book", "border", "brave",
34.247 + "bread", "break", "broken", "bucket", "buenos", "buffalo",
34.248 + "bundle", "button", "buzzer", "byte", "caesar", "camilla",
34.249 + "canary", "candid", "carrot", "cave", "chant", "child",
34.250 + "choice", "chris", "cipher", "clarion", "clark", "clever",
34.251 + "cliff", "clone", "conan", "conduct", "congo", "content",
34.252 + "costume", "cotton", "cover", "crack", "current", "danube",
34.253 + "data", "decide", "desire", "detail", "dexter", "dinner",
34.254 + "dispute", "donor", "druid", "drum", "easy", "eddie",
34.255 + "enjoy", "enrico", "epoxy", "erosion", "except", "exile",
34.256 + "explain", "fame", "fast", "father", "felix", "field",
34.257 + "fiona", "fire", "fish", "flame", "flex", "flipper",
34.258 + "float", "flood", "floor", "forbid", "forever", "fractal",
34.259 + "frame", "freddie", "front", "fuel", "gallop", "game",
34.260 + "garbo", "gate", "gibson", "ginger", "giraffe", "gizmo",
34.261 + "glass", "goblin", "gopher", "grace", "gray", "gregory",
34.262 + "grid", "griffin", "ground", "guest", "gustav", "gyro",
34.263 + "hair", "halt", "harris", "heart", "heavy", "herman",
34.264 + "hippie", "hobby", "honey", "hope", "horse", "hostel",
34.265 + "hydro", "imitate", "info", "ingrid", "inside", "invent",
34.266 + "invest", "invite", "iron", "ivan", "james", "jester",
34.267 + "jimmy", "join", "joseph", "juice", "julius", "july",
34.268 + "justin", "kansas", "karl", "kevin", "kiwi", "ladder",
34.269 + "lake", "laura", "learn", "legacy", "legend", "lesson",
34.270 + "life", "light", "list", "locate", "lopez", "lorenzo",
34.271 + "love", "lunch", "malta", "mammal", "margo", "marion",
34.272 + "mask", "match", "mayday", "meaning", "mercy", "middle",
34.273 + "mike", "mirror", "modest", "morph", "morris", "nadia",
34.274 + "nato", "navy", "needle", "neuron", "never", "newton",
34.275 + "nice", "night", "nissan", "nitro", "nixon", "north",
34.276 + "oberon", "octavia", "ohio", "olga", "open", "opus",
34.277 + "orca", "oval", "owner", "page", "paint", "palma",
34.278 + "parade", "parent", "parole", "paul", "peace", "pearl",
34.279 + "perform", "phoenix", "phrase", "pierre", "pinball", "place",
34.280 + "plate", "plato", "plume", "pogo", "point", "polite",
34.281 + "polka", "poncho", "powder", "prague", "press", "presto",
34.282 + "pretty", "prime", "promo", "quasi", "quest", "quick",
34.283 + "quiz", "quota", "race", "rachel", "raja", "ranger",
34.284 + "region", "remark", "rent", "reward", "rhino", "ribbon",
34.285 + "rider", "road", "rodent", "round", "rubber", "ruby",
34.286 + "rufus", "sabine", "saddle", "sailor", "saint", "salt",
34.287 + "satire", "scale", "scuba", "season", "secure", "shake",
34.288 + "shallow", "shannon", "shave", "shelf", "sherman", "shine",
34.289 + "shirt", "side", "sinatra", "sincere", "size", "slalom",
34.290 + "slow", "small", "snow", "sofia", "song", "sound",
34.291 + "south", "speech", "spell", "spend", "spoon", "stage",
34.292 + "stamp", "stand", "state", "stella", "stick", "sting",
34.293 + "stock", "store", "sunday", "sunset", "support", "sweden",
34.294 + "swing", "tape", "think", "thomas", "tictac", "time",
34.295 + "toast", "tobacco", "tonight", "torch", "torso", "touch",
34.296 + "toyota", "trade", "tribune", "trinity", "triton", "truck",
34.297 + "trust", "type", "under", "unit", "urban", "urgent",
34.298 + "user", "value", "vendor", "venice", "verona", "vibrate",
34.299 + "virgo", "visible", "vista", "vital", "voice", "vortex",
34.300 + "waiter", "watch", "wave", "weather", "wedding", "wheel",
34.301 + "whiskey", "wisdom", "deal", "null", "nurse", "quebec",
34.302 + "reserve", "reunion", "roof", "singer", "verbal", "amen",
34.303 + "ego", "fax", "jet", "job", "rio", "ski",
34.304 + "yes"
34.305 +};
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
35.2 +++ b/mnemonicode-0.73/mndecode.c Sat Mar 08 21:04:41 2008 -0800
35.3 @@ -0,0 +1,21 @@
35.4 +#include <stdio.h>
35.5 +#include "mnemonic.h"
35.6 +
35.7 +main ()
35.8 +{
35.9 + char buf[0x90000];
35.10 + mn_byte outbuf[0x10000];
35.11 + int buflen;
35.12 + int n;
35.13 +
35.14 + buflen = fread (buf, 1, sizeof buf - 1, stdin);
35.15 + buf[buflen] = 0;
35.16 +
35.17 + n = mn_decode (buf, outbuf, sizeof outbuf);
35.18 + if (n < 0)
35.19 + fprintf (stderr, "mn_decode result %d\n", n);
35.20 + else
35.21 + fwrite (outbuf, 1, n, stdout);
35.22 +
35.23 + return 0;
35.24 +}
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
36.2 +++ b/mnemonicode-0.73/mnemonic.c Sat Mar 08 21:04:41 2008 -0800
36.3 @@ -0,0 +1,467 @@
36.4 +/* mnemonic.c
36.5 +
36.6 + Copyright (c) 2000 Oren Tirosh <oren@hishome.net>
36.7 +
36.8 + Permission is hereby granted, free of charge, to any person obtaining a copy
36.9 + of this software and associated documentation files (the "Software"), to deal
36.10 + in the Software without restriction, including without limitation the rights
36.11 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36.12 + copies of the Software, and to permit persons to whom the Software is
36.13 + furnished to do so, subject to the following conditions:
36.14 +
36.15 + The above copyright notice and this permission notice shall be included in
36.16 + all copies or substantial portions of the Software.
36.17 +
36.18 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36.19 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36.20 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36.21 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36.22 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36.23 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
36.24 + THE SOFTWARE.
36.25 +
36.26 +*/
36.27 +
36.28 +#include "mnemonic.h"
36.29 +#include <string.h>
36.30 +
36.31 +
36.32 +/*
36.33 + * mn_words_required
36.34 + *
36.35 + * Description:
36.36 + * Calculate the number of words required to encode data using mnemonic
36.37 + * encoding.
36.38 + *
36.39 + * Parameters:
36.40 + * size - Size in bytes of data to be encoded
36.41 + *
36.42 + * Return value:
36.43 + * number of words required for the encoding
36.44 + */
36.45 +
36.46 +int
36.47 +mn_words_required (int size)
36.48 +{
36.49 + return ((size + 1) * 3) / 4;
36.50 +}
36.51 +
36.52 +
36.53 +/*
36.54 + * mn_encode_word_index
36.55 + *
36.56 + * Description:
36.57 + * Perform one step of encoding binary data into words. Returns word index.
36.58 + *
36.59 + * Parameters:
36.60 + * src - Pointer to data buffer to encode
36.61 + * srcsize - Size in bytes of data to encode
36.62 + * n - Sequence number of word to encode
36.63 + * 0 <= n < mn_words_required(srcsize)
36.64 + *
36.65 + * Return value:
36.66 + * 0 - no more words to encode / n is out of range
36.67 + * 1..MN_WORDS - word index. May be used as index to the mn_words[] array
36.68 + */
36.69 +
36.70 +mn_index mn_encode_word_index (void *src, int srcsize, int n)
36.71 +{
36.72 + mn_word32 x = 0; /* Temporary for MN_BASE arithmetic */
36.73 + int offset; /* Offset into src */
36.74 + int remaining; /* Octets remaining to end of src */
36.75 + int extra = 0; /* Index 7 extra words for 24 bit data */
36.76 + int i;
36.77 +
36.78 + if (n < 0 || n >= mn_words_required (srcsize))
36.79 + return 0; /* word out of range */
36.80 + offset = (n / 3) * 4; /* byte offset into src */
36.81 + remaining = srcsize - offset;
36.82 + if (remaining <= 0)
36.83 + return 0;
36.84 + if (remaining >= 4)
36.85 + remaining = 4;
36.86 + for (i = 0; i < remaining; i++)
36.87 + x |= ((mn_byte *) src)[offset + i] << (i * 8); /* endianness-agnostic */
36.88 +
36.89 + switch (n % 3)
36.90 + {
36.91 + case 2: /* Third word of group */
36.92 + if (remaining == 3) /* special case for 24 bits */
36.93 + extra = MN_BASE; /* use one of the 7 3-letter words */
36.94 + x /= (MN_BASE * MN_BASE);
36.95 + break;
36.96 + case 1: /* Second word of group */
36.97 + x /= MN_BASE;
36.98 + }
36.99 + return x % MN_BASE + extra + 1;
36.100 +}
36.101 +
36.102 +
36.103 +/*
36.104 + * mn_encode_word
36.105 + *
36.106 + * Description:
36.107 + * Perform one step of encoding binary data into words. Returns pointer
36.108 + * to word.
36.109 + *
36.110 + * Parameters:
36.111 + * src - Pointer to data buffer to encode
36.112 + * srcsize - Size of data to encode in bytes
36.113 + * n - Sequence number of word to encode.
36.114 + * 0 <= n < mn_words_required(srcsize)
36.115 + *
36.116 + * Return value:
36.117 + * NULL - no more words to encode / n is out of range
36.118 + * valid pointer - pointer to null-terminated lowercase word. length<=7
36.119 + */
36.120 +
36.121 +const char *
36.122 +mn_encode_word (void *src, int srcsize, int n)
36.123 +{
36.124 + return mn_words[mn_encode_word_index (src, srcsize, n)];
36.125 +}
36.126 +
36.127 +
36.128 +/*
36.129 + * isletter
36.130 + * Utility function - returns nonzero if character c is an ASCII letter.
36.131 + */
36.132 +
36.133 +static int
36.134 +isletter (char c)
36.135 +{
36.136 + return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
36.137 +}
36.138 +
36.139 +/*
36.140 + * mn_next_word_index
36.141 + *
36.142 + * Description:
36.143 + * Perform one step of decoding a null-terminated buffer into word indices.
36.144 + * A word is defined as a sequence of letter character separated by one
36.145 + * or more non-letter separator characters.
36.146 + *
36.147 + * Parameters:
36.148 + * ptr - Pointer to a pointer to the next character in the buffer.
36.149 + * *ptr is modified by the function; see Return Value below.
36.150 + *
36.151 + * Return value:
36.152 + * 0 - If *ptr==0 (points to the null at the end of the buffer) no more
36.153 + * words were found in the buffer. Otherwise *ptr points to beginning
36.154 + * of an unrecognized word.
36.155 + * >0 - index of word found, suitable for decoding with mn_decode_word_index
36.156 + * or comparison to values returned from mn_encode_index. *ptr points
36.157 + * to first character of next word or to terminating null.
36.158 + */
36.159 +
36.160 +mn_index
36.161 +mn_next_word_index (char **ptr)
36.162 +{
36.163 + char *wordstart;
36.164 + char wordbuf[MN_WORD_BUFLEN];
36.165 + int i = 0;
36.166 + char c;
36.167 + mn_index idx;
36.168 +
36.169 + while (**ptr && !isletter (**ptr)) /* skip separator chars */
36.170 + (*ptr)++;
36.171 + wordstart = *ptr; /* save for error reporting */
36.172 + while (**ptr && isletter (**ptr) && i < MN_WORD_BUFLEN - 1)
36.173 + {
36.174 + c = *(*ptr)++;
36.175 + if (c >= 'A' && c <= 'Z')
36.176 + c += 'a' - 'A'; /* convert to lowercase */
36.177 + wordbuf[i++] = c;
36.178 + }
36.179 + wordbuf[i] = '\0';
36.180 + while (**ptr && isletter (**ptr)) /* skip tail of long words */
36.181 + (*ptr)++;
36.182 + while (**ptr && !isletter (**ptr)) /* skip separators */
36.183 + (*ptr)++;
36.184 +
36.185 + if (wordbuf[0] == '\0')
36.186 + return 0; /* EOF, no word found */
36.187 +
36.188 + for (idx = 1; idx <= MN_WORDS; idx++)
36.189 + {
36.190 + if (!strcmp (wordbuf, mn_words[idx]))
36.191 + return idx;
36.192 + /* FIXME: some fancy code should go here
36.193 + to accept misspellings and soundalikes.
36.194 + (replacing the linear search would also be nice) */
36.195 + }
36.196 + *ptr = wordstart;
36.197 + return 0; /* not found */
36.198 +}
36.199 +
36.200 +
36.201 +/*
36.202 + * mn_decode_word_index
36.203 + *
36.204 + * Description:
36.205 + * Perform one step of decoding a sequence of words into binary data.
36.206 + *
36.207 + * Parameters:
36.208 + * index - Index of word, e.g. return value of mn_next_word_index. Use
36.209 + * the value MN_EOF(=0) to signal the end of input.
36.210 + * dest - Points to buffer to receive decoded binary result.
36.211 + * destsize - Size of buffer
36.212 + * offset - Pointer to an integer offset into the destination buffer for
36.213 + * next data byte. Initialize *offset to 0 before first call to
36.214 + * function. Modified by function and may be used as an
36.215 + * indication for the amount of data actually decoded.
36.216 + *
36.217 + * Return value:
36.218 + * The return value indicates the status of the decoding function. It is
36.219 + * ok to ignore this value on all calls to the function except the last
36.220 + * one (with index=MN_EOF). Any errors encountered will be reported on.
36.221 + * the last call. The error code is also returned in *offset (negative
36.222 + * values indicate error).
36.223 + *
36.224 + * MN_OK (==0)
36.225 + * for index!=MN_EOF a return value of MN_OK means that
36.226 + * decoding has been successful so far.
36.227 + * for index==MN_EOF a return value of MN_OK means that decoding
36.228 + * of the entire buffer has been successful and the decoder is in
36.229 + * a valid state for the end of the message. A total of *offset
36.230 + * valid decoded bytes is in the buffer.
36.231 + * MN_EREM
36.232 + * returned on MN_EOF when an unaccounted arithmetic remainder is
36.233 + * in the decoder. Most likely indicates a truncated word sequence.
36.234 + * MN_EOVERRUN
36.235 + * Not enough room in buffer for decoded data.
36.236 + * MN_EOVERRUN24
36.237 + * Returned when decoding of data is attempted after decoding one
36.238 + * of the 7 words reserved for 24 bit remainders at the end of the
36.239 + * message. Probably indicates a garbled messages.
36.240 + * MN_EINDEX
36.241 + * Bad input index. Naturally this should not happen when using
36.242 + * the result of mn_next_word_index.
36.243 + * MN_EINDEX24
36.244 + * Returned when one of the 7 words reserved for 24 bit remainders
36.245 + * is received at an offset inappropriate for a 24 bit remainder.
36.246 + * MN_EENCODING
36.247 + * Indicates an overflow in MN_BASE arithmetic. Approximately 0.09%
36.248 + * of the 3 word combinations are unused and will generate this error.
36.249 + */
36.250 +
36.251 +int
36.252 +mn_decode_word_index (mn_index index, void *dest, int destsize, int *offset)
36.253 +{
36.254 + mn_word32 x; /* Temporary for MN_BASE arithmetic */
36.255 + int groupofs;
36.256 + int i;
36.257 +
36.258 + if (*offset < 0) /* Error from previous call? report it */
36.259 + return *offset;
36.260 +
36.261 + if (index < 0 || index > MN_WORDS) /* Word index out of range */
36.262 + {
36.263 + *offset = MN_EINDEX;
36.264 + return *offset;
36.265 + }
36.266 +
36.267 + if (*offset > destsize) /* out of range? */
36.268 + {
36.269 + *offset = MN_EOVERRUN;
36.270 + return *offset;
36.271 + }
36.272 +
36.273 + if (index > MN_BASE && *offset % 4 != 2)
36.274 + { /* Unexpected 24 bit remainder word */
36.275 + *offset = MN_EINDEX24;
36.276 + return *offset;
36.277 + }
36.278 +
36.279 + groupofs = *offset & ~3; /* Offset of 4 byte group containing offet */
36.280 + x = 0;
36.281 + for (i = 0; i < 4; i++)
36.282 + if (groupofs + i < destsize) /* Ignore any bytes outside buffer */
36.283 + x |= ((mn_byte *) dest)[groupofs + i] << (i * 8); /* assemble number */
36.284 +
36.285 + if (index == MN_EOF) /* Got EOF signal */
36.286 + {
36.287 + switch (*offset % 4)
36.288 + {
36.289 + case 3: /* group was three words and the last */
36.290 + return MN_OK; /* word was a 24 bit remainder */
36.291 + case 2: /* last group has two words */
36.292 + if (x <= 0xFFFF) /* should encode 16 bit data */
36.293 + return MN_OK;
36.294 + else
36.295 + {
36.296 + *offset = MN_EREM;
36.297 + return *offset;
36.298 + }
36.299 + case 1: /* last group has just one word */
36.300 + if (x <= 0xFF) /* should encode 8 bits */
36.301 + return MN_OK;
36.302 + else
36.303 + {
36.304 + *offset = MN_EREM;
36.305 + return *offset;
36.306 + }
36.307 +
36.308 + case 0: /* last group was full 3 words */
36.309 + return MN_OK;
36.310 + }
36.311 + }
36.312 + if (*offset == destsize) /* At EOF but didn't get MN_EOF */
36.313 + {
36.314 + *offset = MN_EOVERRUN;
36.315 + return *offset;
36.316 + }
36.317 +
36.318 + index--; /* 1 based to 0 based index */
36.319 +
36.320 + switch (*offset % 4)
36.321 + {
36.322 + case 3: /* Got data past 24 bit remainder */
36.323 + *offset = MN_EOVERRUN24;
36.324 + return *offset;
36.325 + case 2:
36.326 + if (index >= MN_BASE)
36.327 + { /* 24 bit remainder */
36.328 + x += (index - MN_BASE) * MN_BASE * MN_BASE;
36.329 + (*offset)++; /* *offset%4 == 3 for next time */
36.330 + }
36.331 + else
36.332 + { /* catch invalid encodings */
36.333 + if (index >= 1625 || (index == 1624 && x > 1312671))
36.334 + {
36.335 + *offset = MN_EENCODING;
36.336 + return *offset;
36.337 + }
36.338 + x += index * MN_BASE * MN_BASE;
36.339 + (*offset) += 2; /* *offset%4 == 0 for next time */
36.340 + }
36.341 + break;
36.342 + case 1:
36.343 + x += index * MN_BASE;
36.344 + (*offset)++;
36.345 + break;
36.346 + case 0:
36.347 + x = index;
36.348 + (*offset)++;
36.349 + break;
36.350 + }
36.351 +
36.352 + for (i = 0; i < 4; i++)
36.353 + if (groupofs + i < destsize) /* Don't step outside the buffer */
36.354 + {
36.355 + ((mn_byte *) dest)[groupofs + i] = (mn_byte) x % 256;
36.356 + x /= 256;
36.357 + }
36.358 + return MN_OK;
36.359 +}
36.360 +
36.361 +/*
36.362 + * mn_encode
36.363 + *
36.364 + * Description:
36.365 + * Encode a binary data buffer into a null-terminated sequence of words.
36.366 + * The word separators are taken from the format string.
36.367 + *
36.368 + * Parameters:
36.369 + * src - Pointer to the beginning of the binary data buffer.
36.370 + * srcsize - Size in bytes of binary data buffer
36.371 + * dest - Pointer to the beginning of a character buffer
36.372 + * destsize - Size in characters of character buffer
36.373 + * format - Null-terminated string describing the output format.
36.374 + * In the format string any letter or sequence of letters
36.375 + * acts as a placeholder for the encoded words. The word
36.376 + * placeholders are separated by one or more non-letter
36.377 + * characters. When the encoder reaches the end of the
36.378 + * format string it starts reading it again.
36.379 + * For sample formats see MN_F* constants in mnemonic.h
36.380 + * If format is empty or NULL the format MN_FDEFAULT
36.381 + * is used.
36.382 + *
36.383 + * Return value:
36.384 + * MN_OK(=0)
36.385 + * Encoding was successful.
36.386 + * MN_EOVERRUN
36.387 + * Output size exceeds size of destination buffer
36.388 + * MN_EFORMAT
36.389 + * Invalid format string. This function enforces formats which
36.390 + * will result in a string which can be successfully decoded by
36.391 + * the mn_decode function.
36.392 + */
36.393 +
36.394 +int
36.395 +mn_encode (void *src, int srcsize, char *dest, int destsize, char *format)
36.396 +{
36.397 + int n;
36.398 + char *fmt;
36.399 + char *destend = dest + destsize;
36.400 + const char *word;
36.401 +
36.402 + if (format == 0 || format[0] == '\0')
36.403 + format = MN_FDEFAULT;
36.404 + fmt = format;
36.405 + for (n = 0; n < mn_words_required (srcsize); n++)
36.406 + {
36.407 + while (dest < destend && *fmt != '\0' && !isletter (*fmt))
36.408 + *dest++ = *fmt++;
36.409 + if (dest >= destend)
36.410 + return MN_EOVERRUN;
36.411 + if (*fmt == '\0')
36.412 + {
36.413 + if (isletter (fmt[-1]) && isletter (format[0]))
36.414 + return MN_EFORMAT;
36.415 + fmt = format;
36.416 + while (dest < destend && *fmt != '\0' && !isletter (*fmt))
36.417 + *dest++ = *fmt++;
36.418 + if (!isletter (*fmt))
36.419 + return MN_EFORMAT;
36.420 + }
36.421 + word = mn_encode_word (src, srcsize, n);
36.422 + if (word == 0)
36.423 + return MN_EOVERRUN; /* shouldn't happen, actually */
36.424 +
36.425 + while (isletter (*fmt))
36.426 + fmt++;
36.427 + while (dest < destend && *word != '\0')
36.428 + *dest++ = *word++;
36.429 + }
36.430 + if (dest < destend)
36.431 + *dest++ = '\0';
36.432 + else
36.433 + return MN_EOVERRUN;
36.434 + return MN_OK;
36.435 +}
36.436 +
36.437 +/*
36.438 + * mn_decode
36.439 + *
36.440 + * Description:
36.441 + * Decode a text representation in null-terminated character buffer src to
36.442 + * binary buffer dest.
36.443 + *
36.444 + * Parameters:
36.445 + * src - Pointer to null-terminated character buffer
36.446 + * dest - Pointer to beginning of destination buffer
36.447 + * destsize - Size in bytes of destination buffer
36.448 + *
36.449 + * Return value:
36.450 + * This function may return all the value returned by mn_decode_word_index
36.451 + * plus the following result code:
36.452 + *
36.453 + * MN_EWORD - Unrecognized word.
36.454 + */
36.455 +
36.456 +int
36.457 +mn_decode (char *src, void *dest, int destsize)
36.458 +{
36.459 + mn_index index;
36.460 + int offset = 0;
36.461 +
36.462 + while ((index = mn_next_word_index (&src)) != 0)
36.463 + {
36.464 + if (index == 0 && *src != 0)
36.465 + return MN_EWORD;
36.466 + (void) mn_decode_word_index (index, dest, destsize, &offset);
36.467 + }
36.468 + (void) mn_decode_word_index (MN_EOF, dest, destsize, &offset);
36.469 + return offset;
36.470 +}
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
37.2 +++ b/mnemonicode-0.73/mnemonic.h Sat Mar 08 21:04:41 2008 -0800
37.3 @@ -0,0 +1,68 @@
37.4 +/* mnemonic.h
37.5 +
37.6 + Copyright (c) 2000 Oren Tirosh <oren@hishome.net>
37.7 +
37.8 + Permission is hereby granted, free of charge, to any person obtaining a copy
37.9 + of this software and associated documentation files (the "Software"), to deal
37.10 + in the Software without restriction, including without limitation the rights
37.11 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
37.12 + copies of the Software, and to permit persons to whom the Software is
37.13 + furnished to do so, subject to the following conditions:
37.14 +
37.15 + The above copyright notice and this permission notice shall be included in
37.16 + all copies or substantial portions of the Software.
37.17 +
37.18 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37.19 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
37.20 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
37.21 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37.22 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37.23 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
37.24 + THE SOFTWARE.
37.25 +
37.26 +*/
37.27 +
37.28 +#define MN_BASE 1626 /* cubic root of 2^32, rounded up */
37.29 +#define MN_REMAINDER 7 /* extra words for 24 bit remainders */
37.30 +#define MN_WORDS (MN_BASE+MN_REMAINDER) /* total number of words */
37.31 +#define MN_WORD_BUFLEN 25 /* size for a word buffer+headroom */
37.32 +
37.33 +#define MN_EOF 0 /* signal end to mn_decode_word_index */
37.34 +
37.35 +/* result codes */
37.36 +#define MN_OK 0 /* decoding ok */
37.37 +#define MN_EREM -1 /* unexpected arithmetic remainder */
37.38 +#define MN_EOVERRUN -2 /* output buffer overrun */
37.39 +#define MN_EOVERRUN24 -3 /* data after 24 bit remainder */
37.40 +#define MN_EINDEX -4 /* bad word index */
37.41 +#define MN_EINDEX24 -5 /* unexpected 24 bit remainder word */
37.42 +#define MN_EENCODING -6 /* invalid arithmetic encoding */
37.43 +#define MN_EWORD -7 /* unrecognized word */
37.44 +#define MN_EFORMAT -8 /* bad format string */
37.45 +
37.46 +/* Sample formats for mn_encode */
37.47 +#define MN_FDEFAULT "x-x-x--"
37.48 +#define MN_F64BITSPERLINE " x-x-x--x-x-x\n"
37.49 +#define MN_F96BITSPERLINE " x-x-x--x-x-x--x-x-x\n"
37.50 +#define MN_F128BITSPERLINE " x-x-x--x-x-x--x-x-x--x-x-x\n"
37.51 +/* Note that the last format does not fit in a standard 80 character line */
37.52 +
37.53 +typedef unsigned char mn_byte; /* 8 bit quantity */
37.54 +typedef unsigned long mn_word32; /* temporary value, at least 32 bits */
37.55 +typedef unsigned int mn_index; /* index into wordlist */
37.56 +
37.57 +extern const char *mn_words[]; /* the word list itself */
37.58 +extern const char *mn_wordlist_version; /* version notice string */
37.59 +
37.60 +int mn_decode (char *src, void *dest, int destsize);
37.61 +int mn_encode (void *src , int srcsize,
37.62 + char *dest, int destsize, char *format);
37.63 +
37.64 +int mn_words_required (int size);
37.65 +mn_index mn_encode_word_index (void *src, int srcsize, int n);
37.66 +const char* mn_encode_word (void *src, int srcsize, int n);
37.67 +mn_index mn_next_word_index (char **ptr);
37.68 +int mn_decode_word_index (mn_index index, void *dest,
37.69 + int destsize, int *offset);
37.70 +
37.71 +
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
38.2 +++ b/mnemonicode-0.73/mnencode.c Sat Mar 08 21:04:41 2008 -0800
38.3 @@ -0,0 +1,22 @@
38.4 +#include <stdio.h>
38.5 +#include "mnemonic.h"
38.6 +
38.7 +main ()
38.8 +{
38.9 + mn_byte buf[0x10000];
38.10 + char outbuf[0x90000];
38.11 + int buflen;
38.12 + int n;
38.13 +
38.14 + fprintf (stderr, "%s\n", mn_wordlist_version);
38.15 +
38.16 + buflen = fread (buf, 1, sizeof (buf), stdin);
38.17 + n = mn_encode (buf, buflen, outbuf, sizeof outbuf, MN_F64BITSPERLINE);
38.18 + if (n == 0)
38.19 + fwrite (outbuf, 1, strlen (outbuf), stdout);
38.20 + else
38.21 + fprintf (stderr, "mn_encode error %d\n", n);
38.22 + putchar ('\n');
38.23 +
38.24 + return 0;
38.25 +}