* Source/DKArgument.[mh]: Implement marshalling of variant types. Also add the

ability to customize the unboxing of objects.
* Source/DKEndpoint.m 
  Source/DKMethod.m
  Source/DKPort.m: 
  Compile fixes for clang.
* Source/DKOutgoingProxy.[mh]
  Source/GNUmakefile:
  Add stub implementation for outgoing proxies.
* Source/DKProxy.m: Add method to distinguish outgoing and incoming proxies.
* Source/Tests/TestDKProxy.m: Fix runtime.h include.
* Source/Tests/TestDKArgument.m: Add test for custom unboxing methods.
* Source/config.h.in
  config.make.in
  configure.ac
  GNUmakefile.postamble:
  Update configure script and paraphernalia to check for advanced runtime
  features.
* configure: Regenerate

Finish implementation of (un-)marshalling values between NSInvocation and D-Bus
messages. More flexible scheme for unboxing values. Various smaller fixes.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/dbuskit/trunk@30844 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Niels Grewe 2010-06-24 20:01:40 +00:00
parent 00783650d9
commit c3bc3287dd
16 changed files with 2271 additions and 448 deletions

View File

@ -29,13 +29,14 @@ after-clean::
@-$(RM) -rf DBusKit.framework
@-$(RM) -rf derived_src
@-$(RM) config.make
@-$(RM) Source/config.h
# Things to do before distcleaning
# before-distclean::
# Things to do after distcleaning
after-distclean::
@-$(RM) config.log config.status config.make
@-$(RM) config.log config.status config.make Source/config.h
@-$(RM) -rf autom4te.cache
# Things to do before checking
@ -47,5 +48,5 @@ after-distclean::
# Rule to generate configuration data:
config.make: config.make.in
config.make: config.make.in Source/config.h.in
./configure

View File

@ -41,6 +41,14 @@ extern NSString *DKArgumentDirectionOut;
Class objCEquivalent;
}
/**
* Registers the selector to be used for unboxing objects to specific
* D-Bus types. The method named by the selector may not take any arguments and
* its return value can not exceed 8 bytes.
*/
+ (void)registerUnboxingSelector: (SEL)selector
forDBusType: (int)type;
- (id) initWithDBusSignature: (const char*)characters
name: (NSString*)name
parent: (id)parent;
@ -67,6 +75,11 @@ extern NSString *DKArgumentDirectionOut;
*/
- (Class) objCEquivalent;
/**
* Returns the D-Bus type of the argument.
*/
- (int) DBusType;
/**
* Return the D-Bus type signature equivalent to the argument.
*/

View File

