/* 
   Copyright (C) 1996 
	Ovidiu Predescu <ovidiu@bx.logicnet.ro>
	Mircea Oancea <mircea@jupiter.elcom.pub.ro>

   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>

   This file is part of the FoundationExtensions 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; see the file COPYING.LIB.
   If not, write to the Free Software Foundation,
   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include <stdarg.h>
#include <stdio.h>
#include <Foundation/NSString.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSValue.h>

#include <extensions/NSException.h>
#include <extensions/exceptions/GeneralExceptions.h>
#include <extensions/MissingMethods.h>

#if GNUSTEP_BASE_LIBRARY || LIBOBJECTS_LIBRARY
# define name_ivar e_name
# define reason_ivar e_reason
# define userInfo_ivar e_info
#else
# define name_ivar name
# define reason_ivar reason
# define userInfo_ivar userInfo
#endif

#if LIB_FOUNDATION_LIBRARY
@implementation MemoryExhaustedException

MemoryExhaustedException* memoryExhaustedException = nil;

- __init
{
    name = [NSMallocException retain];
    reason = @"Memory exhausted";
    return self;
}

+ (void)initialize
{
    memoryExhaustedException = [NSAllocateObject(self, 0, NULL) init];
}

+ (id)alloc
{
    return memoryExhaustedException;
}

+ (id)allocWithZone:(NSZone*)zone
{
    return memoryExhaustedException;
}

- (void)release
{
    pointer = NULL;
    size = 0;
}

- (id)init
{
    return self;
}

- setPointer:(void**)_pointer memorySize:(unsigned)_size
{
    pointer = _pointer;
    size = _size;
    return self;
}

@end /* MemoryExhaustedException */


@implementation MemoryDeallocationException

- setPointer:(void**)_pointer memorySize:(unsigned)_size
{
    pointer = _pointer;
    size = _size;
    name = NSMallocException;
    reason = @"Deallocation error";
    return self;
}

@end  /* MemoryDeallocationException */


@implementation MemoryCopyException
@end

#endif /* LIB_FOUNDATION_LIBRARY */


@implementation FileNotFoundException
- initWithFilename:(NSString*)f
{
    id aux =  @"filename";
    self = [self initWithName:@"FileNotFoundException"
	reason:[NSString stringWithFormat:@"File not found: %s", [f cString]]
	userInfo:[NSDictionary dictionaryWithObjectsAndKeys:f, aux, nil]];
    return self;
}

- (NSString*)filename
{
    return [[self userInfo] objectForKey:@"filename"];
}
@end /* FileNotFoundException */


@implementation AssertException
- init
{
    self = [self initWithName:NSInternalInconsistencyException
		    reason:nil userInfo:nil];
    return self;
}
@end /* AssertException */


@implementation SyntaxErrorException
- init
{
    self = [self initWithName:@"Syntax error" reason:nil userInfo:nil];
    return self;
}
- initWithReason:(NSString*)aReason
{
    self = [self initWithName:@"Syntax error" reason:aReason userInfo:nil];
    return self;
}
@end /* SyntaxErrorException */


@implementation UnknownTypeException
- initForType:(const char*)type
{
    self = [self initWithName:NSInvalidArgumentException
		    reason:@"Unknown Objective-C type encoding"
		    userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
			    [NSString stringWithCString:type], @"type",
			    nil]];
    return self;
}
@end /* UnknownTypeException */


@implementation UnknownClassException
- setClassName:(NSString*)className
{
    self = [self initWithName:NSInvalidArgumentException
		    reason:@"Unknown Objective-C class"
		    userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
			    className, @"name",
			    nil]];
    return self;
}
@end /* UnknownClassException */


@implementation ObjcRuntimeException
@end /* ObjcRuntimeException */


@implementation InternalInconsistencyException
- init
{
    self = [self initWithName:@"Internal inconsistency exception" reason:nil userInfo:nil];
    return self;
}
@end /* InternalInconsistencyException */


@implementation InvalidArgumentException
- init
{
    self = [self initWithName:NSInvalidArgumentException reason:nil userInfo:nil];
    return self;
}
- initWithReason:(NSString*)aReason
{
    self = [self initWithName:NSInvalidArgumentException 
	    reason:aReason userInfo:nil];
    return self;
}
@end /* InvalidArgumentException */


@implementation IndexOutOfRangeException
- init
{
    self = [self initWithName:@"Index out of range"
		    reason:nil userInfo:nil];
    return self;
}

- initForSize:(int)size index:(int)index
{
    id keys[] = { @"size", @"index" };
    id values[] = { [NSNumber numberWithInt:size],
		    [NSNumber numberWithInt:index] };
    self = [self initWithName:@"Index out of range"
	    reason:nil
	    userInfo:[NSDictionary dictionaryWithObjects:values
				    forKeys:keys
				    count:2]];
    return self;
}

@end /* IndexOutOfRangeException */


@implementation RangeException
- init
{
    self = [self initWithName:NSRangeException reason:nil userInfo:nil];
    return self;
}

- initWithReason:(NSString*)aReason size:(int)size index:(int)index
{
    id keys[] = { @"size", @"index" };
    id values[] = { [NSNumber numberWithInt:size],
		    [NSNumber numberWithInt:index] };
    self = [self initWithName:@"Index out of range"
	    reason:aReason
	    userInfo:[NSDictionary dictionaryWithObjects:values
				    forKeys:keys
				    count:2]];
    return self;
}
@end /* RangeException */


