ftp.nice.ch/Attic/openStep/implementation/gnustep/sources/libobjects-0.1.19.tgz#/libobjects-0.1.19/src/String.m

This is String.m in view mode; [Download] [Up]

/* Implementation for Objective-C String object
   Copyright (C) 1993,1994,1995, 1996 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 */
      /* xxx eventually: class_add_behavior_category(NSStringStuff),
         but we'll have to be careful about these methods overriding
	 the ones inherited in NSCString from NSString!  */
    }
}

// INITIALIZING;

/* For now, this is the designated initializer for this class */
- initWithCString: (const char*)aCharPtr range: (IndexRange)aRange
{
  [self subclassResponsibility:_cmd];
  return self;
}

/* This override in mutable string classes */
- empty
{
  [self subclassResponsibility:_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"];
  [super initWithType:contentEncoding];
  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: (id <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: (id <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: (id <String>)aString range: (IndexRange)aRange
{
  return [self initWithCString:[aString cString] range:aRange];
}

- initWithString: (id <String>)aString length: (unsigned)aLength
{
  return [self initWithCString:[aString cString]];
}

- initWithString: (id <String>)aString
{
  return [self initWithCString:[aString cString]];
}


// GETTING NEW, AUTORELEASED STRING OBJECTS, NO NEED TO RELEASE THESE;

+ stringWithString: (id <String>)aString range: (IndexRange)aRange
{
  return [[[CString alloc] initWithString:aString range:aRange]
	  autorelease];
}

+ stringWithString: (id <String>)aString
{
  return [[[CString alloc] initWithString:aString]
	  autorelease];
}

+ stringWithFormat: (id <String>)aFormatString, ...
{
  va_list ap;
  id ret;
  
  va_start(ap, aFormatString);
  ret = [[self stringWithFormat:aFormatString arguments:ap]
	 autorelease];
  va_end(ap);
  return ret;
}

+ stringWithFormat: (id <String>)aFormatString arguments: (va_list)arg
{
  return [[[CString alloc] initWithFormat:aFormatString arguments:arg]
	  autorelease];
}

+ stringWithCString: (const char*)cp range: (IndexRange)r
{
  return [[[CString alloc] initWithCString:cp range:r]
	  autorelease];
}

+ stringWithCString: (const char*)aCharPtr
{
  return [[[CString alloc] initWithCString:aCharPtr]
	  autorelease];
}


- stringByAppendingFormat: (id <String>)aString, ...
{
  [self notImplemented:_cmd];
  return nil;
}

- stringByAppendingFormat: (id <String>)aString arguments: (va_list)arg
{
  [self notImplemented:_cmd];
  return nil;
}

- stringByPrependingFormat: (id <String>)aString, ...
{
  [self notImplemented:_cmd];
  return nil;
}

- stringByPrependingFormat: (id <String>)aString arguments: (va_list)arg
{
  [self notImplemented:_cmd];
  return nil;
}

- stringByAppendingString: (id <String>)aString
{
  [self notImplemented:_cmd];
  return nil;
}

- stringByPrependingString: (id <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]})];
}

- copyWithZone: (NSZone*)z
{
  return [[[self class] allocWithZone:z] initWithString:(NSString*)self];
}

- mutableCopyWithZone: (NSZone*)z
{
  return [[MutableCString allocWithZone:z] initWithString:(NSString*)self];
}

// TESTING;

- (const char *) contentsDescription
{
  return @encode(char);
}

- (const char *) contentType
{
  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: (id <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

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.