/*****
 NAME
 	cfile.m - source code for CFile class
 VERSION
 	$Id$
 CHANGELOG
 	$Log$
 */

#include <coconut/cfile.h>
#include <coconut/cconststr.h>
#include <coconut/csystem.h>
#include <coconut/cerror.h>
#include <coconut/dconststr.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>
#include <unistd.h>
#include <errno.h>

@implementation CFile

+ (boolean) isLegalName: (const char *) name
{
	int	ch ;
	if(!name)
		return FALSE ;
	if(name[0] == '\0')
		return FALSE ;
	for( ; (ch = *name) != '\0' ; name++){
		if(ch == '/' || isspace(ch))
			return FALSE ;
	}
	return TRUE ;
}

+ (boolean) isFileExist: (const char *) name
{
	struct stat	fst ;
	if(stat(name, &fst) == 0){
		return TRUE ;
	}
	return FALSE ;
}

+ (boolean) isAbsolutePath: (const char *) path
{
	return g_path_is_absolute(path) ;
}

+ (id <PConstStr>) getBaseName: (const char *) name
{
	id <PConstStr>	str ;
	gchar *		result ;

	if((result = g_path_get_basename(name)) != NULL){
		str = [CConstStr newConstStr: result copy: FALSE free: TRUE] ;
		return str ;
	} else
		return nil ;
}

+ (id <PConstStr>) getDirName: (const char *) name
{
	id <PConstStr>	str ;
	gchar *		result ;

	if((result = g_path_get_dirname(name)) != NULL){
		str = [CConstStr newConstStr: result copy: FALSE free: TRUE] ;
		return str ;
	} else
		return nil ;
}

+ (id <PFile>) newFile: (open_t) mode name: (const char *) fname
{
	id <PFile>	newfile ;
	newfile = [[CFile alloc] init] ;
	[CSystem checkPtr: newfile] ;
	return [newfile open: mode name: fname] == no_error ?  newfile : nil ;
}

- init
{
	access_mode = not_open ;
	file_name = [[CConstStr alloc] init] ;
	return [super init] ;
}

- (void) dealloc
{
	id <PError>	err ;
	err = [self close] ;
	g_assert(err == nil) ;
	[file_name release] ;
	[super dealloc] ;
}

- (id <PError>) open: (open_t) mode name: (const char *) filename
{
	static const char	readMode[] = "r" ;
	static const char	writeMode[] = "w" ;
	static const char	appendMode[] = "a" ;
	GIOChannel *		channel ;
	int			fd ;
	const char *		modestr ;
	char *			newname ;

	if(filename == NULL){
		fd = IS_WRITABLE_OPEN(mode) ? STDOUT_FILENO : STDIN_FILENO ;
		channel  = g_io_channel_unix_new(fd) ;
		g_io_channel_set_close_on_unref(channel, FALSE) ;
		[file_name setPtr: ""] ;
	} else if(mode == temp_open){
		fd = g_file_open_tmp(TEMP_FILE_NAME_STR, &newname, NULL) ;
		channel  = g_io_channel_unix_new(fd) ;
		[file_name setPtr: newname copy: FALSE free: TRUE] ;
	} else {
		switch(mode){
		  case read_open: modestr = readMode ; break ;
		  case write_open: modestr = writeMode ; break ;
		  case append_open: modestr = appendMode ; break ;
		  default:
		  	return [CError illegal_parameter] ;
		  break ;
		}
		channel = g_io_channel_new_file(filename, modestr, NULL) ;
		[file_name setPtr: filename] ;
	}
	return [super openChannel: channel] ;
}

- (id <PError>) close
{
	[file_name setPtr: NULL] ;
	return [super closeChannel] ;
}

- (id <PConstStr>) fileName
{
	return file_name ;
}

- (id <PConstStr>) fileNameStr
{
	return file_name ;
}

@end

