2 Copyright (C) 2000-2003 SKYRIX Software AG
4 This file is part of OGo
6 OGo is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with OGo; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 #include "NGXmlRpcInvocation.h"
24 #include "NGXmlRpcMethodSignature.h"
25 #include "NGXmlRpcClient.h"
28 @implementation NGXmlRpcInvocation
30 static NSNull *null = nil;
35 if (self->arguments) return;
36 if (self->signature == nil) return;
37 if (null == nil) null = [[NSNull null] retain];
39 count = [self->signature numberOfArguments];
41 self->arguments = [[NSMutableArray alloc] initWithCapacity:count];
42 for (i = 0; i < count; i++)
43 [self->arguments addObject:null];
46 - (id)initWithMethodSignature:(NGXmlRpcMethodSignature *)_sig {
52 self->signature = RETAIN(_sig);
58 return [self initWithMethodSignature:nil];
62 RELEASE(self->arguments);
63 RELEASE(self->result);
64 RELEASE(self->target);
65 RELEASE(self->methodName);
66 RELEASE(self->signature);
72 - (NGXmlRpcMethodSignature *)methodSignature {
73 return self->signature;
76 - (void)setArgument:(id)_argument atIndex:(int)_idx {
77 if (_argument == nil) _argument = null;
78 [self->arguments replaceObjectAtIndex:_idx withObject:_argument];
80 - (id)argumentAtIndex:(int)_idx {
83 res = [self->arguments objectAtIndex:_idx];
84 if (res == null) res = nil;
88 - (void)setTarget:(NGXmlRpcClient *)_target {
89 ASSIGN(self->target, _target);
91 - (NGXmlRpcClient *)target {
95 - (void)setMethodName:(NSString *)_name {
96 ASSIGNCOPY(self->methodName, _name);
98 - (NSString *)methodName {
99 return self->methodName;
102 - (void)setReturnValue:(id)_result {
103 ASSIGN(self->result, _result);
109 /* Dispatching an Invocation */
112 [self invokeWithTarget:[self target]];
115 - (void)invokeWithTarget:(NGXmlRpcClient *)_target {
116 NSAutoreleasePool *pool;
118 pool = [[NSAutoreleasePool alloc] init];
123 NGXmlRpcMethodSignature *sig;
125 sig = [self methodSignature];
127 /* collect arguments, coerce types ... */
128 if ((count = [self->arguments count]) == 0)
129 args = self->arguments;
134 aa = calloc(count, sizeof(id));
135 for (i = 0; i < count; i++) {
139 xrtype = [sig argumentTypeAtIndex:i];
141 value = [self->arguments objectAtIndex:i];
142 value = [value asXmlRpcValueOfType:xrtype];
143 aa[i] = value ? value : null;
145 args = [NSArray arrayWithObjects:aa count:count];
149 args = self->arguments;
151 /* invoke remote method */
152 res = [_target invokeMethodNamed:[self methodName] parameters:args];
154 /* store return value */
155 [self setReturnValue:res];
162 - (void)encodeWithCoder:(NSCoder *)_coder {
163 [_coder encodeObject:self->target];
164 [_coder encodeObject:self->methodName];
165 [_coder encodeObject:self->signature];
166 [_coder encodeObject:self->arguments];
167 [_coder encodeObject:self->result];
169 - (id)initWithCoder:(NSCoder *)_coder {
170 if (null == nil) null = [[NSNull null] retain];
172 self->target = [[_coder decodeObject] retain];
173 self->methodName = [[_coder decodeObject] copy];
174 self->signature = [[_coder decodeObject] retain];
175 self->arguments = [[_coder decodeObject] retain];
176 self->result = [[_coder decodeObject] retain];
178 if (self->signature == nil) {
179 NSLog(@"%s: missing signature (required during decoding)",
180 __PRETTY_FUNCTION__);
189 @end /* NGXmlRpcInvocation */
191 @implementation NSObject(XmlRpcValue)
193 - (NSArray *)asXmlRpcArray {
194 if ([self respondsToSelector:@selector(objectEnumerator)]) {
195 return [[[NSArray alloc]
196 initWithObjectsFromEnumerator:
197 [(id)self objectEnumerator]]
203 - (NSDictionary *)asXmlRpcStruct {
204 return [self valuesForKeys:[[self classDescription] attributeKeys]];
207 - (NSString *)asXmlRpcString {
208 return [self stringValue];
211 return [self intValue];
213 - (int)asXmlRpcDouble {
214 return [self doubleValue];
217 - (NSData *)asXmlRpcBase64 {
218 return [[self stringValue] dataUsingEncoding:NSUTF8StringEncoding];
220 - (NSDate *)asXmlRpcDateTime {
221 return [[[NSDate alloc] initWithString:[self stringValue]] autorelease];
224 - (id)asXmlRpcValueOfType:(NSString *)_xmlRpcValueType {
227 if ((len = [_xmlRpcValueType length]) == 0)
230 if ([_xmlRpcValueType isEqualToString:@"string"])
231 return [self asXmlRpcString];
232 if ([_xmlRpcValueType isEqualToString:@"int"])
233 return [NSNumber numberWithInt:[self asXmlRpcInt]];
234 if ([_xmlRpcValueType isEqualToString:@"i4"])
235 return [NSNumber numberWithInt:[self asXmlRpcInt]];
236 if ([_xmlRpcValueType isEqualToString:@"double"])
237 return [NSNumber numberWithDouble:[self asXmlRpcDouble]];
238 if ([_xmlRpcValueType isEqualToString:@"float"])
239 return [NSNumber numberWithDouble:[self asXmlRpcDouble]];
240 if ([_xmlRpcValueType isEqualToString:@"array"])
241 return [self asXmlRpcArray];
242 if ([_xmlRpcValueType isEqualToString:@"struct"])
243 return [self asXmlRpcStruct];
244 if ([_xmlRpcValueType isEqualToString:@"datetime"])
245 return [self asXmlRpcDateTime];
246 if ([_xmlRpcValueType isEqualToString:@"base64"])
247 return [self asXmlRpcBase64];
252 @end /* NSObject(XmlRpcValue) */
254 @implementation NSArray(XmlRpcValue)
256 - (NSArray *)asXmlRpcArray {
260 - (id)asXmlRpcValueOfType:(NSString *)_xmlRpcValueType {
264 @end /* NSArray(XmlRpcValue) */
266 @implementation NSDictionary(XmlRpcValue)
268 - (NSArray *)asXmlRpcArray {
269 return [self allValues];
272 - (NSDictionary *)asXmlRpcStruct {
276 @end /* NSDictionary(XmlRpcValue) */
278 @implementation NSDate(XmlRpcValue)
280 - (NSDate *)asXmlRpcDateTime {
284 @end /* NSDate(XmlRpcValue) */
286 @implementation NSData(XmlRpcValue)
288 - (NSData *)asXmlRpcBase64 {
292 @end /* NSCalendarDate(XmlRpcValue) */