/*
 * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer. 
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution. 
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#import <WebKit/WebNSDataExtras.h>

#import <JavaScriptCore/Assertions.h>

@implementation NSDictionary (WebNSDictionaryExtras)
-(NSNumber *)_webkit_numberForKey:(id)key
{
    id object = [self objectForKey:key];
    return [object isKindOfClass:[NSNumber class]] ? object : nil;
}

-(int)_webkit_intForKey:(NSString *)key
{
    NSNumber *number = [self _webkit_numberForKey:key];
    return number == nil ? 0 : [number intValue];
}

-(NSString *)_webkit_stringForKey:(id)key
{
    id object = [self objectForKey:key];
    return [object isKindOfClass:[NSString class]] ? object : nil;
}

-(id)_webkit_objectForMIMEType:(NSString *)MIMEType
{
    id result;
    NSRange slashRange;
    
    result = [self objectForKey:MIMEType];
    if (result) {
        return result;
    }
    
    slashRange = [MIMEType rangeOfString:@"/"];
    if (slashRange.location == NSNotFound) {
        return nil;
    }
    
    return [self objectForKey:[MIMEType substringToIndex:slashRange.location + 1]];
}

@end

@implementation NSMutableDictionary (WebNSDictionaryExtras)
-(void)_webkit_setObject:(id)object forUncopiedKey:(id)key
{
    CFDictionarySetValue((CFMutableDictionaryRef)self, key, object);
}

-(void)_webkit_setInt:(int)value forKey:(id)key
{
    NSNumber *object = [[NSNumber alloc] initWithInt:value];
    [self setObject:object forKey:key];
    [object release];
}

-(void)_webkit_setFloat:(float)value forKey:(id)key
{
    NSNumber *object = [[NSNumber alloc] initWithFloat:value];
    [self setObject:object forKey:key];
    [object release];
}

-(void)_webkit_setBool:(BOOL)value forKey:(id)key
{
    NSNumber *object = [[NSNumber alloc] initWithBool:value];
    [self setObject:object forKey:key];
    [object release];
}

@end

