// MOStringANSI.m
//
// by Mike Ferris
// Part of MOKit
// Copyright 1993, all rights reserved.

// ABOUT MOKit
// by Mike Ferris (mike@lorax.com)
//
// MOKit is a collection of useful and general objects.  Permission is 
// granted by the author to use MOKit in your own programs in any way 
// you see fit.  All other rights pertaining to the kit are reserved by the 
// author including the right to sell these objects as objects,  as part 
// of a LIBRARY, or as SOURCE CODE.  In plain English, I wish to retain 
// rights to these objects as objects, but allow the use of the objects 
// as pieces in a fully functional program.  Permission is also granted to 
// redistribute the source code of MOKit for FREE as long as this copyright 
// notice is left intact and unchanged.  NO WARRANTY is expressed or implied.  
// The author will under no circumstances be held responsible for ANY 
// consequences from the use of these objects.  Since you don't have to pay 
// for them, and full source is provided, I think this is perfectly fair.

#import "MOString.h"

extern char *MOBuildStringFromFormatV(const char *formatStr, 
			va_list param_list);

@implementation MOString(ANSI)

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ANSI covers -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//            (strtok is not provided... see -tokenize: above)
//                 (strcoll, and strxfrm are not provided)

- (size_t)strlen
// Returns the length of the string.  Returns 0 if the string is empty.
{
	return len;
}

- (const char *)strcpy:(const char *)s
// Simply the same as -setStringValue: but returns the string as well.
{
	[self setStringValue:s];
	return str;
}

- (const char *)strncpy:(const char *)s :(size_t)n
// Sets the string to be the first n characters of s.
{
	char *buf=NULL;
	
	if ((s) && (n>0))  {
		NX_MALLOC(buf, char, n+1);
		strncpy(buf, s, n);
		buf[n]='\0';
	}
	[self setStringValueNoCopy:buf shouldFree:YES];
	return str;
}

- (const char *)strcat:(const char *)s
// Adds the the given char string to the receiver's contents.
// Returns NULL if s is NULL or empty or the receiver is unique, self if 
// it succeeds.
// Unique strings CANNOT be modified.
{
	if (isUnique)  {
		return NULL;
	}
	if ((!s) || (strlen(s)==0))  {
		return NULL;
	}
	if ([self isNull])  {
		[self setStringValue:s];
	}  else  {
		char *newStr;
		
		NX_MALLOC(newStr, char, len+strlen(s)+1);
		strcpy(newStr, str);
		strcat(newStr, s);
		[self setStringValueNoCopy:newStr shouldFree:YES];
	}
	return str;
}

- (const char *)strncat:(const char *)s :(size_t)n
// Adds the first n characters of s to the string.
// Unique strings CANNOT be modified.
{
	char *buf=NULL;
	
	if (isUnique)  {
		return NULL;
	}
	if ((s) && (n>0))  {
		NX_MALLOC(buf, char, n+1);
		strncpy(buf, s, n);
		buf[n]='\0';
	}
	return [self strcat:buf];
}

- (int)strcmp:(const char *)s
// Compares the receiver's contents with s using strcmp.  
// Returns the normal strcmp values or -2 on error.
{
	if ((isUnique?!uStr:!str) || (!s))  {
		return -2;
	}
	return strcmp((isUnique?uStr:str), s);
}

- (int)strncmp:(const char *)s :(size_t)n
// Compares the receiver's contents with s using strcmp to n significant chars.  
// Returns the normal strcmp values or -2 on error.
{
	if ((isUnique?!uStr:!str) || (!s))  {
		return -2;
	}
	return strncmp((isUnique?uStr:str), s, n);
}

- (const char *)strchr:(char)aChar
// Returns a pointer to the first occurrence of aChar in the string.
// Returns NULL if the string is empty or aChar does not appear in it.
{
	if (isUnique?!uStr:!str)  {
		return NULL;
	}
	return strchr((isUnique?uStr:str), aChar);
}

- (const char *)strrchr:(char)aChar
// Returns a pointer to the first occurrence of aChar in the string.
// Returns NULL if the string is empty or aChar does not appear in it.
{
	if (isUnique?!uStr:!str)  {
		return NULL;
	}
	return strrchr((isUnique?uStr:str), aChar);
}

- (const char *)strstr:(const char *)searchStr
// Returns a pointer to the first occurrence of searchStr in the
// contents of the receiver or NULL if there isn't one.
{
	if ((isUnique?!uStr:!str) || (!searchStr))  {
		return NULL;
	}
	return strstr((isUnique?uStr:str), searchStr);
}

- (const char *)strpbrk:(const char *)breakChars
// Returns a pointer to the first occurrence of any char in breakChars or
// NULL if there isn't one.
{
	if ((isUnique?!uStr:!str) || (!breakChars))  {
		return NULL;
	}
	return strpbrk((isUnique?uStr:str), breakChars);
}

- (size_t)strspn:(const char *)acceptableChars
// Returns the length of the segment of the contents of the receiver 
// starting from the beginning which consists entirely of characters in 
// acceptableChars or -1 if one of the strings is NULL.
{
	if ((isUnique?!uStr:!str) || (!acceptableChars))  {
		return 0;
	}
	return strspn((isUnique?uStr:str), acceptableChars);
}

- (size_t)strcspn:(const char *)breakChars
// Returns the length of the segment of the contents of the receiver 
// starting from the beginning which consists entirely of characters not in 
// breakChars or 0 if one of the strings is NULL.
{
	if ((isUnique?!uStr:!str) || (!breakChars))  {
		return 0;
	}
	return strcspn((isUnique?uStr:str), breakChars);
}

- sprintf:(const char *)formatStr, ...
// Sets the strings contents as the result of printf'ing with the
// given format string and arguments.  Same as setFromFormat:, ...
{
	va_list param_list;
	char *buf;
	
	va_start(param_list, formatStr);
	buf = MOBuildStringFromFormatV(formatStr, param_list);
	va_end(param_list);
	
	[self setStringValueNoCopy:buf shouldFree:YES];
	
	return self;
}

@end

