Allow D-Bus byte-typed arrays to be unmarshalled as NSData objects. We don't

do that by default (whether an array of byte-sized values is conceptually an
array or a blob of data is not always obvious, so the plain D-Bus introspection
data is not expressive enough) but only if the argument is annotated as being 
of the Objective-C class "NSData" (that's already supported by the libclang
based introspection interface)

Test cases pending.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/dbuskit/trunk@37534 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Niels Grewe 2014-01-04 15:24:36 +00:00
parent b471299b3a
commit 85053ffd1e
2 changed files with 62 additions and 1 deletions

View File

@ -1,3 +1,8 @@
2014-01-04 Niels Grewe <niels.grewe@halbordnung.de>
* Source/DKArgument.m: Decode byte arrays as NSData
if the introspection data says we should.
2014-01-01 Niels Grewe <niels.grewe@halbordnung.de>
* Headers/DKStruct.h

View File

@ -1620,17 +1620,73 @@ DKDBusTypeForUnboxingObject(id object)
@"Type mismatch between D-Bus message and introspection data.");
}
- (NSData*)dataFromSubIter: (DBusMessageIter*)iter
{
uint8_t bytes[128];
NSMutableData *data = [NSMutableData new];
NSData *returnData = nil;
NSUInteger idx = 0;
do
{
if (0 == dbus_message_iter_get_arg_type(iter))
{
// If we opened an empty iterator, we just break from the loop
break;
}
else if (DBUS_TYPE_BYTE != dbus_message_iter_get_arg_type(iter))
{
//Very bad, should never happen, but it would trash the stack
// if it did, so we protect against it.
[data release];
[NSException raise: @"DKInternalInconsistencyException"
format: @"Mistyped array iterator"];
}
NSUInteger offset = idx++ % 128;
dbus_message_iter_get_basic(iter, (void*)(&bytes[0] + offset));
// We filled the last byte of the on stack buffer, so we
if (127 == offset)
{
[data appendBytes: &bytes[0] length: 128];
}
} while (dbus_message_iter_next(iter));
// We dropped out of the loop after we incremented the running idx
// so idx % 128 will now be at offset + 1, which is the length we
// used off of our on stack buffer
NSUInteger len = idx % 128;
if (0 != len)
{
[data appendBytes: &bytes[0] length: len];
}
returnData = [NSData dataWithData: data];
[data release];
return data;
}
-(id) unmarshalledObjectFromIterator: (DBusMessageIter*)iter
{
DKArgument *theChild = [self elementTypeArgument];
DBusMessageIter subIter;
NSMutableArray *theArray = [NSMutableArray new];
NSString *className = [self annotationValueForKey: @"org.gnustep.objc.class"];
BOOL returnAsNSData = NO;
// Check whether we are decoding a byte array that has been anotated as being
// an NSData instance
if ((DBUS_TYPE_BYTE == [theChild DBusType]) &&
([NSClassFromString(className) isSubclassOfClass: [NSData class]]))
{
returnAsNSData = YES;
}
NSMutableArray *theArray = (returnAsNSData) ? nil : [NSMutableArray new];
NSArray *returnArray = nil;
NSNull *theNull = [NSNull null];
[self assertSaneIterator: iter];
dbus_message_iter_recurse(iter, &subIter);
if (returnAsNSData)
{
return [self dataFromSubIter: &subIter];
}
do
{
id obj = nil;