/*
 *  Copyright (c) 2014-2015 Erik Doernenburg and contributors
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
 *  not use these files except in compliance with the License. You may obtain
 *  a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 *  License for the specific language governing permissions and limitations
 *  under the License.
 */

#import "NSValue+OCMAdditions.h"


@implementation NSValue(OCMAdditions)

static CFNumberType OCMNumberTypeForObjCType(const char *objcType)
{
    switch (objcType[0])
    {
        case 'c': return kCFNumberCharType;
        case 'C': return kCFNumberCharType;
        case 'B': return kCFNumberCharType;
        case 's': return kCFNumberShortType;
        case 'S': return kCFNumberShortType;
        case 'i': return kCFNumberIntType;
        case 'I': return kCFNumberIntType;
        case 'l': return kCFNumberLongType;
        case 'L': return kCFNumberLongType;
        case 'q': return kCFNumberLongLongType;
        case 'Q': return kCFNumberLongLongType;
        case 'f': return kCFNumberFloatType;
        case 'd': return kCFNumberDoubleType;
        default:  return 0;
    }
}


static NSNumber *OCMNumberForValue(NSValue *value)
{
#define CREATE_NUM(_type) ({ _type _v; [value getValue:&_v]; @(_v); })
    switch([value objCType][0])
    {
        case 'c': return CREATE_NUM(char);
        case 'C': return CREATE_NUM(unsigned char);
        case 'B': return CREATE_NUM(bool);
        case 's': return CREATE_NUM(short);
        case 'S': return CREATE_NUM(unsigned short);
        case 'i': return CREATE_NUM(int);
        case 'I': return CREATE_NUM(unsigned int);
        case 'l': return CREATE_NUM(long);
        case 'L': return CREATE_NUM(unsigned long);
        case 'q': return CREATE_NUM(long long);
        case 'Q': return CREATE_NUM(unsigned long long);
        case 'f': return CREATE_NUM(float);
        case 'd': return CREATE_NUM(double);
        default:  return nil;
    }
}


- (BOOL)getBytes:(void *)outputBuf objCType:(const char *)targetType
{
    /*
     * See if they are similar number types, and if we can convert losslessly between them.
     * For the most part, we set things up to use CFNumberGetValue, which returns false if
     * conversion will be lossy.
     */
    CFNumberType inputType = OCMNumberTypeForObjCType([self objCType]);
    CFNumberType outputType = OCMNumberTypeForObjCType(targetType);

    if(inputType == 0 || outputType == 0) // one or both are non-number types
        return NO;

    NSNumber *inputNumber = [self isKindOfClass:[NSNumber class]] ? (NSNumber *)self : OCMNumberForValue(self);

    /*
     * Due to some legacy, back-compatible requirements in CFNumber.c, CFNumberGetValue can return true for
     * some conversions which should not be allowed (by reading source, conversions from integer types to
     * 8-bit or 16-bit integer types).  So, check ourselves.
     */
    long long min;
    long long max;
    long long val = [inputNumber longLongValue];
    switch(targetType[0])
    {
        case 'B':
        case 'c': min =  CHAR_MIN; max =  CHAR_MAX; break;
        case 'C': min =         0; max = UCHAR_MAX; break;
        case 's': min =  SHRT_MIN; max =  SHRT_MAX; break;
        case 'S': min =         0; max = USHRT_MAX; break;
        default:  min = LLONG_MIN; max = LLONG_MAX; break;
    }
    if(val < min || val > max)
        return NO;

    /* Get the number, and return NO if the value was out of range or conversion was lossy */
    return CFNumberGetValue((CFNumberRef)inputNumber, outputType, outputBuf);
}


@end
