2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE 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 SOPE 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 SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #include "NGXmlRpcInvocation.h"
23 #include "NGXmlRpcMethodSignature.h"
24 #include "NGXmlRpcClient.h"
27 @implementation NGXmlRpcInvocation
29 static NSNull *null = nil;
34 if (self->arguments) return;
35 if (self->signature == nil) return;
36 if (null == nil) null = [[NSNull null] retain];
38 count = [self->signature numberOfArguments];
40 self->arguments = [[NSMutableArray alloc] initWithCapacity:count];
41 for (i = 0; i < count; i++)
42 [self->arguments addObject:null];
45 - (id)initWithMethodSignature:(NGXmlRpcMethodSignature *)_sig {
51 self->signature = RETAIN(_sig);
57 return [self initWithMethodSignature:nil];
61 RELEASE(self->arguments);
62 RELEASE(self->result);
63 RELEASE(self->target);
64 RELEASE(self->methodName);
65 RELEASE(self->signature);
71 - (NGXmlRpcMethodSignature *)methodSignature {
72 return self->signature;
75 - (void)setArgument:(id)_argument atIndex:(int)_idx {
76 if (_argument == nil) _argument = null;
77 [self->arguments replaceObjectAtIndex:_idx withObject:_argument];
79 - (id)argumentAtIndex:(int)_idx {
82 res = [self->arguments objectAtIndex:_idx];
83 if (res == null) res = nil;
87 - (void)setTarget:(NGXmlRpcClient *)_target {
88 ASSIGN(self->target, _target);
90 - (NGXmlRpcClient *)target {
94 - (void)setMethodName:(NSString *)_name {
95 ASSIGNCOPY(self->methodName, _name);
97 - (NSString *)methodName {
98 return self->methodName;
101 - (void)setReturnValue:(id)_result {
102 ASSIGN(self->result, _result);
108 /* Dispatching an Invocation */
111 [self invokeWithTarget:[self target]];
114 - (void)invokeWithTarget:(NGXmlRpcClient *)_target {
115 NSAutoreleasePool *pool;
117 pool = [[NSAutoreleasePool alloc] init];
122 NGXmlRpcMethodSignature *sig;
124 sig = [self methodSignature];
126 /* collect arguments, coerce types ... */
127 if ((count = [self->arguments count]) == 0)
128 args = self->arguments;
133 aa = calloc(count, sizeof(id));
134 for (i = 0; i < count; i++) {
138 xrtype = [sig argumentTypeAtIndex:i];
140 value = [self->arguments objectAtIndex:i];
141 value = [value asXmlRpcValueOfType:xrtype];
142 aa[i] = value ? value : null;
144 args = [NSArray arrayWithObjects:aa count:count];
148 args = self->arguments;
150 /* invoke remote method */
151 res = [_target invokeMethodNamed:[self methodName] parameters:args];
153 /* store return value */
154 [self setReturnValue:res];
161 - (void)encodeWithCoder:(NSCoder *)_coder {
162 [_coder encodeObject:self->target];
163 [_coder encodeObject:self->methodName];
164 [_coder encodeObject:self->signature];
165 [_coder encodeObject:self->arguments];
166 [_coder encodeObject:self->result];
168 - (id)initWithCoder:(NSCoder *)_coder {
169 if (null == nil) null = [[NSNull null] retain];
171 self->target = [[_coder decodeObject] retain];
172 self->methodName = [[_coder decodeObject] copy];
173 self->signature = [[_coder decodeObject] retain];
174 self->arguments = [[_coder decodeObject] retain];
175 self->result = [[_coder decodeObject] retain];
177 if (self->signature == nil) {
178 NSLog(@"%s: missing signature (required during decoding)",
179 __PRETTY_FUNCTION__);
188 @end /* NGXmlRpcInvocation */
190 @implementation NSObject(XmlRpcValue)
192 - (NSArray *)asXmlRpcArray {
193 if ([self respondsToSelector:@selector(objectEnumerator)]) {
194 return [[[NSArray alloc]
195 initWithObjectsFromEnumerator:
196 [(id)self objectEnumerator]]
202 - (NSDictionary *)asXmlRpcStruct {
203 return [self valuesForKeys:[[self classDescription] attributeKeys]];
206 - (NSString *)asXmlRpcString {
207 return [self stringValue];
210 return [self intValue];
212 - (int)asXmlRpcDouble {
213 return [self doubleValue];
216 - (NSData *)asXmlRpcBase64 {
217 return [[self stringValue] dataUsingEncoding:NSUTF8StringEncoding];
219 - (NSDate *)asXmlRpcDateTime {
220 return [[[NSDate alloc] initWithString:[self stringValue]] autorelease];
223 - (id)asXmlRpcValueOfType:(NSString *)_xmlRpcValueType {
226 if ((len = [_xmlRpcValueType length]) == 0)
229 if ([_xmlRpcValueType isEqualToString:@"string"])
230 return [self asXmlRpcString];
231 if ([_xmlRpcValueType isEqualToString:@"int"])
232 return [NSNumber numberWithInt:[self asXmlRpcInt]];
233 if ([_xmlRpcValueType isEqualToString:@"i4"])
234 return [NSNumber numberWithInt:[self asXmlRpcInt]];
235 if ([_xmlRpcValueType isEqualToString:@"double"])
236 return [NSNumber numberWithDouble:[self asXmlRpcDouble]];
237 if ([_xmlRpcValueType isEqualToString:@"float"])
238 return [NSNumber numberWithDouble:[self asXmlRpcDouble]];
239 if ([_xmlRpcValueType isEqualToString:@"array"])
240 return [self asXmlRpcArray];
241 if ([_xmlRpcValueType isEqualToString:@"struct"])
242 return [self asXmlRpcStruct];
243 if ([_xmlRpcValueType isEqualToString:@"datetime"])
244 return [self asXmlRpcDateTime];
245 if ([_xmlRpcValueType isEqualToString:@"base64"])
246 return [self asXmlRpcBase64];
251 @end /* NSObject(XmlRpcValue) */
253 @implementation NSArray(XmlRpcValue)
255 - (NSArray *)asXmlRpcArray {
259 - (id)asXmlRpcValueOfType:(NSString *)_xmlRpcValueType {
263 @end /* NSArray(XmlRpcValue) */
265 @implementation NSDictionary(XmlRpcValue)
267 - (NSArray *)asXmlRpcArray {
268 return [self allValues];
271 - (NSDictionary *)asXmlRpcStruct {
275 @end /* NSDictionary(XmlRpcValue) */
277 @implementation NSDate(XmlRpcValue)
279 - (NSDate *)asXmlRpcDateTime {
283 @end /* NSDate(XmlRpcValue) */
285 @implementation NSData(XmlRpcValue)
287 - (NSData *)asXmlRpcBase64 {
291 @end /* NSCalendarDate(XmlRpcValue) */