libs-base/Source/String.m

443 lines
8.8 KiB
Mathematica
Raw Normal View History

/* Implementation for Objective-C String object
Copyright (C) 1993,1994,1995 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
This file is part of the GNU Objective C Class Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <objects/String.h>
#include <objects/IndexedCollectionPrivate.h>
/* memcpy(), strlen(), strcmp() are gcc builtin's */
#include <stdarg.h>
#include <assert.h>
/* Deal with strchr: */
#if STDC_HEADERS || HAVE_STRING_H
#include <string.h>
/* An ANSI string.h and pre-ANSI memory.h might conflict. */
#if !STDC_HEADERS && HAVE_MEMORY_H
#include <memory.h>
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
#define rindex strrchr
#define bcopy(s, d, n) memcpy ((d), (s), (n))
#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
#define bzero(s, n) memset ((s), 0, (n))
#else /* not STDC_HEADERS and not HAVE_STRING_H */
#include <strings.h>
/* memory.h and strings.h conflict on some systems. */
#endif /* not STDC_HEADERS and not HAVE_STRING_H */
@implementation String
+ (void) initialize
{
if (self == [String class])
[self setVersion:0]; /* beta release */
}
// INITIALIZING;
/* For now, this is the designated initializer for this class */
- initWithCString: (const char*)aCharPtr range: (IndexRange)aRange
{
[self notImplemented:_cmd];
return self;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
[self notImplemented:_cmd];
return self;
}
/* This override in mutable string classes */
- empty
{
[self shouldNotImplement:_cmd];
return self;
}
/* Override the designated initializer of superclass */
- initWithType: (const char *)contentEncoding
{
if (strcmp(contentEncoding, @encode(char)))
[self error:"invalid args to String initializer"];
[self initWithCString:NULL range:((IndexRange){0,0})];
return self;
}
- initWithCString: (const char*)aCharPtr length: (unsigned)aLength
{
return [self initWithCString:aCharPtr
range:((IndexRange){0,aLength})];
}
- initWithCString: (const char*)aCharPtr
{
return [self initWithCString:aCharPtr
range:((IndexRange){0, strlen(aCharPtr)})];
}
#if HAVE_VSPRINTF
- initWithFormat: (String*)aFormatString arguments: (va_list)arg
{
char buf[128]; /* xxx horrible, disgusting, fix this */
vsprintf(buf, [aFormatString cString], arg);
return [self initWithCString:buf];
}
- initWithCFormat: (const char*)formatCharPtr arguments: (va_list)arg
{
char buf[128]; /* xxx horrible, disgusting, fix this */
vsprintf(buf, formatCharPtr, arg);
return [self initWithCString:buf];
}
#endif /* HAVE_VSPRINTF */
- initWithFormat: (String*)aFormatString, ...
{
va_list ap;
va_start(ap, aFormatString);
[self initWithCFormat:[aFormatString cString] arguments:ap];
va_end(ap);
return self;
}
- initWithCFormat: (const char*)formatCharPtr, ...
{
va_list ap;
va_start(ap, formatCharPtr);
[self initWithCFormat:formatCharPtr arguments:ap];
va_end(ap);
return self;
}
- init
{
return [self initWithCString:""];
}
- initWithString: (String*)aString range: (IndexRange)aRange
{
return [self initWithCString:[aString cString] range:aRange];
}
- initWithString: (String*)aString length: (unsigned)aLength
{
return [self initWithCString:[aString cString]];
}
- initWithString: (String*)aString
{
return [self initWithCString:[aString cString]];
}
// GETTING NEW, AUTORELEASED STRING OBJECTS, NO NEED TO RELEASE THESE;
+ (String*) stringWithString: (String*)aString range: (IndexRange)aRange
{
return [[[CString alloc] initWithString:aString range:aRange]
autorelease];
}
+ (String*) stringWithString: (String*)aString
{
return [[[CString alloc] initWithString:aString]
autorelease];
}
+ (String*) stringWithFormat: (String*)aFormatString, ...
{
va_list ap;
id ret;
va_start(ap, aFormatString);
ret = [[self stringWithFormat:aFormatString arguments:ap]
autorelease];
va_end(ap);
return ret;
}
+ (String*) stringWithFormat: (String*)aFormatString arguments: (va_list)arg
{
return [[[CString alloc] initWithFormat:aFormatString arguments:arg]
autorelease];
}
+ (String*) stringWithCString: (const char*)cp range: (IndexRange)r
{
return [[[CString alloc] initWithCString:cp range:r]
autorelease];
}
+ (String*) stringWithCString: (const char*)aCharPtr
{
return [[[CString alloc] initWithCString:aCharPtr]
autorelease];
}
- (String*) stringByAppendingFormat: (String*)aString, ...
{
[self notImplemented:_cmd];
return nil;
}
- (String*) stringByAppendingFormat: (String*)aString arguments: (va_list)arg
{
[self notImplemented:_cmd];
return nil;
}
- (String*) stringByPrependingFormat: (String*)aString, ...
{
[self notImplemented:_cmd];
return nil;
}
- (String*) stringByPrependingFormat: (String*)aString arguments: (va_list)arg
{
[self notImplemented:_cmd];
return nil;
}
- (String*) stringByAppendingString: (String*)aString
{
[self notImplemented:_cmd];
return nil;
}
- (String*) stringByPrependingString: (String*)aString
{
[self notImplemented:_cmd];
return nil;
}
// COPYING;
/* This is the designated copier */
- (char *) cStringCopyRange: (IndexRange)aRange;
{
[self notImplemented:_cmd];
return "";
}
- (char *) cStringCopyLength: (unsigned)aLength
{
// xxx need to check aLength against _count;
return [self cStringCopyRange:((IndexRange){0,aLength})];
}
- (char *) cStringCopy
{
return [self cStringCopyRange:((IndexRange){0, [self count]})];
}
- copy
{
return [[[self class] alloc] initWithString:self];
}
- mutableCopy
{
return [[MutableCString alloc] initWithString:self];
}
// TESTING;
- (const char *) contentsDescription
{
return @encode(char);
}
- (int(*)(elt,elt)) comparisonFunction
{
return elt_compare_chars;
}
- (unsigned) hash
{
return elt_hash_string([self cString]);
}
- (int) compare: anObject
{
if ([anObject isKindOfClass:[String class]])
return strcmp([self cString], [anObject cString]);
return [super compare:anObject];
}
- (BOOL) isEqual: anObject
{
if (self == anObject)
return YES;
if (! [anObject isKindOf:[String class]]
|| [self count] != [anObject count]
|| [anObject hash] != [self hash] )
return NO;
return ! [self compare:anObject];
}
- (unsigned) count
{
/* Should be overridden for efficiency. */
return strlen([self cString]);
}
- (unsigned) length
{
return [self count];
}
- (IndexRange) stringRange
{
IndexRange r = {0, [self count]};
return r;
}
/* xxx These next three need error checking to handle the case in which
we're looking for never appears */
- (unsigned) indexOfChar: (char)aChar
{
const char *s = [self cString];
return (strchr(s, aChar) - s);
}
- (unsigned) indexOfLastChar: (char)aChar
{
const char *s = [self cString];
return (strrchr(s, aChar) - s);
}
- (unsigned) indexOfString: (String*)aString
{
const char *s = [self cString];
return (strstr(s, [aString cString]) - s);
}
- (char) charAtIndex: (unsigned)index
{
[self notImplemented:_cmd];
return ' ';
}
- (const char *) cString
{
[self notImplemented:_cmd];
return NULL;
}
- (unsigned) cStringLength
{
[self notImplemented:_cmd];
return 0;
}
- (void) getCString: (char*)buffer
{
strcpy(buffer, [self cString]);
}
- (void) getCString: (char*)buffer range: (IndexRange)aRange
{
memcpy(buffer, ([self cString] + aRange.location), aRange.length);
}
- (IndexRange) range
{
return (IndexRange){0, [self count]};
}
// GETTING VALUES;
- (int) intValue
{
return atoi([self cString]);
}
- (float) floatValue
{
return (float) atof([self cString]);
}
- (double) doubleValue
{
return atof([self cString]);
}
- (const char *) cStringValue
{
return [self cString];
}
- (String *) stringValue
{
return self;
}
// FOR FILE AND PATH NAMES;
- (IndexRange) fileRange
{
IndexRange r;
[self notImplemented:_cmd];
return r;
}
- (IndexRange) pathRange
{
IndexRange r;
[self notImplemented:_cmd];
return r;
}
- (IndexRange) extensionRange
{
IndexRange r;
[self notImplemented:_cmd];
return r;
}
- (IndexRange) fileWithOutExtentionRange
{
IndexRange r;
[self notImplemented:_cmd];
return r;
}
- (BOOL) isAbsolute
{
[self notImplemented:_cmd];
return NO;
}
- (BOOL) isRelative
{
[self notImplemented:_cmd];
return NO;
}
@end