Index: ObjFW.xcodeproj/project.pbxproj ================================================================== --- ObjFW.xcodeproj/project.pbxproj +++ ObjFW.xcodeproj/project.pbxproj @@ -913,10 +913,16 @@ 4BA85BCD140ECCE800E91D51 /* OFMutableSet_hashtable.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BA85BC7140ECCE800E91D51 /* OFMutableSet_hashtable.m */; }; 4BA85BCE140ECCE800E91D51 /* OFSet_hashtable.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BA85BC8140ECCE800E91D51 /* OFSet_hashtable.h */; }; 4BA85BCF140ECCE800E91D51 /* OFSet_hashtable.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BA85BC9140ECCE800E91D51 /* OFSet_hashtable.m */; }; 4BA9CFA415E129D30076DC74 /* autorelease.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BA9CFA315E129D30076DC74 /* autorelease.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BAA60C814D09699006F068D /* OFJSONTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BAA60C714D09699006F068D /* OFJSONTests.m */; }; + 4BAD891F1F65E6B300CF44B7 /* OFInvocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAD891E1F65E68800CF44B7 /* OFInvocation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BAD89201F65E6B300CF44B7 /* OFInvocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAD891E1F65E68800CF44B7 /* OFInvocation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BAD89211F65E6B600CF44B7 /* OFInvocation.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BAD891D1F65E68800CF44B7 /* OFInvocation.m */; }; + 4BAD89221F65E6B700CF44B7 /* OFInvocation.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BAD891D1F65E68800CF44B7 /* OFInvocation.m */; }; + 4BAD89241F65E80A00CF44B7 /* OFInvocationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BAD89231F65E80A00CF44B7 /* OFInvocationTests.m */; }; + 4BAD89251F65E80A00CF44B7 /* OFInvocationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BAD89231F65E80A00CF44B7 /* OFInvocationTests.m */; }; 4BAE7354139C508E00F682ED /* serialization.xml in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4BAE7353139C507F00F682ED /* serialization.xml */; }; 4BAFC168182EAA7800BE5E57 /* OFOptionsParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAFC166182EAA7800BE5E57 /* OFOptionsParser.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BAFC169182EAA7800BE5E57 /* OFOptionsParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BAFC167182EAA7800BE5E57 /* OFOptionsParser.m */; }; 4BB25E88139C388A00F574EA /* OFObject+Serialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BB25E82139C388A00F574EA /* OFObject+Serialization.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BB25E89139C388A00F574EA /* OFObject+Serialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BB25E83139C388A00F574EA /* OFObject+Serialization.m */; }; @@ -1612,10 +1618,13 @@ 4BA85BC8140ECCE800E91D51 /* OFSet_hashtable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSet_hashtable.h; path = src/OFSet_hashtable.h; sourceTree = ""; }; 4BA85BC9140ECCE800E91D51 /* OFSet_hashtable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSet_hashtable.m; path = src/OFSet_hashtable.m; sourceTree = ""; }; 4BA9CFA315E129D30076DC74 /* autorelease.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = autorelease.h; path = src/autorelease.h; sourceTree = ""; }; 4BAA60C714D09699006F068D /* OFJSONTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFJSONTests.m; path = tests/OFJSONTests.m; sourceTree = ""; }; 4BABC29A197A8212006A93BD /* threading_pthread.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = threading_pthread.m; path = src/threading_pthread.m; sourceTree = ""; }; + 4BAD891D1F65E68800CF44B7 /* OFInvocation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OFInvocation.m; path = src/OFInvocation.m; sourceTree = ""; }; + 4BAD891E1F65E68800CF44B7 /* OFInvocation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OFInvocation.h; path = src/OFInvocation.h; sourceTree = ""; }; + 4BAD89231F65E80A00CF44B7 /* OFInvocationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFInvocationTests.m; path = tests/OFInvocationTests.m; sourceTree = ""; }; 4BAE7353139C507F00F682ED /* serialization.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = serialization.xml; path = tests/serialization.xml; sourceTree = ""; }; 4BAF5F46123460C900F4E111 /* OFCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFCollection.h; path = src/OFCollection.h; sourceTree = ""; }; 4BAF5F49123460C900F4E111 /* OFStreamSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFStreamSocket.h; path = src/OFStreamSocket.h; sourceTree = ""; }; 4BAF5F4A123460C900F4E111 /* OFStreamSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFStreamSocket.m; path = src/OFStreamSocket.m; sourceTree = ""; }; 4BAFC166182EAA7800BE5E57 /* OFOptionsParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFOptionsParser.h; path = src/OFOptionsParser.h; sourceTree = ""; }; @@ -2116,10 +2125,12 @@ 4B06855218B2AD3800FC731A /* OFINICategory+Private.h */, 4B5B02BC18B288A400CE6AE4 /* OFINIFile.h */, 4B5B02BD18B288A400CE6AE4 /* OFINIFile.m */, 4BA49D8E13DB113B00381CDB /* OFIntrospection.h */, 4BA49D8F13DB113B00381CDB /* OFIntrospection.m */, + 4BAD891E1F65E68800CF44B7 /* OFInvocation.h */, + 4BAD891D1F65E68800CF44B7 /* OFInvocation.m */, 4BA02B9F15041F5900002F84 /* OFJSONRepresentation.h */, 4B0EA9181898690E00F573A4 /* OFKernelEventObserver.h */, 4B0EA9191898690E00F573A4 /* OFKernelEventObserver.m */, 4B0EA91A1898690E00F573A4 /* OFKernelEventObserver+Private.h */, 4B0EA9121898690E00F573A4 /* OFKernelEventObserver_kqueue.h */, @@ -2363,10 +2374,11 @@ 4BF0DD731D44645D001D9949 /* OFHMACTests.m */, 4BB4B54916776094002A2DCE /* OFHTTPClientTests.m */, 4B2610C51D86305C001F16C9 /* OFHTTPCookieTests.m */, 4B11D09B1EC901440094423D /* OFHTTPCookieManagerTests.m */, 4B5B02C018B2897500CE6AE4 /* OFINIFileTests.m */, + 4BAD89231F65E80A00CF44B7 /* OFInvocationTests.m */, 4BAA60C714D09699006F068D /* OFJSONTests.m */, 4B22BE1F1AE594A000CD320A /* OFKernelEventObserverTests.m */, 4B6EF6721235358D0076B512 /* OFListTests.m */, 4B6EF6731235358D0076B512 /* OFMD5HashTests.m */, 4B61CB081F6497C40000DDDA /* OFMethodSignatureTests.m */, @@ -2521,10 +2533,11 @@ 4BF20C521EEBF5F000C53220 /* OFInflate64Stream.h in Headers */, 4BF20C561EEBF5F000C53220 /* OFInflateStream.h in Headers */, 4B2C21F41DA292BE00735907 /* OFINICategory.h in Headers */, 4B2C21F51DA292BE00735907 /* OFINIFile.h in Headers */, 4B2C21F61DA292BE00735907 /* OFIntrospection.h in Headers */, + 4BAD891F1F65E6B300CF44B7 /* OFInvocation.h in Headers */, 4B2C21F71DA292BE00735907 /* OFJSONRepresentation.h in Headers */, 4B2C21F81DA292BE00735907 /* OFKernelEventObserver.h in Headers */, 4B2C21F91DA292BE00735907 /* OFKeyValueCoding.h in Headers */, 4B2C21FA1DA292BE00735907 /* OFList.h in Headers */, 4B46E2221E235EA700121ED6 /* OFLocalization.h in Headers */, @@ -2755,10 +2768,11 @@ 4BF20C511EEBF5F000C53220 /* OFInflate64Stream.h in Headers */, 4BF20C551EEBF5F000C53220 /* OFInflateStream.h in Headers */, 4B06855318B2AD3800FC731A /* OFINICategory.h in Headers */, 4B5B02BE18B288A400CE6AE4 /* OFINIFile.h in Headers */, 4BA49D9013DB113B00381CDB /* OFIntrospection.h in Headers */, + 4BAD89201F65E6B300CF44B7 /* OFInvocation.h in Headers */, 4BA02BA115041F5900002F84 /* OFJSONRepresentation.h in Headers */, 4B0EA9211898690E00F573A4 /* OFKernelEventObserver.h in Headers */, 4BC1762F1D04963000C32718 /* OFKeyValueCoding.h in Headers */, 4B3D23CB1337FCB000DD29B8 /* OFList.h in Headers */, 4B46E2211E235EA700121ED6 /* OFLocalization.h in Headers */, @@ -3322,10 +3336,11 @@ 4BF20C541EEBF5F000C53220 /* OFInflate64Stream.m in Sources */, 4BF20C581EEBF5F000C53220 /* OFInflateStream.m in Sources */, 4B2C213C1DA292BE00735907 /* OFINICategory.m in Sources */, 4B2C213D1DA292BE00735907 /* OFINIFile.m in Sources */, 4B2C213E1DA292BE00735907 /* OFIntrospection.m in Sources */, + 4BAD89221F65E6B700CF44B7 /* OFInvocation.m in Sources */, 4B2C213F1DA292BE00735907 /* OFGZIPStream.m in Sources */, 4B2C21401DA292BE00735907 /* OFKernelEventObserver.m in Sources */, 4B2C21411DA292BE00735907 /* OFKernelEventObserver_kqueue.m in Sources */, 4B2C21421DA292BE00735907 /* OFKernelEventObserver_poll.m in Sources */, 4B2C21431DA292BE00735907 /* OFKernelEventObserver_select.m in Sources */, @@ -3529,10 +3544,11 @@ 4BF20C531EEBF5F000C53220 /* OFInflate64Stream.m in Sources */, 4BF20C571EEBF5F000C53220 /* OFInflateStream.m in Sources */, 4B06855418B2AD3800FC731A /* OFINICategory.m in Sources */, 4B5B02BF18B288A400CE6AE4 /* OFINIFile.m in Sources */, 4BA49D9113DB113B00381CDB /* OFIntrospection.m in Sources */, + 4BAD89211F65E6B600CF44B7 /* OFInvocation.m in Sources */, 4BD112611CCB73A60076FDB9 /* OFGZIPStream.m in Sources */, 4B0EA9221898690E00F573A4 /* OFKernelEventObserver.m in Sources */, 4B0EA91C1898690E00F573A4 /* OFKernelEventObserver_kqueue.m in Sources */, 4B0EA91E1898690E00F573A4 /* OFKernelEventObserver_poll.m in Sources */, 4B0EA9201898690E00F573A4 /* OFKernelEventObserver_select.m in Sources */, @@ -3724,10 +3740,11 @@ 4BD9CA061DA2C60B00E5AD52 /* OFHMACTests.m in Sources */, 4BD9CA071DA2C60E00E5AD52 /* OFHTTPClientTests.m in Sources */, 4BD9CA081DA2C61900E5AD52 /* OFHTTPCookieTests.m in Sources */, 4B11D09D1EC901440094423D /* OFHTTPCookieManagerTests.m in Sources */, 4BD9CA091DA2C61E00E5AD52 /* OFINIFileTests.m in Sources */, + 4BAD89251F65E80A00CF44B7 /* OFInvocationTests.m in Sources */, 4BD9CA0A1DA2C62000E5AD52 /* OFJSONTests.m in Sources */, 4BD9CA0B1DA2C62200E5AD52 /* OFKernelEventObserverTests.m in Sources */, 4BD9CA0C1DA2C62500E5AD52 /* OFListTests.m in Sources */, 4BD9CA0D1DA2C62800E5AD52 /* OFMD5HashTests.m in Sources */, 4B61CB0A1F6497FB0000DDDA /* OFMethodSignatureTests.m in Sources */, @@ -3771,10 +3788,11 @@ 4BF0DD741D44645D001D9949 /* OFHMACTests.m in Sources */, 4BB4B54A16776094002A2DCE /* OFHTTPClientTests.m in Sources */, 4B2610C61D86305C001F16C9 /* OFHTTPCookieTests.m in Sources */, 4B11D09C1EC901440094423D /* OFHTTPCookieManagerTests.m in Sources */, 4B5B02C118B2897500CE6AE4 /* OFINIFileTests.m in Sources */, + 4BAD89241F65E80A00CF44B7 /* OFInvocationTests.m in Sources */, 4BAA60C814D09699006F068D /* OFJSONTests.m in Sources */, 4B22BE201AE594A000CD320A /* OFKernelEventObserverTests.m in Sources */, 4BF33B03133807A20059CEF7 /* OFListTests.m in Sources */, 4BF33B04133807A20059CEF7 /* OFMD5HashTests.m in Sources */, 4BF33B05133807A20059CEF7 /* OFNumberTests.m in Sources */, Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -25,13 +25,14 @@ OFHMAC.m \ OFHTTPCookie.m \ OFHTTPCookieManager.m \ OFHTTPRequest.m \ OFHTTPResponse.m \ - OFInflateStream.m \ OFInflate64Stream.m \ + OFInflateStream.m \ OFIntrospection.m \ + OFInvocation.m \ OFList.m \ OFLocalization.m \ OFMapTable.m \ OFMD5Hash.m \ OFMessagePackExtension.m \ ADDED src/OFInvocation.h Index: src/OFInvocation.h ================================================================== --- /dev/null +++ src/OFInvocation.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * 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 "OFObject.h" + +OF_ASSUME_NONNULL_BEGIN + +@class OFMethodSignature; +@class OFMutableArray OF_GENERIC(ObjectType); +@class OFMutableData; + +/*! + * @class OFInvocation OFInvocation.h ObjFW/OFInvocation.h + * + * @brief A class for storing and accessing invocations, and invoking them. + */ +@interface OFInvocation: OFObject +{ + OFMethodSignature *_methodSignature; + OFMutableArray OF_GENERIC(OFMutableData *) *_arguments; + OFMutableData *_returnValue; +} + +/*! + * The method signature for the invocation. + */ +@property (readonly, nonatomic) OFMethodSignature *methodSignature; + +/*! + * @brief Creates a new invocation with the specified method signature. + * + * @param signature The method signature for the invocation + * @return A new, autoreleased OFInvocation + */ ++ (instancetype)invocationWithMethodSignature: (OFMethodSignature *)signature; + +/*! + * @brief Initializes an already allocated invocation with the specified method + * signature. + * + * @param signature The method signature for the invocation + * @return An initialized OFInvocation + */ +- initWithMethodSignature: (OFMethodSignature *)signature; + +/*! + * @brief Sets the argument for the specified index. + * + * @param buffer The buffer in which the argument is stored + * @param index The index of the argument to set + */ +- (void)setArgument: (const void *)buffer + atIndex: (size_t)index; + +/*! + * @brief Gets the argument for the specified index. + * + * @param buffer The buffer in which the argument is stored + * @param index The index of the argument to get + */ +- (void)getArgument: (void *)buffer + atIndex: (size_t)index; + +/*! + * @brief Sets the return value. + * + * @param buffer The buffer in which the return value is stored + */ +- (void)setReturnValue: (const void *)buffer; + +/*! + * @brief Gets the return value. + * + * @param buffer The buffer in which the return value is stored + */ +- (void)getReturnValue: (void *)buffer; +@end + +OF_ASSUME_NONNULL_END ADDED src/OFInvocation.m Index: src/OFInvocation.m ================================================================== --- /dev/null +++ src/OFInvocation.m @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * 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. + */ + +#include "config.h" + +#include + +#import "OFInvocation.h" +#import "OFArray.h" +#import "OFData.h" +#import "OFMethodSignature.h" + +@implementation OFInvocation +@synthesize methodSignature = _methodSignature; + ++ (instancetype)invocationWithMethodSignature: (OFMethodSignature *)signature +{ + return [[[self alloc] initWithMethodSignature: signature] autorelease]; +} + +- initWithMethodSignature: (OFMethodSignature *)signature +{ + self = [super init]; + + @try { + void *pool = objc_autoreleasePoolPush(); + size_t numberOfArguments = [signature numberOfArguments]; + const char *typeEncoding; + size_t typeSize; + + _methodSignature = [signature retain]; + _arguments = [[OFMutableArray alloc] init]; + + for (size_t i = 0; i < numberOfArguments; i++) { + OFMutableData *data; + + typeEncoding = [_methodSignature + argumentTypeAtIndex: i]; + typeSize = of_sizeof_type_encoding(typeEncoding); + + data = [OFMutableData dataWithItemSize: typeSize + capacity: 1]; + [data increaseCountBy: 1]; + [_arguments addObject: data]; + } + + typeEncoding = [_methodSignature methodReturnType]; + typeSize = of_sizeof_type_encoding(typeEncoding); + _returnValue = [[OFMutableData alloc] initWithItemSize: typeSize + capacity: 1]; + [_returnValue increaseCountBy: 1]; + + objc_autoreleasePoolPop(pool); + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [_methodSignature release]; + [_arguments release]; + [_returnValue release]; + + [super dealloc]; +} + +- (void)setArgument: (const void *)buffer + atIndex: (size_t)index +{ + OFMutableData *data = [_arguments objectAtIndex: index]; + + memcpy([data items], buffer, [data itemSize]); +} + +- (void)getArgument: (void *)buffer + atIndex: (size_t)index +{ + OFData *data = [_arguments objectAtIndex: index]; + + memcpy(buffer, [data items], [data itemSize]); +} + +- (void)setReturnValue: (const void *)buffer +{ + memcpy([_returnValue items], buffer, [_returnValue itemSize]); +} + +- (void)getReturnValue: (void *)buffer +{ + memcpy(buffer, [_returnValue items], [_returnValue itemSize]); +} +@end Index: src/OFLocalization.h ================================================================== --- src/OFLocalization.h +++ src/OFLocalization.h @@ -42,11 +42,11 @@ OFString *_decimalPoint; OFMutableArray OF_GENERIC(OFDictionary OF_GENERIC(OFString *, id) *) *_localizedStrings; } -/** +/*! * The language of the locale for messages. * * If the language is unknown, it is `nil`. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *language; @@ -82,11 +82,11 @@ * * @return The shared OFLocalization instance */ + (instancetype)sharedLocalization; -/** +/*! * @brief Returns the language of the locale. * * If the language is unknown, `nil` is returned. * * @return The language of the locale. @@ -171,11 +171,11 @@ */ - (OFString *)localizedStringForID: (OFConstantString *)ID fallback: (OFConstantString *)fallback, ... OF_SENTINEL; -/** +/*! * @brief Returns the localized string for the specified ID, using the fallback * string if it cannot be looked up or is missing. * * @note This takes a variadic argument, terminated by `nil` and passed as * va_list, that consists of pairs of variable names and variable values, Index: src/OFMethodSignature.h ================================================================== --- src/OFMethodSignature.h +++ src/OFMethodSignature.h @@ -47,12 +47,11 @@ * @note This is platform-dependent! */ @property (readonly, nonatomic) size_t frameLength; /*! - * @brief Creates a new, autoreleased OFMethodSignature with the specified - * ObjC types. + * @brief Creates a new OFMethodSignature with the specified ObjC types. * * @param types The ObjC types of the method * @return A new, autoreleased OFMethodSignature */ + (instancetype)signatureWithObjCTypes: (const char *)types; @@ -79,12 +78,11 @@ * specified index. * * @note This is platform-dependent! * * @param index The index of the argument for which to return the offset - * @returns The offset on the stack frame of the argument at the - * specified index + * @return The offset on the stack frame of the argument at the specified index */ - (size_t)argumentOffsetAtIndex: (size_t)index; @end #ifdef __cplusplus Index: src/OFMethodSignature.m ================================================================== --- src/OFMethodSignature.m +++ src/OFMethodSignature.m @@ -23,10 +23,12 @@ #import "OFData.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" + +#import "macros.h" size_t sizeofEncoding(const char **type, size_t *length); size_t alignofEncoding(const char **type, size_t *length); size_t Index: src/OFTLSSocket.h ================================================================== --- src/OFTLSSocket.h +++ src/OFTLSSocket.h @@ -77,11 +77,11 @@ * swapping! This is also the reason why this is not an OFString. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) const char *privateKeyPassphrase; -/** +/*! * Whether certificate verification is enabled. * * The default is enabled. */ @property (nonatomic, getter=isCertificateVerificationEnabled) Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -14,10 +14,11 @@ OFDataTests.m \ OFDateTests.m \ OFDictionaryTests.m \ OFHTTPCookieTests.m \ OFHTTPCookieManagerTests.m \ + OFInvocationTests.m \ OFJSONTests.m \ OFListTests.m \ OFMethodSignatureTests.m \ OFNumberTests.m \ OFObjectTests.m \ ADDED tests/OFInvocationTests.m Index: tests/OFInvocationTests.m ================================================================== --- /dev/null +++ tests/OFInvocationTests.m @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * 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. + */ + +#include "config.h" + +#include + +#import "OFInvocation.h" +#import "OFMethodSignature.h" +#import "OFAutoreleasePool.h" + +#import "TestsAppDelegate.h" + +static OFString *module = @"OFInvocation"; + +struct test_struct { + unsigned char c; + unsigned int i; +}; + +@implementation TestsAppDelegate (OFInvocationTests) +- (struct test_struct)invocationTestMethod: (unsigned char)c + : (unsigned int)i + : (struct test_struct *)ptr + : (struct test_struct)st +{ + return st; +} + +- (void)invocationTests +{ + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + OFMethodSignature *sig = [self methodSignatureForSelector: + @selector(invocationTestMethod::::)]; + OFInvocation *invocation; + struct test_struct st, st2, *stp = &st, *stp2; + unsigned const char c = 0xAA; + unsigned char c2; + const unsigned int i = 0x55555555; + unsigned int i2; + + memset(&st, '\xFF', sizeof(st)); + st.c = 0x55; + st.i = 0xAAAAAAAA; + + TEST(@"+[invocationWithMethodSignature:]", + (invocation = [OFInvocation invocationWithMethodSignature: sig])) + + TEST(@"-[setReturnValue]", R([invocation setReturnValue: &st])) + + TEST(@"-[getReturnValue]", R([invocation getReturnValue: &st2]) && + memcmp(&st, &st2, sizeof(st)) == 0) + + memset(&st2, '\0', sizeof(st2)); + + TEST(@"-[setArgument:atIndex:] #1", R([invocation setArgument: &c + atIndex: 2])) + + TEST(@"-[setArgument:atIndex:] #2", R([invocation setArgument: &i + atIndex: 3])) + + TEST(@"-[setArgument:atIndex:] #3", R([invocation setArgument: &stp + atIndex: 4])) + + TEST(@"-[setArgument:atIndex:] #4", R([invocation setArgument: &st + atIndex: 5])) + + TEST(@"-[getArgument:atIndex:] #1", R([invocation getArgument: &c2 + atIndex: 2]) && + c == c2) + + TEST(@"-[getArgument:atIndex:] #2", R([invocation getArgument: &i2 + atIndex: 3]) && + i == i2) + + TEST(@"-[getArgument:atIndex:] #3", R([invocation getArgument: &stp2 + atIndex: 4]) && + stp == stp2) + + TEST(@"-[getArgument:atIndex:] #4", R([invocation getArgument: &st2 + atIndex: 5]) && + memcmp(&st, &st2, sizeof(st)) == 0) + + [pool drain]; +} +@end Index: tests/TestsAppDelegate.h ================================================================== --- tests/TestsAppDelegate.h +++ tests/TestsAppDelegate.h @@ -109,10 +109,14 @@ @end @interface TestsAppDelegate (OFINIFileTests) - (void)INIFileTests; @end + +@interface TestsAppDelegate (OFInvocationTests) +- (void)invocationTests; +@end @interface TestsAppDelegate (OFJSONTests) - (void)JSONTests; @end Index: tests/TestsAppDelegate.m ================================================================== --- tests/TestsAppDelegate.m +++ tests/TestsAppDelegate.m @@ -379,10 +379,11 @@ changeCurrentDirectoryPath: @"/apps/objfw-tests"]; #endif [self runtimeTests]; [self methodSignatureTests]; + [self invocationTests]; [self forwardingTests]; [self objectTests]; #ifdef OF_HAVE_BLOCKS [self blockTests]; #endif