mirror of
https://github.com/darlinghq/darling-dbuskit.git
synced 2025-02-17 00:09:53 +00:00
Support for explicitly designating an object to be exposed as a structure
on D-Bus. This is only required in some corner cases where the structure appears inside a variant-typed argument. This means that we don't have any introspection information to decide whether we want to marshall an NSArray as a D-Bus structure or a D-Bus array. Also start support for converting NSData to D-Bus byte arrays. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/dbuskit/trunk@37531 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
b15241515a
commit
12639b9de3
14
ChangeLog
14
ChangeLog
@ -1,3 +1,17 @@
|
||||
2014-01-01 Niels Grewe <niels.grewe@halbordnung.de>
|
||||
|
||||
* Headers/DKStruct.h
|
||||
* Headers/DBusKit.h
|
||||
* Source/DKStruct.m:
|
||||
Helper class for structure-like arrays. This is needed
|
||||
only for variant typed arguments because these don't
|
||||
carry the introspection information that lets us decide
|
||||
whether something is an array or a D-Bus structure
|
||||
* Source/DKArgument.m:
|
||||
Support explicit structure typed arguments and start
|
||||
working on support for converting from NSData to D-Bus
|
||||
byte arrays.
|
||||
|
||||
2013-12-30 Niels Grewe <niels.grewe@halbordnung.de>
|
||||
|
||||
* Source/DKMethod.m
|
||||
|
@ -24,3 +24,4 @@
|
||||
#import <DBusKit/DKPort.h>
|
||||
#import <DBusKit/DKProxy.h>
|
||||
#import <DBusKit/NSConnection+DBus.h>
|
||||
#import <DBusKit/DKStruct.h>
|
||||
|
52
Headers/DKStruct.h
Normal file
52
Headers/DKStruct.h
Normal file
@ -0,0 +1,52 @@
|
||||
/** Interface for collection classes that are boxed as D-Bus structures
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Niels Grewe <niels.grewe@halbordnung.de>
|
||||
Created: January 2014
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
|
||||
/**
|
||||
* The DKStruct protocol should be adopted by all collection classes
|
||||
* that are required to be converted to D-Bus structures. A default
|
||||
* implementation is provided for NSArray, which just returns NO.
|
||||
* The object also needs to implement -objectEnumerator.
|
||||
*/
|
||||
@protocol DKStruct
|
||||
/**
|
||||
* Return YES from this method if the D-Bus representation of the
|
||||
* receiver should be a struct instead of an array.
|
||||
*/
|
||||
- (BOOL)isDBusStruct;
|
||||
@end
|
||||
|
||||
@interface NSArray (DBusKit) <DKStruct>
|
||||
@end
|
||||
|
||||
@interface DKStructArray : NSArray
|
||||
{
|
||||
NSArray *backingStore;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface DKMutableStructArray : NSMutableArray
|
||||
{
|
||||
NSMutableArray *backingStore;
|
||||
}
|
||||
@end
|
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSData.h>
|
||||
#import <Foundation/NSDebug.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSException.h>
|
||||
@ -48,6 +49,8 @@
|
||||
#import "DKArgument.h"
|
||||
#import "DKBoxingUtils.h"
|
||||
|
||||
#import "DBusKit/DKStruct.h"
|
||||
|
||||
#define INCLUDE_RUNTIME_H
|
||||
#include "config.h"
|
||||
#undef INCLUDE_RUNTIME_H
|
||||
@ -1660,31 +1663,54 @@ DKDBusTypeForUnboxingObject(id object)
|
||||
{
|
||||
object = [NSArray array];
|
||||
}
|
||||
NSAssert1([object respondsToSelector: @selector(objectEnumerator)],
|
||||
@"Cannot enumerate contents of %@ when creating D-Bus array.",
|
||||
object);
|
||||
if (DBUS_TYPE_BYTE != [theChild DBusType])
|
||||
{
|
||||
NSAssert1([object respondsToSelector: @selector(objectEnumerator)],
|
||||
@"Cannot enumerate contents of %@ when creating D-Bus array.",
|
||||
object);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSAssert1(([object respondsToSelector: @selector(objectEnumerator)] ||
|
||||
[object isKindOfClass: [NSData class]]),
|
||||
@"Cannot enumerate contents of %@ when creating D-Bus array.",
|
||||
object
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
DK_ITER_OPEN_CONTAINER(iter, DBUS_TYPE_ARRAY, [[theChild DBusTypeSignature] UTF8String], &subIter);
|
||||
|
||||
elementEnum = [object objectEnumerator];
|
||||
NS_DURING
|
||||
{
|
||||
while (nil != (element = [elementEnum nextObject]))
|
||||
{
|
||||
[theChild marshallObject: element
|
||||
intoIterator: &subIter];
|
||||
if ([object respondsToSelector: @selector(objectEnumerator)])
|
||||
{
|
||||
elementEnum = [object objectEnumerator];
|
||||
while (nil != (element = [elementEnum nextObject]))
|
||||
{
|
||||
[theChild marshallObject: element
|
||||
intoIterator: &subIter];
|
||||
|
||||
}
|
||||
}
|
||||
else if ([object isKindOfClass: [NSData class]])
|
||||
{
|
||||
NSUInteger len = [object length];
|
||||
const void *bytes = [object bytes];
|
||||
NSUInteger pos = 0;
|
||||
for (pos = 0; pos < len; pos++)
|
||||
{
|
||||
DK_ITER_APPEND(&subIter, DBUS_TYPE_BYTE, bytes++);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
// We are already screwed and don't care whether
|
||||
// dbus_message_iter_close_container() returns OOM.
|
||||
dbus_message_iter_close_container(iter, &subIter);
|
||||
[localException raise];
|
||||
}
|
||||
{
|
||||
// We are already screwed and don't care whether
|
||||
// dbus_message_iter_close_container() returns OOM.
|
||||
dbus_message_iter_close_container(iter, &subIter);
|
||||
[localException raise];
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
|
||||
DK_ITER_CLOSE_CONTAINER(iter, &subIter);
|
||||
}
|
||||
@end
|
||||
@ -1833,7 +1859,7 @@ DKDBusTypeForUnboxingObject(id object)
|
||||
@implementation DKStructTypeArgument
|
||||
-(id) unmarshalledObjectFromIterator: (DBusMessageIter*)iter
|
||||
{
|
||||
NSMutableArray *theArray = [NSMutableArray new];
|
||||
DKMutableStructArray *theArray = [DKMutableStructArray new];
|
||||
NSArray *returnArray = nil;
|
||||
NSNull *theNull = [NSNull null];
|
||||
NSUInteger index = 0;
|
||||
@ -1916,34 +1942,54 @@ DKDBusTypeForUnboxingObject(id object)
|
||||
* keys/values. This can only be a proper signature if all elements are of the
|
||||
* same type. Otherwise, the variant type will be returned.
|
||||
*/
|
||||
- (NSString*)validSubSignatureOrVariantForEnumerator: (NSEnumerator*)theEnum
|
||||
- (NSString*)subSignatureForEnumerator: (NSEnumerator*)theEnum
|
||||
forStruct: (BOOL)isStruct
|
||||
{
|
||||
id element = [theEnum nextObject];
|
||||
NSString *thisSig = [[self DKArgumentWithObject: element] DBusTypeSignature];
|
||||
NSString *nextSig = thisSig;
|
||||
|
||||
NSMutableString *allTypes = [NSMutableString stringWithString: thisSig];
|
||||
// For homogenous collection, we can get the proper signature, for non-homogenous
|
||||
// ones, we need to pass down the variant type.
|
||||
// ones, we need to pass down the variant type if it's not a signature for a struct.
|
||||
BOOL isHomogenous = YES;
|
||||
if (nil == element)
|
||||
{
|
||||
thisSig = @"v";
|
||||
}
|
||||
while ((nil != (element = [theEnum nextObject]))
|
||||
&& (YES == isHomogenous))
|
||||
{
|
||||
thisSig = nextSig;
|
||||
nextSig = [[self DKArgumentWithObject: element] DBusTypeSignature];
|
||||
isHomogenous = [thisSig isEqualToString: nextSig];
|
||||
[allTypes appendString: nextSig];
|
||||
if (isStruct == NO)
|
||||
{
|
||||
isHomogenous = [thisSig isEqualToString: nextSig];
|
||||
}
|
||||
}
|
||||
|
||||
if (isHomogenous)
|
||||
{
|
||||
return thisSig;
|
||||
}
|
||||
else
|
||||
{
|
||||
return @"v";
|
||||
}
|
||||
if (NO == isStruct)
|
||||
{
|
||||
if (isHomogenous)
|
||||
{
|
||||
return thisSig;
|
||||
}
|
||||
else
|
||||
{
|
||||
return @"v";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return allTypes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (NSString*)validSubSignatureOrVariantForEnumerator: (NSEnumerator*)theEnum
|
||||
{
|
||||
return [self subSignatureForEnumerator: theEnum forStruct: NO];
|
||||
}
|
||||
- (DKArgument*) DKArgumentWithObject: (id)object
|
||||
{
|
||||
if (([object respondsToSelector: @selector(keyEnumerator)])
|
||||
@ -1972,8 +2018,19 @@ DKDBusTypeForUnboxingObject(id object)
|
||||
else if ([object respondsToSelector: @selector(objectEnumerator)])
|
||||
{
|
||||
NSEnumerator *theEnum = [object objectEnumerator];
|
||||
NSString *subSig = [self validSubSignatureOrVariantForEnumerator: theEnum];
|
||||
return [[[DKArgument alloc] initWithDBusSignature: [[@"a" stringByAppendingString: subSig] UTF8String]
|
||||
NSString *signature = nil;
|
||||
if ([object respondsToSelector: @selector(isDBusStruct)]
|
||||
&& [object isDBusStruct])
|
||||
{
|
||||
NSString *subSig = [self subSignatureForEnumerator: theEnum forStruct: YES];
|
||||
signature = [NSString stringWithFormat: @"(%@)", subSig];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSString *subSig = [self validSubSignatureOrVariantForEnumerator: theEnum];
|
||||
signature = [NSString stringWithFormat: @"a%@", subSig];
|
||||
}
|
||||
return [[[DKArgument alloc] initWithDBusSignature: [signature UTF8String]
|
||||
name: nil
|
||||
parent: self] autorelease];
|
||||
}
|
||||
@ -1987,6 +2044,13 @@ DKDBusTypeForUnboxingObject(id object)
|
||||
parent: self] autorelease];
|
||||
}
|
||||
}
|
||||
else if ([object isKindOfClass: [NSData class]])
|
||||
{
|
||||
return [[[DKArgument alloc] initWithDBusSignature: "ay"
|
||||
name: nil
|
||||
parent: self] autorelease];
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Simple types are quite straightforward, if we can find an appropriate
|
||||
|
146
Source/DKStruct.m
Normal file
146
Source/DKStruct.m
Normal file
@ -0,0 +1,146 @@
|
||||
/** Categories on NSArray so that it's boxed as D-Bus structures
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Niels Grewe <niels.grewe@halbordnung.de>
|
||||
Created: January 2014
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#import "DBusKit/DKStruct.h"
|
||||
|
||||
@implementation NSArray (DBusKit)
|
||||
- (BOOL)isDBusStruct
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation DKStructArray
|
||||
- (BOOL)isDBusStruct
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id) initWithObjects: (const id[])objects count: (NSUInteger)count
|
||||
{
|
||||
// Special case, class cluster: No super init
|
||||
backingStore = [[NSArray alloc] initWithObjects: objects count: count];
|
||||
if (nil == backingStore)
|
||||
{
|
||||
DESTROY(self);
|
||||
return nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSUInteger)count
|
||||
{
|
||||
return [backingStore count];
|
||||
}
|
||||
|
||||
- (id)objectAtIndex: (NSUInteger)index
|
||||
{
|
||||
return [backingStore objectAtIndex: index];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
DESTROY(backingStore);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state
|
||||
objects:(id *)stackbuf
|
||||
count:(NSUInteger)len
|
||||
{
|
||||
return [backingStore countByEnumeratingWithState: state
|
||||
objects: stackbuf
|
||||
count: len];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation DKMutableStructArray
|
||||
- (BOOL)isDBusStruct
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id) initWithCapacity: (NSUInteger)count
|
||||
{
|
||||
// Special case, class cluster: No super init
|
||||
backingStore = [[NSMutableArray alloc] initWithCapacity: count];
|
||||
if (nil == backingStore)
|
||||
{
|
||||
DESTROY(self);
|
||||
return nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSUInteger)count
|
||||
{
|
||||
return [backingStore count];
|
||||
}
|
||||
|
||||
- (id)objectAtIndex: (NSUInteger)index
|
||||
{
|
||||
return [backingStore objectAtIndex: index];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
DESTROY(backingStore);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state
|
||||
objects:(id *)stackbuf
|
||||
count:(NSUInteger)len
|
||||
{
|
||||
return [backingStore countByEnumeratingWithState: state
|
||||
objects: stackbuf
|
||||
count: len];
|
||||
}
|
||||
|
||||
- (void)insertObject: (id)obj atIndex: (NSUInteger)idx
|
||||
{
|
||||
[backingStore insertObject: obj atIndex: idx];
|
||||
}
|
||||
|
||||
- (void)removeObjectAtIndex: (NSUInteger)idx
|
||||
{
|
||||
[backingStore removeObjectAtIndex: idx];
|
||||
}
|
||||
|
||||
- (void)addObject: (id)obj
|
||||
{
|
||||
[backingStore addObject: obj];
|
||||
}
|
||||
|
||||
- (void)removeLastObject
|
||||
{
|
||||
[backingStore removeLastObject];
|
||||
}
|
||||
|
||||
|
||||
- (void)replaceObjectAtIndex: (NSUInteger)idx withObject: (id)obj
|
||||
{
|
||||
[backingStore replaceObjectAtIndex: idx withObject: obj];
|
||||
}
|
||||
|
||||
@end
|
@ -19,6 +19,7 @@ DBusKit_HEADER_FILES = \
|
||||
DKPort.h \
|
||||
DKPortNameServer.h \
|
||||
DKProxy.h \
|
||||
DKStruct.h \
|
||||
NSConnection+DBus.h
|
||||
#
|
||||
# Class files
|
||||
@ -45,6 +46,7 @@ DBusKit_OBJC_FILES = \
|
||||
DKPropertyMethod.m \
|
||||
DKProxy.m \
|
||||
DKSignal.m \
|
||||
DKStruct.m \
|
||||
NSConnection+DBus.m
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user