//---------------------------------------------------------------------------------------
//	StructuredHeaderFieldBody.m created by erik on Sun 23-Mar-1997
//	This code is part of the Alexandra Newsreader Project. For copyright details see
//	GNU public license version 2 or above. No warranties implied. Use at own risk.
//	More information can be found at <http://www.object-factory.com/Alexandra>.
//	@(#)$Id: StructuredHeaderFieldBody.m,v 1.1 1998/05/05 15:29:57 erik Exp $
//---------------------------------------------------------------------------------------

#import "Utilities.h"
#import "Message.h"


//---------------------------------------------------------------------------------------
    @implementation StructuredHeaderFieldBody
//---------------------------------------------------------------------------------------


//---------------------------------------------------------------------------------------
//	STRING TO OBJECT
//---------------------------------------------------------------------------------------

- initWithString:(NSString *)string;
{
    NSArray			*fieldBodyParts;
    NSEnumerator	*fieldBodyPartEnum;
    NSString		*mainPart, *parameterPart, *attribute, *attrValue;
    NSScanner		*scanner;

	TRACE_IN
    NSAssert1([self class] != [StructuredHeaderFieldBody class], @"%@ is an abstract superclass and cannot be instantiated", [self class]);
    [super init];

    fieldBodyParts = [string componentsSeparatedByString:@";"];
    fieldBodyPartEnum = [fieldBodyParts objectEnumerator];

    if((mainPart = [fieldBodyPartEnum nextObject]) == nil)
        [NSException raise:MIMEFormatException format:@"no value in '%@'", self];
	[self takeValueFromString:mainPart];

     // forgiving, ie. simply skips syntactially incorrect attribute/value pairs...
    parameters = [[NSMutableDictionary allocWithZone:[self zone]] init];
    while((parameterPart = [fieldBodyPartEnum nextObject]) != nil)
        {
        scanner = [NSScanner scannerWithString:parameterPart];
        if([scanner scanCharactersFromSet:[NSCharacterSet MIMETokenCharacterSet] intoString:&attribute] == NO)
            continue;
        attribute = [attribute lowercaseString];
        if([scanner scanString:@"=" intoString:NULL] == NO)
            continue;
        if([scanner scanString:DOUBLEQUOTE intoString:NULL] == NO)
            {
            if([scanner scanCharactersFromSet:[NSCharacterSet MIMETokenCharacterSet] intoString:&attrValue] == YES)
                [parameters setObject:attrValue forKey:attribute];
            }
        else
            {
            if([scanner scanUpToString:DOUBLEQUOTE intoString:&attrValue] == YES)
                [parameters setObject:attrValue forKey:attribute];
            }
        }
    return self;
}


//---------------------------------------------------------------------------------------
//	OBJECT TO STRING
//---------------------------------------------------------------------------------------

- (NSString *)stringRepresentation;
{
	TRACE_IN
    if(stringRep == nil)
        {
        NSMutableString	*fieldBody;
        NSString		*attribute, *value;
        NSEnumerator	*attributeEnumerator;

		fieldBody = [[[NSMutableString alloc] init] autorelease];
		[self appendValueToString:fieldBody];

        attributeEnumerator = [parameters keyEnumerator];
        while((attribute = [attributeEnumerator nextObject]) != nil)
            {
            value = [parameters objectForKey:attribute];
            if([value rangeOfCharacterFromSet:[NSCharacterSet MIMENonTokenCharacterSet]].length != 0)
                value = [NSString stringWithFormat:@"\"%@\"", value];
			[fieldBody appendString:@"; "];
			[fieldBody appendString:attribute];
			[fieldBody appendString:@"="];
			[fieldBody appendString:value];
//            [fieldBody appendFormat:@"; %@=%@", attribute, value];
            }
        stringRep = [fieldBody copyWithZone:[self zone]];
        }
    return stringRep;
}


//-------------------------------------------------------------------------------------------
//	TRANSFER REPRESENTATIONS
//-------------------------------------------------------------------------------------------

- initFromTransferRepresentation:(NSData *)data;
{
    NSString *string;

    string = [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] autorelease];
    [self initWithString:string];

    return self;
}


- (NSData *)transferRepresentation;
{
    return [[self stringRepresentation] dataUsingEncoding:NSASCIIStringEncoding];
}


//---------------------------------------------------------------------------------------
//	VALUE
//	Concrete Subclasses must implement this
//---------------------------------------------------------------------------------------

- (void)takeValueFromString:(NSString *)string;
{
    [NSException raise:NSInternalInconsistencyException format:@"Subclass %@ of StructuredHeaderFieldValue must provide concrete implementation of %@.", NSStringFromClass(isa), NSStringFromSelector(_cmd)];
}


- (void)appendValueToString:(NSMutableString *)string;
{
    [NSException raise:NSInternalInconsistencyException format:@"Subclass %@ of StructuredHeaderFieldValue must provide concrete implementation of %@.", NSStringFromClass(isa), NSStringFromSelector(_cmd)];
}


//---------------------------------------------------------------------------------------
//	PARAMETERS
//---------------------------------------------------------------------------------------

- (void)setParameter:(NSString *)value forKey:(NSString *)key;
{
	TRACE_IN
    if([key rangeOfCharacterFromSet:[NSCharacterSet MIMENonTokenCharacterSet]].length != 0)
        [NSException raise:NSInvalidArgumentException format:@"invalid char in parameter '%@'", key];
    if([value rangeOfCharacterFromSet:[NSCharacterSet MIMENonTokenCharacterSet]].length != 0)
        {
        if([value rangeOfCharacterFromSet:[[NSCharacterSet standardASCIICharacterSet] invertedSet]].length != 0)
             [NSException raise:NSInvalidArgumentException format:@"invalid char in attribute value '%@'", value];
         else if([value rangeOfString:DOUBLEQUOTE].length != 0)
             [NSException raise:NSInvalidArgumentException format:@"invalid doublequote in attribute value '%@'", value];
         }
    [parameters setObject:value forKey:key];
	[self invalidateStringRep];
}

- (NSString *)parameterForKey:(NSString *)key;
{
	TRACE_IN
    return [parameters objectForKey:key];
}


- (NSDictionary *)parameters;
{
	TRACE_IN
    return parameters;
}


//---------------------------------------------------------------------------------------
//	NSObject Stuff
//---------------------------------------------------------------------------------------

- (void)dealloc
{
	TRACE_IN
	[parameters release];
	[super dealloc];
}


//---------------------------------------------------------------------------------------
    @end
//---------------------------------------------------------------------------------------
