/*
        Copyright (c) 1996, NeXT Software, Inc.
        All rights reserved.

        You may freely copy, distribute and reuse the code in this example.
        NeXT disclaims any warranty of any kind, expressed or implied,
        as to its fitness for any particular use.
*/
#import "FlatFileColumn.h"
#import <EOAccess/EOAccess.h>

#define DataBegin '<'
#define DataEnd   '>'

@implementation FlatFileColumn

+ (Class)columnClassForAttribute:(EOAttribute *)attr
{
    switch ([attr adaptorValueType]) {
        case EOAdaptorNumberType : return [FlatFileNumberColumn class];
        case EOAdaptorCharactersType : return [FlatFileStringColumn class];
        case EOAdaptorBytesType : return [FlatFileDataColumn class];
        case EOAdaptorDateType : return [FlatFileDateColumn class];
    }

    return nil;
}

+ columnForAttribute:(EOAttribute *)attr
{
    return [[[[self columnClassForAttribute:attr] alloc] initWithAttribute:attr] autorelease];
}

- initWithAttribute:(EOAttribute *)attr
{
    [super init];
    attribute = [attr retain];

    return self;
}

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

- (void)bindAtIndex:(int)index
{
    bindingIndex = index;
}

- (int)bindingIndex
{
    return bindingIndex;
}

- (id)newValueForBytes:(void *)bytes length:(int)length
{
    return nil;
}

@end

@implementation FlatFileNumberColumn

- initWithAttribute:(EOAttribute *)attr
{
    [super initWithAttribute:attr];
    useIntValue = [[attribute valueType] isEqualToString:@"i"];

    return self;
}

- (id)newValueForBytes:(void *)bytes length:(int)length
{
    NSString *helper = [[NSString alloc] initWithCString:(char *)bytes length:length];
    NSDecimalNumber *value = [NSDecimalNumber decimalNumberWithString:helper];

    [helper release];
    return value;
}

@end

@implementation FlatFileStringColumn

- initWithAttribute:(EOAttribute *)attr
{
    [super initWithAttribute:attr];
    encoding = [NSString defaultCStringEncoding];

    return self;
}

- (id)newValueForBytes:(void *)bytes length:(int)length
{
    return [attribute newValueForBytes:bytes length:length encoding:encoding];
}

@end

@implementation FlatFileDataColumn

- (id)newValueForBytes:(void *)bytes length:(int)length
{
    char *valueBytes = (char *)malloc(length * sizeof(char)), *currentValueByte = valueBytes, byte = 0, nibble;
    int i = 0, valueLength = 0;
    id value;
    BOOL haveFirstNibble = NO;
    
    if (*(char *)bytes == DataBegin)
        bytes++;

    while ((i++ < length) && ((nibble = *(char *)bytes++) != DataEnd)) {
        if ((nibble >= '0') && (nibble <= '9'))
            nibble -= '0';
        else if ((nibble >= 'a') && (nibble <= 'z'))
            nibble -= ('a' - 10);
        else
            continue;

        if (haveFirstNibble) {
            byte += nibble;
            *currentValueByte++ = byte;
            valueLength++;
        } else
            byte = nibble << 4;

        haveFirstNibble = !haveFirstNibble;
    }

    value = [attribute newValueForBytes:valueBytes length:valueLength];
    free(valueBytes);
    return value;
}

@end

@implementation FlatFileDateColumn

- (id)newValueForBytes:(void *)bytes length:(int)length
{
    NSString *helper = [NSString stringWithCString:bytes length:length];
    return [NSCalendarDate dateWithString:helper calendarFormat:FlatFileCalendarFormat];
}

@end