@ -27,14 +27,19 @@
#import <Foundation/NSDictionary.h>
#import <Foundation/NSException.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSHashTable.h>
#import <Foundation/NSInvocation.h>
#import <Foundation/NSLock.h>
#import <Foundation/NSMapTable.h>
#import <Foundation/NSMethodSignature.h>
#import <Foundation/NSNull.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
#import <GNUstepBase/NSDebug+GNUstepBase.h>
#import "DBusKit/DKProxy.h"
#import "DKEndpoint.h"
#import "DKOutgoingProxy.h"
#import "DKArgument.h"
#include <dbus/dbus.h>
@ -82,13 +87,62 @@ DKObjCClassForDBusType(int type)
return Nil;
}
/*
* Conversion from Objective-C types to D-Bus types. NOTE: This is not meant to
* be complete. It is just used to give some hints for the boxing of D-Bus
* variant types. (NSValue responds to -objCType, so we can use the information
* to construct a correctly typed DKArgument at least some of the time.)
*/
static int
DKDBusTypeForObjCType(const char* code)
{
switch (*code)
{
case _C_BOOL:
return DBUS_TYPE_BOOLEAN;
case _C_CHR:
case _C_SHT:
return DBUS_TYPE_INT16;
case _C_INT:
return DBUS_TYPE_INT32;
case _C_LNG_LNG:
return DBUS_TYPE_INT64;
case _C_UCHR:
return DBUS_TYPE_BYTE;
case _C_USHT:
return DBUS_TYPE_UINT16;
case _C_UINT:
return DBUS_TYPE_UINT32;
case _C_ULNG_LNG:
return DBUS_TYPE_UINT64;
case _C_FLT:
case _C_DBL:
return DBUS_TYPE_DOUBLE;
case _C_CHARPTR:
return DBUS_TYPE_STRING;
case _C_ID:
return DBUS_TYPE_OBJECT_PATH;
case _C_ARY_B:
return DBUS_TYPE_ARRAY;
case _C_STRUCT_B:
return DBUS_TYPE_STRUCT;
default:
return DBUS_TYPE_INVALID;
}
return DBUS_TYPE_INVALID;
}
/*
* Map D-Bus types to corresponding Objective-C types. Assumes that complex
* types are always boxed.
*/
static char*
DKUnboxedObjCTypeForDBusType(int type)
{
switch (type)
{
case DBUS_TYPE_BYTE:
return @encode(char);
return @encode(unsigned char);
case DBUS_TYPE_BOOLEAN:
return @encode(BOOL);
case DBUS_TYPE_INT16:
@ -170,6 +224,7 @@ DKUnboxedObjCTypeSizeForDBusType(int type)
- (NSString*)_path;
- (NSString*)_service;
- (DKEndpoint*)_endpoint;
- (BOOL)_isLocal;
@end
@ -190,6 +245,7 @@ DKUnboxedObjCTypeSizeForDBusType(int type)
@end
@interface DKVariantTypeArgument: DKContainerTypeArgument
- (DKArgument*) DKArgumentWithObject: (id)object;
@end
/* It seems sensible to regard dict entries as struct types. */
@ -204,10 +260,206 @@ DKUnboxedObjCTypeSizeForDBusType(int type)
intoIterator: (DBusMessageIter*)iter;
@end
/*
* Tables and paraphernalia for managing unboxing of objects: We want some
* degree of flexibility on how to unbox objects of arbitrary types. To that
* end, we define two tables:
*
* (1) selectorTypeMap, which maps selectors used to unbox objects to D-Bus
* types so that we can construct appropriate DKArguments if we encounter
* objects responding to the selector.
*
* (2) typeSelectorMap, which maps D-Bus types to hash-tables containing all
* selectors that can be used to obtain an unboxed value of a specified
* type.
*
* NOTE: Unfortunately, we cannot unbox container types this way.
*/
static NSMapTable *selectorTypeMap;
static NSMapTable *typeSelectorMap;
static NSLock *selectorTypeMapLock;
typedef struct
{
SEL selector;
int type;
} DKSelectorTypePair;
#define DK_INSTALL_TYPE_SELECTOR_PAIR(type,theSel) \
do \
{\
SEL selector = theSel;\
NSHashTable *selTable = NSCreateHashTable(NSIntHashCallBacks,\
1); \
NSMapInsert(selectorTypeMap,\
(void*)(uintptr_t)selector,\
(void*)(intptr_t)type);\
NSMapInsert(typeSelectorMap,\
(void*)(intptr_t)type,\
(void*)selTable);\
NSHashInsert(selTable,selector);\
} while (0)
static void
DKInstallDefaultSelectorTypeMapping()
{
[selectorTypeMapLock lock];
DK_INSTALL_TYPE_SELECTOR_PAIR(DBUS_TYPE_INT64, @selector(longLongValue));
DK_INSTALL_TYPE_SELECTOR_PAIR(DBUS_TYPE_UINT64, @selector(unsignedLongLongValue));
DK_INSTALL_TYPE_SELECTOR_PAIR(DBUS_TYPE_INT32, @selector(intValue));
DK_INSTALL_TYPE_SELECTOR_PAIR(DBUS_TYPE_UINT32, @selector(unsignedIntValue));
DK_INSTALL_TYPE_SELECTOR_PAIR(DBUS_TYPE_INT16, @selector(shortValue));
DK_INSTALL_TYPE_SELECTOR_PAIR(DBUS_TYPE_UINT16, @selector(unsignedShortValue));
DK_INSTALL_TYPE_SELECTOR_PAIR(DBUS_TYPE_BYTE, @selector(unsignedCharValue));
DK_INSTALL_TYPE_SELECTOR_PAIR(DBUS_TYPE_BOOLEAN, @selector(boolValue));
DK_INSTALL_TYPE_SELECTOR_PAIR(DBUS_TYPE_DOUBLE, @selector(doubleValue));
DK_INSTALL_TYPE_SELECTOR_PAIR(DBUS_TYPE_DOUBLE, @selector(floatValue));
DK_INSTALL_TYPE_SELECTOR_PAIR(DBUS_TYPE_STRING, @selector(UTF8String));
[selectorTypeMapLock unlock];
}
static void
DKRegisterSelectorTypePair(DKSelectorTypePair *pair)
{
NSHashTable *selTable = nil;
SEL selector = pair->selector;
int type = pair->type;
void* mapReturn = NULL;
if (0 == selector)
{
return;
}
[selectorTypeMapLock lock];
selTable = NSMapGet(typeSelectorMap, (void*)(intptr_t)type);
if (!selTable)
{
[selectorTypeMapLock unlock];
return;
}
mapReturn = NSMapInsertIfAbsent(selectorTypeMap,
(void*)(uintptr_t)selector,
(void*)(intptr_t)type);
// InsertIfAbsent returns NULL if the key had been absent, which is the only
// case where we also want to install the new type-selector mapping.
if (NULL == mapReturn)
{
NSHashInsertIfAbsent(selTable, (void*)(uintptr_t)selector);
}
[selectorTypeMapLock unlock];
}
static SEL
DKSelectorForUnboxingObjectAsType(id object, int DBusType)
{
SEL theSel = 0;
NSHashTable *table = nil;
NSHashEnumerator tableEnum;
[selectorTypeMapLock lock];
table = NSMapGet(typeSelectorMap, (void*)(intptr_t)DBusType);
tableEnum = NSEnumerateHashTable(table);
while (0 != (theSel = (SEL)NSNextHashEnumeratorItem(&tableEnum)))
{
if ([object respondsToSelector: theSel])
{
NSEndHashTableEnumeration(&tableEnum);
[selectorTypeMapLock unlock];
return theSel;
}
}
NSEndHashTableEnumeration(&tableEnum);
[selectorTypeMapLock unlock];
return 0;
}
static int
DKDBusTypeForUnboxingObject(id object)
{
int type = DBUS_TYPE_INVALID;
// Fast case: The object implements objCType, so we can simply gather the
// D-Bus type from the Obj-C type code.
if ([object respondsToSelector: @selector(objCType)])
{
type = DKDBusTypeForObjCType([object objCType]);
}
// Slow case: We need to find a selector in the table and get the matching
// type.
if (DBUS_TYPE_INVALID == type)
{
SEL aSel = 0;
NSMapEnumerator mapEnum;
[selectorTypeMapLock lock];
mapEnum = NSEnumerateMapTable(selectorTypeMap);
while (NSNextMapEnumeratorPair(&mapEnum,
(void**)&aSel,
(void**)&type))
{
if (aSel != 0)
{
if ([object respondsToSelector: aSel])
{
// The object responds to the selector. We need to make sure that we
// get a correctly sized return value by invoking the corresponding
// method.
NSMethodSignature *sig = [object methodSignatureForSelector: aSel];
if ((type == DKDBusTypeForObjCType([sig methodReturnType])))
{
NSEndMapTableEnumeration(&mapEnum);
[selectorTypeMapLock unlock];
return type;
}
}
}
}
NSEndMapTableEnumeration(&mapEnum);
[selectorTypeMapLock unlock];
}
return type;
}
/**
* DKArgument encapsulates D-Bus argument information
*/
@implementation DKArgument
+ (void) initialize
{
if ([DKArgument class] != self)
{
return;
}
selectorTypeMap = NSCreateMapTable(NSIntMapKeyCallBacks,
NSIntMapValueCallBacks,
17); // We have 17 D-Bus types.
typeSelectorMap = NSCreateMapTable(NSIntMapKeyCallBacks,
NSObjectMapValueCallBacks,
17); // We have 17 D-Bus types.
selectorTypeMapLock = [NSLock new];
DKInstallDefaultSelectorTypeMapping();
}
+ (void)registerUnboxingSelector: (SEL)selector
forDBusType: (int)type
{
DKSelectorTypePair pair = {selector, type};
DKRegisterSelectorTypePair(&pair);
}
- (id) initWithIterator: (DBusSignatureIter*)iterator
name: (NSString*)_name
parent: (id)_parent
@ -316,6 +568,7 @@ DKUnboxedObjCTypeSizeForDBusType(int type)
- (BOOL) unboxValue: (id)value
intoBuffer: (long long*)buffer
{
SEL aSelector = 0;
switch (DBusType)
{
case DBUS_TYPE_BYTE:
@ -397,16 +650,37 @@ DKUnboxedObjCTypeSizeForDBusType(int type)
case DBUS_TYPE_OBJECT_PATH:
if ([value isKindOfClass: [DKProxy class]])
{
DKProxy *rootProxy = [self proxyParent];
/*
* Handle remote objects:
* We need to make sure that the paths are from the same proxy, because
* that is the widest scope in which they are valid.
*/
if ([[self proxyParent] hasSameScopeAs: value])
if ([rootProxy hasSameScopeAs: value])
{
*buffer = (uintptr_t)[[value _path] UTF8String];
return YES;
}
}
else
{
DKProxy *rootProxy = [self proxyParent];
/*
* Handle local objects:
* We need to find out if the proxy we derive from is an outgoing proxy.
* If so, we can export the object via D-Bus, so that the caller can
* interact with it.
*/
if ([rootProxy _isLocal])
{
DKOutgoingProxy *newProxy = [DKOutgoingProxy proxyWithParent: rootProxy
object: value];
*buffer = (uintptr_t)[[newProxy _path] UTF8String];
[newProxy release];
return YES;
}
}
break;
case DBUS_TYPE_SIGNATURE:
if ([value respondsToSelector: @selector(DBusTypeSignature)])
@ -418,6 +692,29 @@ DKUnboxedObjCTypeSizeForDBusType(int type)
default:
break;
}
/*
* None of the built in mappings worked. We still have a slight chance that a
* custom selector was installed to unbox the type. So we try again by looking
* up the selector.
*/
aSelector = DKSelectorForUnboxingObjectAsType(value, DBusType);
if (0 != aSelector)
{
NSMethodSignature *sig = [value methodSignatureForSelector: aSelector];
// Only call it if we don't need arguments and the returnvalue fits into
// the buffer:
if ((2 == [sig numberOfArguments])
&& ([sig methodReturnLength] <= sizeof(long long)))
{
IMP unboxFun = [value methodForSelector: aSelector];
// Cast to void* first so that we don't get any funny implicit casts
*buffer = (long long)(void*)unboxFun(value, aSelector);
return YES;
}
}
return NO;
}
@ -662,9 +959,11 @@ DKUnboxedObjCTypeSizeForDBusType(int type)
case DBUS_TYPE_VARIANT:
/*
* A shortcut is needed for variant types. libdbus classifies them as
* containers, but it is clearly wrong about that: They have no children
* and dbus will fail and crash if it tries to loop over their non-existent
* sub-arguments. Hence we return after setting the subclass.
* containers, but it is clearly wrong about that at least with regard to
* the signatures:
* They have no children and dbus will fail and crash if it tries to loop
* over their non-existent sub-arguments. Hence we return after setting the
* subclass.
*/
isa = [DKVariantTypeArgument class];
return self;
@ -814,13 +1113,13 @@ DKUnboxedObjCTypeSizeForDBusType(int type)
if (-1 == index)
{
NSAssert((@encode(id) == [[inv methodSignature] methodReturnType]),
NSAssert((0 == strcmp(@encode(id), [[inv methodSignature] methodReturnType])),
@"Type mismatch between introspection data and invocation.");
[inv setReturnValue: &value];
}
else
{
NSAssert((@encode(id) == [[inv methodSignature] getArgumentTypeAtIndex: index]),
NSAssert((0 == strcmp(@encode(id), [[inv methodSignature] getArgumentTypeAtIndex: index])),
@"Type mismatch between introspection data and invocation.");
[inv setArgument: &value
atIndex: index];
@ -842,13 +1141,13 @@ DKUnboxedObjCTypeSizeForDBusType(int type)
if (-1 == index)
{
NSAssert((@encode(id) == [[inv methodSignature] methodReturnType]),
NSAssert((0 == strcmp(@encode(id), [[inv methodSignature] methodReturnType])),
@"Type mismatch between introspection data and invocation.");
[inv getReturnValue: &value];
}
else
{
NSAssert((@encode(id) == [[inv methodSignature] getArgumentTypeAtIndex: index]),
NSAssert((0 == strcmp(@encode(id), [[inv methodSignature] getArgumentTypeAtIndex: index])),
@"Type mismatch between introspection data and invocation.");
[inv getArgument: &value
atIndex: index];
@ -1214,7 +1513,105 @@ DKUnboxedObjCTypeSizeForDBusType(int type)
}
@end
@implementation DKVariantTypeArgument
- (NSString*)validSubSignatureOrVariantForEnumerator: (NSEnumerator*)theEnum
{
id element = [theEnum nextObject];
NSString *thisSig = [[self DKArgumentWithObject: element] DBusTypeSignature];
NSString *nextSig = thisSig;
// For homogenous collection, we can the proper signature, for non-homogenous
// ones, we need to pass down the variant type.
BOOL isHomogenous = YES;
while ((nil != (element = [theEnum nextObject]))
&& (YES == isHomogenous))
{
thisSig = nextSig;
nextSig = [[self DKArgumentWithObject: element] DBusTypeSignature];
isHomogenous = [thisSig isEqualToString: nextSig];
}
if (isHomogenous)
{
return thisSig;
}
else
{
return @"v";
}
}
- (DKArgument*) DKArgumentWithObject: (id)object
{
if (([object respondsToSelector: @selector(keyEnumerator)])
&& ([object respondsToSelector: @selector(objectEnumerator)]))
{
NSEnumerator *keyEnum = [object keyEnumerator];
NSEnumerator *objEnum = [object objectEnumerator];
NSString *keySig = [self validSubSignatureOrVariantForEnumerator: keyEnum];
NSString *objSig = [self validSubSignatureOrVariantForEnumerator: objEnum];
NSString *theSig = [NSString stringWithFormat: @"a{%@%@}", keySig, objSig];
DKArgument *subArg = [[[DKArgument alloc] initWithDBusSignature: [theSig UTF8String]
name: nil
parent: self] autorelease];
if (nil == subArg)
{
// This might happen if the dictionary could not properly be represented as
// a D-Bus dictionary (i.e. it has keys of complex type. In this case, we
// fall back to representing it as an array of structs:
theSig = [NSString stringWithFormat: @"a(%@%@)", keySig, objSig];
subArg = [[[DKArgument alloc] initWithDBusSignature: [theSig UTF8String]
name: nil
parent: self] autorelease];
}
return subArg;
}
else if ([object respondsToSelector: @selector(objectEnumerator)])
{
NSEnumerator *theEnum = [object objectEnumerator];
NSString *subSig = [self validSubSignatureOrVariantForEnumerator: theEnum];
return [[[DKArgument alloc] initWithDBusSignature: [[@"a" stringByAppendingString: subSig] UTF8String]
name: nil
parent: self] autorelease];
}
else if ([object isKindOfClass: [DKProxy class]])
{
DKProxy *rootProxy = [self proxyParent];
if ([rootProxy hasSameScopeAs: object])
{
return [[[DKArgument alloc] initWithDBusSignature: DBUS_TYPE_OBJECT_PATH_AS_STRING
name: nil
parent: self] autorelease];
}
}
else
{
// Simple types are quite straightforward, if we can find an appropriate
// deserialization selector.
int type = DKDBusTypeForUnboxingObject(object);
if ((DBUS_TYPE_INVALID != type) && (DBUS_TYPE_OBJECT_PATH != type))
{
return [[DKArgument alloc] initWithDBusSignature: (char*)&type
name: nil
parent: self];
}
else if ([[self proxyParent] _isLocal])
{
// If this fails, and the proxy from which this argument derives is an
// outgoing proxy, we can export it as an object path.
return [[[DKArgument alloc] initWithDBusSignature: DBUS_TYPE_OBJECT_PATH_AS_STRING
name: nil
parent: self] autorelease];
}
}
// Too bad, we have apparantely no chance to generate an argument tree for
// this object.
return nil;
}
- (id) unmarshalledObjectFromIterator: (DBusMessageIter*)iter
{
char *theSig = NULL;
@ -1238,7 +1635,33 @@ DKUnboxedObjCTypeSizeForDBusType(int type)
- (void) marshallObject: (id)object
intoIterator: (DBusMessageIter*)iter
{
//FIXME: Implement
DKArgument *subArg = [self DKArgumentWithObject: object];
DBusMessageIter subIter;
NSAssert1(subArg,
@"Could not marshall object %@ as D-Bus variant type",
subArg);
NSAssert(dbus_message_iter_open_container(iter,
DBUS_TYPE_ARRAY,
[[subArg DBusTypeSignature] UTF8String],
&subIter),
@"Out of memory when creating D-Bus iterator for container.");
NS_DURING
{
[subArg marshallObject: object
intoIterator: &subIter];
}
NS_HANDLER
{
dbus_message_iter_close_container(iter, &subIter);
[localException raise];
}
NS_ENDHANDLER
NSAssert(dbus_message_iter_close_container(iter, &subIter),
@"Out of memory when closing D-Bus container.");
}
@end

View File

@ -327,14 +327,12 @@ static NSRecursiveLock *activeConnectionLock;
- (id) initWithCoder: (NSCoder*)coder
{
if ([super respondsToSelector: @selector(initWithCoder:)])
// NSObject does not adopt NSCoding
if (nil == (self = [super init]))
{
self = [(id<NSCoding>)super initWithCoder: coder];
}
else
{
self = [super init];
return nil;
}
if ([coder allowsKeyedCoding])
{
info = [coder decodeObjectForKey: @"DKEndpointInfo"];
@ -448,10 +446,7 @@ static NSRecursiveLock *activeConnectionLock;
format: @"This DKEndpoint has been create with a private initializer and cannot be encoded."];
}
if ([super respondsToSelector: @selector(encodeWithCoder:)])
{
[(id<NSCoding>)super encodeWithCoder: coder];
}
// NSObject doesn't adopt NSCoding, so we don't do [super encodeWithCoder:].
if ([coder allowsKeyedCoding])
{

View File

@ -288,7 +288,7 @@ DKMethod *_DKMethodIntrospect;
NSMethodSignature *sig = [inv methodSignature];
// Make sure the method did return an object:
NSAssert2((@encode(id) == [sig methodReturnType]),
NSAssert2((0 == strcmp(@encode(id), [sig methodReturnType])),
@"Invalid return value when constucting D-Bus reply for '%@' on %@",
NSStringFromSelector([inv selector]),
[inv target]);

33
Source/DKOutgoingProxy.h Normal file
View File

@ -0,0 +1,33 @@
/** Interface for the DKOutgoingProxy class for exporting objects via D-Bus
Copyright (C) 2010 Free Software Foundation, Inc.
Written by: Niels Grewe <niels.grewe@halbordnung.de>
Created: June 2010
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
*/
#include "DBusKit/DKProxy.h"
@interface DKOutgoingProxy: DKProxy
/**
* Exports anObject via D-Bus by installing it in the object graph as a child of
* rootProxy.
*/
+ (id) proxyWithParent: (DKProxy*)rootProxy
object: (id)anObject;
@end

37
Source/DKOutgoingProxy.m Normal file
View File

@ -0,0 +1,37 @@
/** Implementation of the DKOutgoingProxy class for exporting objects via D-Bus
Copyright (C) 2010 Free Software Foundation, Inc.
Written by: Niels Grewe <niels.grewe@halbordnung.de>
Created: June 2010
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
*/
#include "DKOutgoingProxy.h"
@implementation DKOutgoingProxy
+ (id) proxyWithParent: (DKProxy*)rootProxy
object: (id)anObject
{
return nil;
}
- (BOOL)_isLocal
{
return YES;
}
@end

View File

@ -122,7 +122,7 @@ enum {
* This is the main method used to dispatch stuff from the DO system to D-Bus.
*/
- (BOOL)sendBeforeDate: (NSDate *)limitDate
msgid: (NSUInteger)msgid
msgid: (NSInteger)msgid
components: (NSMutableArray *)components
from: (NSPort *)recievePort
reserved: (NSUInteger)reserverdHeaderSpace
@ -215,7 +215,7 @@ enum {
extra: (void*)extra
forMode: (NSString*)mode
{
NSLog(@"RunLoop events: Ignoring event of type %ld", type);
NSLog(@"RunLoop events: Ignoring event of type %llu", (unsigned long long)type);
}
/**

View File

@ -320,6 +320,11 @@
return path;
}
- (BOOL)_isLocal
{
// True only for outgoing proxies representing local objects.
return NO;
}
- (BOOL) hasSameScopeAs: (DKProxy*)aProxy
{
BOOL sameService = [service isEqualToString: [aProxy _service]];

View File

@ -18,6 +18,7 @@ libDBusKit_OBJC_FILES = \
DKInterface.m \
DKIntrospectionNode.m \
DKMethod.m \
DKOutgoingProxy.m \
DKPort.m \
DKProxy.m

View File

@ -35,6 +35,32 @@
#include <stdint.h>
#include <math.h>
@interface CustomUnboxableObject: NSObject
{
int32_t foo;
}
- (int32_t)myInt32Value;
@end
@implementation CustomUnboxableObject
- (id) init
{
if (nil == (self = [super init]))
{
return nil;
}
foo = 42;
return self;
}
- (int32_t)myInt32Value
{
return foo;
}
@end
@interface TestDKArgument: NSObject <UKTest>
@end
@ -449,4 +475,19 @@ static NSDictionary *basicSigsAndClasses;
[arg release];
}
- (void)testCustomUnboxingSelector
{
DKArgument *arg = [[DKArgument alloc] initWithDBusSignature: "i"
name: nil
parent: nil];
id boxedFoo = [[CustomUnboxableObject alloc] init];
int32_t foo = [boxedFoo myInt32Value];
[DKArgument registerUnboxingSelector: @selector(myInt32Value)
forDBusType: DBUS_TYPE_INT32];
TEST_UNBOX_INTTYPE(int32_t);
[boxedFoo release];
[arg release];
}
@end

View File

@ -22,7 +22,9 @@
*/
#import <Foundation/NSObject.h>
#import <UnitKit/UnitKit.h>
#import <objc/runtime.h>
#define INCLUDE_RUNTIME_H
#include "../config.h"
#undef INCLUDE_RUNTIME_H
#import "../../Headers/DKProxy.h"
#import "../DKEndpoint.h"

47
Source/config.h.in Normal file
View File

@ -0,0 +1,47 @@
/** Configuration dependent information for DBusKit.
Copyright (C) 2010 Free Software Foundation, Inc.
Written by: Niels Grewe <niels.grewe@halbordnung.de>
Created: June 2010
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
*/
/*
* Having libtoydispatch enables some asynchronous behaviour.
*/
#ifndef HAVE_TOYDISPATCH
# define HAVE_TOYDISPATCH @HAVE_TOYDISPATCH@
#endif
/*
* Typed selectors enable automatic distinction between boxed and unboxed
* variants of D-Bus method calls.
*/
#ifndef HAVE_TYPED_SELECTORS
# define HAVE_TYPED_SELECTORS @HAVE_TYPED_SELECTORS@
#endif
/*
* Correct location of runtime.h, if requested.
*/
#ifdef INCLUDE_RUNTIME_H
# include <@OBJC_RUNTIME_H@>
#endif

View File

@ -1,3 +1,6 @@
ifeq ($(strip $(CC)),)
CC=@CC@
endif
ADDITIONAL_OBJCFLAGS+=@DBUS_CFLAGS@
WARN_FLAGS+=@WARN_FLAGS@
DBusKit_LDFLAGS+=@DBUS_LIBS@
DBusKit_LDFLAGS+=@DBUS_LIBS@ @MORE_LIBS@

1995
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,9 @@
# autoconf template for the configure script
AC_INIT
AC_PROG_CC(clang gcc cc c1 egcs)
AC_PROG_CPP
AC_LANG(Objective C)
PKG_PROG_PKG_CONFIG([])
# FIXME: We need a proper test for libobjc2 for some advanced features (e.g.
@ -43,6 +45,69 @@ fi
AC_SUBST(WARN_FLAGS)
AC_CONFIG_FILES([config.make])
#--------------------------------------------------------------------
# Check whether we have libtoydispatch for asynchronous table management.
#--------------------------------------------------------------------
HAVE_TOYDISPATCH=0
saved_CFLAGS="$CFLAGS"
saved_CPPFLAGS="$CPPFLAGS$"
saved_LDFLAGS="$LDFLAGS"
GS_OBJCFLAGS=`gnustep-config --objc-flags`
CFLAGS="$CFLAGS $GS_OBJCFLAGS"
CPPFLAGS="$CPPFLAGS $GS_OBJCFLAGS"
GS_LDFLAGS=`gnustep-config --objc-libs`
LDFLAGS="$LDFLAGS $GS_LDFLAGS"
AC_CHECK_HEADERS(toydispatch/toydispatch.h,have_toydispatch=yes,have_toydispatch=no)
if test "$have_toydispatch" = "yes"; then
AC_CHECK_LIB(toydispatch, toy_dispatch_queue_create, have_toydispatch=yes, have_toydispatch=no)
if test "$have_toydispatch" = "yes"; then
HAVE_TOYDISPATCH=1
MORE_LIBS="$MORE_LIBS -ltoydispatch"
fi
fi
AC_SUBST(HAVE_TOYDISPATCH)
#--------------------------------------------------------------------
# Check whether we can use typed selectors
#--------------------------------------------------------------------
HAVE_TYPED_SELECTORS=0
AC_CHECK_LIB(objc, sel_registerTypedName_np, have_typed_selectors=yes, have_typed_selectors=no)
if test "$have_typed_selectors" = "yes"; then
HAVE_TYPED_SELECTORS=1
fi
AC_SUBST(HAVE_TYPED_SELECTORS)
#--------------------------------------------------------------------
# Check whether we get runtime.h from libobjc2 or from the ObjectiveC2
# framework
#--------------------------------------------------------------------
AC_CHECK_HEADERS(objc/runtime.h,have_libobjc2_runtime_h=yes,have_libobjc2_runtime_h=no)
if test "$have_libobjc2_runtime_h" = "yes"; then
OBJC_RUNTIME_H="objc/runtime.h"
else
AC_CHECK_HEADERS(ObjectiveC2/runtime.h,have_objectivec2_runtime_h=yes,have_objectivec2_runtime_h=no)
if test "$have_objectivec2_runtime_h" = "yes"; then
OBJC_RUNTIME_H="ObjectiveC2/runtime.h"
else
AC_MSG_ERROR("could not find runtime.h. DBusKit requires gnustep-base >=1.20.")
fi
fi
AC_SUBST(OBJC_RUNTIME_H)
CFLAGS="$saved_CFLAGS"
CPPFLAGS="$saved_CPPFLAGS"
LDFLAGS="$saved_LDFLAGS"
AC_SUBST(MORE_LIBS)
AC_CONFIG_FILES([config.make Source/config.h])
AC_OUTPUT