This is MailAddress.m in view mode; [Download] [Up]
//---------------------------------------------------------------------------------------
// MailAddress.h created by moritz on Mon 09-Mar-1998
// This code is part of the Alexandra Newsreader Project. For copyright details see
// GNU public license version 2 or above. No warranties implied. Use at own risk.
// More information can be found at <http://www.object-factory.com/Alexandra>.
// @(#)$Id: MailAddress.m,v 1.7 1998/10/22 14:27:20 erik Exp $
//---------------------------------------------------------------------------------------
#import "Utilities.h"
#import "Message.h"
#import "MailAddress.h"
//-------------------------------------------------------------------------------------------
// PRIVATE API
//-------------------------------------------------------------------------------------------
@interface MailAddress (Tokenizer)
- (NSString *)_scanToken:(NSScanner *)aScanner intoString:(NSString **)aToken expect:(NSString *)aString;
- (void)_scanToken:(NSScanner *)aScanner expect:(NSString *)aString withValue:(NSString *)aToken;
- (NSString *)_scanToken:(NSScanner *)aScanner withNonASCII:(BOOL)nonASCII intoString:(NSString **)aString;
- (NSString *)_scanDomain:(NSScanner *)aScanner;
- (NSString *)_scanPhrase:(NSScanner *)aScanner;
- (BOOL)_scan:(NSScanner *)aScanner special:(NSString *)aString;
- (NSString *)_scanWord:(NSScanner *)aScanner withNonASCII:(BOOL)nonASCII;
- (NSString *)_unquotedDomainLiteral:(NSString *)aString;
- (NSString *)_unquotedString:(NSString *)aString;
- (NSString *)_unqotedWord:(NSString *)aString;
- (NSString *)_unquotedPhrase:(NSString *)aString;
@end
@interface MailAddress (Parser)
- (void)__assertParseCompleted:(NSScanner *)aScanner;
- (NSString *)__parseLocalPart:(NSScanner *)aScanner;
- (NSString *)_parseLocalPart:(NSString *)aString;
- (NSString *)__parseDomain:(NSScanner *)aScanner;
- (NSString *)_parseDomain:(NSString *)aString;
- (void)__parseAddressSpecification:(NSScanner *)aScanner;
- (void)_parseAddressSpecification:(NSString *)aString;
- (void)__parseRouteAddress:(NSScanner *)aScanner;
- (void)_parseRouteAddress:(NSString *)aString;
- (NSString *)_stringByExtractingComments:(NSString *)aString;
@end
@interface MailAddress (Private)
- (void)setRouteAddress:(NSString *)aString;
- (void)setLocalPartKnownToBeValid:(NSString *)aString;
- (void)setDomainKnownToBeValid:(NSString *)aString;
- (void)setRealNameKnownToBeValid:(NSString *)aString;
@end
//-------------------------------------------------------------------------------------------
@implementation MailAddress
//-------------------------------------------------------------------------------------------
NSString *RFC822ParseException = @"RFC822ParseError";
NSString *RFC822Scanner = @"RFC822Scanner";
static NSString *RFCTokenSpecial = @"RFCSpecial";
static NSString *RFCTokenQuotedString = @"RFCQuotedString";
static NSString *RFCTokenDomainLiteral = @"RFCDomainLiteral";
static NSString *RFCTokenComment = @"RFCComment";
static NSString *RFCTokenAtom = @"RFCAtom";
static BOOL sloppy = NO;
+ (BOOL)sloppyParser;
{
return sloppy;
}
+ (void)setSloppyParser:(BOOL)flag;
{
sloppy = flag;
}
//-------------------------------------------------------------------------------------------
// FACTORY
//-------------------------------------------------------------------------------------------
+ (MailAddress *)mailAddressWithString:(NSString *)aString;
{
return [[[self alloc] initWithString:aString] autorelease];
}
+ (MailAddress *)mailAddressWithLocalPart:(NSString *)aString domain:(NSString *)otherString;
{
MailAddress *new;
new = [[[self alloc] init] autorelease];
[new setLocalPart:aString];
[new setDomain:otherString];
return new;
}
+ (MailAddress *)mailAddressWithAddressSpecification:(NSString *)aString realName:(NSString *)aName;
{
MailAddress *new;
new = [[[self alloc] init] autorelease];
[new setAddressSpecification:aString];
[new setRealName:aName];
return new;
}
//-------------------------------------------------------------------------------------------
// Initialiser
//-------------------------------------------------------------------------------------------
- init;
{
[super init];
routes = [[NSMutableArray alloc] init];
comments = [[NSMutableArray alloc] init];
return self;
}
- initWithString:(NSString *)string;
{
[self init];
string = [self _stringByExtractingComments:string];
#ifdef DEBUG
NSLog(@"after removing comments %@: %@", comments, string);
#endif
NS_DURING
[self setAddressSpecification:string];
NS_HANDLER
[self setRouteAddress:string];
NS_ENDHANDLER
return self;
}
- initWithLocalPart:(NSString *)aString domain:(NSString *)otherString;
{
[self init];
[self setLocalPart:aString];
[self setDomain:otherString];
return self;
}
//-------------------------------------------------------------------------------------------
// ATTRIBUTES
//-------------------------------------------------------------------------------------------
- (NSString *)_localPart;
{
return localPart;
}
- (NSString *)localPart;
{
return localPart ? localPart : @"";
}
- (void)setLocalPartKnownToBeValid:(NSString *)aString;
{
if (localPart != aString)
{
[self invalidateStringRep];
[localPart release];
aString = [self _unquotedDomainLiteral:aString];
localPart = [aString copy];
}
}
- (void)setLocalPart:(NSString *)aString;
{
NSString *s;
s = [self _parseLocalPart:aString];
[self setLocalPartKnownToBeValid:s];
}
- (NSString *)_domain;
{
return domain;
}
- (NSString *)domain;
{
return domain ? domain : @"";
}
- (NSArray *)domains;
{
return [domain componentsSeparatedByString:@"."];
}
- (void)setDomainKnownToBeValid:(NSString *)aString;
{
if (domain != aString)
{
[self invalidateStringRep];
[domain release];
aString = [self _unquotedDomainLiteral:aString];
domain = [aString copy];
}
}
- (void)setDomain:(NSString *)aString;
{
NSString *s;
s = [self _parseDomain:aString];
[self setDomainKnownToBeValid:s];
}
- (NSString *)_realName;
{
if (!realName)
{
if ([comments count] > 0)
{
return [comments componentsJoinedByString:@" "];
}
return nil;
}
return realName;
}
- (NSString *)realName;
{
NSString *n = [self _realName];
return n ? n : @"";
}
- (void)setRealNameKnownToBeValid:(NSString *)aString;
{
if (realName != aString)
{
[self invalidateStringRep];
[realName release];
aString = [self _unquotedPhrase:aString];
realName = [aString copy];
}
}
- (void)setRealName:(NSString *)aString;
{
[self setRealNameKnownToBeValid:aString];
}
//-------------------------------------------------------------------------------------------
// DERIVED ATTRIBUTES
//-------------------------------------------------------------------------------------------
- (void)setAddressSpecification:(NSString *)aString;
{
[self _parseAddressSpecification:aString];
}
- (void)setRouteAddress:(NSString *)aString;
{
[self _parseRouteAddress:aString];
}
- (NSString *)addressSpecification
{
if (domain)
return [NSString stringWithFormat:@"%@@%@", [self localPart], [self domain]];
else
return [self localPart];
}
- (NSString *)stringRepresentation;
{
NSString *name;
if(stringRep == nil)
{
if((name = [self _realName]))
{
NSRange r1, r2;
r1 = [name rangeOfCharacterFromSet:[NSCharacterSet MASpecialCharacterSet]];
r2 = [name rangeOfCharacterFromSet:[NSCharacterSet controlCharacterSet]];
if ((r1.length > 0) || (r2.length > 0)) // needs quoting
name = [NSString stringWithFormat:@"\"%@\"", name];
stringRep = [[NSString stringWithFormat:@"%@ <%@>", name, [self addressSpecification]] retain];
}
else
{
stringRep = [[self addressSpecification] retain];
}
}
return stringRep;
}
//-------------------------------------------------------------------------------------------
// TRANSFER REPRESENTATIONS
//-------------------------------------------------------------------------------------------
/* We should really override initFromTransferRepresentation and only decode comments and
words/phrases, but the parser is string based and the decoding function will do the right
thing anyway. */
- (NSData *)transferRepresentation;
{
NSMutableCharacterSet *qCharset;
NSData *nameData, *transfRep;
NSMutableData *buffer;
NSString *name;
const unsigned char *cp, quote[1] = "\"", space[1] = " ", lt[1] = "<", gt[1] = ">";
unsigned int i;
if((name = [self _realName]) != nil)
{
buffer = [NSMutableData data];
nameData = [name dataForMIMEHeaderField];
qCharset = [[[NSCharacterSet MASpecialCharacterSet] mutableCopy] autorelease];
[qCharset formUnionWithCharacterSet:[NSCharacterSet controlCharacterSet]];
cp = [nameData bytes];
for(i = [nameData length]; i > 0; i--)
if([qCharset characterIsMember:(unichar)*cp++])
break;
if(i != 0)
{
[buffer appendBytes:quote length:1];
[buffer appendData:nameData];
[buffer appendBytes:quote length:1];
}
else
{
[buffer appendData:nameData];
}
[buffer appendBytes:space length:1];
[buffer appendBytes:lt length:1];
[buffer appendData:[[self addressSpecification] dataUsingEncoding:NSASCIIStringEncoding]];
[buffer appendBytes:gt length:1];
transfRep = [[buffer copy] autorelease];
}
else
{
transfRep = [[self addressSpecification] dataUsingEncoding:NSASCIIStringEncoding];
}
return transfRep;
}
//-------------------------------------------------------------------------------------------
// WRAPPER (WebScript!)
//-------------------------------------------------------------------------------------------
+ (BOOL)isValidMailAddress:(NSString *)aString;
{
BOOL valid;
NS_DURING
valid = NO;
[self mailAddressWithString:aString];
valid = YES;
NS_HANDLER
#ifdef LITTLE_FOUNDATION
NSLog(@"invalid address '%@': %@, %@", aString, [exception exceptionName], [exception exceptionReason]);
#else
NSLog(@"invalid address '%@': %@, %@", aString, [localException name], [localException reason]);
#endif
NS_ENDHANDLER
return valid;
}
//-------------------------------------------------------------------------------------------
// NSObject Stuff
//-------------------------------------------------------------------------------------------
- (void)dealloc;
{
[comments release];
[routes release];
[realName release];
[domain release];
[localPart release];
[super dealloc];
}
//-------------------------------------------------------------------------------------------
@end
//-------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------
@implementation MailAddress (Tokenizer)
//-------------------------------------------------------------------------------------------
- (NSString *)_scanToken:(NSScanner *)aScanner intoString:(NSString **)aToken expect:(NSString *)aString;
{
NSString *type, *token;
while ((type = [self _scanToken:aScanner withNonASCII:NO intoString:&token]))
{
if (type == aString)
{
if (aToken)
{
*aToken = token;
}
return type;
}
else //if (type != RFCTokenComment)
{
[NSException raise:RFC822ParseException format:@"expected token %@; found %@", aString, type];
}
}
[NSException raise:RFC822ParseException format:@" expected %@; found end of string", aString];
return nil;
}
- (void)_scanToken:(NSScanner *)aScanner expect:(NSString *)aString withValue:(NSString *)aToken;
{
NSString *type, *token = nil;
if ((type = [self _scanToken:aScanner intoString:&token expect:aString]))
{
if (![token isEqual:aToken])
{
[NSException raise:RFC822ParseException format:@"expected %@; found %@", aToken, token];
}
return ;
}
[NSException raise:RFC822ParseException format:@" expected %@; found end of string", aToken];
}
- (NSString *)_scanQuotedPair:(NSScanner *)aScanner;
{
NSRange quote, character;
quote = [[aScanner string] rangeOfComposedCharacterSequenceAtIndex:[aScanner scanLocation] - 1];
character = [[aScanner string] rangeOfComposedCharacterSequenceAtIndex:[aScanner scanLocation]];
quote.length += character.length;
[aScanner setScanLocation:[aScanner scanLocation] + 1];
return [[aScanner string] substringWithRange:quote];
}
- (NSString *)_scanQuotedString:(NSScanner *)aScanner;
{
NSMutableString *quoted = [NSMutableString string];
NSString *part;
do
{
if ([aScanner scanString:@"\\" intoString:NULL])
{
[quoted appendString:[self _scanQuotedPair:aScanner]];
}
else if ([aScanner scanString:@"\"" intoString:NULL])
{
return [NSString stringWithFormat:@"\"%@\"", quoted];
}
else if ([aScanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"\"\n\\"] intoString:&part])
//[NSCharacterSet MAQuoteCharacterSet] intoString:&part])
{
[quoted appendString:part];
}
else
{
if (![aScanner scanString:@"\"" intoString:NULL])
{
[NSException raise:RFC822ParseException format:@"expected \""];
}
}
}
while (1);
// shoudln't come here
return nil;
}
- (NSString *)_scanDomainLiteral:(NSScanner *)aScanner;
{
NSMutableString *quoted = [NSMutableString string];
NSString *part;
do
{
if ([aScanner scanString:@"\\" intoString:NULL])
{
[quoted appendString:[self _scanQuotedPair:aScanner]];
}
else if ([aScanner scanString:@"]" intoString:NULL])
{
return [NSString stringWithFormat:@"[%@]", quoted];
}
else if ([aScanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"[]\n\\"] intoString:&part])
{
[quoted appendString:part];
}
else
{
if (![aScanner scanString:@"]" intoString:NULL])
{
[NSException raise:RFC822ParseException format:@"expected ]" ];
}
}
}
while (1);
// shoudln't come here
return nil;
}
- (NSString *)_scanComment:(NSScanner *)aScanner;
{
// does not yet handle nested comments
NSMutableString *comment;
[aScanner scanUpToString:@")" intoString:&comment];
if (![aScanner scanString:@")" intoString:NULL])
{
[NSException raise:RFC822ParseException format:@"expected )"];
}
return comment;
}
- (NSString *)_scanToken:(NSScanner *)aScanner withNonASCII:(BOOL)nonASCII intoString:(NSString **)aString;
{
NSString *tokenName;
NSString *token = nil;
int scanLocation;
// eat whitespace
// does this handle folding correctly?
[aScanner setCharactersToBeSkipped:nil];
[aScanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL];
[aScanner setCharactersToBeSkipped:[NSCharacterSet whitespaceCharacterSet]];
scanLocation = [aScanner scanLocation];
if (scanLocation >= [[aScanner string] length])
{
tokenName = nil;
}
else if ([[self class] sloppyParser] && [aScanner scanString:@"\\" intoString:NULL])
{
#ifdef DEBUG
NSLog(@"quoted pair not allowed here (strictly speaking)");
#endif
tokenName = RFCTokenQuotedString;
token = [self _scanQuotedPair:aScanner];
}
else if ([aScanner scanString:@"\"" intoString:NULL]) // quoted-string
{
tokenName = RFCTokenQuotedString;
token = [self _scanQuotedString:aScanner];
}
else if ([aScanner scanString:@"[" intoString:NULL]) // domain-literal
{
tokenName = RFCTokenDomainLiteral;
token = [self _scanDomainLiteral:aScanner];
}
else if ([aScanner scanString:@"(" intoString:NULL]) // comment
{
tokenName = RFCTokenComment;
token = [self _scanComment:aScanner];
// [comments addObject:token];
}
else
{
unichar character;
character = [[aScanner string] characterAtIndex:scanLocation];
if ([[NSCharacterSet MASpecialCharacterSet] characterIsMember:character])
{
NSRange range = [[aScanner string] rangeOfComposedCharacterSequenceAtIndex:scanLocation];
tokenName = RFCTokenSpecial;
token = [[aScanner string] substringWithRange:range];
[aScanner setScanLocation:++scanLocation];
}
else
{
tokenName = RFCTokenAtom;
if (![aScanner scanCharactersFromSet:nonASCII ? [NSCharacterSet MAEncodedAtomCharacterSet] : [NSCharacterSet MAAtomCharacterSet] intoString:&token])
{
[NSException raise:RFC822ParseException format:@"found illegal character 0x%x for 'atom' at %d", character, [aScanner scanLocation]];
}
}
}
if (aString)
{
*aString = token;
}
return tokenName;
}
- (NSString *)_scanDomain:(NSScanner *)aScanner;
{
NSString *type, *token;
while ((type = [self _scanToken:aScanner withNonASCII:NO intoString:&token]))
{
if ((type == RFCTokenAtom) || (type == RFCTokenDomainLiteral))
{
return token;
}
else //if (type != RFCTokenComment)
{
[NSException raise:RFC822ParseException format:@"expexected atom or quoted string"];
}
}
return nil;
}
- (NSString *)_scanWord:(NSScanner *)aScanner withNonASCII:(BOOL)nonASCII;
{
NSString *type, *token;
while ((type = [self _scanToken:aScanner withNonASCII:nonASCII intoString:&token]))
{
if ((type == RFCTokenAtom) || (type == RFCTokenQuotedString))
{
return token;
}
else //if (type != RFCTokenComment)
{
[NSException raise:RFC822ParseException format:@"expexected atom or quoted string"];
}
}
return nil;
}
- (NSString *)_scanPhrase:(NSScanner *)aScanner;
{
NSMutableArray *parts = [NSMutableArray array];
NSString *word;
unsigned scanLocation;
NS_DURING
{
scanLocation = [aScanner scanLocation];
while ((word = [self _scanWord:aScanner withNonASCII:YES]) != nil)
{
[parts addObject:word];
scanLocation = [aScanner scanLocation];
}
}
NS_HANDLER
{
[aScanner setScanLocation:scanLocation];
return [parts componentsJoinedByString:@" "];
}
NS_ENDHANDLER
return [parts componentsJoinedByString:@" "];
}
- (BOOL)_scan:(NSScanner *)aScanner special:(NSString *)aString;
{
unsigned int scanLocation = [aScanner scanLocation];
NS_DURING
{
[self _scanToken:aScanner expect:RFCTokenSpecial withValue:aString];
}
NS_HANDLER
{
[aScanner setScanLocation:scanLocation];
return NO;
}
NS_ENDHANDLER
return YES;
}
- (NSString *)_unquotedDomainLiteral:(NSString *)aString;
{
NSScanner *scanner = [NSScanner scannerWithString:aString];
NSMutableString *unquoted = [NSMutableString string];
NSCharacterSet *cs = [NSCharacterSet characterSetWithCharactersInString:@"]\\"];
NSString *part;
if ([scanner scanString:@"[" intoString:NULL])
{
while (![scanner scanString:@"]" intoString:NULL])
{
if ([scanner scanString:@"\\" intoString:NULL])
[unquoted appendString:[self _scanQuotedPair:scanner]];
if (([scanner scanUpToCharactersFromSet:cs intoString:&part]))
[unquoted appendString:part];
}
return unquoted;
}
return aString;
}
- (NSString *)_unquotedString:(NSString *)aString;
{
NSScanner *scanner = [NSScanner scannerWithString:aString];
NSMutableString *unquoted = [NSMutableString string];
NSCharacterSet *cs = [NSCharacterSet characterSetWithCharactersInString:@"\"\\"];
NSString *part;
if ([scanner scanString:@"\"" intoString:NULL])
{
while (![scanner scanString:@"\"" intoString:NULL])
{
if ([scanner scanString:@"\\" intoString:NULL])
[unquoted appendString:[self _scanQuotedPair:scanner]];
if (([scanner scanUpToCharactersFromSet:cs intoString:&part]))
[unquoted appendString:part];
}
return unquoted;
}
return aString;
}
- (NSString *)_unqotedWord:(NSString *)aString;
{
return [self _unquotedString:aString];
}
- (NSString *)_unquotedPhrase:(NSString *)aString;
{
return [self _unquotedString:aString];
}
//-------------------------------------------------------------------------------------------
@end
//-------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------
@implementation MailAddress (Parser)
//-------------------------------------------------------------------------------------------
- (void)__assertParseCompleted:(NSScanner *)aScanner;
{
/* NSString *token, *type;
while ((type = [self _scanToken:aScanner withNonASCII:YES intoString:&token]))
{
if (type != RFCTokenComment)
{
[NSException raise:RFC822ParseException format:@"'%@' not allowed after address specification", token];
}
}*/
if ([aScanner scanLocation] != [[aScanner string] length])
{
[NSException raise:RFC822ParseException format:@"'%@' not allowed after address specification", [[aScanner string] substringFromIndex:[aScanner scanLocation]]];
}
}
- (NSString *)__parseLocalPart:(NSScanner *)aScanner;
{
NSMutableArray *words = [NSMutableArray array];
NSString *word;
do
{
if((word = [self _scanWord:aScanner withNonASCII:NO]) != nil)
[words addObject:word];
}
while ([self _scan:aScanner special:@"."]);
return [words componentsJoinedByString:@"."];
}
- (NSString *)_parseLocalPart:(NSString *)aString;
{
NSScanner *scanner = [NSScanner scannerWithString:aString];
return [self __parseLocalPart:scanner];
}
- (NSString *)__parseDomain:(NSScanner *)aScanner;
{
NSMutableArray *subdomains = [NSMutableArray array];
NSString *subdomain;
do
{
if((subdomain = [self _scanDomain:aScanner]) != nil)
[subdomains addObject:subdomain];
}
while ([self _scan:aScanner special:@"."]);
return [subdomains componentsJoinedByString:@"."];
}
- (NSString *)_parseDomain:(NSString *)aString;
{
NSScanner *scanner = [NSScanner scannerWithString:aString];
return [self __parseDomain:scanner];
}
- (void)__parseAddressSpecification:(NSScanner *)aScanner;
{
NSString *_localPart, *_domain = nil;
NS_DURING
{
_localPart = [self __parseLocalPart:aScanner];
if ([self _scan:aScanner special:@"@"])
{
_domain = [self __parseDomain:aScanner];
}
else if (![[self class] sloppyParser])
{
[NSException raise:RFC822ParseException format:@"expected '@'"];
}
}
NS_HANDLER
{
#ifndef LITTLE_FOUNDATION
[[NSException exceptionWithName:[localException name] reason:[localException reason] userInfo:[NSDictionary dictionaryWithObject:aScanner forKey:RFC822Scanner]] raise];
#else
[[NSException exceptionWithName:[exception exceptionName] reason:[exception exceptionReason] userInfo:[NSDictionary dictionaryWithObject:aScanner forKey:RFC822Scanner]] raise];
#endif
}
NS_ENDHANDLER
[self setLocalPartKnownToBeValid:_localPart];
[self setDomainKnownToBeValid:_domain];
}
- (void)_parseAddressSpecification:(NSString *)aString;
{
NSScanner *theScanner;
theScanner = [NSScanner scannerWithString:aString];
[self __parseAddressSpecification:theScanner];
[self __assertParseCompleted:theScanner];
}
- (NSArray *)__parseRoutes:(NSScanner *)aScanner;
{
unsigned scanLocation = [aScanner scanLocation];
NSMutableArray *_routes = [NSMutableArray array];
NS_DURING
{
do
{
[self _scanToken:aScanner expect:RFCTokenSpecial withValue:@"@"];
[_routes addObject:[self _scanDomain:aScanner]];
if ([self _scan:aScanner special:@":"])
return _routes;
}
while ([self _scan:aScanner special:@","]);
}
NS_HANDLER
{
[aScanner setScanLocation:scanLocation];
return nil;
}
NS_ENDHANDLER
return _routes;
}
- (void)__parseRouteAddress:(NSScanner *)aScanner;
{
NSString *_phrase;
NS_DURING
{
_phrase = [self _scanPhrase:aScanner];
[self _scanToken:aScanner expect:RFCTokenSpecial withValue:@"<"];
routes = [[self __parseRoutes:aScanner] copy];
[self __parseAddressSpecification:aScanner];
[self _scanToken:aScanner expect:RFCTokenSpecial withValue:@">"];
}
NS_HANDLER
{
#ifndef LITTLE_FOUNDATION
[[NSException exceptionWithName:[localException name] reason:[localException reason] userInfo:[NSDictionary dictionaryWithObject:aScanner forKey:RFC822Scanner]] raise];
#else
[[NSException exceptionWithName:[exception exceptionName] reason:[exception exceptionReason] userInfo:[NSDictionary dictionaryWithObject:aScanner forKey:RFC822Scanner]] raise];
#endif
}
NS_ENDHANDLER
[self setRealName:_phrase];
}
- (void)_parseRouteAddress:(NSString *)aString;
{
NSScanner *theScanner;
theScanner = [NSScanner scannerWithString:aString];
[self __parseRouteAddress:theScanner];
[self __assertParseCompleted:theScanner];
}
- (NSString *)_stringByExtractingComments:(NSString *)aString;
{
NSString *token, *type;
NSScanner *scanner;
NSMutableArray *tokens = [NSMutableArray array];
scanner = [NSScanner scannerWithString:aString];
while ((type = [self _scanToken:scanner withNonASCII:YES intoString:&token]))
{
if (type == RFCTokenComment)
{
[comments addObject:token];
}
else
{
[tokens addObject:token];
}
}
return [tokens componentsJoinedByString:@" "];
}
//-------------------------------------------------------------------------------------------
@end
//-------------------------------------------------------------------------------------------
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.