/*****
 NAME
	cconststr.m - source code for CConstStr class
 VERSION
	$Id$
 CHANGELOG
	$Log$
 */

#include <coconut/cconststr.h>
#include <coconut/cstring.h>
#include <coconut/cmemalloc.h>
#include <coconut/csystem.h>
#include <coconut/cerror.h>
#include <coconut/ptext.h>
#include <coconut/dconststr.h>
#include <stdlib.h>
#include <ctype.h>

@implementation CConstStr

+ newConstStr
{
	return [[CConstStr alloc] init] ;
}

+ newConstStr: (const utf8_char *) ptr
{
	return [[CConstStr alloc] initConstStr: ptr] ;
}

+ newConstStr: (const utf8_char *) ptr copy: (boolean) docopy 
    free:(boolean) dofree ;
{
	return [[CConstStr alloc] initConstStr: ptr copy: docopy free: dofree] ;
}

- init
{
	this_str = EMPTY_STR ; do_free = FALSE ;
	return [super init] ;
}

- initConstStr: (const utf8_char *) str 
{
	id 	result ;
	result = [super init] ;
	if(result){
		this_str = EMPTY_STR ; do_free = FALSE ;
		[self setPtr: str copy: TRUE free: TRUE] ;
	}
	return result ;
}

- initConstStr: (const utf8_char *) str copy: (boolean) docopy 
    free: (boolean) dofree
{
	id 	result ;
	result = [super init] ;
	if(result){
		this_str = EMPTY_STR ; do_free = FALSE ;
		[self setPtr: str copy: docopy free: dofree] ;
	}
	return result ;
}

- (void) dealloc
{
	if(do_free)
		[CMemAlloc free: (void *) this_str] ;
	[super dealloc] ;
}

- (const utf8_char *) setStr: (id <PBasicStr>) str 
{
	return [self setPtr: [str ptr] copy: TRUE free: TRUE] ;
}

- (const utf8_char *) setPtr: (const utf8_char *) str
{
	return [self setPtr: str copy: TRUE free: TRUE] ;
}

- (const utf8_char *) setPtr: (const utf8_char *) str length: (u_int) len
{
	if(do_free)
		[CMemAlloc free: (void *) this_str] ;
	if(str){
		this_str = [CString duplicate: str length: len] ; 
		do_free = TRUE ;
	} else {
		this_str = EMPTY_STR ; do_free = FALSE ;
	}
	return this_str ;
}

- (const utf8_char *) setPtr: (const utf8_char *) str copy: (boolean) docopy
    free: (boolean) dofree
{
	if(do_free)
		[CMemAlloc free: (void *) this_str] ;
	if(str) {
		if(docopy){
			this_str = [CString duplicate: str] ;
			do_free = TRUE ;
		} else {
			this_str = str ; do_free = dofree ;
		}
	} else {
		this_str = EMPTY_STR ; do_free = FALSE ;
	}
	return this_str ;
}

- (const utf8_char *) ptr
{
	return this_str ;
}

- (boolean) isEmpty
{
	const utf8_char * 	str ;
	utf8_char 		c ;
	for(str = this_str ; (c = *str) != '\0' ; str++)
		if(!isspace(c))
			return FALSE ;
	return TRUE ;
}

- (u_int) length
{
	return strlen(this_str) ;
}

- (size_t) size
{
	return strlen(this_str) + 1 ;
}

- (int) compare: (id <PBasicStr>) str
{
	return [self comparePtr: [str ptr] length: [str length]] ;
}

- (int) comparePtr: (const utf8_char *) str length: (u_int) len
{
	return strncmp(this_str, str, len) ;
}

- (int) comparePtr: (const utf8_char *) str 
{
	return strcmp(this_str, str) ;
}

- (int) comparePtrWoCase: (const utf8_char *) str length: (u_int) len
{
	return strncasecmp(this_str, str, len) ;
}

- (int) comparePtrWoCase: (const utf8_char *) str 
{
	return strcasecmp(this_str, str) ;
}

- (u_int) hashkey
{
	return g_str_hash(this_str) ;
}

#define	STREAM	((id <PIndentStream>) stream)
- print: (id) stream
{
	io_status_t	stat ;
	stat = [STREAM putPtr: this_str] ;
	return stat == io_status_normal ? nil : [CError can_not_happen] ;
}

- (id <PConstStr>) duplicate
{
	id <PConstStr>	newstr ;
	newstr =  [[CConstStr alloc] initConstStr: this_str] ;
	[CSystem checkPtr: newstr] ;
	return newstr ;
}

@end

