Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -172,10 +172,11 @@ OFSet_hashtable.m \ OFString_UTF8.m \ OFValue_bytes.m \ OFValue_nonretainedObject.m \ OFValue_pointer.m \ + OFValue_range.m \ ${AUTORELEASE_M} \ ${FOUNDATION_COMPAT_M} \ ${INSTANCE_M} SRCS_FILES += OFSettings_INIFile.m \ OFURLHandler_file.m Index: src/OFValue.h ================================================================== --- src/OFValue.h +++ src/OFValue.h @@ -31,21 +31,28 @@ @property (readonly, nonatomic) const char *objCType; /*! * @brief The value as a pointer to void. * - * If the value is not pointer-sized, @ref OFInvalidFormatException is thrown. + * If the value is not pointer-sized, @ref OFOutOfRangeException is thrown. */ @property (readonly, nonatomic) void *pointerValue; /*! * @brief The value as a non-retained object. * - * If the value is not pointer-sized, @ref OFInvalidFormatException is thrown. + * If the value is not pointer-sized, @ref OFOutOfRangeException is thrown. */ @property (readonly, nonatomic) id nonretainedObjectValue; +/*! + * @brief The value as a range. + * + * If the value is not range-sized, @ref OFOutOfRangeException is thrown. + */ +@property (readonly, nonatomic) of_range_t rangeValue; + /*! * @brief Creates a new, autorelease OFValue with the specified bytes of the * specified type. * * @param bytes The bytes containing the value @@ -75,10 +82,18 @@ * @param object The object the OFValue should contain without retaining it * @return A new, autoreleased OFValue */ + (instancetype)valueWithNonretainedObject: (id)object; +/*! + * @brief Creates a new, autoreleased OFValue containing the specified range. + * + * @param range The range the OFValue should contain + * @return A new, autoreleased OFValue + */ ++ (instancetype)valueWithRange: (of_range_t)range; + /*! * @brief Initializes an already allocated OFValue with the specified bytes of * the specified type. * * @param bytes The bytes containing the value @@ -109,10 +124,19 @@ * @param object The object the OFValue should contain without retaining it * @return An initialized OFValue */ - (instancetype)initWithNonretainedObject: (id)object; +/*! + * @brief Initializes an already allocated OFValue containing the specified + * range. + * + * @param range The range the OFValue should contain + * @return An initialized OFValue + */ +- (instancetype)initWithRange: (of_range_t)range; + /*! * @brief Gets the value. * * If the specified size does not match, this raises an * @ref OFOutOfRangeException. Index: src/OFValue.m ================================================================== --- src/OFValue.m +++ src/OFValue.m @@ -19,12 +19,12 @@ #import "OFMethodSignature.h" #import "OFString.h" #import "OFValue_bytes.h" #import "OFValue_nonretainedObject.h" #import "OFValue_pointer.h" +#import "OFValue_range.h" -#import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" static struct { Class isa; } placeholder; @@ -48,10 +48,15 @@ - (instancetype)initWithNonretainedObject: (id)object { return (id)[[OFValue_nonretainedObject alloc] initWithNonretainedObject: object]; } + +- (instancetype)initWithRange: (of_range_t)range +{ + return (id)[[OFValue_range alloc] initWithRange: range]; +} @end @implementation OFValue + (void)initialize { @@ -81,10 +86,15 @@ + (instancetype)valueWithNonretainedObject: (id)object { return [[[self alloc] initWithNonretainedObject: object] autorelease]; } + ++ (instancetype)valueWithRange: (of_range_t)range +{ + return [[[self alloc] initWithRange: range] autorelease]; +} - (instancetype)initWithBytes: (const void *)bytes objCType: (const char *)objCType { OF_INVALID_INIT_METHOD @@ -95,10 +105,15 @@ OF_INVALID_INIT_METHOD } - (instancetype)initWithNonretainedObject: (id)object { + OF_INVALID_INIT_METHOD +} + +- (instancetype)initWithRange: (of_range_t)range +{ OF_INVALID_INIT_METHOD } - (bool)isEqual: (id)object { @@ -193,10 +208,20 @@ } - (id)nonretainedObjectValue { id ret; + + [self getValue: &ret + size: sizeof(ret)]; + + return ret; +} + +- (of_range_t)rangeValue +{ + of_range_t ret; [self getValue: &ret size: sizeof(ret)]; return ret; ADDED src/OFValue_range.h Index: src/OFValue_range.h ================================================================== --- src/OFValue_range.h +++ src/OFValue_range.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFValue.h" + +OF_ASSUME_NONNULL_BEGIN + +@interface OFValue_range: OFValue +{ + of_range_t _range; +} +@end + +OF_ASSUME_NONNULL_END ADDED src/OFValue_range.m Index: src/OFValue_range.m ================================================================== --- src/OFValue_range.m +++ src/OFValue_range.m @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFValue_range.h" +#import "OFMethodSignature.h" +#import "OFString.h" + +#import "OFOutOfRangeException.h" + +@implementation OFValue_range +@synthesize rangeValue = _range; + +- (instancetype)initWithRange: (of_range_t)range +{ + self = [super init]; + + _range = range; + + return self; +} + +- (void)getValue: (void *)value + size: (size_t)size +{ + if (size != sizeof(_range)) + @throw [OFOutOfRangeException exception]; + + memcpy(value, &_range, sizeof(_range)); +} + +- (OFString *)description +{ + return [OFString stringWithFormat: @"", + _range.location, _range.length]; +} +@end Index: tests/OFValueTests.m ================================================================== --- tests/OFValueTests.m +++ tests/OFValueTests.m @@ -77,8 +77,23 @@ EXPECT_EXCEPTION(@"-[nonretainedObjectValue] with wrong size throws", OFOutOfRangeException, [[OFValue valueWithBytes: "a" objCType: @encode(char)] nonretainedObjectValue]) + TEST(@"+[valueWithRange:]", + (value = [OFValue valueWithRange: range])) + + TEST(@"-[rangeValue]", + R(range = [value rangeValue]) && + memcmp(&range, &range2, sizeof(of_range_t)) == 0 && R(range = + [[OFValue valueWithBytes: &range + objCType: @encode(of_range_t)] rangeValue]) && + memcmp(&range, &range2, sizeof(of_range_t)) == 0) + + EXPECT_EXCEPTION(@"-[rangeValue] with wrong size throws", + OFOutOfRangeException, + [[OFValue valueWithBytes: "a" + objCType: @encode(char)] rangeValue]) + [pool drain]; } @end