+++ /dev/null
-//
-// ITInetServerSocket.h
-// ITFoundation
-//
-// Created by Alexander Strange on Thu Feb 13 2003.
-// Copyright (c) 2003 __MyCompanyName__. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-
-@class ITInetSocket;
-
-@protocol ITInetServerSocketOwner
-- (oneway void)newClientJoined:(ITInetSocket*)client;
-@end
-
-@interface ITInetServerSocket : NSObject {
- @private
- int sockfd;
- volatile int dieflag;
- NSMutableSet *clients;
- NSNetService *service;
- id delegate;
- short port;
- NSString *rndType,*rndName;
- NSTimer *timer;
-}
-
-- (id)init;
-- (id)initWithDelegate:(id)d;
-
-- (BOOL)start;
-- (void)stop;
-
-- (int)sockfd;
-- (NSSet*)clients;
-- (id)delegate;
-- (short)port;
-
-- (void)setServiceType:(NSString*)type useForPort:(BOOL)p;
-- (void)setServiceName:(NSString*)name; // generally the computer's AppleTalk name
-- (void)setPort:(short)p;
-@end
+++ /dev/null
-//
-// ITInetServerSocket.m
-// ITFoundation
-//
-// Created by Alexander Strange on Thu Feb 13 2003.
-// Copyright (c) 2003 __MyCompanyName__. All rights reserved.
-//
-
-#import "ITInetServerSocket.h"
-#import "ITInetSocket.h"
-#import <sys/types.h>
-#import <sys/time.h>
-#import <arpa/inet.h>
-#import <netinet/in.h>
-#import <sys/socket.h>
-#import <netdb.h>
-#import <fcntl.h>
-#import <unistd.h>
-
-@interface ITInetServerSocket(Private)
--(short)lookupPortForServiceType:(NSString*)name;
--(void)setupConnection;
--(void)stopConnection;
--(void)setupRendezvousAdvertising;
--(void)stopRendezvousAdvertising;
--(void)setupThread;
--(void)stopThread;
--(void)newClient:(int)cfd;
--(void)socketAcceptLoop:(id)data;
-@end
-
-@implementation ITInetServerSocket
-- (id)init
-{
- if (self = [super init])
- {
- sockfd = -1;
- delegate = nil;
- clients = [[NSMutableSet alloc] init];
- service = nil;
- port = 0;
- dieflag = 0;
- rndType = rndName = nil;
- timer = nil;
- }
- return self;
-}
-
-- (id)initWithDelegate:(id)d
-{
- if (self = [super init])
- {
- sockfd = -1;
- delegate = [d retain];
- clients = [[NSMutableSet alloc] init];
- service = nil;
- port = 0;
- dieflag = 0;
- rndType = rndName = nil;
- timer = nil;
- }
- return self;
-}
-
-- (void)dealloc
-{
- [self stopConnection];
- [clients release];
- [delegate release];
- [rndName release];
- [rndType release];
-}
-
-- (BOOL)start
-{
- if (!rndName || !rndType || !port) return NO;
- [self setupConnection];
- return YES;
-}
-
-- (int)sockfd
-{
- return sockfd;
-}
-
-- (NSSet*)clients
-{
- return clients;
-}
-
-- (id)delegate
-{
- return delegate;
-}
-
-- (short)port
-{
- return port;
-}
-
-- (void)stop
-{
- [self stopConnection];
-}
-
-- (void)setServiceType:(NSString*)type useForPort:(BOOL)p
-{
- rndType = [type retain];
- if (p) {
- port = [self lookupPortForServiceType:type];
- }
-}
-
-- (void)setServiceName:(NSString*)name
-{
- rndName = [name retain];
-}
-
-- (void)setPort:(short)p
-{
- port = p;
-}
-@end
-
-@implementation ITInetServerSocket(Private)
--(short)lookupPortForServiceType:(NSString*)name
-{
- const char *_name = [name cString];
- struct addrinfo *res;
- short p;
- getaddrinfo(NULL,_name,NULL,&res);
- p = ntohs(((struct sockaddr_in *)res->ai_addr)->sin_port);
- freeaddrinfo(res);
- return p;
-}
-
--(void)setupConnection
-{
- struct addrinfo hints, *ai;
- hints.ai_flags = AI_PASSIVE;
- hints.ai_family = PF_INET6;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
- hints.ai_addrlen = 0;
- hints.ai_canonname = hints.ai_addr = hints.ai_next = NULL;
- getaddrinfo(NULL,[[[NSNumber numberWithShort:port] stringValue] cString],&hints,&ai);
- sockfd = socket(PF_INET6,SOCK_STREAM,IPPROTO_TCP);
- bind(sockfd,ai->ai_addr,ai->ai_addrlen);
- listen(sockfd, SOMAXCONN);
- freeaddrinfo(ai);
- [self setupRendezvousAdvertising];
- [self setupThread];
-}
-
-- (void)stopConnection
-{
- [self stopRendezvousAdvertising];
- [clients makeObjectsPerformSelector:@selector(disconnect)];
- [self stopThread];
- close(sockfd);
- sockfd = -1;
-}
-
-- (void)setupRendezvousAdvertising
-{
- NSString *a = [NSString stringWithFormat:@"_%@._tcp.",rndType];
- service = [[NSNetService alloc] initWithDomain:@"" type:a name:rndName port:htons(port)];
- NSLog(@"Advertising a service of type %@ name %@",a,rndName);
- [service publish];
-}
-
-- (void)stopRendezvousAdvertising
-{
- [service stop];
- [service release];
- service = nil;
-}
-
-- (void)setupThread
-{
- NSPort *p1 = [NSPort port], *p2 = [NSPort port];
- NSConnection *dcon = [[NSConnection alloc] initWithReceivePort:p1 sendPort:p2];
- NSArray *par = [NSArray arrayWithObjects:p2,p1,nil];
- [dcon setRootObject:self];
- NSLog(@"detached server thread");
- [NSThread detachNewThreadSelector:@selector(socketAcceptLoop:) toTarget:self withObject:par];
-}
-
-- (void)stopThread
-{
- NSLog(@"stopping server thread");
- dieflag = 1;
- do {} while (dieflag == 1);
-}
-
-- (void)newClient:(int)cfd
-{
- ITInetSocket *csocket = [[ITInetSocket alloc] initWithFD:cfd delegate:delegate];
- NSLog(@"new client for this server");
- [clients addObject:csocket];
-}
-
-- (void)socketAcceptLoop:(id)data
-{
- NSAutoreleasePool *ap = [[NSAutoreleasePool alloc] init];
- NSArray *par = data;
- NSConnection *dcon = [[NSConnection alloc] initWithReceivePort:[par objectAtIndex:0] sendPort:[par objectAtIndex:1]];
- NSProxy *dp = [dcon rootProxy];
- while ((sockfd >= 0) && !dieflag)
- {
- signed int cfd;
- cfd = accept(sockfd,NULL,NULL);
- NSLog(@"Someone connected!");
- [(id)dp newClient:cfd];
- [ap release];
- ap = [[NSAutoreleasePool alloc] init];
- }
-
- NSLog(@"suiciding");
- dieflag = 0;
- [dcon release];
- [ap release];
-}
-@end
\ No newline at end of file
+++ /dev/null
-//
-// ITInetSocket.h
-// ITFoundation
-//
-// Created by Alexander Strange on Tue Feb 11 2003.
-// Copyright (c) 2003 __MyCompanyName__. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-#import <netinet/in.h>
-#import <netdb.h>
-#import "ITByteStream.h"
-
-/*!
- * @header ITInetSocket
- * @abstract Definitions for the ITInetSocket class
- */
-
-
-/*!
- * @enum ITInetSocketState
- * @abstract Possible states of a socket
- * @constant ITInetSocketConnecting The socket is negotiating a connection.
- * @constant ITInetSocketListening The socket is a server socket.
- * @constant ITInetSocketReading The socket is reading data from the other side.
- * @constant ITInetSocketWriting The socket is sending data to the other side.
- * @constant ITInetSocketDisconnected The socket does not have a connection.
- */
-typedef enum {
- ITInetSocketConnecting,
- ITInetSocketListening,
- ITInetSocketReading,
- ITInetSocketWriting,
- ITInetSocketDisconnected
-} ITInetSocketState;
-
-/*!
- * @enum ITInetSocketError
- * @abstract Possible error conditions of a socket
- * @constant ITInetHostNotFound The host specified does not actually exist.
- * @constant ITInetConnectionDropped The remote side dropped the connection.
- * @constant ITInetCouldNotConnect The socket was unable to connect for some reason
- */
-typedef enum {
- ITInetHostNotFound,
- ITInetConnectionDropped,
- ITInetCouldNotConnect
-} ITInetSocketError;
-
-@class ITInetSocket;
-
-/*!
- * @protocol ITInetSocketDelegate
- * @abstract Delegate methods for ITInetSocket
- * @discussion ITInetSockets use these methods to communicate with their delegates
- */
-@protocol ITInetSocketDelegate <DataReciever>
-/*!
- * @method errorOccured:during:onSocket:
- * @abstract Alerts the delegate of an error condition.
- * @discussion The delegate can try retryCondition.
- * @param err The error class.
- * @param state What the socket was doing when the error occured.
- * @param sender The socket the error occured on.
- */
-- (oneway void) errorOccured:(ITInetSocketError)err during:(ITInetSocketState)state onSocket:(ITInetSocket*)sender;
-/*!
- * @method finishedConnecting:
- * @abstract Alerts the delegate of a successful connection attempt.
- * @discussion The delegate should send whatever initial data is required for the protocol (nickname for IRC, etc.)
- * @param sender The socket that established the connection.
- */
-- (oneway void) finishedConnecting:(ITInetSocket *)sender;
-@end
-
-/*!
- * @class ITInetSocket
- * @abstract An Internet socket class.
- * @discussion ITInetSocket is an Internet socket class supporting IPv6 and Rendezvous.
- */
-@interface ITInetSocket : NSObject <DataReciever> {
- int sockfd;
- int port;
- int nc;
- unsigned short bufs;
- volatile int dieflag;
- volatile int actionflag;
- id <ITInetSocketDelegate> delegate;
- struct addrinfo *ai, *ai_cur;
- ITByteStream *readPipe, *writePipe;
- ITInetSocketState state;
- NSArray *sarr;
-}
-/*!
- * @method startAutoconnectingToService:delegate:
- * @abstract Automatically creates sockets whenever a certain type of Rendezvous service appears.
- * @discussion The auto-created sockets will send finishedConnecting: to the delegate.
- * @param type The type of Rendezvous service to listen on.
- * @param d The delegate that the sockets will belong to.
- */
-+(void)startAutoconnectingToService:(NSString*)type delegate:(id <ITInetSocketDelegate>)d;
-/*!
- * @method initWithFD:delegate:
- * @abstract Wraps a socket around an existing socket descriptor.
- * @discussion The socket will start listening on the descriptor as normal.
- * @param fd The descriptor.
- * @param d The delegate for the socket.
- */
--(id) initWithFD:(int)fd delegate:(id <ITInetSocketDelegate>)d;
-/*!
- * @method initWithDelegate:
- * @abstract Creates a new socket.
- * @discussion The socket will not be connected to anything.
- * @param d The delegate of the socket.
- */
--(id) initWithDelegate:(id <ITInetSocketDelegate>)d;
-
--(id <ITInetSocketDelegate>)delegate;
--(unsigned short)bufferSize;
--(void)setBufferSize:(unsigned short)bufs;
--(void) connectToHost:(NSString*)host onPort:(short)port;
--(void) connectToHost:(NSString*)host onNamedPort:(NSString*)port;
--(void) connectWithSockaddrArray:(NSArray*)arr;
--(ITInetSocketState) state;
--(void) retryConnection;
--(void) disconnect;
--(ITByteStream *)readPipe;
--(ITByteStream *)writePipe;
-@end
+++ /dev/null
-//
-// ITInetSocket.m
-// ITFoundation
-//
-// Created by Alexander Strange on Tue Feb 11 2003.
-// Copyright (c) 2003 __MyCompanyName__. All rights reserved.
-//
-
-#import "ITInetSocket.h"
-#import "ITServiceBrowserDelegate.h"
-#import <sys/socket.h>
-#import <arpa/inet.h>
-#import <unistd.h>
-
-@interface ITInetSocket(Debugging)
--(NSString*)dumpv6Addrinfo:(struct addrinfo *)_ai;
-@end
-
-@interface ITInetSocket(Private)
--(void)doConnSetupWithHost:(NSString*)host namedPort:(NSString*)namedPort;
--(void)realDoConnection;
--(void)spinoffReadLoop;
--(void)socketReadLoop:(id)data;
-@end
-
-@implementation ITInetSocket
-+(void)startAutoconnectingToService:(NSString*)type delegate:(id <ITInetSocketDelegate,NSObject>)d
-{
- NSNetServiceBrowser *browse = [[NSNetServiceBrowser alloc] init];
- ITServiceBrowserDelegate *bd = [[ITServiceBrowserDelegate alloc] initWithDelegate:d];
-
- [browse setDelegate:bd];
- [browse searchForServicesOfType:[NSString stringWithFormat:@"_%@._tcp.",type] inDomain:@""];
-}
-
--(id)initWithFD:(int)fd delegate:(id <ITInetSocketDelegate,NSObject>)d
-{
- if (self = [super init])
- {
- state = ITInetSocketListening;
- sockfd = fd;
- delegate = [d retain];
- port = 0;
- writePipe = [[ITByteStream alloc] initWithDelegate:self];
- readPipe = [[ITByteStream alloc] initWithDelegate:d];
- ai = nil;
- sarr = nil;
- bufs = 512;
- actionflag = dieflag = 0;
- nc = 0;
- }
- [self spinoffReadLoop];
- return self;
-}
-
--(id)initWithDelegate:(id <ITInetSocketDelegate,NSObject>)d
-{
- if (self = [super init])
- {
- state = ITInetSocketDisconnected;
- sockfd = -1;
- delegate = [d retain];
- port = 0;
- writePipe = [[ITByteStream alloc] initWithDelegate:self];
- readPipe = [[ITByteStream alloc] initWithDelegate:d];
- ai = nil;
- sarr = nil;
- bufs = 512;
- actionflag = dieflag = 0;
- nc = 1;
- }
- return self;
-}
-
-
--(void) dealloc
-{
- shutdown(sockfd,2);
- [delegate release];
- [writePipe release];
- [readPipe release];
- if (!sarr) freeaddrinfo(ai);
- [sarr release];
-}
-
--(void) connectToHost:(NSString*)host onPort:(short)thePort
-{
- if (state == ITInetSocketDisconnected)
- {
- NSString *nport = [[NSNumber numberWithShort:thePort] stringValue];
- [self doConnSetupWithHost:host namedPort:nport];
- }
-}
-
--(void) connectToHost:(NSString*)host onNamedPort:(NSString*)_port
-{
- if (state == ITInetSocketDisconnected)
- {
- [self doConnSetupWithHost:host namedPort:_port];
- }
-}
-
--(void) connectWithSockaddrArray:(NSArray*)arr
-{
- if (state == ITInetSocketDisconnected)
- {
- NSEnumerator *e = [arr objectEnumerator];
- NSData *d;
- struct addrinfo *a,*oa;
- ai = malloc(sizeof(struct addrinfo));
- ai_cur = ai;
- oa = a = ai;
- bzero(a,sizeof(struct addrinfo));
- while (d = [e nextObject])
- {
- struct sockaddr *s = (struct sockaddr*)[d bytes];
- bzero(a,sizeof(struct addrinfo));
- a->ai_family = s->sa_family;
- a->ai_addr = s;
- a->ai_next = malloc(sizeof(struct addrinfo));
- oa = a;
- a = a->ai_next;
- }
- free(a);
- oa->ai_next = NULL;
- NSLog(@"Sockaddr connecting....");
- [self dumpv6Addrinfo:ai];
- [self realDoConnection];
- }
-}
-
--(void)disconnect
-{
- NSLog(@"Got a disconnect");
- dieflag = 1;
- do {} while (dieflag == 1);
-}
-
--(void)retryConnection
-{
- ai_cur = ai_cur->ai_next?ai_cur->ai_next:ai_cur;
- [self disconnect];
- [self realDoConnection];
-}
-
--(ITInetSocketState)state
-{
- return state;
-}
--(id <ITInetSocketDelegate>)delegate
-{
- return delegate;
-}
-
--(unsigned short)bufferSize
-{
- return bufs;
-}
-
--(void)setBufferSize:(unsigned short)_bufs
-{
- bufs = _bufs;
-}
-
--(void)newDataAdded:(ITByteStream*)sender
-{
-}
-
--(ITByteStream*)readPipe {return readPipe;}
--(ITByteStream*)writePipe {return writePipe;}
-@end
-
-@implementation ITInetSocket(Debugging)
--(NSString*)dumpv6Addrinfo:(struct addrinfo *)_ai
-{
- const char *cfmt =
- "{\n"
- "Flags = %x\n"
- "Family = %x\n"
- "Socktype = %x\n"
- "Protocol = %x\n"
- "Canonname = %s\n"
- "Sockaddr = \n"
- "\t{\n"
- "\tLength = %x\n"
- "\tFamily = %x\n"
- "\tPort = %d\n"
- "\tFlowinfo = %x\n"
- "\tAddr = {%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx}\n"
- "\tScope = %x\n"
- "\t}\n"
- "Next = %@\n"
- "}\n";
- NSString *nsfmt = [NSString stringWithCString:cfmt];
- struct sockaddr_in6 *sa = (struct sockaddr_in6 *)_ai->ai_addr;
- NSString *buf = [[NSMutableString alloc] initWithFormat:nsfmt,_ai->ai_flags,_ai->ai_family,_ai->ai_socktype,_ai->ai_protocol,_ai->ai_canonname?_ai->ai_canonname:"",sa->sin6_len,sa->sin6_family,sa->sin6_port,sa->sin6_flowinfo,sa->sin6_addr.__u6_addr.__u6_addr16[0],sa->sin6_addr.__u6_addr.__u6_addr16[1],sa->sin6_addr.__u6_addr.__u6_addr16[2],sa->sin6_addr.__u6_addr.__u6_addr16[3],sa->sin6_addr.__u6_addr.__u6_addr16[4],sa->sin6_addr.__u6_addr.__u6_addr16[5],sa->sin6_addr.__u6_addr.__u6_addr16[6],sa->sin6_addr.__u6_addr.__u6_addr16[7],sa->sin6_scope_id,_ai->ai_next?[self dumpv6Addrinfo:_ai->ai_next]:@"nil"];
-
- return buf;
-}
-@end
-
-@implementation ITInetSocket(Private)
--(void)doConnSetupWithHost:(NSString*)host namedPort:(NSString*)namedPort
-{
- struct addrinfo hints;
- int err;
- const char *portNam = [namedPort cString], *hostCStr = [host cString];
- state = ITInetSocketConnecting;
- hints.ai_flags = 0;
- hints.ai_family = PF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
- hints.ai_addrlen = 0;
- hints.ai_canonname = NULL;
- hints.ai_addr = NULL;
- hints.ai_next = NULL;
-
- err = getaddrinfo(hostCStr,portNam,&hints,&ai);
-
- NSLog(@"%s, h %@ p %@",gai_strerror(err),host,namedPort);
- NSLog(ai?[self dumpv6Addrinfo:ai]:@"");
- ai_cur = ai;
- [self realDoConnection];
-}
-
--(void)realDoConnection
-{
- sockfd = socket(ai_cur->ai_family,SOCK_STREAM,IPPROTO_TCP);
- [self spinoffReadLoop];
-}
-
--(void)spinoffReadLoop
-{
- NSPort *p1 = [NSPort port], *p2 = [NSPort port];
- NSConnection *dcon = [[NSConnection alloc] initWithReceivePort:p1 sendPort:p2];
- NSArray *par = [NSArray arrayWithObjects:p2,p1,nil];
- [dcon setRootObject:delegate];
- [NSThread detachNewThreadSelector:@selector(socketReadLoop:) toTarget:self withObject:par]; //spawn read thread
-}
-
--(void)socketReadLoop:(id)data
-{
- NSAutoreleasePool *ap = [[NSAutoreleasePool alloc] init];
- NSConnection *dcon = [[NSConnection alloc] initWithReceivePort:[data objectAtIndex:0] sendPort:[data objectAtIndex:1]];
- NSProxy *dp = [[dcon rootProxy] retain];
- char *buf = malloc(bufs);
- unsigned long readLen = 0,wpl = 0;
- signed int err;
- [readPipe setDelegate:(id <ITInetSocketDelegate>)dp];
- if (nc){
- NSLog(@"Connecting");
- err = connect(sockfd,ai_cur->ai_addr,ai_cur->ai_addrlen);
- if (err == -1)
- {
- perror("CAwh");
- *((char*)NULL) = 12;
- [(id)dp errorOccured:ITInetCouldNotConnect during:ITInetSocketConnecting onSocket:self];
- goto dieaction;
- }
- }
- NSLog(@"Sending finishedConnecting");
- [(id)dp finishedConnecting:self];
-lstart:
- state = ITInetSocketListening;
- while (!actionflag && !dieflag && !(wpl = CFDataGetLength((CFDataRef)writePipe->data)))
- {
- readLen = recv(sockfd,buf,bufs,0);
- state = ITInetSocketReading;
- if (readLen == -1) {[(id)dp errorOccured:ITInetConnectionDropped during:ITInetSocketReading onSocket:self];goto dieaction;}
- if (readLen) {
- NSLog(@"recv'd");
- NSLog(@"Doing writeData to readPipe");
- [readPipe writeBytes:buf len:readLen];
- [ap release];
- ap = [[NSAutoreleasePool alloc] init];
- }
- }
- state = ITInetSocketListening;
- actionflag = 0;
-
- if (dieflag)
- {
-dieaction:
- state = ITInetSocketDisconnected;
- perror("Awh");
- free(buf);
- shutdown(sockfd,2);
- [dcon release];
- [dp release];
- [ap release];
- dieflag = 0;
- return;
- }
-
- {
- const char *d = CFDataGetBytePtr((CFDataRef)writePipe->data);
- state = ITInetSocketWriting;
- NSLog(@"Writing");
- [writePipe lockStream];
- wpl = send(sockfd,d,wpl,0);
- [writePipe shortenData:wpl];
- [writePipe unlockStream];
- [ap release];
- ap = [[NSAutoreleasePool alloc] init];
- goto lstart;
- }
- goto dieaction;
-}
-@end
\ No newline at end of file
+++ /dev/null
-//
-// ITServiceBrowserDelegate.h
-// ITFoundation
-//
-// Created by Alexander Strange on Sat Mar 15 2003.
-// Copyright (c) 2003 __MyCompanyName__. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-#import <Foundation/NSNetServices.h>
-
-@interface ITServiceBrowserDelegate : NSObject {
- id delegate;
-}
--(id) initWithDelegate:(id)delegate;
-@end
+++ /dev/null
-//
-// ITServiceBrowserDelegate.m
-// ITFoundation
-//
-// Created by Alexander Strange on Sat Mar 15 2003.
-// Copyright (c) 2003 __MyCompanyName__. All rights reserved.
-//
-
-#import "ITServiceBrowserDelegate.h"
-#import "ITInetSocket.h"
-#import <Foundation/NSNetServices.h>
-
-@implementation ITServiceBrowserDelegate
-- (id) initWithDelegate:(id)_delegate
-{
- if (self = [super init])
- {
- delegate = [_delegate retain];
- }
- return self;
-}
-
-- (void) dealloc
-{
- [delegate release];
-}
-
-- (void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didFindService:(NSNetService *)aNetService moreComing:(BOOL)moreComing
-{
- ITInetSocket *sock;
- NSArray *arr;
- id d = delegate;
- if (!moreComing)
- {
- NSLog(@"Nothing more coming");
- [[aNetService retain] autorelease];
- [aNetServiceBrowser stop];
- [aNetServiceBrowser release];
- [self release];
- }
- sock = [[ITInetSocket alloc] initWithDelegate:d];
- NSLog(@"Detected a service! name %@ type %@",[aNetService name],[aNetService type]);
- arr = [aNetService addresses];
- if ([arr count])
- [sock connectWithSockaddrArray:arr];
- else
- NSLog(@"There are no sockaddrs for this service!");
-}
-
-@end
+++ /dev/null
-/*
- * ITFoundation
- * ITStringScanner
- * A super-fast replacement for NSScanner
- *
- * Original Author : Alexander Strange <alexander.strange@ithinksw.com>
- * Responsibility : Matt Judy <mjudy@ithinksw.com>
- * Responsibility : Alexander Strange <alexander.strange@ithinksw.com>
- *
- * Copyright (c) 2002 - 2003 iThink Software.
- * All Rights Reserved
- *
- */
-
-#import <Foundation/Foundation.h>
-#import <stdlib.h>
-
-/*!
-@class ITStringScanner
-@discussion A super-fast replacement for NSScanner
-*/
-
-@interface ITStringScanner : NSObject {
- NSString *_string;
- char *_cString;
- size_t _currentPosition;
- size_t _size;
-}
-- (id)initWithString:(NSString*)string;
-- (NSString *)scanUpToCharacter:(char)character;
-- (NSString *)scanUpToString:(NSString*)string;
-@end
+++ /dev/null
-// I *could* use OWStringScanner, but I don't want to. Shut up, sabi :)
-
-#import "ITStringScanner.h"
-
-@implementation ITStringScanner
-
-- (id)init
-{
- if ( ( self = [super init] ) )
- {
- _cString = NULL;
- _string = nil;
- _currentPosition = 0;
- _size = 0;
- }
- return self;
-}
-
-- (id)initWithString:(NSString*)string
-{
- if ( ( self = [super init] ) )
- {
- _cString = (char *)[string cString];
- _string = [string retain];
- _currentPosition = 0;
- _size = [string length];
- }
- return self;
-}
-
-- (NSString *)scanUpToCharacter:(char)character
-{
- size_t i=_currentPosition,j=0;
-
- if (_cString[i] == character)
- {
- i++;
- return @"";
- }
- else
- {
- NSRange r = {i,0};
- NSString *tmpStr = nil;
- const size_t tmp = _size;
- unsigned char foundIt = NO;
-
- do
- {
- i++,j++;
-
- if (_cString[i] == character)
- {
- foundIt = YES;
- r.length = j;
- }
-
- }
- while ((!foundIt) && (i<tmp));
-
- if (foundIt)
- {
- tmpStr = [_string substringWithRange:r];
- _currentPosition = i;
- }
- return tmpStr;
- }
-}
-
-- (NSString *)scanUpToString:(NSString*)string
-{
- size_t i=_currentPosition,j=0, len = [string length];
- const char *str2cstr = [string cString];
-
-
- if (len <= 1)
- {
- if (len)
- return [self scanUpToCharacter:str2cstr[0]];
- else
- return @"";
- }
- else
- {
- NSRange r = {i,0};
- NSString *tmpStr = nil;
- const size_t tmp = _size;
- unsigned char foundIt = NO;
-
- do
- {
- i++,j++;
-
- if (0)
- {//now we check for the rest of the string
- foundIt = YES;
- r.length = j;
- }
-
- }
- while ((!foundIt) && (i<tmp));
-
- if (foundIt)
- {
- tmpStr = [_string substringWithRange:r];
- _currentPosition = i;
- }
- return tmpStr;
- }
-
-}
-@end