/*
** StringStorage.m,v 1.5 1992/09/24 03:34:31 nwc Exp
**
** Copyright (c) 1991 Ronin Consulting, Inc.
*/


#import "StringStorage.h"
#import <string.h>

static char EOS = (char)0;

@implementation StringStorage

- init
{
   [self init: ""];
   return self;
}

- init: (const char *) str
{
   [super init];
   
   [self initCount: 0 elementSize: sizeof(char) description: "c"];
   [self setStringValue: str];
   return self;
}

- setStringValue: (const char *) str;
{
   int len;

   if(!str)
       str = "";			     /* avoid nil strings */

   len = strlen(str);			     /* get length - no reason to do it twice */
   [self setNumSlots: len + 1];		     /* use setNumSlots vs setAvailCapacity since it sets count */

					     /* bcopy is far faster than strcpy if the length is known */
   bcopy(str, (char *)dataPtr, len); 
   [self replaceElementAt: len with: (char *)&EOS];
   return self;
}

- (const char *) stringValue
{
   return dataPtr;
}

- appendStringValue: (const char *)str
{
   int oldCount = [self count];
   int len;

   if(!str || !*str)			     /* nothing to append */
       return self;
   
   len = strlen(str);			     
   [self setNumSlots: oldCount + len];
   bcopy(str, (char *)[self elementAt: oldCount - 1], len);
   [self replaceElementAt: oldCount + len - 1 with: (char *)&EOS ];
   return self;
}

- appendCharValue: (char) c
{
   char buf[2];
   
   buf[0] = c;
   buf[1] = (char)0;

   [self appendStringValue: buf];

   return self;
}

- empty					     /* override to ensure null termination */
{
   [super empty];
   [self setStringValue: ""];
   return self;
}

- (int) strlen				     /* just (count - 1)...but nicer */
{
   return [self count] - 1;
}

- (int) matchSubstring: (const char *)str
{
   int x, cnt;

   if(!str)
       return -1;

   for (x = 0, cnt = [self strlen]; x <  cnt; x++)
       if(((char *)dataPtr)[x] == *str && !strncmp(str,(char *)dataPtr + x, strlen(str)))
	   return x;

   return -1;
}

- (char *) getSubstring: (const char *)str
{
   int offset;

   offset = [self matchSubstring: str];
   if(offset != -1)
       return dataPtr + offset;
   else
       return (char*)0;
}

- replaceSubstring: (const char *)str with: (const char *)str2
{
   int offset, len1, len2;

   if(!(str && str2))
       return nil;

   offset = [self matchSubstring: str];
   if(offset == -1)
       return nil;

   len1 = strlen(str);
   len2 = strlen(str2);

   if(len2 > len1)
       [self setNumSlots: [self count] + len2 - len1];

   bcopy((char *)dataPtr + offset + len1, (char *)dataPtr + offset + len2, 
	 [self count] - offset - len1);

   bcopy((char *)str2, (char *)dataPtr + offset, len2);
   
   if(len2 < len1)
   {
      [self setNumSlots: [self count] + len2 - len1];
      ((char *)dataPtr)[[self strlen]] = (char)0;
   }
   
   return self;
}


@end
