├── .gitignore ├── Configurations ├── Common.xcconfig ├── CommonDevelopment.xcconfig ├── CommonRelease.xcconfig ├── XMLRPC.xcconfig ├── XMLRPCDevelopment.xcconfig ├── XMLRPCRelease.xcconfig ├── XMLRPCUnitTests.xcconfig ├── XMLRPCUnitTestsDevelopment.xcconfig └── XMLRPCUnitTestsRelease.xcconfig ├── LICENSE.md ├── Languages └── English.lproj │ └── InfoPlist.strings ├── NSData+Base64.h ├── NSData+Base64.m ├── NSStringAdditions.h ├── NSStringAdditions.m ├── README.md ├── Resources ├── Property Lists │ ├── TestCases.plist │ ├── XMLRPC-Info.plist │ └── XMLRPCUnitTests-Info.plist └── Test Cases │ ├── AlternativeDateFormatsTestCase.xml │ ├── DefaultTypeTestCase.xml │ ├── EmptyBooleanTestCase.xml │ ├── EmptyDataTestCase.xml │ ├── EmptyDoubleTestCase.xml │ ├── EmptyIntegerTestCase.xml │ ├── EmptyStringTestCase.xml │ ├── SimpleArrayTestCase.xml │ └── SimpleStructTestCase.xml ├── Tools ├── Test Client │ ├── Configurations │ │ ├── Common.xcconfig │ │ ├── CommonDevelopment.xcconfig │ │ ├── CommonRelease.xcconfig │ │ ├── TestClient.xcconfig │ │ ├── TestClientDevelopment.xcconfig │ │ └── TestClientRelease.xcconfig │ ├── Languages │ │ └── English.lproj │ │ │ ├── InfoPlist.strings │ │ │ ├── TestClient.xib │ │ │ ├── TestClientMainWindow.xib │ │ │ └── TestClientXMLParserWindow.xib │ ├── Test Client.xcodeproj │ │ └── project.pbxproj │ ├── TestClient-Info.plist │ ├── TestClient.pch │ ├── TestClientApplicationController.h │ ├── TestClientApplicationController.m │ ├── TestClientMainWindowController.h │ ├── TestClientMainWindowController.m │ ├── TestClientXMLParserWindowController.h │ ├── TestClientXMLParserWindowController.m │ └── main.m └── Test Server │ ├── README.md │ ├── build.properties │ ├── build.xml │ ├── lib │ ├── commons-logging-1.1.1.jar │ ├── log4j-1.2.15.jar │ ├── ws-commons-util-1.0.2.jar │ ├── xmlrpc-common-3.1.jar │ └── xmlrpc-server-3.1.jar │ ├── resources │ ├── handlers.properties │ └── log4j.xml │ ├── server.sh │ └── src │ └── com │ └── divisiblebyzero │ └── xmlrpc │ ├── Application.java │ ├── controller │ └── XmlRpcServerControlPanelController.java │ ├── model │ ├── Server.java │ └── handlers │ │ └── Echo.java │ └── view │ └── XmlRpcServerControlPanel.java ├── Unit Tests ├── XMLRPCParserTest.h └── XMLRPCParserTest.m ├── XMLRPC.h ├── XMLRPC.pch ├── XMLRPC.xcodeproj └── project.pbxproj ├── XMLRPCConnection.h ├── XMLRPCConnection.m ├── XMLRPCConnectionDelegate.h ├── XMLRPCConnectionManager.h ├── XMLRPCConnectionManager.m ├── XMLRPCDefaultEncoder.h ├── XMLRPCDefaultEncoder.m ├── XMLRPCEncoder.h ├── XMLRPCEventBasedParser.h ├── XMLRPCEventBasedParser.m ├── XMLRPCEventBasedParserDelegate.h ├── XMLRPCEventBasedParserDelegate.m ├── XMLRPCRequest.h ├── XMLRPCRequest.m ├── XMLRPCResponse.h └── XMLRPCResponse.m /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .DS_Store 3 | .project 4 | *.jar 5 | *.mode1v3 6 | *.mode1 7 | *.mode2 8 | *.pbxuser 9 | *.perspectivev3 10 | *.xcworkspace 11 | build/ 12 | classes/ 13 | logs/ 14 | xcuserdata/ 15 | -------------------------------------------------------------------------------- /Configurations/Common.xcconfig: -------------------------------------------------------------------------------- 1 | ARCHS = $(ARCHS_STANDARD_32_64_BIT) 2 | VALID_ARCHS = i386 ppc x86_64 3 | SDKROOT = macosx 4 | 5 | RUN_CLANG_STATIC_ANALYZER = YES 6 | 7 | GCC_C_LANGUAGE_STANDARD = gnu99 8 | GCC_PRECOMPILE_PREFIX_HEADER = YES 9 | 10 | GCC_WARN_ABOUT_MISSING_NEWLINE = YES 11 | GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = YES 12 | GCC_WARN_ABOUT_RETURN_TYPE = YES 13 | GCC_WARN_UNUSED_VARIABLE = YES 14 | GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO 15 | GCC_TREAT_WARNINGS_AS_ERRORS = YES 16 | -------------------------------------------------------------------------------- /Configurations/CommonDevelopment.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Common.xcconfig" 2 | 3 | DEBUG_INFORMATION_FORMAT = dwarf 4 | 5 | GCC_DYNAMIC_NO_PIC = NO 6 | GCC_OPTIMIZATION_LEVEL = 0 7 | -------------------------------------------------------------------------------- /Configurations/CommonRelease.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Common.xcconfig" 2 | 3 | DEBUG_INFORMATION_FORMAT = dwarf-with-dsym 4 | -------------------------------------------------------------------------------- /Configurations/XMLRPC.xcconfig: -------------------------------------------------------------------------------- 1 | PRODUCT_NAME = XMLRPC 2 | INFOPLIST_FILE = Resources/Property Lists/XMLRPC-Info.plist 3 | 4 | FRAMEWORK_VERSION = A 5 | DYLIB_CURRENT_VERSION = 1 6 | DYLIB_COMPATIBILITY_VERSION = 1 7 | 8 | GCC_PRECOMPILE_PREFIX_HEADER = YES 9 | GCC_PREFIX_HEADER = XMLRPC.pch 10 | 11 | INSTALL_PATH = @loader_path/../Frameworks 12 | -------------------------------------------------------------------------------- /Configurations/XMLRPCDevelopment.xcconfig: -------------------------------------------------------------------------------- 1 | #include "XMLRPC.xcconfig" 2 | #include "CommonDevelopment.xcconfig" 3 | -------------------------------------------------------------------------------- /Configurations/XMLRPCRelease.xcconfig: -------------------------------------------------------------------------------- 1 | #include "XMLRPC.xcconfig" 2 | #include "CommonRelease.xcconfig" 3 | -------------------------------------------------------------------------------- /Configurations/XMLRPCUnitTests.xcconfig: -------------------------------------------------------------------------------- 1 | PRODUCT_NAME = XMLRPCUnitTests 2 | INFOPLIST_FILE = Resources/Property Lists/XMLRPCUnitTests-Info.plist 3 | 4 | WRAPPER_EXTENSION=octest 5 | 6 | GCC_PRECOMPILE_PREFIX_HEADER = YES 7 | GCC_PREFIX_HEADER = XMLRPC.pch 8 | -------------------------------------------------------------------------------- /Configurations/XMLRPCUnitTestsDevelopment.xcconfig: -------------------------------------------------------------------------------- 1 | #include "XMLRPCUnitTests.xcconfig" 2 | #include "CommonDevelopment.xcconfig" 3 | -------------------------------------------------------------------------------- /Configurations/XMLRPCUnitTestsRelease.xcconfig: -------------------------------------------------------------------------------- 1 | #include "XMLRPCUnitTests.xcconfig" 2 | #include "CommonRelease.xcconfig" 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # License 2 | 3 | ## The Cocoa XML-RPC Framework is distributed under the MIT License: 4 | 5 | Copyright (c) 2012 Eric Czarny 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /Languages/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikolaykasyanov/xmlrpc/f54c8c970c2296f0a1a3f599a25adb5f85dfc128/Languages/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /NSData+Base64.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+Base64.h 3 | // base64 4 | // 5 | // Created by Matt Gallagher on 2009/06/03. 6 | // Copyright 2009 Matt Gallagher. All rights reserved. 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. Permission is granted to anyone to 11 | // use this software for any purpose, including commercial applications, and to 12 | // alter it and redistribute it freely, subject to the following restrictions: 13 | // 14 | // 1. The origin of this software must not be misrepresented; you must not 15 | // claim that you wrote the original software. If you use this software 16 | // in a product, an acknowledgment in the product documentation would be 17 | // appreciated but is not required. 18 | // 2. Altered source versions must be plainly marked as such, and must not be 19 | // misrepresented as being the original software. 20 | // 3. This notice may not be removed or altered from any source 21 | // distribution. 22 | // 23 | 24 | #import 25 | 26 | void *NewBase64Decode( 27 | const char *inputBuffer, 28 | size_t length, 29 | size_t *outputLength); 30 | 31 | char *NewBase64Encode( 32 | const void *inputBuffer, 33 | size_t length, 34 | bool separateLines, 35 | size_t *outputLength); 36 | 37 | @interface NSData (Base64) 38 | 39 | + (NSData *)dataFromBase64String:(NSString *)aString; 40 | - (NSString *)base64EncodedString; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /NSData+Base64.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+Base64.m 3 | // base64 4 | // 5 | // Created by Matt Gallagher on 2009/06/03. 6 | // Copyright 2009 Matt Gallagher. All rights reserved. 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. Permission is granted to anyone to 11 | // use this software for any purpose, including commercial applications, and to 12 | // alter it and redistribute it freely, subject to the following restrictions: 13 | // 14 | // 1. The origin of this software must not be misrepresented; you must not 15 | // claim that you wrote the original software. If you use this software 16 | // in a product, an acknowledgment in the product documentation would be 17 | // appreciated but is not required. 18 | // 2. Altered source versions must be plainly marked as such, and must not be 19 | // misrepresented as being the original software. 20 | // 3. This notice may not be removed or altered from any source 21 | // distribution. 22 | // 23 | 24 | #import "NSData+Base64.h" 25 | 26 | // 27 | // Mapping from 6 bit pattern to ASCII character. 28 | // 29 | static unsigned char base64EncodeLookup[65] = 30 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 31 | 32 | // 33 | // Definition for "masked-out" areas of the base64DecodeLookup mapping 34 | // 35 | #define xx 65 36 | 37 | // 38 | // Mapping from ASCII character to 6 bit pattern. 39 | // 40 | static unsigned char base64DecodeLookup[256] = 41 | { 42 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 43 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 44 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 62, xx, xx, xx, 63, 45 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, xx, xx, xx, xx, xx, xx, 46 | xx, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 47 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, xx, xx, xx, xx, xx, 48 | xx, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 49 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, xx, xx, xx, xx, xx, 50 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 51 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 52 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 53 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 54 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 55 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 56 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 57 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 58 | }; 59 | 60 | // 61 | // Fundamental sizes of the binary and base64 encode/decode units in bytes 62 | // 63 | #define BINARY_UNIT_SIZE 3 64 | #define BASE64_UNIT_SIZE 4 65 | 66 | // 67 | // NewBase64Decode 68 | // 69 | // Decodes the base64 ASCII string in the inputBuffer to a newly malloced 70 | // output buffer. 71 | // 72 | // inputBuffer - the source ASCII string for the decode 73 | // length - the length of the string or -1 (to specify strlen should be used) 74 | // outputLength - if not-NULL, on output will contain the decoded length 75 | // 76 | // returns the decoded buffer. Must be free'd by caller. Length is given by 77 | // outputLength. 78 | // 79 | void *NewBase64Decode( 80 | const char *inputBuffer, 81 | size_t length, 82 | size_t *outputLength) 83 | { 84 | if (length == -1) 85 | { 86 | length = strlen(inputBuffer); 87 | } 88 | 89 | size_t outputBufferSize = 90 | ((length+BASE64_UNIT_SIZE-1) / BASE64_UNIT_SIZE) * BINARY_UNIT_SIZE; 91 | unsigned char *outputBuffer = (unsigned char *)malloc(outputBufferSize); 92 | 93 | size_t i = 0; 94 | size_t j = 0; 95 | while (i < length) 96 | { 97 | // 98 | // Accumulate 4 valid characters (ignore everything else) 99 | // 100 | unsigned char accumulated[BASE64_UNIT_SIZE]; 101 | size_t accumulateIndex = 0; 102 | while (i < length) 103 | { 104 | unsigned char decode = base64DecodeLookup[inputBuffer[i++]]; 105 | if (decode != xx) 106 | { 107 | accumulated[accumulateIndex] = decode; 108 | accumulateIndex++; 109 | 110 | if (accumulateIndex == BASE64_UNIT_SIZE) 111 | { 112 | break; 113 | } 114 | } 115 | } 116 | 117 | // 118 | // Store the 6 bits from each of the 4 characters as 3 bytes 119 | // 120 | // (Uses improved bounds checking suggested by Alexandre Colucci) 121 | // 122 | if(accumulateIndex >= 2) 123 | outputBuffer[j] = (accumulated[0] << 2) | (accumulated[1] >> 4); 124 | if(accumulateIndex >= 3) 125 | outputBuffer[j + 1] = (accumulated[1] << 4) | (accumulated[2] >> 2); 126 | if(accumulateIndex >= 4) 127 | outputBuffer[j + 2] = (accumulated[2] << 6) | accumulated[3]; 128 | j += accumulateIndex - 1; 129 | } 130 | 131 | if (outputLength) 132 | { 133 | *outputLength = j; 134 | } 135 | return outputBuffer; 136 | } 137 | 138 | // 139 | // NewBase64Encode 140 | // 141 | // Encodes the arbitrary data in the inputBuffer as base64 into a newly malloced 142 | // output buffer. 143 | // 144 | // inputBuffer - the source data for the encode 145 | // length - the length of the input in bytes 146 | // separateLines - if zero, no CR/LF characters will be added. Otherwise 147 | // a CR/LF pair will be added every 64 encoded chars. 148 | // outputLength - if not-NULL, on output will contain the encoded length 149 | // (not including terminating 0 char) 150 | // 151 | // returns the encoded buffer. Must be free'd by caller. Length is given by 152 | // outputLength. 153 | // 154 | char *NewBase64Encode( 155 | const void *buffer, 156 | size_t length, 157 | bool separateLines, 158 | size_t *outputLength) 159 | { 160 | const unsigned char *inputBuffer = (const unsigned char *)buffer; 161 | 162 | #define MAX_NUM_PADDING_CHARS 2 163 | #define OUTPUT_LINE_LENGTH 64 164 | #define INPUT_LINE_LENGTH ((OUTPUT_LINE_LENGTH / BASE64_UNIT_SIZE) * BINARY_UNIT_SIZE) 165 | #define CR_LF_SIZE 2 166 | 167 | // 168 | // Byte accurate calculation of final buffer size 169 | // 170 | size_t outputBufferSize = 171 | ((length / BINARY_UNIT_SIZE) 172 | + ((length % BINARY_UNIT_SIZE) ? 1 : 0)) 173 | * BASE64_UNIT_SIZE; 174 | if (separateLines) 175 | { 176 | outputBufferSize += 177 | (outputBufferSize / OUTPUT_LINE_LENGTH) * CR_LF_SIZE; 178 | } 179 | 180 | // 181 | // Include space for a terminating zero 182 | // 183 | outputBufferSize += 1; 184 | 185 | // 186 | // Allocate the output buffer 187 | // 188 | char *outputBuffer = (char *)malloc(outputBufferSize); 189 | if (!outputBuffer) 190 | { 191 | return NULL; 192 | } 193 | 194 | size_t i = 0; 195 | size_t j = 0; 196 | const size_t lineLength = separateLines ? INPUT_LINE_LENGTH : length; 197 | size_t lineEnd = lineLength; 198 | 199 | while (true) 200 | { 201 | if (lineEnd > length) 202 | { 203 | lineEnd = length; 204 | } 205 | 206 | for (; i + BINARY_UNIT_SIZE - 1 < lineEnd; i += BINARY_UNIT_SIZE) 207 | { 208 | // 209 | // Inner loop: turn 48 bytes into 64 base64 characters 210 | // 211 | outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0xFC) >> 2]; 212 | outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i] & 0x03) << 4) 213 | | ((inputBuffer[i + 1] & 0xF0) >> 4)]; 214 | outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i + 1] & 0x0F) << 2) 215 | | ((inputBuffer[i + 2] & 0xC0) >> 6)]; 216 | outputBuffer[j++] = base64EncodeLookup[inputBuffer[i + 2] & 0x3F]; 217 | } 218 | 219 | if (lineEnd == length) 220 | { 221 | break; 222 | } 223 | 224 | // 225 | // Add the newline 226 | // 227 | outputBuffer[j++] = '\r'; 228 | outputBuffer[j++] = '\n'; 229 | lineEnd += lineLength; 230 | } 231 | 232 | if (i + 1 < length) 233 | { 234 | // 235 | // Handle the single '=' case 236 | // 237 | outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0xFC) >> 2]; 238 | outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i] & 0x03) << 4) 239 | | ((inputBuffer[i + 1] & 0xF0) >> 4)]; 240 | outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i + 1] & 0x0F) << 2]; 241 | outputBuffer[j++] = '='; 242 | } 243 | else if (i < length) 244 | { 245 | // 246 | // Handle the double '=' case 247 | // 248 | outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0xFC) >> 2]; 249 | outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0x03) << 4]; 250 | outputBuffer[j++] = '='; 251 | outputBuffer[j++] = '='; 252 | } 253 | outputBuffer[j] = 0; 254 | 255 | // 256 | // Set the output length and return the buffer 257 | // 258 | if (outputLength) 259 | { 260 | *outputLength = j; 261 | } 262 | return outputBuffer; 263 | } 264 | 265 | @implementation NSData (Base64) 266 | 267 | // 268 | // dataFromBase64String: 269 | // 270 | // Creates an NSData object containing the base64 decoded representation of 271 | // the base64 string 'aString' 272 | // 273 | // Parameters: 274 | // aString - the base64 string to decode 275 | // 276 | // returns the autoreleased NSData representation of the base64 string 277 | // 278 | + (NSData *)dataFromBase64String:(NSString *)aString 279 | { 280 | NSData *data = [aString dataUsingEncoding:NSASCIIStringEncoding]; 281 | size_t outputLength; 282 | void *outputBuffer = NewBase64Decode([data bytes], [data length], &outputLength); 283 | NSData *result = [NSData dataWithBytes:outputBuffer length:outputLength]; 284 | free(outputBuffer); 285 | return result; 286 | } 287 | 288 | // 289 | // base64EncodedString 290 | // 291 | // Creates an NSString object that contains the base 64 encoding of the 292 | // receiver's data. Lines are broken at 64 characters long. 293 | // 294 | // returns an autoreleased NSString being the base 64 representation of the 295 | // receiver. 296 | // 297 | - (NSString *)base64EncodedString 298 | { 299 | size_t outputLength = 0; 300 | char *outputBuffer = 301 | NewBase64Encode([self bytes], [self length], true, &outputLength); 302 | 303 | NSString *result =[[NSString alloc] initWithBytes:outputBuffer 304 | length:outputLength 305 | encoding:NSASCIIStringEncoding]; 306 | #if ! __has_feature(objc_arc) 307 | [result autorelease]; 308 | #endif 309 | free(outputBuffer); 310 | return result; 311 | } 312 | 313 | @end 314 | -------------------------------------------------------------------------------- /NSStringAdditions.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface NSString (NSStringAdditions) 4 | 5 | + (NSString *)stringByGeneratingUUID; 6 | 7 | #pragma mark - 8 | 9 | - (NSString *)unescapedString; 10 | 11 | - (NSString *)escapedString; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /NSStringAdditions.m: -------------------------------------------------------------------------------- 1 | #import "NSStringAdditions.h" 2 | 3 | @implementation NSString (NSStringAdditions) 4 | 5 | + (NSString *)stringByGeneratingUUID { 6 | CFUUIDRef UUIDReference = CFUUIDCreate(nil); 7 | CFStringRef temporaryUUIDString = CFUUIDCreateString(nil, UUIDReference); 8 | 9 | CFRelease(UUIDReference); 10 | #if ! __has_feature(objc_arc) 11 | return [NSMakeCollectable(temporaryUUIDString) autorelease]; 12 | #else 13 | return (__bridge_transfer NSString*)temporaryUUIDString; 14 | #endif 15 | } 16 | 17 | #pragma mark - 18 | 19 | - (NSString *)unescapedString { 20 | NSMutableString *string = [NSMutableString stringWithString: self]; 21 | 22 | [string replaceOccurrencesOfString: @"&" withString: @"&" options: NSLiteralSearch range: NSMakeRange(0, [string length])]; 23 | [string replaceOccurrencesOfString: @""" withString: @"\"" options: NSLiteralSearch range: NSMakeRange(0, [string length])]; 24 | [string replaceOccurrencesOfString: @"'" withString: @"'" options: NSLiteralSearch range: NSMakeRange(0, [string length])]; 25 | [string replaceOccurrencesOfString: @"9" withString: @"'" options: NSLiteralSearch range: NSMakeRange(0, [string length])]; 26 | [string replaceOccurrencesOfString: @"’" withString: @"'" options: NSLiteralSearch range: NSMakeRange(0, [string length])]; 27 | [string replaceOccurrencesOfString: @"–" withString: @"'" options: NSLiteralSearch range: NSMakeRange(0, [string length])]; 28 | [string replaceOccurrencesOfString: @">" withString: @">" options: NSLiteralSearch range: NSMakeRange(0, [string length])]; 29 | [string replaceOccurrencesOfString: @"<" withString: @"<" options: NSLiteralSearch range: NSMakeRange(0, [string length])]; 30 | 31 | return [NSString stringWithString: string]; 32 | } 33 | 34 | - (NSString *)escapedString { 35 | NSMutableString *string = [NSMutableString stringWithString: self]; 36 | 37 | // NOTE: we use unicode entities instead of & > < etc. since some hosts (powweb, fatcow, and similar) 38 | // have a weird PHP/libxml2 combination that ignores regular entities 39 | [string replaceOccurrencesOfString: @"&" withString: @"&" options: NSLiteralSearch range: NSMakeRange(0, [string length])]; 40 | [string replaceOccurrencesOfString: @">" withString: @">" options: NSLiteralSearch range: NSMakeRange(0, [string length])]; 41 | [string replaceOccurrencesOfString: @"<" withString: @"<" options: NSLiteralSearch range: NSMakeRange(0, [string length])]; 42 | 43 | return [NSString stringWithString: string]; 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # THIS LIBRARY IS NO LONGER MAINTAINED 2 | 3 | I'd suggest using https://github.com/wordpress-mobile/wpxmlrpc, which is based on this library and still maintained. 4 | -------------------------------------------------------------------------------- /Resources/Property Lists/TestCases.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AlternativeDateFormatsTestCase 6 | 7 | 2009-12-02T01:49:00Z 8 | 2009-12-02T01:50:00Z 9 | 10 | DefaultTypeTestCase 11 | Hello World! 12 | EmptyBooleanTestCase 13 | 0 14 | EmptyDataTestCase 15 | 16 | EmptyDoubleTestCase 17 | 0 18 | EmptyIntegerTestCase 19 | 0 20 | EmptyStringTestCase 21 | 22 | SimpleArrayTestCase 23 | 24 | Hello World! 25 | 42 26 | 3.14 27 | 1 28 | 2009-07-18T21:34:00Z 29 | eW91IGNhbid0IHJlYWQgdGhpcyE= 30 | 31 | SimpleStructTestCase 32 | 33 | Name 34 | Eric Czarny 35 | Birthday 36 | 1984-04-15T05:00:00Z 37 | Age 38 | 25 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Resources/Property Lists/XMLRPC-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | XMLRPC 9 | CFBundleIdentifier 10 | com.divisiblebyzero.XMLRPC 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | XMLRPC 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 2.3.4 19 | CFBundleSignature 20 | ZERO 21 | CFBundleVersion 22 | 2.3.4 23 | 24 | 25 | -------------------------------------------------------------------------------- /Resources/Property Lists/XMLRPCUnitTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleIdentifier 8 | com.divisiblebyzero.XMLRPCUnitTests 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundleName 12 | XMLRPCUnitTests 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleSignature 16 | ZERO 17 | CFBundleVersion 18 | 1.0 19 | CFBundleShortVersionString 20 | 1.0 21 | 22 | 23 | -------------------------------------------------------------------------------- /Resources/Test Cases/AlternativeDateFormatsTestCase.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 20091201T20:49:00 9 | 2009-12-01T20:50:00 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Resources/Test Cases/DefaultTypeTestCase.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hello World! 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Resources/Test Cases/EmptyBooleanTestCase.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Resources/Test Cases/EmptyDataTestCase.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Resources/Test Cases/EmptyDoubleTestCase.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Resources/Test Cases/EmptyIntegerTestCase.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Resources/Test Cases/EmptyStringTestCase.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Resources/Test Cases/SimpleArrayTestCase.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Hello World! 9 | 42 10 | 3.14 11 | 1 12 | 20090718T17:34:00 13 | eW91IGNhbid0IHJlYWQgdGhpcyE= 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Resources/Test Cases/SimpleStructTestCase.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Name 9 | Eric Czarny 10 | 11 | 12 | Birthday 13 | 1984-04-15T00:00:00 14 | 15 | 16 | Age 17 | 25 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Tools/Test Client/Configurations/Common.xcconfig: -------------------------------------------------------------------------------- 1 | ARCHS = $(ARCHS_STANDARD_32_64_BIT) 2 | VALID_ARCHS = i386 ppc x86_64 3 | SDKROOT = macosx10.6 4 | PREBINDING = NO 5 | 6 | GCC_C_LANGUAGE_STANDARD = gnu99 7 | GCC_PRECOMPILE_PREFIX_HEADER = YES 8 | GCC_MODEL_TUNING = G5 9 | 10 | GCC_WARN_ABOUT_MISSING_NEWLINE = YES 11 | GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = YES 12 | GCC_WARN_ABOUT_RETURN_TYPE = YES 13 | GCC_WARN_UNUSED_VARIABLE = YES 14 | GCC_TREAT_WARNINGS_AS_ERRORS = YES 15 | -------------------------------------------------------------------------------- /Tools/Test Client/Configurations/CommonDevelopment.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Common.xcconfig" 2 | 3 | ONLY_ACTIVE_ARCH = YES 4 | 5 | DEBUG_INFORMATION_FORMAT = dwarf 6 | 7 | GCC_OPTIMIZATION_LEVEL = 0 8 | -------------------------------------------------------------------------------- /Tools/Test Client/Configurations/CommonRelease.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Common.xcconfig" 2 | 3 | DEBUG_INFORMATION_FORMAT = dwarf-with-dsym 4 | 5 | GCC_OPTIMIZATION_LEVEL = s 6 | -------------------------------------------------------------------------------- /Tools/Test Client/Configurations/TestClient.xcconfig: -------------------------------------------------------------------------------- 1 | PRODUCT_NAME = Test Client 2 | INFOPLIST_FILE = TestClient-Info.plist 3 | 4 | GCC_PRECOMPILE_PREFIX_HEADER = YES 5 | GCC_PREFIX_HEADER = TestClient.pch 6 | 7 | INSTALL_PATH = /Applications 8 | -------------------------------------------------------------------------------- /Tools/Test Client/Configurations/TestClientDevelopment.xcconfig: -------------------------------------------------------------------------------- 1 | #include "TestClient.xcconfig" 2 | #include "CommonDevelopment.xcconfig" 3 | -------------------------------------------------------------------------------- /Tools/Test Client/Configurations/TestClientRelease.xcconfig: -------------------------------------------------------------------------------- 1 | #include "TestClient.xcconfig" 2 | #include "CommonRelease.xcconfig" 3 | -------------------------------------------------------------------------------- /Tools/Test Client/Languages/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikolaykasyanov/xmlrpc/f54c8c970c2296f0a1a3f599a25adb5f85dfc128/Tools/Test Client/Languages/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /Tools/Test Client/Test Client.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 070043021144653D000D05B6 /* TestClient.xib in Resources */ = {isa = PBXBuildFile; fileRef = 070043001144653D000D05B6 /* TestClient.xib */; }; 11 | 070043051144656D000D05B6 /* TestClientXMLParserWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 070043031144656D000D05B6 /* TestClientXMLParserWindow.xib */; }; 12 | 0700430C11446593000D05B6 /* TestClientMainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0700430A11446593000D05B6 /* TestClientMainWindow.xib */; }; 13 | 070043131144667B000D05B6 /* TestClientApplicationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0700430E1144667B000D05B6 /* TestClientApplicationController.m */; }; 14 | 070043141144667B000D05B6 /* TestClientMainWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 070043101144667B000D05B6 /* TestClientMainWindowController.m */; }; 15 | 070043151144667B000D05B6 /* TestClientXMLParserWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 070043121144667B000D05B6 /* TestClientXMLParserWindowController.m */; }; 16 | 07E6DAB013679C6E00454D31 /* XMLRPC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 07E6DAA513679B7600454D31 /* XMLRPC.framework */; }; 17 | 07E6DAB213679F3000454D31 /* XMLRPC.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 07E6DAA513679B7600454D31 /* XMLRPC.framework */; }; 18 | 2DC70E311004D90100BBEEA6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2DC70E2F1004D90100BBEEA6 /* InfoPlist.strings */; }; 19 | 2DC70E381004D90F00BBEEA6 /* Common.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 2DC70E321004D90F00BBEEA6 /* Common.xcconfig */; }; 20 | 2DC70E391004D90F00BBEEA6 /* CommonDevelopment.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 2DC70E331004D90F00BBEEA6 /* CommonDevelopment.xcconfig */; }; 21 | 2DC70E3A1004D90F00BBEEA6 /* CommonRelease.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 2DC70E341004D90F00BBEEA6 /* CommonRelease.xcconfig */; }; 22 | 2DC70E3B1004D90F00BBEEA6 /* TestClientDevelopment.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 2DC70E351004D90F00BBEEA6 /* TestClientDevelopment.xcconfig */; }; 23 | 2DC70E3C1004D90F00BBEEA6 /* TestClientRelease.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 2DC70E361004D90F00BBEEA6 /* TestClientRelease.xcconfig */; }; 24 | 2DC70E3D1004D90F00BBEEA6 /* TestClient.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 2DC70E371004D90F00BBEEA6 /* TestClient.xcconfig */; }; 25 | 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; 26 | 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXCopyFilesBuildPhase section */ 30 | 07E6DAB113679F1400454D31 /* Copy Frameworks */ = { 31 | isa = PBXCopyFilesBuildPhase; 32 | buildActionMask = 2147483647; 33 | dstPath = ""; 34 | dstSubfolderSpec = 10; 35 | files = ( 36 | 07E6DAB213679F3000454D31 /* XMLRPC.framework in Copy Frameworks */, 37 | ); 38 | name = "Copy Frameworks"; 39 | runOnlyForDeploymentPostprocessing = 0; 40 | }; 41 | /* End PBXCopyFilesBuildPhase section */ 42 | 43 | /* Begin PBXFileReference section */ 44 | 070043011144653D000D05B6 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Languages/English.lproj/TestClient.xib; sourceTree = ""; }; 45 | 070043041144656D000D05B6 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Languages/English.lproj/TestClientXMLParserWindow.xib; sourceTree = ""; }; 46 | 0700430B11446593000D05B6 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Languages/English.lproj/TestClientMainWindow.xib; sourceTree = ""; }; 47 | 0700430D1144667B000D05B6 /* TestClientApplicationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestClientApplicationController.h; sourceTree = ""; }; 48 | 0700430E1144667B000D05B6 /* TestClientApplicationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestClientApplicationController.m; sourceTree = ""; }; 49 | 0700430F1144667B000D05B6 /* TestClientMainWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestClientMainWindowController.h; sourceTree = ""; }; 50 | 070043101144667B000D05B6 /* TestClientMainWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestClientMainWindowController.m; sourceTree = ""; }; 51 | 070043111144667B000D05B6 /* TestClientXMLParserWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestClientXMLParserWindowController.h; sourceTree = ""; }; 52 | 070043121144667B000D05B6 /* TestClientXMLParserWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestClientXMLParserWindowController.m; sourceTree = ""; }; 53 | 0759A73511434C0D000DFE98 /* XMLRPCEventBasedParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XMLRPCEventBasedParser.h; path = ../../XMLRPCEventBasedParser.h; sourceTree = SOURCE_ROOT; }; 54 | 0759A73C11434C3C000DFE98 /* XMLRPCEventBasedParserDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XMLRPCEventBasedParserDelegate.h; path = ../../XMLRPCEventBasedParserDelegate.h; sourceTree = SOURCE_ROOT; }; 55 | 07E6DAA513679B7600454D31 /* XMLRPC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XMLRPC.framework; path = "../../../../../../Library/Developer/Xcode/DerivedData/XMLRPC-gcawxlhfrkyvgjeolligeasrfeux/Build/Products/Development/XMLRPC.framework"; sourceTree = ""; }; 56 | 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 57 | 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; 58 | 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 59 | 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 60 | 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 61 | 2DC70E301004D90100BBEEA6 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = Languages/English.lproj/InfoPlist.strings; sourceTree = ""; }; 62 | 2DC70E321004D90F00BBEEA6 /* Common.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Common.xcconfig; path = Configurations/Common.xcconfig; sourceTree = ""; }; 63 | 2DC70E331004D90F00BBEEA6 /* CommonDevelopment.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = CommonDevelopment.xcconfig; path = Configurations/CommonDevelopment.xcconfig; sourceTree = ""; }; 64 | 2DC70E341004D90F00BBEEA6 /* CommonRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = CommonRelease.xcconfig; path = Configurations/CommonRelease.xcconfig; sourceTree = ""; }; 65 | 2DC70E351004D90F00BBEEA6 /* TestClientDevelopment.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = TestClientDevelopment.xcconfig; path = Configurations/TestClientDevelopment.xcconfig; sourceTree = ""; }; 66 | 2DC70E361004D90F00BBEEA6 /* TestClientRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = TestClientRelease.xcconfig; path = Configurations/TestClientRelease.xcconfig; sourceTree = ""; }; 67 | 2DC70E371004D90F00BBEEA6 /* TestClient.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = TestClient.xcconfig; path = Configurations/TestClient.xcconfig; sourceTree = ""; }; 68 | 32CA4F630368D1EE00C91783 /* TestClient.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestClient.pch; sourceTree = ""; }; 69 | 8D1107310486CEB800E47090 /* TestClient-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "TestClient-Info.plist"; sourceTree = ""; }; 70 | 8D1107320486CEB800E47090 /* Test Client.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Test Client.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 71 | /* End PBXFileReference section */ 72 | 73 | /* Begin PBXFrameworksBuildPhase section */ 74 | 8D11072E0486CEB800E47090 /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, 79 | 07E6DAB013679C6E00454D31 /* XMLRPC.framework in Frameworks */, 80 | ); 81 | runOnlyForDeploymentPostprocessing = 0; 82 | }; 83 | /* End PBXFrameworksBuildPhase section */ 84 | 85 | /* Begin PBXGroup section */ 86 | 0759A75B11434CC8000DFE98 /* Private Headers */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 0759A73511434C0D000DFE98 /* XMLRPCEventBasedParser.h */, 90 | 0759A73C11434C3C000DFE98 /* XMLRPCEventBasedParserDelegate.h */, 91 | ); 92 | name = "Private Headers"; 93 | sourceTree = ""; 94 | }; 95 | 080E96DDFE201D6D7F000001 /* Classes */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | 0700430D1144667B000D05B6 /* TestClientApplicationController.h */, 99 | 0700430E1144667B000D05B6 /* TestClientApplicationController.m */, 100 | 0700430F1144667B000D05B6 /* TestClientMainWindowController.h */, 101 | 070043101144667B000D05B6 /* TestClientMainWindowController.m */, 102 | 070043111144667B000D05B6 /* TestClientXMLParserWindowController.h */, 103 | 070043121144667B000D05B6 /* TestClientXMLParserWindowController.m */, 104 | ); 105 | name = Classes; 106 | sourceTree = ""; 107 | }; 108 | 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, 112 | 07E6DAA513679B7600454D31 /* XMLRPC.framework */, 113 | ); 114 | name = "Linked Frameworks"; 115 | sourceTree = ""; 116 | }; 117 | 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | 29B97324FDCFA39411CA2CEA /* AppKit.framework */, 121 | 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */, 122 | 29B97325FDCFA39411CA2CEA /* Foundation.framework */, 123 | ); 124 | name = "Other Frameworks"; 125 | sourceTree = ""; 126 | }; 127 | 19C28FACFE9D520D11CA2CBB /* Products */ = { 128 | isa = PBXGroup; 129 | children = ( 130 | 8D1107320486CEB800E47090 /* Test Client.app */, 131 | ); 132 | name = Products; 133 | sourceTree = ""; 134 | }; 135 | 29B97314FDCFA39411CA2CEA /* Test Client */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | 080E96DDFE201D6D7F000001 /* Classes */, 139 | 0759A75B11434CC8000DFE98 /* Private Headers */, 140 | 29B97315FDCFA39411CA2CEA /* Other Sources */, 141 | 29B97317FDCFA39411CA2CEA /* Resources */, 142 | 29B97323FDCFA39411CA2CEA /* Frameworks */, 143 | 19C28FACFE9D520D11CA2CBB /* Products */, 144 | ); 145 | name = "Test Client"; 146 | sourceTree = ""; 147 | }; 148 | 29B97315FDCFA39411CA2CEA /* Other Sources */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | 29B97316FDCFA39411CA2CEA /* main.m */, 152 | 32CA4F630368D1EE00C91783 /* TestClient.pch */, 153 | ); 154 | name = "Other Sources"; 155 | sourceTree = ""; 156 | }; 157 | 29B97317FDCFA39411CA2CEA /* Resources */ = { 158 | isa = PBXGroup; 159 | children = ( 160 | 2DC70E201004D85400BBEEA6 /* Configurations */, 161 | 2DC70E211004D85C00BBEEA6 /* Interface Builder */, 162 | 2DC70E221004D86F00BBEEA6 /* Localized Strings */, 163 | 2DC70E231004D87A00BBEEA6 /* Property Lists */, 164 | ); 165 | name = Resources; 166 | sourceTree = ""; 167 | }; 168 | 29B97323FDCFA39411CA2CEA /* Frameworks */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, 172 | 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, 173 | ); 174 | name = Frameworks; 175 | sourceTree = ""; 176 | }; 177 | 2DC70E201004D85400BBEEA6 /* Configurations */ = { 178 | isa = PBXGroup; 179 | children = ( 180 | 2DC70E321004D90F00BBEEA6 /* Common.xcconfig */, 181 | 2DC70E331004D90F00BBEEA6 /* CommonDevelopment.xcconfig */, 182 | 2DC70E341004D90F00BBEEA6 /* CommonRelease.xcconfig */, 183 | 2DC70E351004D90F00BBEEA6 /* TestClientDevelopment.xcconfig */, 184 | 2DC70E361004D90F00BBEEA6 /* TestClientRelease.xcconfig */, 185 | 2DC70E371004D90F00BBEEA6 /* TestClient.xcconfig */, 186 | ); 187 | name = Configurations; 188 | sourceTree = ""; 189 | }; 190 | 2DC70E211004D85C00BBEEA6 /* Interface Builder */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | 070043001144653D000D05B6 /* TestClient.xib */, 194 | 0700430A11446593000D05B6 /* TestClientMainWindow.xib */, 195 | 070043031144656D000D05B6 /* TestClientXMLParserWindow.xib */, 196 | ); 197 | name = "Interface Builder"; 198 | sourceTree = ""; 199 | }; 200 | 2DC70E221004D86F00BBEEA6 /* Localized Strings */ = { 201 | isa = PBXGroup; 202 | children = ( 203 | 2DC70E2F1004D90100BBEEA6 /* InfoPlist.strings */, 204 | ); 205 | name = "Localized Strings"; 206 | sourceTree = ""; 207 | }; 208 | 2DC70E231004D87A00BBEEA6 /* Property Lists */ = { 209 | isa = PBXGroup; 210 | children = ( 211 | 8D1107310486CEB800E47090 /* TestClient-Info.plist */, 212 | ); 213 | name = "Property Lists"; 214 | sourceTree = ""; 215 | }; 216 | /* End PBXGroup section */ 217 | 218 | /* Begin PBXNativeTarget section */ 219 | 8D1107260486CEB800E47090 /* Test Client */ = { 220 | isa = PBXNativeTarget; 221 | buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Test Client" */; 222 | buildPhases = ( 223 | 8D1107290486CEB800E47090 /* Resources */, 224 | 07E6DAB113679F1400454D31 /* Copy Frameworks */, 225 | 8D11072C0486CEB800E47090 /* Sources */, 226 | 8D11072E0486CEB800E47090 /* Frameworks */, 227 | 0759A72C11434B8D000DFE98 /* Run Script: Include Git commit hash */, 228 | ); 229 | buildRules = ( 230 | ); 231 | dependencies = ( 232 | ); 233 | name = "Test Client"; 234 | productInstallPath = "$(HOME)/Applications"; 235 | productName = "XMLRPC Client"; 236 | productReference = 8D1107320486CEB800E47090 /* Test Client.app */; 237 | productType = "com.apple.product-type.application"; 238 | }; 239 | /* End PBXNativeTarget section */ 240 | 241 | /* Begin PBXProject section */ 242 | 29B97313FDCFA39411CA2CEA /* Project object */ = { 243 | isa = PBXProject; 244 | buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Test Client" */; 245 | compatibilityVersion = "Xcode 3.1"; 246 | developmentRegion = English; 247 | hasScannedForEncodings = 1; 248 | knownRegions = ( 249 | en, 250 | ); 251 | mainGroup = 29B97314FDCFA39411CA2CEA /* Test Client */; 252 | projectDirPath = ""; 253 | projectRoot = ""; 254 | targets = ( 255 | 8D1107260486CEB800E47090 /* Test Client */, 256 | ); 257 | }; 258 | /* End PBXProject section */ 259 | 260 | /* Begin PBXResourcesBuildPhase section */ 261 | 8D1107290486CEB800E47090 /* Resources */ = { 262 | isa = PBXResourcesBuildPhase; 263 | buildActionMask = 2147483647; 264 | files = ( 265 | 2DC70E381004D90F00BBEEA6 /* Common.xcconfig in Resources */, 266 | 2DC70E391004D90F00BBEEA6 /* CommonDevelopment.xcconfig in Resources */, 267 | 2DC70E3A1004D90F00BBEEA6 /* CommonRelease.xcconfig in Resources */, 268 | 2DC70E311004D90100BBEEA6 /* InfoPlist.strings in Resources */, 269 | 2DC70E3D1004D90F00BBEEA6 /* TestClient.xcconfig in Resources */, 270 | 070043021144653D000D05B6 /* TestClient.xib in Resources */, 271 | 2DC70E3B1004D90F00BBEEA6 /* TestClientDevelopment.xcconfig in Resources */, 272 | 0700430C11446593000D05B6 /* TestClientMainWindow.xib in Resources */, 273 | 2DC70E3C1004D90F00BBEEA6 /* TestClientRelease.xcconfig in Resources */, 274 | 070043051144656D000D05B6 /* TestClientXMLParserWindow.xib in Resources */, 275 | ); 276 | runOnlyForDeploymentPostprocessing = 0; 277 | }; 278 | /* End PBXResourcesBuildPhase section */ 279 | 280 | /* Begin PBXShellScriptBuildPhase section */ 281 | 0759A72C11434B8D000DFE98 /* Run Script: Include Git commit hash */ = { 282 | isa = PBXShellScriptBuildPhase; 283 | buildActionMask = 2147483647; 284 | files = ( 285 | ); 286 | inputPaths = ( 287 | ); 288 | name = "Run Script: Include Git commit hash"; 289 | outputPaths = ( 290 | ); 291 | runOnlyForDeploymentPostprocessing = 0; 292 | shellPath = /usr/bin/ruby; 293 | shellScript = "raise \"Must be executed from within Xcode.\" unless ENV['XCODE_VERSION_ACTUAL']\n\ninfo_plist = \"#{ENV['BUILT_PRODUCTS_DIR']}/#{ENV['WRAPPER_NAME']}/Contents/Info.plist\"\n\nif !File.exist?('/usr/local/bin/git')\n exit\nend\n\ncommit = `/usr/local/bin/git rev-parse --short HEAD`.chomp!\n\nif commit.nil? or commit.empty?\n exit\nend\n\nlines = IO.readlines(info_plist).join\n\nlines.gsub! /(CFBundleShortVersionString<\\/key>\\n\\t)(\\d+\\.\\d+(?:\\.\\d)*[a-z])<\\/string>/, \"\\\\1\\\\2 rev. #{commit}\"\n\nFile.open(info_plist, 'w') { |f| f.puts lines }"; 294 | }; 295 | /* End PBXShellScriptBuildPhase section */ 296 | 297 | /* Begin PBXSourcesBuildPhase section */ 298 | 8D11072C0486CEB800E47090 /* Sources */ = { 299 | isa = PBXSourcesBuildPhase; 300 | buildActionMask = 2147483647; 301 | files = ( 302 | 8D11072D0486CEB800E47090 /* main.m in Sources */, 303 | 070043131144667B000D05B6 /* TestClientApplicationController.m in Sources */, 304 | 070043141144667B000D05B6 /* TestClientMainWindowController.m in Sources */, 305 | 070043151144667B000D05B6 /* TestClientXMLParserWindowController.m in Sources */, 306 | ); 307 | runOnlyForDeploymentPostprocessing = 0; 308 | }; 309 | /* End PBXSourcesBuildPhase section */ 310 | 311 | /* Begin PBXVariantGroup section */ 312 | 070043001144653D000D05B6 /* TestClient.xib */ = { 313 | isa = PBXVariantGroup; 314 | children = ( 315 | 070043011144653D000D05B6 /* English */, 316 | ); 317 | name = TestClient.xib; 318 | sourceTree = ""; 319 | }; 320 | 070043031144656D000D05B6 /* TestClientXMLParserWindow.xib */ = { 321 | isa = PBXVariantGroup; 322 | children = ( 323 | 070043041144656D000D05B6 /* English */, 324 | ); 325 | name = TestClientXMLParserWindow.xib; 326 | sourceTree = ""; 327 | }; 328 | 0700430A11446593000D05B6 /* TestClientMainWindow.xib */ = { 329 | isa = PBXVariantGroup; 330 | children = ( 331 | 0700430B11446593000D05B6 /* English */, 332 | ); 333 | name = TestClientMainWindow.xib; 334 | sourceTree = ""; 335 | }; 336 | 2DC70E2F1004D90100BBEEA6 /* InfoPlist.strings */ = { 337 | isa = PBXVariantGroup; 338 | children = ( 339 | 2DC70E301004D90100BBEEA6 /* English */, 340 | ); 341 | name = InfoPlist.strings; 342 | sourceTree = ""; 343 | }; 344 | /* End PBXVariantGroup section */ 345 | 346 | /* Begin XCBuildConfiguration section */ 347 | C01FCF4B08A954540054247B /* Development */ = { 348 | isa = XCBuildConfiguration; 349 | baseConfigurationReference = 2DC70E351004D90F00BBEEA6 /* TestClientDevelopment.xcconfig */; 350 | buildSettings = { 351 | INFOPLIST_FILE = "TestClient-Info.plist"; 352 | }; 353 | name = Development; 354 | }; 355 | C01FCF4C08A954540054247B /* Release */ = { 356 | isa = XCBuildConfiguration; 357 | baseConfigurationReference = 2DC70E361004D90F00BBEEA6 /* TestClientRelease.xcconfig */; 358 | buildSettings = { 359 | INFOPLIST_FILE = "TestClient-Info.plist"; 360 | }; 361 | name = Release; 362 | }; 363 | C01FCF4F08A954540054247B /* Development */ = { 364 | isa = XCBuildConfiguration; 365 | baseConfigurationReference = 2DC70E331004D90F00BBEEA6 /* CommonDevelopment.xcconfig */; 366 | buildSettings = { 367 | }; 368 | name = Development; 369 | }; 370 | C01FCF5008A954540054247B /* Release */ = { 371 | isa = XCBuildConfiguration; 372 | baseConfigurationReference = 2DC70E341004D90F00BBEEA6 /* CommonRelease.xcconfig */; 373 | buildSettings = { 374 | }; 375 | name = Release; 376 | }; 377 | /* End XCBuildConfiguration section */ 378 | 379 | /* Begin XCConfigurationList section */ 380 | C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Test Client" */ = { 381 | isa = XCConfigurationList; 382 | buildConfigurations = ( 383 | C01FCF4B08A954540054247B /* Development */, 384 | C01FCF4C08A954540054247B /* Release */, 385 | ); 386 | defaultConfigurationIsVisible = 0; 387 | defaultConfigurationName = Release; 388 | }; 389 | C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Test Client" */ = { 390 | isa = XCConfigurationList; 391 | buildConfigurations = ( 392 | C01FCF4F08A954540054247B /* Development */, 393 | C01FCF5008A954540054247B /* Release */, 394 | ); 395 | defaultConfigurationIsVisible = 0; 396 | defaultConfigurationName = Release; 397 | }; 398 | /* End XCConfigurationList section */ 399 | }; 400 | rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; 401 | } 402 | -------------------------------------------------------------------------------- /Tools/Test Client/TestClient-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | Test Client 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.divisiblebyzero.Test Client 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | Test Client 17 | CFBundlePackageType 18 | APPL 19 | CFBundleSignature 20 | ZERO 21 | CFBundleVersion 22 | 100.0 23 | CFBundleShortVersionString 24 | 1.0.0d 25 | NSMainNibFile 26 | TestClient 27 | NSPrincipalClass 28 | NSApplication 29 | 30 | 31 | -------------------------------------------------------------------------------- /Tools/Test Client/TestClient.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #import 4 | #endif 5 | -------------------------------------------------------------------------------- /Tools/Test Client/TestClientApplicationController.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface TestClientApplicationController : NSObject { 4 | 5 | } 6 | 7 | - (void)toggleTestClientWindow: (id)sender; 8 | 9 | - (void)toggleXMLParserWindow: (id)sender; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /Tools/Test Client/TestClientApplicationController.m: -------------------------------------------------------------------------------- 1 | #import "TestClientApplicationController.h" 2 | #import "TestClientMainWindowController.h" 3 | #import "TestClientXMLParserWindowController.h" 4 | 5 | @implementation TestClientApplicationController 6 | 7 | - (void)applicationDidFinishLaunching: (NSNotification *)notification { 8 | [self toggleTestClientWindow: self]; 9 | } 10 | 11 | #pragma mark - 12 | 13 | - (void)toggleTestClientWindow: (id)sender { 14 | [[TestClientMainWindowController sharedController] toggleTestClientWindow: self]; 15 | } 16 | 17 | - (void)toggleXMLParserWindow: (id)sender { 18 | [[TestClientXMLParserWindowController sharedController] toggleXMLParserWindow: self]; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Tools/Test Client/TestClientMainWindowController.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface TestClientMainWindowController : NSWindowController { 4 | XMLRPCResponse *myResponse; 5 | IBOutlet NSTextField *myRequestURL; 6 | IBOutlet NSTextField *myMethod; 7 | IBOutlet NSTextField *myParameter; 8 | IBOutlet NSProgressIndicator *myProgressIndicator; 9 | IBOutlet NSTextField *myActiveConnection; 10 | IBOutlet NSButton *mySendRequest; 11 | IBOutlet NSTextView *myRequestBody; 12 | IBOutlet NSTextView *myResponseBody; 13 | IBOutlet NSOutlineView *myParsedResponse; 14 | } 15 | 16 | + (TestClientMainWindowController *)sharedController; 17 | 18 | #pragma mark - 19 | 20 | - (void)showTestClientWindow: (id)sender; 21 | 22 | - (void)hideTestClientWindow: (id)sender; 23 | 24 | #pragma mark - 25 | 26 | - (void)toggleTestClientWindow: (id)sender; 27 | 28 | #pragma mark - 29 | 30 | - (void)sendRequest: (id)sender; 31 | 32 | @end 33 | 34 | #pragma mark - 35 | 36 | @interface TestClientMainWindowController (XMLRPCConnectionDelegate) 37 | 38 | - (void)request: (XMLRPCRequest *)request didReceiveResponse: (XMLRPCResponse *)response; 39 | 40 | - (void)request: (XMLRPCRequest *)request didFailWithError: (NSError *)error; 41 | 42 | - (void)request: (XMLRPCRequest *)request didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge; 43 | 44 | - (void)request: (XMLRPCRequest *)request didCancelAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge; 45 | 46 | - (BOOL)request: (XMLRPCRequest *)request canAuthenticateAgainstProtectionSpace: (NSURLProtectionSpace *)protectionSpace; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Tools/Test Client/TestClientMainWindowController.m: -------------------------------------------------------------------------------- 1 | #import "TestClientMainWindowController.h" 2 | 3 | @implementation TestClientMainWindowController 4 | 5 | static TestClientMainWindowController *sharedInstance = nil; 6 | 7 | - (id)init { 8 | if ((self = [super initWithWindowNibName: @"TestClientMainWindow"])) { 9 | myResponse = nil; 10 | } 11 | 12 | return self; 13 | } 14 | 15 | #pragma mark - 16 | 17 | + (id)allocWithZone: (NSZone *)zone { 18 | @synchronized(self) { 19 | if (!sharedInstance) { 20 | sharedInstance = [super allocWithZone: zone]; 21 | 22 | return sharedInstance; 23 | } 24 | } 25 | 26 | return nil; 27 | } 28 | 29 | #pragma mark - 30 | 31 | + (TestClientMainWindowController *)sharedController { 32 | @synchronized(self) { 33 | if (!sharedInstance) { 34 | [[self alloc] init]; 35 | } 36 | } 37 | 38 | return sharedInstance; 39 | } 40 | 41 | #pragma mark - 42 | 43 | - (void)awakeFromNib { 44 | [[self window] center]; 45 | } 46 | 47 | #pragma mark - 48 | 49 | - (void)showTestClientWindow: (id)sender { 50 | [self showWindow: sender]; 51 | } 52 | 53 | - (void)hideTestClientWindow: (id)sender { 54 | [self close]; 55 | } 56 | 57 | #pragma mark - 58 | 59 | - (void)toggleTestClientWindow: (id)sender { 60 | if ([[self window] isKeyWindow]) { 61 | [self hideTestClientWindow: sender]; 62 | } else { 63 | [self showTestClientWindow: sender]; 64 | } 65 | } 66 | 67 | #pragma mark - 68 | 69 | - (void)sendRequest: (id)sender { 70 | NSURL *URL = [NSURL URLWithString: [myRequestURL stringValue]]; 71 | XMLRPCRequest *request = [[[XMLRPCRequest alloc] initWithURL: URL] autorelease]; 72 | NSString *connectionIdentifier; 73 | 74 | [request setMethod: [myMethod stringValue] withParameter: [myParameter stringValue]]; 75 | 76 | [myProgressIndicator startAnimation: self]; 77 | 78 | [myRequestBody setString: [request body]]; 79 | 80 | connectionIdentifier = [[XMLRPCConnectionManager sharedManager] spawnConnectionWithXMLRPCRequest: request delegate: self]; 81 | 82 | [myActiveConnection setHidden: NO]; 83 | 84 | [myActiveConnection setStringValue: [NSString stringWithFormat: @"Active Connection: %@", connectionIdentifier]]; 85 | 86 | [mySendRequest setEnabled: NO]; 87 | } 88 | 89 | #pragma mark - 90 | 91 | - (void)dealloc { 92 | [myResponse release]; 93 | 94 | [super dealloc]; 95 | } 96 | 97 | #pragma mark - 98 | 99 | #pragma mark Outline View Data Source Methods 100 | 101 | #pragma mark - 102 | 103 | - (id)outlineView: (NSOutlineView *)outlineView child: (NSInteger)index ofItem: (id)item { 104 | if (item == nil) { 105 | item = [myResponse object]; 106 | } 107 | 108 | if ([item isKindOfClass: [NSDictionary class]]) { 109 | return [item objectForKey: [[item allKeys] objectAtIndex: index]]; 110 | } else if ([item isKindOfClass: [NSArray class]]) { 111 | return [item objectAtIndex: index]; 112 | } 113 | 114 | return item; 115 | } 116 | 117 | - (BOOL)outlineView: (NSOutlineView *)outlineView isItemExpandable: (id)item { 118 | if ([item isKindOfClass: [NSDictionary class]] || [item isKindOfClass: [NSArray class]]) { 119 | if ([item count] > 0) { 120 | return YES; 121 | } 122 | } 123 | 124 | return NO; 125 | } 126 | 127 | - (NSInteger)outlineView: (NSOutlineView *)outlineView numberOfChildrenOfItem: (id)item { 128 | if (item == nil) { 129 | item = [myResponse object]; 130 | } 131 | 132 | if ([item isKindOfClass: [NSDictionary class]] || [item isKindOfClass: [NSArray class]]) { 133 | return [item count]; 134 | } else if (item != nil) { 135 | return 1; 136 | } 137 | 138 | return 0; 139 | } 140 | 141 | - (id)outlineView: (NSOutlineView *)outlineView objectValueForTableColumn: (NSTableColumn *)tableColumn byItem: (id)item { 142 | NSString *columnIdentifier = (NSString *)[tableColumn identifier]; 143 | 144 | if ([columnIdentifier isEqualToString: @"type"]) { 145 | id parentObject = [outlineView parentForItem: item] ? [outlineView parentForItem: item] : [myResponse object]; 146 | 147 | if ([parentObject isKindOfClass: [NSDictionary class]]) { 148 | return [[parentObject allKeysForObject: item] objectAtIndex: 0]; 149 | } else if ([parentObject isKindOfClass: [NSArray class]]) { 150 | return [NSString stringWithFormat: @"Item %d", [parentObject indexOfObject: item]]; 151 | } else if ([item isKindOfClass: [NSString class]]) { 152 | return @"String"; 153 | } else { 154 | return @"Object"; 155 | } 156 | } else { 157 | if ([item isKindOfClass: [NSDictionary class]] || [item isKindOfClass: [NSArray class]]) { 158 | return [NSString stringWithFormat: @"%d items", [item count]]; 159 | } else { 160 | return item; 161 | } 162 | } 163 | 164 | return nil; 165 | } 166 | 167 | #pragma mark - 168 | 169 | #pragma mark XMLRPC Connection Delegate Methods 170 | 171 | #pragma mark - 172 | 173 | - (void)request: (XMLRPCRequest *)request didReceiveResponse: (XMLRPCResponse *)response { 174 | [myProgressIndicator stopAnimation: self]; 175 | 176 | [myActiveConnection setHidden: YES]; 177 | 178 | [mySendRequest setEnabled: YES]; 179 | 180 | if ([response isFault]) { 181 | NSAlert *alert = [[[NSAlert alloc] init] autorelease]; 182 | 183 | [alert addButtonWithTitle: @"OK"]; 184 | [alert setMessageText: @"The XML-RPC response returned a fault."]; 185 | [alert setInformativeText: [NSString stringWithFormat: @"Fault String: %@", [response faultString]]]; 186 | [alert setAlertStyle: NSCriticalAlertStyle]; 187 | 188 | [alert runModal]; 189 | } else { 190 | [response retain]; 191 | 192 | [myResponse release]; 193 | 194 | myResponse = response; 195 | } 196 | 197 | [myParsedResponse reloadData]; 198 | 199 | [myResponseBody setString: [response body]]; 200 | } 201 | 202 | - (void)request: (XMLRPCRequest *)request didFailWithError: (NSError *)error { 203 | NSAlert *alert = [[[NSAlert alloc] init] autorelease]; 204 | 205 | [[NSApplication sharedApplication] requestUserAttention: NSCriticalRequest]; 206 | 207 | [alert addButtonWithTitle: @"OK"]; 208 | [alert setMessageText: @"The request failed!"]; 209 | [alert setInformativeText: @"The request failed to return a valid response."]; 210 | [alert setAlertStyle: NSCriticalAlertStyle]; 211 | 212 | [alert runModal]; 213 | 214 | [myParsedResponse reloadData]; 215 | 216 | [myProgressIndicator stopAnimation: self]; 217 | 218 | [myActiveConnection setHidden: YES]; 219 | 220 | [mySendRequest setEnabled: YES]; 221 | } 222 | 223 | - (void)request: (XMLRPCRequest *)request didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge { 224 | if ([challenge previousFailureCount] == 0) { 225 | NSURLCredential *credential = [NSURLCredential credentialWithUser: @"user" password: @"password" persistence: NSURLCredentialPersistenceNone]; 226 | 227 | [[challenge sender] useCredential: credential forAuthenticationChallenge: challenge]; 228 | } else { 229 | [[challenge sender] cancelAuthenticationChallenge: challenge]; 230 | } 231 | } 232 | 233 | - (void)request: (XMLRPCRequest *)request didCancelAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge { 234 | 235 | } 236 | 237 | - (BOOL)request: (XMLRPCRequest *)request canAuthenticateAgainstProtectionSpace: (NSURLProtectionSpace *)protectionSpace { 238 | return NO; 239 | } 240 | 241 | @end 242 | -------------------------------------------------------------------------------- /Tools/Test Client/TestClientXMLParserWindowController.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface TestClientXMLParserWindowController : NSWindowController { 4 | id myParsedObject; 5 | IBOutlet NSTextView *myXML; 6 | IBOutlet NSOutlineView *myParserResult; 7 | } 8 | 9 | + (TestClientXMLParserWindowController *)sharedController; 10 | 11 | #pragma mark - 12 | 13 | - (void)showXMLParserWindow: (id)sender; 14 | 15 | - (void)hideXMLParserWindow: (id)sender; 16 | 17 | #pragma mark - 18 | 19 | - (void)toggleXMLParserWindow: (id)sender; 20 | 21 | #pragma mark - 22 | 23 | - (void)parse: (id)sender; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Tools/Test Client/TestClientXMLParserWindowController.m: -------------------------------------------------------------------------------- 1 | #import "TestClientXMLParserWindowController.h" 2 | #import "XMLRPCEventBasedParser.h" 3 | 4 | @interface TestClientXMLParserWindowController (TestClientXMLParserWindowControllerPrivate) 5 | 6 | - (NSString *)typeForItem: (id)item; 7 | 8 | @end 9 | 10 | #pragma mark - 11 | 12 | @implementation TestClientXMLParserWindowController 13 | 14 | static TestClientXMLParserWindowController *sharedInstance = nil; 15 | 16 | - (id)init { 17 | if (self = [super initWithWindowNibName: @"TestClientXMLParserWindow"]) { 18 | myParsedObject = nil; 19 | } 20 | 21 | return self; 22 | } 23 | 24 | #pragma mark - 25 | 26 | + (id)allocWithZone: (NSZone *)zone { 27 | @synchronized(self) { 28 | if (!sharedInstance) { 29 | sharedInstance = [super allocWithZone: zone]; 30 | 31 | return sharedInstance; 32 | } 33 | } 34 | 35 | return nil; 36 | } 37 | 38 | #pragma mark - 39 | 40 | + (TestClientXMLParserWindowController *)sharedController { 41 | @synchronized(self) { 42 | if (!sharedInstance) { 43 | [[self alloc] init]; 44 | } 45 | } 46 | 47 | return sharedInstance; 48 | } 49 | 50 | #pragma mark - 51 | 52 | - (void)awakeFromNib { 53 | [[self window] center]; 54 | } 55 | 56 | #pragma mark - 57 | 58 | - (void)showXMLParserWindow: (id)sender { 59 | [self showWindow: sender]; 60 | } 61 | 62 | - (void)hideXMLParserWindow: (id)sender { 63 | [self close]; 64 | } 65 | 66 | #pragma mark - 67 | 68 | - (void)toggleXMLParserWindow: (id)sender { 69 | if ([[self window] isKeyWindow]) { 70 | [self hideXMLParserWindow: sender]; 71 | } else { 72 | [self showXMLParserWindow: sender]; 73 | } 74 | } 75 | 76 | #pragma mark - 77 | 78 | - (void)parse: (id)sender { 79 | NSData *data = [[myXML string] dataUsingEncoding: NSUTF8StringEncoding]; 80 | XMLRPCEventBasedParser *parser = (XMLRPCEventBasedParser *)[[XMLRPCEventBasedParser alloc] initWithData: data]; 81 | 82 | if (!parser) { 83 | NSAlert *alert = [[[NSAlert alloc] init] autorelease]; 84 | 85 | [alert addButtonWithTitle: @"OK"]; 86 | [alert setMessageText: @"The parser encountered an error."]; 87 | [alert setInformativeText: @"There was a problem creating the XML parser."]; 88 | [alert setAlertStyle: NSCriticalAlertStyle]; 89 | 90 | [alert runModal]; 91 | 92 | return; 93 | } 94 | 95 | [myParsedObject release]; 96 | 97 | myParsedObject = [[parser parse] retain]; 98 | 99 | NSError *parserError = [[[parser parserError] retain] autorelease]; 100 | 101 | [parser release]; 102 | 103 | if (!myParsedObject) { 104 | NSAlert *alert = [[[NSAlert alloc] init] autorelease]; 105 | 106 | [alert addButtonWithTitle: @"OK"]; 107 | [alert setMessageText: @"The parser encountered an error."]; 108 | [alert setInformativeText: [parserError localizedDescription]]; 109 | [alert setAlertStyle: NSCriticalAlertStyle]; 110 | 111 | [alert runModal]; 112 | 113 | return; 114 | } 115 | 116 | [myParserResult reloadData]; 117 | } 118 | 119 | #pragma mark - 120 | 121 | #pragma mark Outline View Data Source Methods 122 | 123 | #pragma mark - 124 | 125 | - (id)outlineView: (NSOutlineView *)outlineView child: (NSInteger)index ofItem: (id)item { 126 | if (item == nil) { 127 | item = myParsedObject; 128 | } 129 | 130 | if ([item isKindOfClass: [NSDictionary class]]) { 131 | return [item objectForKey: [[item allKeys] objectAtIndex: index]]; 132 | } else if ([item isKindOfClass: [NSArray class]]) { 133 | return [item objectAtIndex: index]; 134 | } 135 | 136 | return item; 137 | } 138 | 139 | - (BOOL)outlineView: (NSOutlineView *)outlineView isItemExpandable: (id)item { 140 | if ([item isKindOfClass: [NSDictionary class]] || [item isKindOfClass: [NSArray class]]) { 141 | if ([item count] > 0) { 142 | return YES; 143 | } 144 | } 145 | 146 | return NO; 147 | } 148 | 149 | - (NSInteger)outlineView: (NSOutlineView *)outlineView numberOfChildrenOfItem: (id)item { 150 | if (item == nil) { 151 | item = myParsedObject; 152 | } 153 | 154 | if ([item isKindOfClass: [NSDictionary class]] || [item isKindOfClass: [NSArray class]]) { 155 | return [item count]; 156 | } else if (item != nil) { 157 | return 1; 158 | } 159 | 160 | return 0; 161 | } 162 | 163 | - (id)outlineView: (NSOutlineView *)outlineView objectValueForTableColumn: (NSTableColumn *)tableColumn byItem: (id)item { 164 | NSString *columnIdentifier = (NSString *)[tableColumn identifier]; 165 | 166 | if ([columnIdentifier isEqualToString: @"type"]) { 167 | id parentObject = [outlineView parentForItem: item] ? [outlineView parentForItem: item] : myParsedObject; 168 | 169 | if ([parentObject isKindOfClass: [NSDictionary class]]) { 170 | return [NSString stringWithFormat: @"\"%@\", %@", [[parentObject allKeysForObject: item] objectAtIndex: 0], [self typeForItem: item]]; 171 | } else if ([parentObject isKindOfClass: [NSArray class]]) { 172 | return [NSString stringWithFormat: @"Item %d, %@", [parentObject indexOfObject: item], [self typeForItem: item]]; 173 | } else { 174 | return [self typeForItem: item]; 175 | } 176 | } else { 177 | if ([item isKindOfClass: [NSDictionary class]] || [item isKindOfClass: [NSArray class]]) { 178 | return [NSString stringWithFormat: @"%d items", [item count]]; 179 | } else { 180 | return [NSString stringWithFormat: @"\"%@\"", item]; 181 | } 182 | } 183 | 184 | return nil; 185 | } 186 | 187 | @end 188 | 189 | #pragma mark - 190 | 191 | @implementation TestClientXMLParserWindowController (TestClientXMLParserWindowControllerPrivate) 192 | 193 | - (NSString *)typeForItem: (id)item { 194 | NSString *type; 195 | 196 | if ([item isKindOfClass: [NSArray class]]) { 197 | type = @"Array"; 198 | } else if ([item isKindOfClass: [NSDictionary class]]) { 199 | type = @"Dictionary"; 200 | } else if ([item isKindOfClass: [NSString class]]) { 201 | type = @"String"; 202 | } else if ([item isKindOfClass: [NSNumber class]]) { 203 | type = @"Number"; 204 | } else if ([item isKindOfClass: [NSDate class]]) { 205 | type = @"Date"; 206 | } else if ([item isKindOfClass: [NSData class]]) { 207 | type = @"Data"; 208 | } else { 209 | type = @"Object"; 210 | } 211 | 212 | return type; 213 | } 214 | 215 | @end 216 | -------------------------------------------------------------------------------- /Tools/Test Client/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | int main(int argc, char *argv[]) { 4 | return NSApplicationMain(argc, (const char **)argv); 5 | } 6 | -------------------------------------------------------------------------------- /Tools/Test Server/README.md: -------------------------------------------------------------------------------- 1 | # The XML-RPC Test Server 2 | 3 | The XML-RPC test server is written in Java and utilizes the Apache XML-RPC server library. This test server can be useful when debugging problems with the XML-RPC framework. 4 | 5 | # Usage 6 | 7 | To start the server simply call Ant from the XML-RPC test server directory: 8 | 9 | $ ant 10 | 11 | This will invoke Ant with the default target. The default target will issue the following targets in the following order, the last target is the default invoked by Ant: 12 | 13 | - init 14 | - compile 15 | - pre-jar 16 | - jar 17 | - run 18 | 19 | These targets each play a role in building and running the Java project. The details of each target can be found in the Ant build script. 20 | 21 | Finally, the XML-RPC test server should now be running. To start the server simply click on the "Start" button. This will start the test server on port 8080, available for any incoming XML-RPC requests. 22 | 23 | ## Creating XML-RPC server handlers 24 | 25 | The XML-RPC test server exposes XML-RPC methods through server handlers. Each server handler is simply a Java class that is registered with the Apache XML-RPC library. Here is an example of the Echo handler provided in the distribution: 26 | 27 | public class Echo { 28 | public String echo(String message) { 29 | return message; 30 | } 31 | } 32 | 33 | This handler simply takes a message provided in the XML-RPC request and returns it in the XML-RPC response. To register this handler with the XML-RPC server simply add it to the propertyHandlerMapping in Server.java: 34 | 35 | try { 36 | propertyHandlerMapping.addHandler("Echo", Echo.class); 37 | 38 | this.embeddedXmlRpcServer.setHandlerMapping(propertyHandlerMapping); 39 | } catch (Exception e) { 40 | this.controlPanel.addLogMessage(e.getMessage()); 41 | } 42 | 43 | The handler is now available to any incoming XML-RPC requests. 44 | 45 | # License 46 | 47 | Copyright (c) 2012 Eric Czarny. 48 | 49 | The Cocoa XML-RPC Framework should be accompanied by a LICENSE file, this file contains the license relevant to this distribution. 50 | 51 | If no LICENSE exists please contact Eric Czarny . 52 | -------------------------------------------------------------------------------- /Tools/Test Server/build.properties: -------------------------------------------------------------------------------- 1 | project.name = test-server 2 | project.main = com.divisiblebyzero.xmlrpc.Application 3 | project.base.directory = . 4 | project.source.directory = ${project.base.directory}/src 5 | project.libraries = commons-logging-1.1.1.jar log4j-1.2.15.jar ws-commons-util-1.0.2.jar xmlrpc-common-3.1.jar xmlrpc-server-3.1.jar 6 | 7 | build.directory = ${project.base.directory} 8 | build.classes.directory = ${build.directory}/classes 9 | 10 | distribution.directory = ${project.base.directory}/lib 11 | distribution.jar = ${distribution.directory}/${project.name}.jar 12 | 13 | resources.directory = ${project.base.directory}/resources 14 | 15 | jar.compress = true 16 | 17 | compiler.debug = true 18 | -------------------------------------------------------------------------------- /Tools/Test Server/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | Stub for project installation. 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Tools/Test Server/lib/commons-logging-1.1.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikolaykasyanov/xmlrpc/f54c8c970c2296f0a1a3f599a25adb5f85dfc128/Tools/Test Server/lib/commons-logging-1.1.1.jar -------------------------------------------------------------------------------- /Tools/Test Server/lib/log4j-1.2.15.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikolaykasyanov/xmlrpc/f54c8c970c2296f0a1a3f599a25adb5f85dfc128/Tools/Test Server/lib/log4j-1.2.15.jar -------------------------------------------------------------------------------- /Tools/Test Server/lib/ws-commons-util-1.0.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikolaykasyanov/xmlrpc/f54c8c970c2296f0a1a3f599a25adb5f85dfc128/Tools/Test Server/lib/ws-commons-util-1.0.2.jar -------------------------------------------------------------------------------- /Tools/Test Server/lib/xmlrpc-common-3.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikolaykasyanov/xmlrpc/f54c8c970c2296f0a1a3f599a25adb5f85dfc128/Tools/Test Server/lib/xmlrpc-common-3.1.jar -------------------------------------------------------------------------------- /Tools/Test Server/lib/xmlrpc-server-3.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikolaykasyanov/xmlrpc/f54c8c970c2296f0a1a3f599a25adb5f85dfc128/Tools/Test Server/lib/xmlrpc-server-3.1.jar -------------------------------------------------------------------------------- /Tools/Test Server/resources/handlers.properties: -------------------------------------------------------------------------------- 1 | # 2 | # XML-RPC Server Handlers 3 | # 4 | 5 | Echo=com.divisiblebyzero.xmlrpc.model.handlers.Echo 6 | -------------------------------------------------------------------------------- /Tools/Test Server/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Tools/Test Server/server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | java -jar lib/test-server.jar $* 4 | -------------------------------------------------------------------------------- /Tools/Test Server/src/com/divisiblebyzero/xmlrpc/Application.java: -------------------------------------------------------------------------------- 1 | package com.divisiblebyzero.xmlrpc; 2 | 3 | import javax.swing.UIManager; 4 | 5 | import org.apache.log4j.Logger; 6 | 7 | import com.divisiblebyzero.xmlrpc.view.XmlRpcServerControlPanel; 8 | 9 | class Application { 10 | private static Logger logger = Logger.getLogger(Application.class); 11 | 12 | private Application() { 13 | new XmlRpcServerControlPanel(); 14 | } 15 | 16 | public static void main(String args[]) { 17 | try { 18 | UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 19 | } catch (Exception e) { 20 | logger.error("Unable to modify application look and feel."); 21 | } 22 | 23 | new Application(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Tools/Test Server/src/com/divisiblebyzero/xmlrpc/controller/XmlRpcServerControlPanelController.java: -------------------------------------------------------------------------------- 1 | package com.divisiblebyzero.xmlrpc.controller; 2 | 3 | import java.awt.event.ActionEvent; 4 | import java.awt.event.ActionListener; 5 | 6 | import com.divisiblebyzero.xmlrpc.model.Server; 7 | import com.divisiblebyzero.xmlrpc.view.XmlRpcServerControlPanel; 8 | 9 | public class XmlRpcServerControlPanelController implements ActionListener { 10 | private XmlRpcServerControlPanel controlPanel; 11 | private Server xmlRpcServer; 12 | 13 | public XmlRpcServerControlPanelController(XmlRpcServerControlPanel controlPanel) { 14 | this.controlPanel = controlPanel; 15 | this.xmlRpcServer = new Server(this.controlPanel); 16 | } 17 | 18 | public void actionPerformed(ActionEvent actionEvent) { 19 | String actionCommand = actionEvent.getActionCommand(); 20 | 21 | if (actionCommand.equals("Start")) { 22 | this.startXmlRpcServer(); 23 | } else if (actionCommand.equals("Stop")) { 24 | this.stopXmlRpcServer(); 25 | } else if (actionCommand.equals("Restart")) { 26 | this.restartXmlRpcServer(); 27 | } 28 | 29 | this.controlPanel.refreshControls(); 30 | } 31 | 32 | public boolean isXmlRpcServerRunning() { 33 | return this.xmlRpcServer.isRunning(); 34 | } 35 | 36 | private void startXmlRpcServer() { 37 | this.controlPanel.addLogMessage("Starting the XML-RPC server."); 38 | 39 | this.xmlRpcServer.startEmbeddedWebServer(); 40 | } 41 | 42 | private void stopXmlRpcServer() { 43 | if (this.xmlRpcServer == null) { 44 | this.controlPanel.addLogMessage("Unable to stop the XML-RPC server, none could be found."); 45 | 46 | return; 47 | } 48 | 49 | this.controlPanel.addLogMessage("Stopping the XML-RPC server."); 50 | 51 | this.xmlRpcServer.stopEmbeddedWebServer(); 52 | } 53 | 54 | private void restartXmlRpcServer() { 55 | if (this.xmlRpcServer == null) { 56 | this.controlPanel.addLogMessage("Unable to restart the XML-RPC server, none could be found."); 57 | 58 | return; 59 | } 60 | 61 | this.controlPanel.addLogMessage("Restarting the XML-RPC server."); 62 | 63 | this.xmlRpcServer.stopEmbeddedWebServer(); 64 | 65 | this.xmlRpcServer.startEmbeddedWebServer(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Tools/Test Server/src/com/divisiblebyzero/xmlrpc/model/Server.java: -------------------------------------------------------------------------------- 1 | package com.divisiblebyzero.xmlrpc.model; 2 | 3 | import com.divisiblebyzero.xmlrpc.view.XmlRpcServerControlPanel; 4 | 5 | import org.apache.xmlrpc.server.PropertyHandlerMapping; 6 | import org.apache.xmlrpc.server.XmlRpcServer; 7 | import org.apache.xmlrpc.webserver.WebServer; 8 | 9 | public class Server { 10 | private static final int port = 8080; 11 | private WebServer embeddedWebServer; 12 | private XmlRpcServer embeddedXmlRpcServer; 13 | private boolean running; 14 | private XmlRpcServerControlPanel controlPanel; 15 | 16 | public Server(XmlRpcServerControlPanel controlPanel) { 17 | this.embeddedWebServer = new WebServer(Server.port); 18 | this.embeddedXmlRpcServer = this.embeddedWebServer.getXmlRpcServer(); 19 | this.running = false; 20 | this.controlPanel = controlPanel; 21 | 22 | PropertyHandlerMapping propertyHandlerMapping = new PropertyHandlerMapping(); 23 | 24 | try { 25 | propertyHandlerMapping.load(Thread.currentThread().getContextClassLoader(), "handlers.properties"); 26 | } catch (Exception e) { 27 | this.controlPanel.addLogMessage(e.getMessage()); 28 | } 29 | 30 | this.embeddedXmlRpcServer.setHandlerMapping(propertyHandlerMapping); 31 | } 32 | 33 | public void startEmbeddedWebServer() { 34 | try { 35 | this.embeddedWebServer.start(); 36 | 37 | this.controlPanel.addLogMessage("The XML-RPC server has been started on port " + Server.port + "."); 38 | } catch (Exception e) { 39 | this.controlPanel.addLogMessage(e.getMessage()); 40 | } 41 | 42 | this.running = true; 43 | } 44 | 45 | public void stopEmbeddedWebServer() { 46 | try { 47 | this.embeddedWebServer.shutdown(); 48 | 49 | this.controlPanel.addLogMessage("The XML-RPC server has been stopped."); 50 | } catch (Exception e) { 51 | this.controlPanel.addLogMessage(e.getMessage()); 52 | } 53 | 54 | this.running = false; 55 | } 56 | 57 | public boolean isRunning() { 58 | return this.running; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Tools/Test Server/src/com/divisiblebyzero/xmlrpc/model/handlers/Echo.java: -------------------------------------------------------------------------------- 1 | package com.divisiblebyzero.xmlrpc.model.handlers; 2 | 3 | public class Echo { 4 | public String echo(String message) { 5 | return message; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Tools/Test Server/src/com/divisiblebyzero/xmlrpc/view/XmlRpcServerControlPanel.java: -------------------------------------------------------------------------------- 1 | package com.divisiblebyzero.xmlrpc.view; 2 | 3 | import java.awt.BorderLayout; 4 | import java.awt.Color; 5 | import java.awt.Container; 6 | import java.awt.Dimension; 7 | import java.awt.Font; 8 | import java.awt.Toolkit; 9 | 10 | import javax.swing.BorderFactory; 11 | import javax.swing.JButton; 12 | import javax.swing.JFrame; 13 | import javax.swing.JLabel; 14 | import javax.swing.JPanel; 15 | import javax.swing.JScrollPane; 16 | import javax.swing.JTextPane; 17 | 18 | import com.divisiblebyzero.xmlrpc.controller.XmlRpcServerControlPanelController; 19 | 20 | public class XmlRpcServerControlPanel extends JFrame { 21 | private static final long serialVersionUID = -7835812670356078909L; 22 | private XmlRpcServerControlPanelController xmlRpcServerControlPanelController; 23 | private JTextPane logMessageTextPane; 24 | private JButton startButton; 25 | private JButton stopButton; 26 | private JButton restartButton; 27 | 28 | public XmlRpcServerControlPanel() { 29 | super("Control Panel"); 30 | 31 | this.xmlRpcServerControlPanelController = new XmlRpcServerControlPanelController(this); 32 | 33 | int x = Toolkit.getDefaultToolkit().getScreenSize().width; 34 | int y = Toolkit.getDefaultToolkit().getScreenSize().height; 35 | 36 | int width, height; 37 | 38 | width = 500; 39 | height = 500; 40 | 41 | this.setBounds(((x - (width)) / 2), ((y - (height)) / 2) - (height / 4), width, height); 42 | 43 | this.setResizable(false); 44 | 45 | this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 46 | 47 | this.initialize(); 48 | 49 | this.setVisible(true); 50 | } 51 | 52 | private void initialize() { 53 | Container container = this.getContentPane(); 54 | 55 | container.setLayout(new BorderLayout()); 56 | 57 | /* North Panel */ 58 | container.add(new JPanel(), BorderLayout.NORTH); 59 | 60 | /* East Panel */ 61 | container.add(new JPanel(), BorderLayout.EAST); 62 | 63 | /* Center Panel */ 64 | JPanel center = new JPanel(); 65 | center.setBorder(BorderFactory.createTitledBorder(" " + "Server Log" + " ")); 66 | 67 | this.logMessageTextPane = new JTextPane(); 68 | 69 | this.logMessageTextPane.setEditable(false); 70 | this.logMessageTextPane.setBackground(Color.WHITE); 71 | this.logMessageTextPane.setFont(new Font("Monospaced", Font.PLAIN, 12)); 72 | 73 | this.logMessageTextPane.setText("Server awaiting action..."); 74 | 75 | JScrollPane scrollableTextPane = new JScrollPane(this.logMessageTextPane); 76 | scrollableTextPane.setBorder(BorderFactory.createLineBorder(Color.GRAY)); 77 | scrollableTextPane.setPreferredSize(new Dimension(435, 374)); 78 | 79 | center.add(scrollableTextPane); 80 | 81 | container.add(center, BorderLayout.CENTER); 82 | 83 | /* South Panel */ 84 | container.add(this.createSouthernPanel(), BorderLayout.SOUTH); 85 | 86 | /* West Panel */ 87 | container.add(new JPanel(), BorderLayout.WEST); 88 | } 89 | 90 | private JPanel createSouthernPanel() { 91 | JPanel south = new JPanel(); 92 | 93 | south.setPreferredSize(new Dimension(425, 47)); 94 | 95 | /* Start & Stop Panel */ 96 | JPanel startAndStopPanel = new JPanel(); 97 | 98 | startButton = new JButton("Start"); 99 | 100 | startButton.setPreferredSize(new Dimension(85, 25)); 101 | startButton.addActionListener(this.xmlRpcServerControlPanelController); 102 | 103 | startAndStopPanel.add(startButton); 104 | 105 | startAndStopPanel.add(new JLabel(" / ")); 106 | 107 | stopButton = new JButton("Stop"); 108 | 109 | stopButton.setPreferredSize(new Dimension(85, 25)); 110 | stopButton.addActionListener(this.xmlRpcServerControlPanelController); 111 | 112 | startAndStopPanel.add(stopButton); 113 | 114 | south.add(startAndStopPanel); 115 | 116 | JPanel padding = new JPanel(); 117 | padding.setPreferredSize(new Dimension(150, 25)); 118 | 119 | south.add(padding); 120 | 121 | /* Restart Panel */ 122 | JPanel restartPanel = new JPanel(); 123 | 124 | restartButton = new JButton("Restart"); 125 | 126 | restartButton.setPreferredSize(new Dimension(95, 25)); 127 | restartButton.addActionListener(this.xmlRpcServerControlPanelController); 128 | 129 | restartPanel.add(restartButton); 130 | 131 | south.add(restartPanel); 132 | 133 | this.refreshControls(); 134 | 135 | return south; 136 | } 137 | 138 | public void addLogMessage(String message) { 139 | String existingLogMessages = this.logMessageTextPane.getText() + "\n"; 140 | 141 | this.logMessageTextPane.setText(existingLogMessages + message); 142 | } 143 | 144 | public void refreshControls() { 145 | if (this.xmlRpcServerControlPanelController.isXmlRpcServerRunning()) { 146 | this.startButton.setEnabled(false); 147 | this.stopButton.setEnabled(true); 148 | this.restartButton.setEnabled(true); 149 | } else { 150 | this.startButton.setEnabled(true); 151 | this.stopButton.setEnabled(false); 152 | this.restartButton.setEnabled(false); 153 | } 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /Unit Tests/XMLRPCParserTest.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface XMLRPCParserTest : SenTestCase { 4 | NSDictionary *myTestCases; 5 | } 6 | 7 | - (void)testEventBasedParser; 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /Unit Tests/XMLRPCParserTest.m: -------------------------------------------------------------------------------- 1 | #import "XMLRPCParserTest.h" 2 | #import "XMLRPCEventBasedParser.h" 3 | 4 | @interface XMLRPCParserTest (XMLRPCParserTestPrivate) 5 | 6 | - (NSBundle *)unitTestBundle; 7 | 8 | #pragma mark - 9 | 10 | - (NSDictionary *)testCases; 11 | 12 | #pragma mark - 13 | 14 | - (BOOL)parsedResult: (id)parsedResult isEqualToTestCaseResult: (id)testCaseResult; 15 | 16 | #pragma mark - 17 | 18 | - (BOOL)parsedResult: (id)parsedResult isEqualToArray: (NSArray *)array; 19 | 20 | - (BOOL)parsedResult: (id)parsedResult isEqualToDictionary: (NSDictionary *)dictionary; 21 | 22 | @end 23 | 24 | #pragma mark - 25 | 26 | @implementation XMLRPCParserTest 27 | 28 | - (void)setUp { 29 | myTestCases = [[self testCases] retain]; 30 | } 31 | 32 | #pragma mark - 33 | 34 | - (void)testEventBasedParser { 35 | NSEnumerator *testCaseEnumerator = [myTestCases keyEnumerator]; 36 | id testCaseName; 37 | 38 | while (testCaseName = [testCaseEnumerator nextObject]) { 39 | NSString *testCase = [[self unitTestBundle] pathForResource: testCaseName ofType: @"xml"]; 40 | NSData *testCaseData =[[[NSData alloc] initWithContentsOfFile: testCase] autorelease]; 41 | XMLRPCEventBasedParser *parser = [[[XMLRPCEventBasedParser alloc] initWithData: testCaseData] autorelease]; 42 | id testCaseResult = [myTestCases objectForKey: testCaseName]; 43 | id parsedResult = [parser parse]; 44 | 45 | STAssertTrue([self parsedResult: parsedResult isEqualToTestCaseResult: testCaseResult], @"The test case failed: %@", testCaseName); 46 | } 47 | } 48 | 49 | #pragma mark - 50 | 51 | - (void)tearDown { 52 | [myTestCases release]; 53 | } 54 | 55 | @end 56 | 57 | #pragma mark - 58 | 59 | @implementation XMLRPCParserTest (XMLRPCParserTestPrivate) 60 | 61 | - (NSBundle *)unitTestBundle { 62 | return [NSBundle bundleForClass: [XMLRPCParserTest class]]; 63 | } 64 | 65 | #pragma mark - 66 | 67 | - (NSDictionary *)testCases { 68 | NSString *file = [[self unitTestBundle] pathForResource: @"TestCases" ofType: @"plist"]; 69 | NSDictionary *testCases = [[[NSDictionary alloc] initWithContentsOfFile: file] autorelease]; 70 | 71 | return testCases; 72 | } 73 | 74 | #pragma mark - 75 | 76 | - (BOOL)parsedResult: (id)parsedResult isEqualToTestCaseResult: (id)testCaseResult { 77 | if ([testCaseResult isKindOfClass: [NSArray class]]) { 78 | return [self parsedResult: parsedResult isEqualToArray: testCaseResult]; 79 | } else if ([testCaseResult isKindOfClass: [NSDictionary class]]) { 80 | return [self parsedResult: parsedResult isEqualToDictionary: testCaseResult]; 81 | } 82 | 83 | if ([testCaseResult isKindOfClass: [NSNumber class]]) { 84 | return [parsedResult isEqualToNumber: testCaseResult]; 85 | } else if ([testCaseResult isKindOfClass: [NSString class]]) { 86 | return [parsedResult isEqualToString: testCaseResult]; 87 | } else if ([testCaseResult isKindOfClass: [NSDate class]]) { 88 | return [parsedResult isEqualToDate: testCaseResult]; 89 | } else if ([testCaseResult isKindOfClass: [NSData class]]) { 90 | return [parsedResult isEqualToData: testCaseResult]; 91 | } 92 | 93 | return YES; 94 | } 95 | 96 | #pragma mark - 97 | 98 | - (BOOL)parsedResult: (id)parsedResult isEqualToArray: (NSArray *)array { 99 | NSEnumerator *arrayEnumerator = [array objectEnumerator]; 100 | id arrayElement; 101 | 102 | if (![parsedResult isKindOfClass: [NSArray class]]) { 103 | return NO; 104 | } 105 | 106 | if ([parsedResult count] != [array count]) { 107 | return NO; 108 | } 109 | 110 | if ([parsedResult isEqualToArray: array]) { 111 | return YES; 112 | } 113 | 114 | while (arrayElement = [arrayEnumerator nextObject]) { 115 | NSInteger index = [array indexOfObject: arrayElement]; 116 | 117 | if (![self parsedResult: [parsedResult objectAtIndex: index] isEqualToTestCaseResult: arrayElement]) { 118 | return NO; 119 | } 120 | } 121 | 122 | return YES; 123 | } 124 | 125 | - (BOOL)parsedResult: (id)parsedResult isEqualToDictionary: (NSDictionary *)dictionary { 126 | NSEnumerator *keyEnumerator = [dictionary keyEnumerator]; 127 | id key; 128 | 129 | if (![parsedResult isKindOfClass: [NSDictionary class]]) { 130 | return NO; 131 | } 132 | 133 | if ([parsedResult count] != [dictionary count]) { 134 | return NO; 135 | } 136 | 137 | if ([parsedResult isEqualToDictionary: dictionary]) { 138 | return YES; 139 | } 140 | 141 | while (key = [keyEnumerator nextObject]) { 142 | if (![self parsedResult: [parsedResult objectForKey: key] isEqualToTestCaseResult: [dictionary objectForKey: key]]) { 143 | return NO; 144 | } 145 | } 146 | 147 | return YES; 148 | } 149 | 150 | @end 151 | -------------------------------------------------------------------------------- /XMLRPC.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | #import 6 | -------------------------------------------------------------------------------- /XMLRPC.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | -------------------------------------------------------------------------------- /XMLRPC.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 033836831527905D00EF8E8A /* NSData+Base64.h in Headers */ = {isa = PBXBuildFile; fileRef = 033836811527905D00EF8E8A /* NSData+Base64.h */; }; 11 | 033836841527905D00EF8E8A /* NSData+Base64.h in Headers */ = {isa = PBXBuildFile; fileRef = 033836811527905D00EF8E8A /* NSData+Base64.h */; settings = {ATTRIBUTES = (Public, ); }; }; 12 | 033836851527905D00EF8E8A /* NSData+Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = 033836821527905D00EF8E8A /* NSData+Base64.m */; }; 13 | 033836861527905D00EF8E8A /* NSData+Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = 033836821527905D00EF8E8A /* NSData+Base64.m */; }; 14 | 0707047810114B9400CB7702 /* XMLRPCEventBasedParserDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0707047610114B9400CB7702 /* XMLRPCEventBasedParserDelegate.h */; }; 15 | 0707047910114B9400CB7702 /* XMLRPCEventBasedParserDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 0707047710114B9400CB7702 /* XMLRPCEventBasedParserDelegate.m */; }; 16 | 07075BAE10C5FE3800589A27 /* AlternativeDateFormatsTestCase.xml in Resources */ = {isa = PBXBuildFile; fileRef = 07075BAD10C5FE3800589A27 /* AlternativeDateFormatsTestCase.xml */; }; 17 | 07452BE30E469C9000A57686 /* XMLRPCConnectionDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 07452BE20E469C9000A57686 /* XMLRPCConnectionDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 18 | 075137FB0E429E560019E4F6 /* XMLRPCConnectionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 075137F90E429E560019E4F6 /* XMLRPCConnectionManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; 19 | 075137FC0E429E560019E4F6 /* XMLRPCConnectionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 075137FA0E429E560019E4F6 /* XMLRPCConnectionManager.m */; }; 20 | 0759A6F31143495E000DFE98 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0759A6F11143495E000DFE98 /* InfoPlist.strings */; }; 21 | 0799AF270F6724E300B71B22 /* XMLRPC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* XMLRPC.framework */; }; 22 | 0799AF5E0F67266400B71B22 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0799AF5D0F67266400B71B22 /* SenTestingKit.framework */; }; 23 | 07A0A9071016A51000CEE3C7 /* EmptyBooleanTestCase.xml in Resources */ = {isa = PBXBuildFile; fileRef = 07A0A9021016A51000CEE3C7 /* EmptyBooleanTestCase.xml */; }; 24 | 07A0A9081016A51000CEE3C7 /* EmptyDataTestCase.xml in Resources */ = {isa = PBXBuildFile; fileRef = 07A0A9031016A51000CEE3C7 /* EmptyDataTestCase.xml */; }; 25 | 07A0A9091016A51000CEE3C7 /* EmptyDoubleTestCase.xml in Resources */ = {isa = PBXBuildFile; fileRef = 07A0A9041016A51000CEE3C7 /* EmptyDoubleTestCase.xml */; }; 26 | 07A0A90A1016A51000CEE3C7 /* EmptyIntegerTestCase.xml in Resources */ = {isa = PBXBuildFile; fileRef = 07A0A9051016A51000CEE3C7 /* EmptyIntegerTestCase.xml */; }; 27 | 07A0A90B1016A51000CEE3C7 /* EmptyStringTestCase.xml in Resources */ = {isa = PBXBuildFile; fileRef = 07A0A9061016A51000CEE3C7 /* EmptyStringTestCase.xml */; }; 28 | 07B0C6070E33A659006453B4 /* NSStringAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B0C5F80E33A659006453B4 /* NSStringAdditions.h */; }; 29 | 07B0C6080E33A659006453B4 /* NSStringAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B0C5F90E33A659006453B4 /* NSStringAdditions.m */; }; 30 | 07B0C6090E33A659006453B4 /* XMLRPC.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B0C5FA0E33A659006453B4 /* XMLRPC.h */; settings = {ATTRIBUTES = (Public, ); }; }; 31 | 07B0C60A0E33A659006453B4 /* XMLRPCConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B0C5FB0E33A659006453B4 /* XMLRPCConnection.h */; settings = {ATTRIBUTES = (Public, ); }; }; 32 | 07B0C60B0E33A659006453B4 /* XMLRPCConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B0C5FC0E33A659006453B4 /* XMLRPCConnection.m */; }; 33 | 07B0C60E0E33A659006453B4 /* XMLRPCDefaultEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B0C5FF0E33A659006453B4 /* XMLRPCDefaultEncoder.h */; }; 34 | 07B0C60F0E33A659006453B4 /* XMLRPCDefaultEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B0C6000E33A659006453B4 /* XMLRPCDefaultEncoder.m */; }; 35 | 07B0C6100E33A659006453B4 /* XMLRPCRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B0C6010E33A659006453B4 /* XMLRPCRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; 36 | 07B0C6110E33A659006453B4 /* XMLRPCRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B0C6020E33A659006453B4 /* XMLRPCRequest.m */; }; 37 | 07B0C6120E33A659006453B4 /* XMLRPCResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B0C6030E33A659006453B4 /* XMLRPCResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; 38 | 07B0C6130E33A659006453B4 /* XMLRPCResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B0C6040E33A659006453B4 /* XMLRPCResponse.m */; }; 39 | 07B0C6170E33A672006453B4 /* XMLRPC.pch in Headers */ = {isa = PBXBuildFile; fileRef = 07B0C6160E33A672006453B4 /* XMLRPC.pch */; }; 40 | 07B52BE7101004670015AD8B /* SimpleArrayTestCase.xml in Resources */ = {isa = PBXBuildFile; fileRef = 07B52BE5101004670015AD8B /* SimpleArrayTestCase.xml */; }; 41 | 07B52BE8101004670015AD8B /* SimpleStructTestCase.xml in Resources */ = {isa = PBXBuildFile; fileRef = 07B52BE6101004670015AD8B /* SimpleStructTestCase.xml */; }; 42 | 07B52BEA101004810015AD8B /* TestCases.plist in Resources */ = {isa = PBXBuildFile; fileRef = 07B52BE9101004810015AD8B /* TestCases.plist */; }; 43 | 07B52C03101008670015AD8B /* XMLRPCParserTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B52C02101008670015AD8B /* XMLRPCParserTest.m */; }; 44 | 07BB09891316B65A00E1911C /* DefaultTypeTestCase.xml in Resources */ = {isa = PBXBuildFile; fileRef = 07BB09881316B65A00E1911C /* DefaultTypeTestCase.xml */; }; 45 | 07E761001011788B00E9BDEE /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; }; 46 | 07EF453B0E721A5D009F2708 /* XMLRPCEventBasedParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 07EF45390E721A5D009F2708 /* XMLRPCEventBasedParser.h */; }; 47 | 07EF453C0E721A5D009F2708 /* XMLRPCEventBasedParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 07EF453A0E721A5D009F2708 /* XMLRPCEventBasedParser.m */; }; 48 | 1F59FCE216CADA75005AECF4 /* XMLRPCEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DCADED91529E06900B47A4F /* XMLRPCEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; 49 | 2DCADEDB1529E24300B47A4F /* XMLRPCEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DCADED91529E06900B47A4F /* XMLRPCEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; 50 | 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; }; 51 | 903B0DC212F7581200BD6E09 /* NSStringAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B0C5F80E33A659006453B4 /* NSStringAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 52 | 903B0DC312F7581200BD6E09 /* NSStringAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B0C5F90E33A659006453B4 /* NSStringAdditions.m */; }; 53 | 903B0DC412F7581200BD6E09 /* XMLRPCConnectionDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 07452BE20E469C9000A57686 /* XMLRPCConnectionDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 54 | 903B0DC512F7581200BD6E09 /* XMLRPC.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B0C5FA0E33A659006453B4 /* XMLRPC.h */; settings = {ATTRIBUTES = (Public, ); }; }; 55 | 903B0DC612F7581200BD6E09 /* XMLRPCConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B0C5FB0E33A659006453B4 /* XMLRPCConnection.h */; settings = {ATTRIBUTES = (Public, ); }; }; 56 | 903B0DC712F7581200BD6E09 /* XMLRPCConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B0C5FC0E33A659006453B4 /* XMLRPCConnection.m */; }; 57 | 903B0DC812F7581200BD6E09 /* XMLRPCConnectionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 075137F90E429E560019E4F6 /* XMLRPCConnectionManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; 58 | 903B0DC912F7581200BD6E09 /* XMLRPCConnectionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 075137FA0E429E560019E4F6 /* XMLRPCConnectionManager.m */; }; 59 | 903B0DCA12F7581200BD6E09 /* XMLRPCDefaultEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B0C5FF0E33A659006453B4 /* XMLRPCDefaultEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; 60 | 903B0DCB12F7581200BD6E09 /* XMLRPCDefaultEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B0C6000E33A659006453B4 /* XMLRPCDefaultEncoder.m */; }; 61 | 903B0DCC12F7581200BD6E09 /* XMLRPCEventBasedParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 07EF45390E721A5D009F2708 /* XMLRPCEventBasedParser.h */; settings = {ATTRIBUTES = (Public, ); }; }; 62 | 903B0DCD12F7581200BD6E09 /* XMLRPCEventBasedParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 07EF453A0E721A5D009F2708 /* XMLRPCEventBasedParser.m */; }; 63 | 903B0DCE12F7581200BD6E09 /* XMLRPCEventBasedParserDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0707047610114B9400CB7702 /* XMLRPCEventBasedParserDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 64 | 903B0DCF12F7581200BD6E09 /* XMLRPCEventBasedParserDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 0707047710114B9400CB7702 /* XMLRPCEventBasedParserDelegate.m */; }; 65 | 903B0DD012F7581200BD6E09 /* XMLRPCRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B0C6010E33A659006453B4 /* XMLRPCRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; 66 | 903B0DD112F7581200BD6E09 /* XMLRPCRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B0C6020E33A659006453B4 /* XMLRPCRequest.m */; }; 67 | 903B0DD212F7581200BD6E09 /* XMLRPCResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B0C6030E33A659006453B4 /* XMLRPCResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; 68 | 903B0DD312F7581200BD6E09 /* XMLRPCResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 07B0C6040E33A659006453B4 /* XMLRPCResponse.m */; }; 69 | 903B0DD412F7581F00BD6E09 /* XMLRPC.pch in Headers */ = {isa = PBXBuildFile; fileRef = 07B0C6160E33A672006453B4 /* XMLRPC.pch */; settings = {ATTRIBUTES = (Public, ); }; }; 70 | /* End PBXBuildFile section */ 71 | 72 | /* Begin PBXContainerItemProxy section */ 73 | 0799AF180F67240B00B71B22 /* PBXContainerItemProxy */ = { 74 | isa = PBXContainerItemProxy; 75 | containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; 76 | proxyType = 1; 77 | remoteGlobalIDString = 8DC2EF4F0486A6940098B216; 78 | remoteInfo = XMLRPC; 79 | }; 80 | /* End PBXContainerItemProxy section */ 81 | 82 | /* Begin PBXFileReference section */ 83 | 033836811527905D00EF8E8A /* NSData+Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Base64.h"; sourceTree = ""; }; 84 | 033836821527905D00EF8E8A /* NSData+Base64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+Base64.m"; sourceTree = ""; }; 85 | 0707047610114B9400CB7702 /* XMLRPCEventBasedParserDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLRPCEventBasedParserDelegate.h; sourceTree = ""; }; 86 | 0707047710114B9400CB7702 /* XMLRPCEventBasedParserDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMLRPCEventBasedParserDelegate.m; sourceTree = ""; }; 87 | 07075BAD10C5FE3800589A27 /* AlternativeDateFormatsTestCase.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = AlternativeDateFormatsTestCase.xml; path = "Resources/Test Cases/AlternativeDateFormatsTestCase.xml"; sourceTree = ""; }; 88 | 07127C580F4266F4009C7476 /* Common.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Common.xcconfig; path = Configurations/Common.xcconfig; sourceTree = ""; }; 89 | 07127C590F4266F4009C7476 /* CommonDevelopment.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = CommonDevelopment.xcconfig; path = Configurations/CommonDevelopment.xcconfig; sourceTree = ""; }; 90 | 07127C5A0F4266F4009C7476 /* CommonRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = CommonRelease.xcconfig; path = Configurations/CommonRelease.xcconfig; sourceTree = ""; }; 91 | 07452BE20E469C9000A57686 /* XMLRPCConnectionDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLRPCConnectionDelegate.h; sourceTree = ""; }; 92 | 075137F90E429E560019E4F6 /* XMLRPCConnectionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLRPCConnectionManager.h; sourceTree = ""; }; 93 | 075137FA0E429E560019E4F6 /* XMLRPCConnectionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMLRPCConnectionManager.m; sourceTree = ""; }; 94 | 0759A6F21143495E000DFE98 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = Languages/English.lproj/InfoPlist.strings; sourceTree = ""; }; 95 | 0799AF030F6721FF00B71B22 /* XMLRPCUnitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XMLRPCUnitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; 96 | 0799AF040F6721FF00B71B22 /* XMLRPCUnitTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "XMLRPCUnitTests-Info.plist"; path = "Resources/Property Lists/XMLRPCUnitTests-Info.plist"; sourceTree = ""; }; 97 | 0799AF0A0F67227F00B71B22 /* XMLRPCUnitTests.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = XMLRPCUnitTests.xcconfig; path = Configurations/XMLRPCUnitTests.xcconfig; sourceTree = ""; }; 98 | 0799AF0B0F67227F00B71B22 /* XMLRPCUnitTestsDevelopment.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = XMLRPCUnitTestsDevelopment.xcconfig; path = Configurations/XMLRPCUnitTestsDevelopment.xcconfig; sourceTree = ""; }; 99 | 0799AF0C0F67227F00B71B22 /* XMLRPCUnitTestsRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = XMLRPCUnitTestsRelease.xcconfig; path = Configurations/XMLRPCUnitTestsRelease.xcconfig; sourceTree = ""; }; 100 | 0799AF0F0F6722D600B71B22 /* XMLRPC.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = XMLRPC.xcconfig; path = Configurations/XMLRPC.xcconfig; sourceTree = ""; }; 101 | 0799AF100F6722D600B71B22 /* XMLRPCDevelopment.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = XMLRPCDevelopment.xcconfig; path = Configurations/XMLRPCDevelopment.xcconfig; sourceTree = ""; }; 102 | 0799AF110F6722D600B71B22 /* XMLRPCRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = XMLRPCRelease.xcconfig; path = Configurations/XMLRPCRelease.xcconfig; sourceTree = ""; }; 103 | 0799AF280F67254B00B71B22 /* XMLRPC-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "XMLRPC-Info.plist"; path = "Resources/Property Lists/XMLRPC-Info.plist"; sourceTree = ""; }; 104 | 0799AF5D0F67266400B71B22 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; }; 105 | 07A0A9021016A51000CEE3C7 /* EmptyBooleanTestCase.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = EmptyBooleanTestCase.xml; path = "Resources/Test Cases/EmptyBooleanTestCase.xml"; sourceTree = ""; }; 106 | 07A0A9031016A51000CEE3C7 /* EmptyDataTestCase.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = EmptyDataTestCase.xml; path = "Resources/Test Cases/EmptyDataTestCase.xml"; sourceTree = ""; }; 107 | 07A0A9041016A51000CEE3C7 /* EmptyDoubleTestCase.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = EmptyDoubleTestCase.xml; path = "Resources/Test Cases/EmptyDoubleTestCase.xml"; sourceTree = ""; }; 108 | 07A0A9051016A51000CEE3C7 /* EmptyIntegerTestCase.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = EmptyIntegerTestCase.xml; path = "Resources/Test Cases/EmptyIntegerTestCase.xml"; sourceTree = ""; }; 109 | 07A0A9061016A51000CEE3C7 /* EmptyStringTestCase.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = EmptyStringTestCase.xml; path = "Resources/Test Cases/EmptyStringTestCase.xml"; sourceTree = ""; }; 110 | 07B0C5F80E33A659006453B4 /* NSStringAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSStringAdditions.h; sourceTree = ""; }; 111 | 07B0C5F90E33A659006453B4 /* NSStringAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSStringAdditions.m; sourceTree = ""; }; 112 | 07B0C5FA0E33A659006453B4 /* XMLRPC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLRPC.h; sourceTree = ""; }; 113 | 07B0C5FB0E33A659006453B4 /* XMLRPCConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLRPCConnection.h; sourceTree = ""; }; 114 | 07B0C5FC0E33A659006453B4 /* XMLRPCConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMLRPCConnection.m; sourceTree = ""; }; 115 | 07B0C5FF0E33A659006453B4 /* XMLRPCDefaultEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLRPCDefaultEncoder.h; sourceTree = ""; }; 116 | 07B0C6000E33A659006453B4 /* XMLRPCDefaultEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMLRPCDefaultEncoder.m; sourceTree = ""; }; 117 | 07B0C6010E33A659006453B4 /* XMLRPCRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLRPCRequest.h; sourceTree = ""; }; 118 | 07B0C6020E33A659006453B4 /* XMLRPCRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMLRPCRequest.m; sourceTree = ""; }; 119 | 07B0C6030E33A659006453B4 /* XMLRPCResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLRPCResponse.h; sourceTree = ""; }; 120 | 07B0C6040E33A659006453B4 /* XMLRPCResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMLRPCResponse.m; sourceTree = ""; }; 121 | 07B0C6160E33A672006453B4 /* XMLRPC.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLRPC.pch; sourceTree = ""; }; 122 | 07B52BE5101004670015AD8B /* SimpleArrayTestCase.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = SimpleArrayTestCase.xml; path = "Resources/Test Cases/SimpleArrayTestCase.xml"; sourceTree = ""; }; 123 | 07B52BE6101004670015AD8B /* SimpleStructTestCase.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = SimpleStructTestCase.xml; path = "Resources/Test Cases/SimpleStructTestCase.xml"; sourceTree = ""; }; 124 | 07B52BE9101004810015AD8B /* TestCases.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = TestCases.plist; path = "Resources/Property Lists/TestCases.plist"; sourceTree = ""; }; 125 | 07B52C01101008670015AD8B /* XMLRPCParserTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XMLRPCParserTest.h; path = "Unit Tests/XMLRPCParserTest.h"; sourceTree = ""; }; 126 | 07B52C02101008670015AD8B /* XMLRPCParserTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XMLRPCParserTest.m; path = "Unit Tests/XMLRPCParserTest.m"; sourceTree = ""; }; 127 | 07BB09881316B65A00E1911C /* DefaultTypeTestCase.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = DefaultTypeTestCase.xml; path = "Resources/Test Cases/DefaultTypeTestCase.xml"; sourceTree = ""; }; 128 | 07EF45390E721A5D009F2708 /* XMLRPCEventBasedParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLRPCEventBasedParser.h; sourceTree = ""; }; 129 | 07EF453A0E721A5D009F2708 /* XMLRPCEventBasedParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMLRPCEventBasedParser.m; sourceTree = ""; }; 130 | 0867D69BFE84028FC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 131 | 0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 132 | 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 133 | 2DCADED91529E06900B47A4F /* XMLRPCEncoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XMLRPCEncoder.h; sourceTree = ""; }; 134 | 8DC2EF5B0486A6940098B216 /* XMLRPC.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = XMLRPC.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 135 | 903B0DB612F7574800BD6E09 /* libXMLRPC.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libXMLRPC.a; sourceTree = BUILT_PRODUCTS_DIR; }; 136 | D2F7E79907B2D74100F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; 137 | /* End PBXFileReference section */ 138 | 139 | /* Begin PBXFrameworksBuildPhase section */ 140 | 0799AF000F6721FF00B71B22 /* Frameworks */ = { 141 | isa = PBXFrameworksBuildPhase; 142 | buildActionMask = 2147483647; 143 | files = ( 144 | 07E761001011788B00E9BDEE /* Cocoa.framework in Frameworks */, 145 | 0799AF5E0F67266400B71B22 /* SenTestingKit.framework in Frameworks */, 146 | 0799AF270F6724E300B71B22 /* XMLRPC.framework in Frameworks */, 147 | ); 148 | runOnlyForDeploymentPostprocessing = 0; 149 | }; 150 | 8DC2EF560486A6940098B216 /* Frameworks */ = { 151 | isa = PBXFrameworksBuildPhase; 152 | buildActionMask = 2147483647; 153 | files = ( 154 | 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */, 155 | ); 156 | runOnlyForDeploymentPostprocessing = 0; 157 | }; 158 | 903B0DB412F7574800BD6E09 /* Frameworks */ = { 159 | isa = PBXFrameworksBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | ); 163 | runOnlyForDeploymentPostprocessing = 0; 164 | }; 165 | /* End PBXFrameworksBuildPhase section */ 166 | 167 | /* Begin PBXGroup section */ 168 | 034768DFFF38A50411DB9C8B /* Products */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | 8DC2EF5B0486A6940098B216 /* XMLRPC.framework */, 172 | 0799AF030F6721FF00B71B22 /* XMLRPCUnitTests.octest */, 173 | 903B0DB612F7574800BD6E09 /* libXMLRPC.a */, 174 | ); 175 | name = Products; 176 | sourceTree = ""; 177 | }; 178 | 07127C570F4266E2009C7476 /* Configurations */ = { 179 | isa = PBXGroup; 180 | children = ( 181 | 07127C580F4266F4009C7476 /* Common.xcconfig */, 182 | 07127C590F4266F4009C7476 /* CommonDevelopment.xcconfig */, 183 | 07127C5A0F4266F4009C7476 /* CommonRelease.xcconfig */, 184 | 0799AF0F0F6722D600B71B22 /* XMLRPC.xcconfig */, 185 | 0799AF100F6722D600B71B22 /* XMLRPCDevelopment.xcconfig */, 186 | 0799AF110F6722D600B71B22 /* XMLRPCRelease.xcconfig */, 187 | 0799AF0A0F67227F00B71B22 /* XMLRPCUnitTests.xcconfig */, 188 | 0799AF0B0F67227F00B71B22 /* XMLRPCUnitTestsDevelopment.xcconfig */, 189 | 0799AF0C0F67227F00B71B22 /* XMLRPCUnitTestsRelease.xcconfig */, 190 | ); 191 | name = Configurations; 192 | sourceTree = ""; 193 | }; 194 | 07452BDC0E469C6900A57686 /* Delegates */ = { 195 | isa = PBXGroup; 196 | children = ( 197 | 07452BE20E469C9000A57686 /* XMLRPCConnectionDelegate.h */, 198 | ); 199 | name = Delegates; 200 | sourceTree = ""; 201 | }; 202 | 074E8A200F6D8D6E00BE0B22 /* Localized Strings */ = { 203 | isa = PBXGroup; 204 | children = ( 205 | 0759A6F11143495E000DFE98 /* InfoPlist.strings */, 206 | ); 207 | name = "Localized Strings"; 208 | sourceTree = ""; 209 | }; 210 | 074E8A220F6D8D8300BE0B22 /* Property Lists */ = { 211 | isa = PBXGroup; 212 | children = ( 213 | 07B52BE9101004810015AD8B /* TestCases.plist */, 214 | 0799AF280F67254B00B71B22 /* XMLRPC-Info.plist */, 215 | 0799AF040F6721FF00B71B22 /* XMLRPCUnitTests-Info.plist */, 216 | ); 217 | name = "Property Lists"; 218 | sourceTree = ""; 219 | }; 220 | 0799AF2F0F67258600B71B22 /* Unit Tests */ = { 221 | isa = PBXGroup; 222 | children = ( 223 | 07B52C01101008670015AD8B /* XMLRPCParserTest.h */, 224 | 07B52C02101008670015AD8B /* XMLRPCParserTest.m */, 225 | ); 226 | name = "Unit Tests"; 227 | sourceTree = ""; 228 | }; 229 | 07B0C6140E33A65E006453B4 /* Additions */ = { 230 | isa = PBXGroup; 231 | children = ( 232 | 033836811527905D00EF8E8A /* NSData+Base64.h */, 233 | 033836821527905D00EF8E8A /* NSData+Base64.m */, 234 | 07B0C5F80E33A659006453B4 /* NSStringAdditions.h */, 235 | 07B0C5F90E33A659006453B4 /* NSStringAdditions.m */, 236 | ); 237 | name = Additions; 238 | sourceTree = ""; 239 | }; 240 | 07B52BE4101004270015AD8B /* Test Cases */ = { 241 | isa = PBXGroup; 242 | children = ( 243 | 07075BAD10C5FE3800589A27 /* AlternativeDateFormatsTestCase.xml */, 244 | 07BB09881316B65A00E1911C /* DefaultTypeTestCase.xml */, 245 | 07A0A9021016A51000CEE3C7 /* EmptyBooleanTestCase.xml */, 246 | 07A0A9031016A51000CEE3C7 /* EmptyDataTestCase.xml */, 247 | 07A0A9041016A51000CEE3C7 /* EmptyDoubleTestCase.xml */, 248 | 07A0A9051016A51000CEE3C7 /* EmptyIntegerTestCase.xml */, 249 | 07A0A9061016A51000CEE3C7 /* EmptyStringTestCase.xml */, 250 | 07B52BE5101004670015AD8B /* SimpleArrayTestCase.xml */, 251 | 07B52BE6101004670015AD8B /* SimpleStructTestCase.xml */, 252 | ); 253 | name = "Test Cases"; 254 | sourceTree = ""; 255 | }; 256 | 0867D691FE84028FC02AAC07 /* XMLRPC */ = { 257 | isa = PBXGroup; 258 | children = ( 259 | 08FB77AEFE84172EC02AAC07 /* Classes */, 260 | 32C88DFF0371C24200C91783 /* Other Sources */, 261 | 089C1665FE841158C02AAC07 /* Resources */, 262 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, 263 | 034768DFFF38A50411DB9C8B /* Products */, 264 | ); 265 | name = XMLRPC; 266 | sourceTree = ""; 267 | }; 268 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { 269 | isa = PBXGroup; 270 | children = ( 271 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */, 272 | 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */, 273 | ); 274 | name = "External Frameworks and Libraries"; 275 | sourceTree = ""; 276 | }; 277 | 089C1665FE841158C02AAC07 /* Resources */ = { 278 | isa = PBXGroup; 279 | children = ( 280 | 07127C570F4266E2009C7476 /* Configurations */, 281 | 074E8A200F6D8D6E00BE0B22 /* Localized Strings */, 282 | 074E8A220F6D8D8300BE0B22 /* Property Lists */, 283 | 07B52BE4101004270015AD8B /* Test Cases */, 284 | ); 285 | name = Resources; 286 | sourceTree = ""; 287 | }; 288 | 08FB77AEFE84172EC02AAC07 /* Classes */ = { 289 | isa = PBXGroup; 290 | children = ( 291 | 07B0C6140E33A65E006453B4 /* Additions */, 292 | 07452BDC0E469C6900A57686 /* Delegates */, 293 | 2DAF1E7E15CAB471009305B2 /* Protocols */, 294 | 07B0C5FA0E33A659006453B4 /* XMLRPC.h */, 295 | 07B0C5FB0E33A659006453B4 /* XMLRPCConnection.h */, 296 | 07B0C5FC0E33A659006453B4 /* XMLRPCConnection.m */, 297 | 075137F90E429E560019E4F6 /* XMLRPCConnectionManager.h */, 298 | 075137FA0E429E560019E4F6 /* XMLRPCConnectionManager.m */, 299 | 07B0C5FF0E33A659006453B4 /* XMLRPCDefaultEncoder.h */, 300 | 07B0C6000E33A659006453B4 /* XMLRPCDefaultEncoder.m */, 301 | 07EF45390E721A5D009F2708 /* XMLRPCEventBasedParser.h */, 302 | 07EF453A0E721A5D009F2708 /* XMLRPCEventBasedParser.m */, 303 | 0707047610114B9400CB7702 /* XMLRPCEventBasedParserDelegate.h */, 304 | 0707047710114B9400CB7702 /* XMLRPCEventBasedParserDelegate.m */, 305 | 07B0C6010E33A659006453B4 /* XMLRPCRequest.h */, 306 | 07B0C6020E33A659006453B4 /* XMLRPCRequest.m */, 307 | 07B0C6030E33A659006453B4 /* XMLRPCResponse.h */, 308 | 07B0C6040E33A659006453B4 /* XMLRPCResponse.m */, 309 | ); 310 | name = Classes; 311 | sourceTree = ""; 312 | }; 313 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */ = { 314 | isa = PBXGroup; 315 | children = ( 316 | 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */, 317 | 0799AF5D0F67266400B71B22 /* SenTestingKit.framework */, 318 | ); 319 | name = "Linked Frameworks"; 320 | sourceTree = ""; 321 | }; 322 | 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */ = { 323 | isa = PBXGroup; 324 | children = ( 325 | 0867D6A5FE840307C02AAC07 /* AppKit.framework */, 326 | D2F7E79907B2D74100F64583 /* CoreData.framework */, 327 | 0867D69BFE84028FC02AAC07 /* Foundation.framework */, 328 | ); 329 | name = "Other Frameworks"; 330 | sourceTree = ""; 331 | }; 332 | 2DAF1E7E15CAB471009305B2 /* Protocols */ = { 333 | isa = PBXGroup; 334 | children = ( 335 | 2DCADED91529E06900B47A4F /* XMLRPCEncoder.h */, 336 | ); 337 | name = Protocols; 338 | sourceTree = ""; 339 | }; 340 | 32C88DFF0371C24200C91783 /* Other Sources */ = { 341 | isa = PBXGroup; 342 | children = ( 343 | 0799AF2F0F67258600B71B22 /* Unit Tests */, 344 | 07B0C6160E33A672006453B4 /* XMLRPC.pch */, 345 | ); 346 | name = "Other Sources"; 347 | sourceTree = ""; 348 | }; 349 | /* End PBXGroup section */ 350 | 351 | /* Begin PBXHeadersBuildPhase section */ 352 | 8DC2EF500486A6940098B216 /* Headers */ = { 353 | isa = PBXHeadersBuildPhase; 354 | buildActionMask = 2147483647; 355 | files = ( 356 | 07B0C6070E33A659006453B4 /* NSStringAdditions.h in Headers */, 357 | 07B0C6090E33A659006453B4 /* XMLRPC.h in Headers */, 358 | 07B0C6170E33A672006453B4 /* XMLRPC.pch in Headers */, 359 | 1F59FCE216CADA75005AECF4 /* XMLRPCEncoder.h in Headers */, 360 | 07B0C60A0E33A659006453B4 /* XMLRPCConnection.h in Headers */, 361 | 07452BE30E469C9000A57686 /* XMLRPCConnectionDelegate.h in Headers */, 362 | 075137FB0E429E560019E4F6 /* XMLRPCConnectionManager.h in Headers */, 363 | 07B0C60E0E33A659006453B4 /* XMLRPCDefaultEncoder.h in Headers */, 364 | 07EF453B0E721A5D009F2708 /* XMLRPCEventBasedParser.h in Headers */, 365 | 0707047810114B9400CB7702 /* XMLRPCEventBasedParserDelegate.h in Headers */, 366 | 07B0C6100E33A659006453B4 /* XMLRPCRequest.h in Headers */, 367 | 07B0C6120E33A659006453B4 /* XMLRPCResponse.h in Headers */, 368 | 033836831527905D00EF8E8A /* NSData+Base64.h in Headers */, 369 | ); 370 | runOnlyForDeploymentPostprocessing = 0; 371 | }; 372 | 903B0DB212F7574800BD6E09 /* Headers */ = { 373 | isa = PBXHeadersBuildPhase; 374 | buildActionMask = 2147483647; 375 | files = ( 376 | 903B0DC212F7581200BD6E09 /* NSStringAdditions.h in Headers */, 377 | 903B0DC412F7581200BD6E09 /* XMLRPCConnectionDelegate.h in Headers */, 378 | 903B0DC512F7581200BD6E09 /* XMLRPC.h in Headers */, 379 | 903B0DC612F7581200BD6E09 /* XMLRPCConnection.h in Headers */, 380 | 903B0DC812F7581200BD6E09 /* XMLRPCConnectionManager.h in Headers */, 381 | 2DCADEDB1529E24300B47A4F /* XMLRPCEncoder.h in Headers */, 382 | 903B0DCA12F7581200BD6E09 /* XMLRPCDefaultEncoder.h in Headers */, 383 | 903B0DCC12F7581200BD6E09 /* XMLRPCEventBasedParser.h in Headers */, 384 | 903B0DCE12F7581200BD6E09 /* XMLRPCEventBasedParserDelegate.h in Headers */, 385 | 903B0DD012F7581200BD6E09 /* XMLRPCRequest.h in Headers */, 386 | 903B0DD212F7581200BD6E09 /* XMLRPCResponse.h in Headers */, 387 | 903B0DD412F7581F00BD6E09 /* XMLRPC.pch in Headers */, 388 | 033836841527905D00EF8E8A /* NSData+Base64.h in Headers */, 389 | ); 390 | runOnlyForDeploymentPostprocessing = 0; 391 | }; 392 | /* End PBXHeadersBuildPhase section */ 393 | 394 | /* Begin PBXNativeTarget section */ 395 | 0799AF020F6721FF00B71B22 /* XMLRPCUnitTests */ = { 396 | isa = PBXNativeTarget; 397 | buildConfigurationList = 0799AF070F67220000B71B22 /* Build configuration list for PBXNativeTarget "XMLRPCUnitTests" */; 398 | buildPhases = ( 399 | 0799AEFE0F6721FF00B71B22 /* Resources */, 400 | 0799AEFF0F6721FF00B71B22 /* Sources */, 401 | 0799AF000F6721FF00B71B22 /* Frameworks */, 402 | 0799AF010F6721FF00B71B22 /* ShellScript */, 403 | ); 404 | buildRules = ( 405 | ); 406 | dependencies = ( 407 | 0799AF190F67240B00B71B22 /* PBXTargetDependency */, 408 | ); 409 | name = XMLRPCUnitTests; 410 | productName = XMLRPCUnitTests; 411 | productReference = 0799AF030F6721FF00B71B22 /* XMLRPCUnitTests.octest */; 412 | productType = "com.apple.product-type.bundle.ocunit-test"; 413 | }; 414 | 8DC2EF4F0486A6940098B216 /* XMLRPC */ = { 415 | isa = PBXNativeTarget; 416 | buildConfigurationList = 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "XMLRPC" */; 417 | buildPhases = ( 418 | 8DC2EF500486A6940098B216 /* Headers */, 419 | 8DC2EF520486A6940098B216 /* Resources */, 420 | 8DC2EF540486A6940098B216 /* Sources */, 421 | 8DC2EF560486A6940098B216 /* Frameworks */, 422 | 0715852011432A78003D3454 /* Run Script: Include Git commit hash */, 423 | ); 424 | buildRules = ( 425 | ); 426 | dependencies = ( 427 | ); 428 | name = XMLRPC; 429 | productInstallPath = "$(HOME)/Library/Frameworks"; 430 | productName = XMLRPC; 431 | productReference = 8DC2EF5B0486A6940098B216 /* XMLRPC.framework */; 432 | productType = "com.apple.product-type.framework"; 433 | }; 434 | 903B0DB512F7574800BD6E09 /* libXMLRPC */ = { 435 | isa = PBXNativeTarget; 436 | buildConfigurationList = 903B0DB912F7577B00BD6E09 /* Build configuration list for PBXNativeTarget "libXMLRPC" */; 437 | buildPhases = ( 438 | 903B0DB212F7574800BD6E09 /* Headers */, 439 | 903B0DB312F7574800BD6E09 /* Sources */, 440 | 903B0DB412F7574800BD6E09 /* Frameworks */, 441 | 903B0DFB12F75B2300BD6E09 /* ShellScript */, 442 | ); 443 | buildRules = ( 444 | ); 445 | dependencies = ( 446 | ); 447 | name = libXMLRPC; 448 | productName = iOSXMLRPC; 449 | productReference = 903B0DB612F7574800BD6E09 /* libXMLRPC.a */; 450 | productType = "com.apple.product-type.library.static"; 451 | }; 452 | /* End PBXNativeTarget section */ 453 | 454 | /* Begin PBXProject section */ 455 | 0867D690FE84028FC02AAC07 /* Project object */ = { 456 | isa = PBXProject; 457 | attributes = { 458 | LastUpgradeCheck = 0630; 459 | }; 460 | buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "XMLRPC" */; 461 | compatibilityVersion = "Xcode 3.2"; 462 | developmentRegion = English; 463 | hasScannedForEncodings = 1; 464 | knownRegions = ( 465 | English, 466 | Japanese, 467 | French, 468 | German, 469 | ); 470 | mainGroup = 0867D691FE84028FC02AAC07 /* XMLRPC */; 471 | productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; 472 | projectDirPath = ""; 473 | projectRoot = ""; 474 | targets = ( 475 | 8DC2EF4F0486A6940098B216 /* XMLRPC */, 476 | 903B0DB512F7574800BD6E09 /* libXMLRPC */, 477 | 0799AF020F6721FF00B71B22 /* XMLRPCUnitTests */, 478 | ); 479 | }; 480 | /* End PBXProject section */ 481 | 482 | /* Begin PBXResourcesBuildPhase section */ 483 | 0799AEFE0F6721FF00B71B22 /* Resources */ = { 484 | isa = PBXResourcesBuildPhase; 485 | buildActionMask = 2147483647; 486 | files = ( 487 | 07075BAE10C5FE3800589A27 /* AlternativeDateFormatsTestCase.xml in Resources */, 488 | 07BB09891316B65A00E1911C /* DefaultTypeTestCase.xml in Resources */, 489 | 07A0A9071016A51000CEE3C7 /* EmptyBooleanTestCase.xml in Resources */, 490 | 07A0A9081016A51000CEE3C7 /* EmptyDataTestCase.xml in Resources */, 491 | 07A0A9091016A51000CEE3C7 /* EmptyDoubleTestCase.xml in Resources */, 492 | 07A0A90A1016A51000CEE3C7 /* EmptyIntegerTestCase.xml in Resources */, 493 | 07A0A90B1016A51000CEE3C7 /* EmptyStringTestCase.xml in Resources */, 494 | 07B52BE7101004670015AD8B /* SimpleArrayTestCase.xml in Resources */, 495 | 07B52BE8101004670015AD8B /* SimpleStructTestCase.xml in Resources */, 496 | 07B52BEA101004810015AD8B /* TestCases.plist in Resources */, 497 | ); 498 | runOnlyForDeploymentPostprocessing = 0; 499 | }; 500 | 8DC2EF520486A6940098B216 /* Resources */ = { 501 | isa = PBXResourcesBuildPhase; 502 | buildActionMask = 2147483647; 503 | files = ( 504 | 0759A6F31143495E000DFE98 /* InfoPlist.strings in Resources */, 505 | ); 506 | runOnlyForDeploymentPostprocessing = 0; 507 | }; 508 | /* End PBXResourcesBuildPhase section */ 509 | 510 | /* Begin PBXShellScriptBuildPhase section */ 511 | 0715852011432A78003D3454 /* Run Script: Include Git commit hash */ = { 512 | isa = PBXShellScriptBuildPhase; 513 | buildActionMask = 2147483647; 514 | files = ( 515 | ); 516 | inputPaths = ( 517 | ); 518 | name = "Run Script: Include Git commit hash"; 519 | outputPaths = ( 520 | ); 521 | runOnlyForDeploymentPostprocessing = 0; 522 | shellPath = /usr/bin/ruby; 523 | shellScript = "raise \"Must be executed from within Xcode.\" unless ENV['XCODE_VERSION_ACTUAL']\n\ninfo_plist = \"#{ENV['BUILT_PRODUCTS_DIR']}/#{ENV['WRAPPER_NAME']}/Resources/Info.plist\"\n\nif !File.exist?('/usr/local/bin/git')\n exit\nend\n\ncommit = `/usr/local/bin/git rev-parse --short HEAD`.chomp!\n\nif commit.nil? or commit.empty?\n exit\nend\n\nlines = IO.readlines(info_plist).join\n\nlines.gsub! /(CFBundleShortVersionString<\\/key>\\W*)(\\d+\\.\\d+(?:\\.\\d)*[a-z]?)<\\/string>/, \"\\\\1\\\\2 rev. #{commit}\"\n\nFile.open(info_plist, 'w') { |f| f.puts lines }"; 524 | }; 525 | 0799AF010F6721FF00B71B22 /* ShellScript */ = { 526 | isa = PBXShellScriptBuildPhase; 527 | buildActionMask = 2147483647; 528 | files = ( 529 | ); 530 | inputPaths = ( 531 | ); 532 | outputPaths = ( 533 | ); 534 | runOnlyForDeploymentPostprocessing = 0; 535 | shellPath = /bin/sh; 536 | shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n"; 537 | }; 538 | 903B0DFB12F75B2300BD6E09 /* ShellScript */ = { 539 | isa = PBXShellScriptBuildPhase; 540 | buildActionMask = 2147483647; 541 | files = ( 542 | ); 543 | inputPaths = ( 544 | ); 545 | outputPaths = ( 546 | ); 547 | runOnlyForDeploymentPostprocessing = 0; 548 | shellPath = /bin/sh; 549 | shellScript = "#\n# Version 2.0 (updated for Xcode 4, with some fixes)\n#\n# Author: Adam Martin - http://twitter.com/redglassesapps\n#\n# For more information see this Stack Overflow question:\n# http://stackoverflow.com/questions/3520977/build-fat-static-library-device-simulator-using-xcode-and-sdk-4\n#\nDEBUG_THIS_SCRIPT=\"false\"\n\nif [ $DEBUG_THIS_SCRIPT = \"true\" ]\nthen\necho \"########### TESTS #############\"\necho \"Use the following variables when debugging this script; note that they may change\"\necho \"BUILD_DIR = $BUILD_DIR\"\necho \"BUILD_ROOT = $BUILD_ROOT\"\necho \"CONFIGURATION_BUILD_DIR = $CONFIGURATION_BUILD_DIR\"\necho \"BUILT_PRODUCTS_DIR = $BUILT_PRODUCTS_DIR\"\necho \"CONFIGURATION_TEMP_DIR = $CONFIGURATION_TEMP_DIR\"\necho \"TARGET_BUILD_DIR = $TARGET_BUILD_DIR\"\nfi\n\n########################################################\n\nSDK_VERSION=$(echo ${SDK_NAME} | grep -o '.\\{3\\}$')\n\nif [ ${PLATFORM_NAME} = \"iphonesimulator\" ]\nthen\nOTHER_SDK_TO_BUILD=iphoneos${SDK_VERSION}\nelse\nOTHER_SDK_TO_BUILD=iphonesimulator${SDK_VERSION}\nfi\n\necho \"XCode has selected SDK: ${PLATFORM_NAME} with version: ${SDK_VERSION} (although back-targetting: ${IPHONEOS_DEPLOYMENT_TARGET})\"\necho \"...therefore, OTHER_SDK_TO_BUILD = ${OTHER_SDK_TO_BUILD}\"\n\n########################################################\n\nif [ \"true\" == ${ALREADYINVOKED:-false} ]\nthen\necho \"RECURSION: I am NOT the root invocation, so I'm NOT going to recurse\"\nelse\nexport ALREADYINVOKED=\"true\"\n\necho \"RECURSION: I am the root ... recursing all missing build targets NOW...\"\necho \"RECURSION: ...about to invoke: xcodebuild -configuration \\\"${CONFIGURATION}\\\" -target \\\"${TARGET_NAME}\\\" -sdk \\\"${OTHER_SDK_TO_BUILD}\\\" ${ACTION} RUN_CLANG_STATIC_ANALYZER=NO\"\n\nxcodebuild -configuration \"${CONFIGURATION}\" -target \"${TARGET_NAME}\" -sdk \"${OTHER_SDK_TO_BUILD}\" ${ACTION} RUN_CLANG_STATIC_ANALYZER=NO BUILD_DIR=\"${BUILD_DIR}\" BUILD_ROOT=\"${BUILD_ROOT}\"\n\nACTION=\"build\"\n\nCURRENTCONFIG_DEVICE_DIR=${SYMROOT}/${CONFIGURATION}-iphoneos\nCURRENTCONFIG_SIMULATOR_DIR=${SYMROOT}/${CONFIGURATION}-iphonesimulator\n\necho \"Taking device build from: ${CURRENTCONFIG_DEVICE_DIR}\"\necho \"Taking simulator build from: ${CURRENTCONFIG_SIMULATOR_DIR}\"\n\nCREATING_UNIVERSAL_DIR=${SYMROOT}/${CONFIGURATION}-universal\n\necho \"...I will output a universal build to: ${CREATING_UNIVERSAL_DIR}\"\n\nrm -rf \"${CREATING_UNIVERSAL_DIR}\"\nmkdir \"${CREATING_UNIVERSAL_DIR}\"\n\necho \"lipo: for current configuration (${CONFIGURATION}) creating output file: ${CREATING_UNIVERSAL_DIR}/${EXECUTABLE_NAME}\"\n\nlipo -create -output \"${CREATING_UNIVERSAL_DIR}/${EXECUTABLE_NAME}\" \"${CURRENTCONFIG_DEVICE_DIR}/${EXECUTABLE_NAME}\" \"${CURRENTCONFIG_SIMULATOR_DIR}/${EXECUTABLE_NAME}\"\n\nif [ -d \"${CURRENTCONFIG_DEVICE_DIR}/usr/local/include\" ]\nthen\nmkdir -p \"${CREATING_UNIVERSAL_DIR}/usr/local/include\"\ncp \"${CURRENTCONFIG_DEVICE_DIR}/usr/local/include/\"* \"${CREATING_UNIVERSAL_DIR}/usr/local/include\"\nfi\nfi"; 550 | showEnvVarsInLog = 0; 551 | }; 552 | /* End PBXShellScriptBuildPhase section */ 553 | 554 | /* Begin PBXSourcesBuildPhase section */ 555 | 0799AEFF0F6721FF00B71B22 /* Sources */ = { 556 | isa = PBXSourcesBuildPhase; 557 | buildActionMask = 2147483647; 558 | files = ( 559 | 07B52C03101008670015AD8B /* XMLRPCParserTest.m in Sources */, 560 | ); 561 | runOnlyForDeploymentPostprocessing = 0; 562 | }; 563 | 8DC2EF540486A6940098B216 /* Sources */ = { 564 | isa = PBXSourcesBuildPhase; 565 | buildActionMask = 2147483647; 566 | files = ( 567 | 07B0C6080E33A659006453B4 /* NSStringAdditions.m in Sources */, 568 | 07B0C60B0E33A659006453B4 /* XMLRPCConnection.m in Sources */, 569 | 075137FC0E429E560019E4F6 /* XMLRPCConnectionManager.m in Sources */, 570 | 07B0C60F0E33A659006453B4 /* XMLRPCDefaultEncoder.m in Sources */, 571 | 07EF453C0E721A5D009F2708 /* XMLRPCEventBasedParser.m in Sources */, 572 | 0707047910114B9400CB7702 /* XMLRPCEventBasedParserDelegate.m in Sources */, 573 | 07B0C6110E33A659006453B4 /* XMLRPCRequest.m in Sources */, 574 | 07B0C6130E33A659006453B4 /* XMLRPCResponse.m in Sources */, 575 | 033836851527905D00EF8E8A /* NSData+Base64.m in Sources */, 576 | ); 577 | runOnlyForDeploymentPostprocessing = 0; 578 | }; 579 | 903B0DB312F7574800BD6E09 /* Sources */ = { 580 | isa = PBXSourcesBuildPhase; 581 | buildActionMask = 2147483647; 582 | files = ( 583 | 903B0DC312F7581200BD6E09 /* NSStringAdditions.m in Sources */, 584 | 903B0DC712F7581200BD6E09 /* XMLRPCConnection.m in Sources */, 585 | 903B0DC912F7581200BD6E09 /* XMLRPCConnectionManager.m in Sources */, 586 | 903B0DCB12F7581200BD6E09 /* XMLRPCDefaultEncoder.m in Sources */, 587 | 903B0DCD12F7581200BD6E09 /* XMLRPCEventBasedParser.m in Sources */, 588 | 903B0DCF12F7581200BD6E09 /* XMLRPCEventBasedParserDelegate.m in Sources */, 589 | 903B0DD112F7581200BD6E09 /* XMLRPCRequest.m in Sources */, 590 | 903B0DD312F7581200BD6E09 /* XMLRPCResponse.m in Sources */, 591 | 033836861527905D00EF8E8A /* NSData+Base64.m in Sources */, 592 | ); 593 | runOnlyForDeploymentPostprocessing = 0; 594 | }; 595 | /* End PBXSourcesBuildPhase section */ 596 | 597 | /* Begin PBXTargetDependency section */ 598 | 0799AF190F67240B00B71B22 /* PBXTargetDependency */ = { 599 | isa = PBXTargetDependency; 600 | target = 8DC2EF4F0486A6940098B216 /* XMLRPC */; 601 | targetProxy = 0799AF180F67240B00B71B22 /* PBXContainerItemProxy */; 602 | }; 603 | /* End PBXTargetDependency section */ 604 | 605 | /* Begin PBXVariantGroup section */ 606 | 0759A6F11143495E000DFE98 /* InfoPlist.strings */ = { 607 | isa = PBXVariantGroup; 608 | children = ( 609 | 0759A6F21143495E000DFE98 /* English */, 610 | ); 611 | name = InfoPlist.strings; 612 | sourceTree = ""; 613 | }; 614 | /* End PBXVariantGroup section */ 615 | 616 | /* Begin XCBuildConfiguration section */ 617 | 0799AF050F67220000B71B22 /* Development */ = { 618 | isa = XCBuildConfiguration; 619 | baseConfigurationReference = 0799AF0B0F67227F00B71B22 /* XMLRPCUnitTestsDevelopment.xcconfig */; 620 | buildSettings = { 621 | COMBINE_HIDPI_IMAGES = YES; 622 | FRAMEWORK_SEARCH_PATHS = ( 623 | "$(inherited)", 624 | "\"$(DEVELOPER_FRAMEWORKS_DIR)\"", 625 | ); 626 | VERSION_INFO_FILE = ""; 627 | }; 628 | name = Development; 629 | }; 630 | 0799AF060F67220000B71B22 /* Release */ = { 631 | isa = XCBuildConfiguration; 632 | baseConfigurationReference = 0799AF0C0F67227F00B71B22 /* XMLRPCUnitTestsRelease.xcconfig */; 633 | buildSettings = { 634 | COMBINE_HIDPI_IMAGES = YES; 635 | FRAMEWORK_SEARCH_PATHS = ( 636 | "$(inherited)", 637 | "\"$(DEVELOPER_FRAMEWORKS_DIR)\"", 638 | ); 639 | VERSION_INFO_FILE = ""; 640 | }; 641 | name = Release; 642 | }; 643 | 1DEB91AE08733DA50010E9CD /* Development */ = { 644 | isa = XCBuildConfiguration; 645 | baseConfigurationReference = 0799AF100F6722D600B71B22 /* XMLRPCDevelopment.xcconfig */; 646 | buildSettings = { 647 | COMBINE_HIDPI_IMAGES = YES; 648 | VERSION_INFO_FILE = ""; 649 | }; 650 | name = Development; 651 | }; 652 | 1DEB91AF08733DA50010E9CD /* Release */ = { 653 | isa = XCBuildConfiguration; 654 | baseConfigurationReference = 0799AF110F6722D600B71B22 /* XMLRPCRelease.xcconfig */; 655 | buildSettings = { 656 | COMBINE_HIDPI_IMAGES = YES; 657 | VERSION_INFO_FILE = ""; 658 | }; 659 | name = Release; 660 | }; 661 | 1DEB91B208733DA50010E9CD /* Development */ = { 662 | isa = XCBuildConfiguration; 663 | baseConfigurationReference = 07127C590F4266F4009C7476 /* CommonDevelopment.xcconfig */; 664 | buildSettings = { 665 | }; 666 | name = Development; 667 | }; 668 | 1DEB91B308733DA50010E9CD /* Release */ = { 669 | isa = XCBuildConfiguration; 670 | baseConfigurationReference = 07127C5A0F4266F4009C7476 /* CommonRelease.xcconfig */; 671 | buildSettings = { 672 | }; 673 | name = Release; 674 | }; 675 | 903B0DB712F7574900BD6E09 /* Development */ = { 676 | isa = XCBuildConfiguration; 677 | buildSettings = { 678 | ALWAYS_SEARCH_USER_PATHS = NO; 679 | COPY_PHASE_STRIP = NO; 680 | GCC_DYNAMIC_NO_PIC = NO; 681 | GCC_OPTIMIZATION_LEVEL = 0; 682 | IPHONEOS_DEPLOYMENT_TARGET = 3.0; 683 | PRODUCT_NAME = XMLRPC; 684 | PUBLIC_HEADERS_FOLDER_PATH = /headers/; 685 | SDKROOT = iphoneos; 686 | VALID_ARCHS = "armv7 armv6 i386"; 687 | }; 688 | name = Development; 689 | }; 690 | 903B0DB812F7574900BD6E09 /* Release */ = { 691 | isa = XCBuildConfiguration; 692 | buildSettings = { 693 | ALWAYS_SEARCH_USER_PATHS = NO; 694 | COPY_PHASE_STRIP = YES; 695 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 696 | IPHONEOS_DEPLOYMENT_TARGET = 3.0; 697 | PRODUCT_NAME = XMLRPC; 698 | PUBLIC_HEADERS_FOLDER_PATH = /headers/; 699 | SDKROOT = iphoneos; 700 | VALID_ARCHS = "armv7 armv6 i386"; 701 | ZERO_LINK = NO; 702 | }; 703 | name = Release; 704 | }; 705 | /* End XCBuildConfiguration section */ 706 | 707 | /* Begin XCConfigurationList section */ 708 | 0799AF070F67220000B71B22 /* Build configuration list for PBXNativeTarget "XMLRPCUnitTests" */ = { 709 | isa = XCConfigurationList; 710 | buildConfigurations = ( 711 | 0799AF050F67220000B71B22 /* Development */, 712 | 0799AF060F67220000B71B22 /* Release */, 713 | ); 714 | defaultConfigurationIsVisible = 0; 715 | defaultConfigurationName = Release; 716 | }; 717 | 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "XMLRPC" */ = { 718 | isa = XCConfigurationList; 719 | buildConfigurations = ( 720 | 1DEB91AE08733DA50010E9CD /* Development */, 721 | 1DEB91AF08733DA50010E9CD /* Release */, 722 | ); 723 | defaultConfigurationIsVisible = 0; 724 | defaultConfigurationName = Release; 725 | }; 726 | 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "XMLRPC" */ = { 727 | isa = XCConfigurationList; 728 | buildConfigurations = ( 729 | 1DEB91B208733DA50010E9CD /* Development */, 730 | 1DEB91B308733DA50010E9CD /* Release */, 731 | ); 732 | defaultConfigurationIsVisible = 0; 733 | defaultConfigurationName = Release; 734 | }; 735 | 903B0DB912F7577B00BD6E09 /* Build configuration list for PBXNativeTarget "libXMLRPC" */ = { 736 | isa = XCConfigurationList; 737 | buildConfigurations = ( 738 | 903B0DB712F7574900BD6E09 /* Development */, 739 | 903B0DB812F7574900BD6E09 /* Release */, 740 | ); 741 | defaultConfigurationIsVisible = 0; 742 | defaultConfigurationName = Release; 743 | }; 744 | /* End XCConfigurationList section */ 745 | }; 746 | rootObject = 0867D690FE84028FC02AAC07 /* Project object */; 747 | } 748 | -------------------------------------------------------------------------------- /XMLRPCConnection.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "XMLRPCConnectionDelegate.h" 3 | 4 | @class XMLRPCConnectionManager, XMLRPCRequest, XMLRPCResponse; 5 | 6 | @interface XMLRPCConnection : NSObject { 7 | XMLRPCConnectionManager *myManager; 8 | XMLRPCRequest *myRequest; 9 | NSString *myIdentifier; 10 | NSMutableData *myData; 11 | NSURLConnection *myConnection; 12 | id myDelegate; 13 | } 14 | 15 | - (id)initWithXMLRPCRequest: (XMLRPCRequest *)request delegate: (id)delegate manager: (XMLRPCConnectionManager *)manager; 16 | 17 | #pragma mark - 18 | 19 | + (XMLRPCResponse *)sendSynchronousXMLRPCRequest: (XMLRPCRequest *)request error: (NSError **)error; 20 | 21 | #pragma mark - 22 | 23 | - (NSString *)identifier; 24 | 25 | #pragma mark - 26 | 27 | - (id)delegate; 28 | 29 | #pragma mark - 30 | 31 | - (void)cancel; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /XMLRPCConnection.m: -------------------------------------------------------------------------------- 1 | #import "XMLRPCConnection.h" 2 | #import "XMLRPCConnectionManager.h" 3 | #import "XMLRPCRequest.h" 4 | #import "XMLRPCResponse.h" 5 | #import "NSStringAdditions.h" 6 | 7 | static NSOperationQueue *parsingQueue; 8 | 9 | @interface XMLRPCConnection (XMLRPCConnectionPrivate) 10 | 11 | - (void)connection: (NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response; 12 | 13 | - (void)connection: (NSURLConnection *)connection didReceiveData: (NSData *)data; 14 | 15 | - (void)connection: (NSURLConnection *)connection didSendBodyData: (NSInteger)bytesWritten totalBytesWritten: (NSInteger)totalBytesWritten totalBytesExpectedToWrite: (NSInteger)totalBytesExpectedToWrite; 16 | 17 | - (void)connection: (NSURLConnection *)connection didFailWithError: (NSError *)error; 18 | 19 | #pragma mark - 20 | 21 | - (BOOL)connection: (NSURLConnection *)connection canAuthenticateAgainstProtectionSpace: (NSURLProtectionSpace *)protectionSpace; 22 | 23 | - (void)connection: (NSURLConnection *)connection didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge; 24 | 25 | - (void)connection: (NSURLConnection *)connection didCancelAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge; 26 | 27 | - (void)connectionDidFinishLoading: (NSURLConnection *)connection; 28 | 29 | #pragma mark - 30 | 31 | - (void)timeoutExpired; 32 | - (void)invalidateTimer; 33 | 34 | #pragma mark - 35 | 36 | + (NSOperationQueue *)parsingQueue; 37 | 38 | @end 39 | 40 | #pragma mark - 41 | 42 | @implementation XMLRPCConnection 43 | 44 | - (id)initWithXMLRPCRequest: (XMLRPCRequest *)request delegate: (id)delegate manager: (XMLRPCConnectionManager *)manager { 45 | self = [super init]; 46 | if (self) { 47 | #if ! __has_feature(objc_arc) 48 | myManager = [manager retain]; 49 | myRequest = [request retain]; 50 | myIdentifier = [[NSString stringByGeneratingUUID] retain]; 51 | #else 52 | myManager = manager; 53 | myRequest = request; 54 | myIdentifier = [NSString stringByGeneratingUUID]; 55 | #endif 56 | myData = [[NSMutableData alloc] init]; 57 | 58 | myConnection = [[NSURLConnection alloc] initWithRequest: [request request] delegate: self startImmediately:NO]; 59 | [myConnection scheduleInRunLoop:[NSRunLoop mainRunLoop] 60 | forMode:NSDefaultRunLoopMode]; 61 | [myConnection start]; 62 | 63 | #if ! __has_feature(objc_arc) 64 | myDelegate = [delegate retain]; 65 | #else 66 | myDelegate = delegate; 67 | #endif 68 | 69 | if (myConnection) { 70 | NSLog(@"The connection, %@, has been established!", myIdentifier); 71 | 72 | [self performSelector:@selector(timeoutExpired) withObject:nil afterDelay:[myRequest timeout]]; 73 | } else { 74 | NSLog(@"The connection, %@, could not be established!", myIdentifier); 75 | #if ! __has_feature(objc_arc) 76 | [self release]; 77 | #endif 78 | return nil; 79 | } 80 | } 81 | 82 | return self; 83 | } 84 | 85 | #pragma mark - 86 | 87 | + (XMLRPCResponse *)sendSynchronousXMLRPCRequest: (XMLRPCRequest *)request error: (NSError **)error { 88 | NSHTTPURLResponse *response = nil; 89 | #if ! __has_feature(objc_arc) 90 | NSData *data = [[[NSURLConnection sendSynchronousRequest: [request request] returningResponse: &response error: error] retain] autorelease]; 91 | #else 92 | NSData *data = [NSURLConnection sendSynchronousRequest: [request request] returningResponse: &response error: error]; 93 | #endif 94 | 95 | if (response) { 96 | NSInteger statusCode = [response statusCode]; 97 | 98 | if ((statusCode < 400) && data) { 99 | #if ! __has_feature(objc_arc) 100 | return [[[XMLRPCResponse alloc] initWithData: data] autorelease]; 101 | #else 102 | return [[XMLRPCResponse alloc] initWithData: data]; 103 | #endif 104 | } 105 | } 106 | 107 | return nil; 108 | } 109 | 110 | #pragma mark - 111 | 112 | - (NSString *)identifier { 113 | #if ! __has_feature(objc_arc) 114 | return [[myIdentifier retain] autorelease]; 115 | #else 116 | return myIdentifier; 117 | #endif 118 | } 119 | 120 | #pragma mark - 121 | 122 | - (id)delegate { 123 | return myDelegate; 124 | } 125 | 126 | #pragma mark - 127 | 128 | - (void)cancel { 129 | [myConnection cancel]; 130 | 131 | [self invalidateTimer]; 132 | } 133 | 134 | #pragma mark - 135 | 136 | - (void)dealloc { 137 | #if ! __has_feature(objc_arc) 138 | [myManager release]; 139 | [myRequest release]; 140 | [myIdentifier release]; 141 | [myData release]; 142 | [myConnection release]; 143 | [myDelegate release]; 144 | 145 | [super dealloc]; 146 | #endif 147 | } 148 | 149 | @end 150 | 151 | #pragma mark - 152 | 153 | @implementation XMLRPCConnection (XMLRPCConnectionPrivate) 154 | 155 | - (void)connection: (NSURLConnection *)connection didReceiveResponse: (NSURLResponse *)response { 156 | if([response respondsToSelector: @selector(statusCode)]) { 157 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 158 | 159 | if(statusCode >= 400) { 160 | NSError *error = [NSError errorWithDomain: @"HTTP" code: statusCode userInfo: nil]; 161 | 162 | [myDelegate request: myRequest didFailWithError: error]; 163 | } else if (statusCode == 304) { 164 | [myManager closeConnectionForIdentifier: myIdentifier]; 165 | } 166 | } 167 | 168 | [myData setLength: 0]; 169 | } 170 | 171 | - (void)connection: (NSURLConnection *)connection didReceiveData: (NSData *)data { 172 | [myData appendData: data]; 173 | } 174 | 175 | - (void)connection: (NSURLConnection *)connection didSendBodyData: (NSInteger)bytesWritten totalBytesWritten: (NSInteger)totalBytesWritten totalBytesExpectedToWrite: (NSInteger)totalBytesExpectedToWrite { 176 | if ([myDelegate respondsToSelector: @selector(request:didSendBodyData:)]) { 177 | float percent = totalBytesWritten / (float)totalBytesExpectedToWrite; 178 | 179 | [myDelegate request:myRequest didSendBodyData:percent]; 180 | } 181 | } 182 | 183 | - (void)connection: (NSURLConnection *)connection didFailWithError: (NSError *)error { 184 | #if ! __has_feature(objc_arc) 185 | XMLRPCRequest *request = [[myRequest retain] autorelease]; 186 | #else 187 | XMLRPCRequest *request = myRequest; 188 | #endif 189 | 190 | NSLog(@"The connection, %@, failed with the following error: %@", myIdentifier, [error localizedDescription]); 191 | 192 | [self invalidateTimer]; 193 | 194 | [myDelegate request: request didFailWithError: error]; 195 | 196 | [myManager closeConnectionForIdentifier: myIdentifier]; 197 | } 198 | 199 | #pragma mark - 200 | 201 | - (BOOL)connection: (NSURLConnection *)connection canAuthenticateAgainstProtectionSpace: (NSURLProtectionSpace *)protectionSpace { 202 | return [myDelegate request: myRequest canAuthenticateAgainstProtectionSpace: protectionSpace]; 203 | } 204 | 205 | - (void)connection: (NSURLConnection *)connection didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge { 206 | [myDelegate request: myRequest didReceiveAuthenticationChallenge: challenge]; 207 | } 208 | 209 | - (void)connection: (NSURLConnection *)connection didCancelAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge { 210 | [myDelegate request: myRequest didCancelAuthenticationChallenge: challenge]; 211 | } 212 | 213 | - (void)connectionDidFinishLoading: (NSURLConnection *)connection { 214 | [self invalidateTimer]; 215 | if (myData && ([myData length] > 0)) { 216 | NSBlockOperation *parsingOperation; 217 | 218 | #if ! __has_feature(objc_arc) 219 | parsingOperation = [NSBlockOperation blockOperationWithBlock:^{ 220 | XMLRPCResponse *response = [[[XMLRPCResponse alloc] initWithData: myData] autorelease]; 221 | XMLRPCRequest *request = [[myRequest retain] autorelease]; 222 | 223 | [[NSOperationQueue mainQueue] addOperation: [NSBlockOperation blockOperationWithBlock:^{ 224 | [myDelegate request: request didReceiveResponse: response]; 225 | }]]; 226 | }]; 227 | #else 228 | parsingOperation = [NSBlockOperation blockOperationWithBlock:^{ 229 | XMLRPCResponse *response = [[XMLRPCResponse alloc] initWithData: myData]; 230 | XMLRPCRequest *request = myRequest; 231 | 232 | [[NSOperationQueue mainQueue] addOperation: [NSBlockOperation blockOperationWithBlock:^{ 233 | [myDelegate request: request didReceiveResponse: response]; 234 | 235 | [myManager closeConnectionForIdentifier: myIdentifier]; 236 | }]]; 237 | }]; 238 | #endif 239 | 240 | [[XMLRPCConnection parsingQueue] addOperation: parsingOperation]; 241 | } 242 | else { 243 | [myManager closeConnectionForIdentifier: myIdentifier]; 244 | } 245 | } 246 | 247 | #pragma mark - 248 | - (void)timeoutExpired 249 | { 250 | NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: 251 | [myRequest URL], NSURLErrorFailingURLErrorKey, 252 | [[myRequest URL] absoluteString], NSURLErrorFailingURLStringErrorKey, 253 | //TODO not good to use hardcoded value for localized description 254 | @"The request timed out.", NSLocalizedDescriptionKey, 255 | nil]; 256 | 257 | NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorTimedOut userInfo:userInfo]; 258 | 259 | [self connection:myConnection didFailWithError:error]; 260 | } 261 | 262 | - (void)invalidateTimer 263 | { 264 | [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(timeoutExpired) object:nil]; 265 | } 266 | 267 | #pragma mark - 268 | 269 | + (NSOperationQueue *)parsingQueue { 270 | if (parsingQueue == nil) { 271 | parsingQueue = [[NSOperationQueue alloc] init]; 272 | } 273 | 274 | return parsingQueue; 275 | } 276 | 277 | @end 278 | -------------------------------------------------------------------------------- /XMLRPCConnectionDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class XMLRPCConnection, XMLRPCRequest, XMLRPCResponse; 4 | 5 | @protocol XMLRPCConnectionDelegate 6 | 7 | @required 8 | - (void)request: (XMLRPCRequest *)request didReceiveResponse: (XMLRPCResponse *)response; 9 | 10 | @optional 11 | - (void)request: (XMLRPCRequest *)request didSendBodyData: (float)percent; 12 | 13 | @required 14 | - (void)request: (XMLRPCRequest *)request didFailWithError: (NSError *)error; 15 | 16 | #pragma mark - 17 | 18 | @required 19 | - (BOOL)request: (XMLRPCRequest *)request canAuthenticateAgainstProtectionSpace: (NSURLProtectionSpace *)protectionSpace; 20 | 21 | @required 22 | - (void)request: (XMLRPCRequest *)request didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge; 23 | 24 | @required 25 | - (void)request: (XMLRPCRequest *)request didCancelAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /XMLRPCConnectionManager.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "XMLRPCConnectionDelegate.h" 3 | 4 | @class XMLRPCConnection, XMLRPCRequest; 5 | 6 | @interface XMLRPCConnectionManager : NSObject { 7 | NSMutableDictionary *myConnections; 8 | } 9 | 10 | + (XMLRPCConnectionManager *)sharedManager; 11 | 12 | #pragma mark - 13 | 14 | - (NSString *)spawnConnectionWithXMLRPCRequest: (XMLRPCRequest *)request delegate: (id)delegate; 15 | 16 | #pragma mark - 17 | 18 | - (NSArray *)activeConnectionIdentifiers; 19 | 20 | - (NSUInteger)numberOfActiveConnections; 21 | 22 | #pragma mark - 23 | 24 | - (XMLRPCConnection *)connectionForIdentifier: (NSString *)identifier; 25 | 26 | #pragma mark - 27 | 28 | - (void)closeConnectionForIdentifier: (NSString *)identifier; 29 | 30 | - (void)closeConnections; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /XMLRPCConnectionManager.m: -------------------------------------------------------------------------------- 1 | #import "XMLRPCConnectionManager.h" 2 | #import "XMLRPCConnection.h" 3 | #import "XMLRPCRequest.h" 4 | 5 | @implementation XMLRPCConnectionManager 6 | 7 | static XMLRPCConnectionManager *sharedInstance = nil; 8 | 9 | - (id)init { 10 | self = [super init]; 11 | if (self) { 12 | myConnections = [[NSMutableDictionary alloc] init]; 13 | } 14 | 15 | return self; 16 | } 17 | 18 | #pragma mark - 19 | 20 | + (id)allocWithZone: (NSZone *)zone { 21 | @synchronized(self) { 22 | if (!sharedInstance) { 23 | sharedInstance = [super allocWithZone: zone]; 24 | 25 | return sharedInstance; 26 | } 27 | } 28 | 29 | return nil; 30 | } 31 | 32 | #pragma mark - 33 | 34 | + (XMLRPCConnectionManager *)sharedManager { 35 | @synchronized(self) { 36 | if (!sharedInstance) { 37 | sharedInstance = [[self alloc] init]; 38 | } 39 | } 40 | 41 | return sharedInstance; 42 | } 43 | 44 | #pragma mark - 45 | 46 | - (NSString *)spawnConnectionWithXMLRPCRequest: (XMLRPCRequest *)request delegate: (id)delegate { 47 | XMLRPCConnection *newConnection = [[XMLRPCConnection alloc] initWithXMLRPCRequest: request delegate: delegate manager: self]; 48 | #if ! __has_feature(objc_arc) 49 | NSString *identifier = [[[newConnection identifier] retain] autorelease]; 50 | #else 51 | NSString *identifier = [newConnection identifier]; 52 | #endif 53 | 54 | [myConnections setObject: newConnection forKey: identifier]; 55 | 56 | #if ! __has_feature(objc_arc) 57 | [newConnection release]; 58 | #endif 59 | 60 | return identifier; 61 | } 62 | 63 | #pragma mark - 64 | 65 | - (NSArray *)activeConnectionIdentifiers { 66 | return [myConnections allKeys]; 67 | } 68 | 69 | - (NSUInteger)numberOfActiveConnections { 70 | return [myConnections count]; 71 | } 72 | 73 | #pragma mark - 74 | 75 | - (XMLRPCConnection *)connectionForIdentifier: (NSString *)identifier { 76 | return [myConnections objectForKey: identifier]; 77 | } 78 | 79 | #pragma mark - 80 | 81 | - (void)closeConnectionForIdentifier: (NSString *)identifier { 82 | XMLRPCConnection *selectedConnection = [self connectionForIdentifier: identifier]; 83 | 84 | if (selectedConnection) { 85 | [selectedConnection cancel]; 86 | 87 | [myConnections removeObjectForKey: identifier]; 88 | } 89 | } 90 | 91 | - (void)closeConnections { 92 | [[myConnections allValues] makeObjectsPerformSelector: @selector(cancel)]; 93 | 94 | [myConnections removeAllObjects]; 95 | } 96 | 97 | #pragma mark - 98 | 99 | 100 | #pragma mark - 101 | 102 | - (void)dealloc { 103 | [self closeConnections]; 104 | 105 | #if ! __has_feature(objc_arc) 106 | [myConnections release]; 107 | 108 | [super dealloc]; 109 | #endif 110 | } 111 | 112 | @end 113 | -------------------------------------------------------------------------------- /XMLRPCDefaultEncoder.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "XMLRPCEncoder.h" 3 | 4 | @interface XMLRPCDefaultEncoder : NSObject { 5 | NSString *myMethod; 6 | NSArray *myParameters; 7 | } 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /XMLRPCDefaultEncoder.m: -------------------------------------------------------------------------------- 1 | #import "XMLRPCDefaultEncoder.h" 2 | #import "NSStringAdditions.h" 3 | #import "NSData+Base64.h" 4 | 5 | @interface XMLRPCDefaultEncoder (XMLRPCEncoderPrivate) 6 | 7 | - (NSString *)valueTag: (NSString *)tag value: (NSString *)value; 8 | 9 | #pragma mark - 10 | 11 | - (NSString *)replaceTarget: (NSString *)target withValue: (NSString *)value inString: (NSString *)string; 12 | 13 | #pragma mark - 14 | 15 | - (NSString *)encodeObject: (id)object; 16 | 17 | #pragma mark - 18 | 19 | - (NSString *)encodeArray: (NSArray *)array; 20 | 21 | - (NSString *)encodeDictionary: (NSDictionary *)dictionary; 22 | 23 | #pragma mark - 24 | 25 | - (NSString *)encodeBoolean: (CFBooleanRef)boolean; 26 | 27 | - (NSString *)encodeNumber: (NSNumber *)number; 28 | 29 | - (NSString *)encodeString: (NSString *)string omitTag: (BOOL)omitTag; 30 | 31 | - (NSString *)encodeDate: (NSDate *)date; 32 | 33 | - (NSString *)encodeData: (NSData *)data; 34 | 35 | @end 36 | 37 | #pragma mark - 38 | 39 | @implementation XMLRPCDefaultEncoder 40 | 41 | - (id)init { 42 | if (self = [super init]) { 43 | myMethod = [[NSString alloc] init]; 44 | myParameters = [[NSArray alloc] init]; 45 | } 46 | 47 | return self; 48 | } 49 | 50 | #pragma mark - 51 | 52 | - (NSString *)encode { 53 | NSMutableString *buffer = [NSMutableString stringWithString: @""]; 54 | 55 | [buffer appendFormat: @"%@", [self encodeString: myMethod omitTag: YES]]; 56 | 57 | [buffer appendString: @""]; 58 | 59 | if (myParameters) { 60 | NSEnumerator *enumerator = [myParameters objectEnumerator]; 61 | id parameter = nil; 62 | 63 | while ((parameter = [enumerator nextObject])) { 64 | [buffer appendString: @""]; 65 | [buffer appendString: [self encodeObject: parameter]]; 66 | [buffer appendString: @""]; 67 | } 68 | } 69 | 70 | [buffer appendString: @""]; 71 | 72 | [buffer appendString: @""]; 73 | 74 | return buffer; 75 | } 76 | 77 | #pragma mark - 78 | 79 | - (void)setMethod: (NSString *)method withParameters: (NSArray *)parameters { 80 | #if ! __has_feature(objc_arc) 81 | if (myMethod) { 82 | [myMethod release]; 83 | } 84 | 85 | if (!method) { 86 | myMethod = nil; 87 | } else { 88 | myMethod = [method retain]; 89 | } 90 | 91 | if (myParameters) { 92 | [myParameters release]; 93 | } 94 | 95 | if (!parameters) { 96 | myParameters = nil; 97 | } else { 98 | myParameters = [parameters retain]; 99 | } 100 | #else 101 | myMethod = method; 102 | myParameters = parameters; 103 | #endif 104 | } 105 | 106 | #pragma mark - 107 | 108 | - (NSString *)method { 109 | return myMethod; 110 | } 111 | 112 | - (NSArray *)parameters { 113 | return myParameters; 114 | } 115 | 116 | #pragma mark - 117 | 118 | - (void)dealloc { 119 | #if ! __has_feature(objc_arc) 120 | [myMethod release]; 121 | [myParameters release]; 122 | 123 | [super dealloc]; 124 | #endif 125 | } 126 | 127 | @end 128 | 129 | #pragma mark - 130 | 131 | @implementation XMLRPCDefaultEncoder (XMLRPCEncoderPrivate) 132 | 133 | - (NSString *)valueTag: (NSString *)tag value: (NSString *)value { 134 | return [NSString stringWithFormat: @"<%@>%@", tag, value, tag]; 135 | } 136 | 137 | #pragma mark - 138 | 139 | - (NSString *)replaceTarget: (NSString *)target withValue: (NSString *)value inString: (NSString *)string { 140 | return [[string componentsSeparatedByString: target] componentsJoinedByString: value]; 141 | } 142 | 143 | #pragma mark - 144 | 145 | - (NSString *)encodeObject: (id)object { 146 | if (!object) { 147 | return nil; 148 | } 149 | 150 | if ([object isKindOfClass: [NSArray class]]) { 151 | return [self encodeArray: object]; 152 | } else if ([object isKindOfClass: [NSDictionary class]]) { 153 | return [self encodeDictionary: object]; 154 | #if ! __has_feature(objc_arc) 155 | } else if (((CFBooleanRef)object == kCFBooleanTrue) || ((CFBooleanRef)object == kCFBooleanFalse)) { 156 | #else 157 | } else if (((__bridge CFBooleanRef)object == kCFBooleanTrue) || ((__bridge CFBooleanRef)object == kCFBooleanFalse)) { 158 | #endif 159 | return [self encodeBoolean: (CFBooleanRef)object]; 160 | } else if ([object isKindOfClass: [NSNumber class]]) { 161 | return [self encodeNumber: object]; 162 | } else if ([object isKindOfClass: [NSString class]]) { 163 | return [self encodeString: object omitTag: NO]; 164 | } else if ([object isKindOfClass: [NSDate class]]) { 165 | return [self encodeDate: object]; 166 | } else if ([object isKindOfClass: [NSData class]]) { 167 | return [self encodeData: object]; 168 | } else { 169 | return [self encodeString: object omitTag: NO]; 170 | } 171 | } 172 | 173 | #pragma mark - 174 | 175 | - (NSString *)encodeArray: (NSArray *)array { 176 | NSMutableString *buffer = [NSMutableString string]; 177 | NSEnumerator *enumerator = [array objectEnumerator]; 178 | 179 | [buffer appendString: @""]; 180 | 181 | id object = nil; 182 | 183 | while (object = [enumerator nextObject]) { 184 | [buffer appendString: [self encodeObject: object]]; 185 | } 186 | 187 | [buffer appendString: @""]; 188 | 189 | return (NSString *)buffer; 190 | } 191 | 192 | - (NSString *)encodeDictionary: (NSDictionary *)dictionary { 193 | NSMutableString * buffer = [NSMutableString string]; 194 | NSEnumerator *enumerator = [dictionary keyEnumerator]; 195 | 196 | [buffer appendString: @""]; 197 | 198 | NSString *key = nil; 199 | NSObject *val; 200 | 201 | while (key = [enumerator nextObject]) { 202 | [buffer appendString: @""]; 203 | [buffer appendFormat: @"%@", [self encodeString: key omitTag: YES]]; 204 | 205 | val = [dictionary objectForKey: key]; 206 | if (val != [NSNull null]) { 207 | [buffer appendString: [self encodeObject: val]]; 208 | } else { 209 | [buffer appendString:@""]; 210 | } 211 | 212 | [buffer appendString: @""]; 213 | } 214 | 215 | [buffer appendString: @""]; 216 | 217 | return (NSString *)buffer; 218 | } 219 | 220 | #pragma mark - 221 | 222 | - (NSString *)encodeBoolean: (CFBooleanRef)boolean { 223 | if (boolean == kCFBooleanTrue) { 224 | return [self valueTag: @"boolean" value: @"1"]; 225 | } else { 226 | return [self valueTag: @"boolean" value: @"0"]; 227 | } 228 | } 229 | 230 | - (NSString *)encodeNumber: (NSNumber *)number { 231 | NSString *numberType = [NSString stringWithCString: [number objCType] encoding: NSUTF8StringEncoding]; 232 | 233 | if ([numberType isEqualToString: @"d"]) { 234 | return [self valueTag: @"double" value: [number stringValue]]; 235 | } else { 236 | return [self valueTag: @"i4" value: [number stringValue]]; 237 | } 238 | } 239 | 240 | - (NSString *)encodeString: (NSString *)string omitTag: (BOOL)omitTag { 241 | return omitTag ? [string escapedString] : [self valueTag: @"string" value: [string escapedString]]; 242 | } 243 | 244 | - (NSString *)encodeDate: (NSDate *)date { 245 | unsigned components = kCFCalendarUnitYear | kCFCalendarUnitMonth | kCFCalendarUnitDay | kCFCalendarUnitHour | kCFCalendarUnitMinute | kCFCalendarUnitSecond; 246 | NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components: components fromDate: date]; 247 | NSString *buffer = [NSString stringWithFormat: @"%.4ld%.2ld%.2ldT%.2ld:%.2ld:%.2ld", (long)[dateComponents year], (long)[dateComponents month], (long)[dateComponents day], (long)[dateComponents hour], (long)[dateComponents minute], (long)[dateComponents second], nil]; 248 | 249 | return [self valueTag: @"dateTime.iso8601" value: buffer]; 250 | } 251 | 252 | - (NSString *)encodeData: (NSData *)data { 253 | return [self valueTag: @"base64" value: [data base64EncodedString]]; 254 | } 255 | 256 | @end 257 | -------------------------------------------------------------------------------- /XMLRPCEncoder.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @protocol XMLRPCEncoder 4 | 5 | - (NSString *)encode; 6 | 7 | #pragma mark - 8 | 9 | - (void)setMethod: (NSString *)method withParameters: (NSArray *)parameters; 10 | 11 | #pragma mark - 12 | 13 | - (NSString *)method; 14 | 15 | - (NSArray *)parameters; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /XMLRPCEventBasedParser.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class XMLRPCEventBasedParserDelegate; 4 | 5 | @interface XMLRPCEventBasedParser : NSObject { 6 | NSXMLParser *myParser; 7 | XMLRPCEventBasedParserDelegate *myParserDelegate; 8 | BOOL isFault; 9 | } 10 | 11 | - (id)initWithData: (NSData *)data; 12 | 13 | #pragma mark - 14 | 15 | - (id)parse; 16 | 17 | - (void)abortParsing; 18 | 19 | #pragma mark - 20 | 21 | - (NSError *)parserError; 22 | 23 | #pragma mark - 24 | 25 | - (BOOL)isFault; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /XMLRPCEventBasedParser.m: -------------------------------------------------------------------------------- 1 | #import "XMLRPCEventBasedParser.h" 2 | #import "XMLRPCEventBasedParserDelegate.h" 3 | 4 | @implementation XMLRPCEventBasedParser 5 | 6 | - (id)initWithData: (NSData *)data { 7 | if (!data) { 8 | return nil; 9 | } 10 | 11 | if (self = [self init]) { 12 | myParser = [[NSXMLParser alloc] initWithData: data]; 13 | myParserDelegate = nil; 14 | isFault = NO; 15 | } 16 | 17 | return self; 18 | } 19 | 20 | #pragma mark - 21 | 22 | - (id)parse { 23 | [myParser setDelegate: self]; 24 | 25 | [myParser parse]; 26 | 27 | if ([myParser parserError]) { 28 | return nil; 29 | } 30 | 31 | return [myParserDelegate elementValue]; 32 | } 33 | 34 | - (void)abortParsing { 35 | [myParser abortParsing]; 36 | } 37 | 38 | #pragma mark - 39 | 40 | - (NSError *)parserError { 41 | return [myParser parserError]; 42 | } 43 | 44 | #pragma mark - 45 | 46 | - (BOOL)isFault { 47 | return isFault; 48 | } 49 | 50 | #pragma mark - 51 | 52 | - (void)dealloc { 53 | #if ! __has_feature(objc_arc) 54 | [myParser release]; 55 | [myParserDelegate release]; 56 | 57 | [super dealloc]; 58 | #endif 59 | } 60 | 61 | @end 62 | 63 | #pragma mark - 64 | 65 | @implementation XMLRPCEventBasedParser (NSXMLParserDelegate) 66 | 67 | - (void)parser: (NSXMLParser *)parser didStartElement: (NSString *)element namespaceURI: (NSString *)namespaceURI qualifiedName: (NSString *)qualifiedName attributes: (NSDictionary *)attributes { 68 | if ([element isEqualToString: @"fault"]) { 69 | isFault = YES; 70 | } else if ([element isEqualToString: @"value"]) { 71 | myParserDelegate = [[XMLRPCEventBasedParserDelegate alloc] initWithParent: nil]; 72 | 73 | [myParser setDelegate: myParserDelegate]; 74 | } 75 | } 76 | 77 | - (void)parser: (NSXMLParser *)parser parseErrorOccurred: (NSError *)parseError { 78 | [self abortParsing]; 79 | } 80 | 81 | @end 82 | -------------------------------------------------------------------------------- /XMLRPCEventBasedParserDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | typedef enum { 4 | XMLRPCElementTypeArray, 5 | XMLRPCElementTypeDictionary, 6 | XMLRPCElementTypeMember, 7 | XMLRPCElementTypeName, 8 | XMLRPCElementTypeInteger, 9 | XMLRPCElementTypeDouble, 10 | XMLRPCElementTypeBoolean, 11 | XMLRPCElementTypeString, 12 | XMLRPCElementTypeDate, 13 | XMLRPCElementTypeData 14 | } XMLRPCElementType; 15 | 16 | #pragma mark - 17 | 18 | @interface XMLRPCEventBasedParserDelegate : NSObject { 19 | #if !__has_feature(objc_arc) 20 | XMLRPCEventBasedParserDelegate *myParent; 21 | #else 22 | // Without ARC this reference is effectively unretained so don't use strong reference here. 23 | XMLRPCEventBasedParserDelegate * __unsafe_unretained myParent; 24 | #endif 25 | NSMutableSet *myChildren; 26 | XMLRPCElementType myElementType; 27 | NSString *myElementKey; 28 | id myElementValue; 29 | } 30 | 31 | - (id)initWithParent: (XMLRPCEventBasedParserDelegate *)parent; 32 | 33 | #pragma mark - 34 | 35 | - (void)setParent: (XMLRPCEventBasedParserDelegate *)parent; 36 | 37 | - (XMLRPCEventBasedParserDelegate *)parent; 38 | 39 | #pragma mark - 40 | 41 | - (void)setElementType: (XMLRPCElementType)elementType; 42 | 43 | - (XMLRPCElementType)elementType; 44 | 45 | #pragma mark - 46 | 47 | - (void)setElementKey: (NSString *)elementKey; 48 | 49 | - (NSString *)elementKey; 50 | 51 | #pragma mark - 52 | 53 | - (void)setElementValue: (id)elementValue; 54 | 55 | - (id)elementValue; 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /XMLRPCEventBasedParserDelegate.m: -------------------------------------------------------------------------------- 1 | #import "XMLRPCEventBasedParserDelegate.h" 2 | #import "NSData+Base64.h" 3 | 4 | @interface XMLRPCEventBasedParserDelegate (XMLRPCEventBasedParserDelegatePrivate) 5 | 6 | - (BOOL)isDictionaryElementType: (XMLRPCElementType)elementType; 7 | 8 | #pragma mark - 9 | 10 | - (void)addElementValueToParent; 11 | 12 | #pragma mark - 13 | 14 | - (NSDate *)parseDateString: (NSString *)dateString withFormat: (NSString *)format; 15 | 16 | #pragma mark - 17 | 18 | - (NSNumber *)parseInteger: (NSString *)value; 19 | 20 | - (NSNumber *)parseDouble: (NSString *)value; 21 | 22 | - (NSNumber *)parseBoolean: (NSString *)value; 23 | 24 | - (NSString *)parseString: (NSString *)value; 25 | 26 | - (NSDate *)parseDate: (NSString *)value; 27 | 28 | - (NSData *)parseData: (NSString *)value; 29 | 30 | @end 31 | 32 | #pragma mark - 33 | 34 | @implementation XMLRPCEventBasedParserDelegate 35 | 36 | - (id)initWithParent: (XMLRPCEventBasedParserDelegate *)parent { 37 | self = [super init]; 38 | if (self) { 39 | myParent = parent; 40 | myChildren = [[NSMutableSet alloc] initWithCapacity: 1]; 41 | myElementType = XMLRPCElementTypeString; 42 | myElementKey = nil; 43 | myElementValue = [[NSMutableString alloc] init]; 44 | } 45 | 46 | return self; 47 | } 48 | 49 | #pragma mark - 50 | 51 | - (void)setParent: (XMLRPCEventBasedParserDelegate *)parent { 52 | #if ! __has_feature(objc_arc) 53 | [parent retain]; 54 | [myParent release]; 55 | #endif 56 | 57 | myParent = parent; 58 | } 59 | 60 | - (XMLRPCEventBasedParserDelegate *)parent { 61 | return myParent; 62 | } 63 | 64 | #pragma mark - 65 | 66 | - (void)setElementType: (XMLRPCElementType)elementType { 67 | myElementType = elementType; 68 | } 69 | 70 | - (XMLRPCElementType)elementType { 71 | return myElementType; 72 | } 73 | 74 | #pragma mark - 75 | 76 | - (void)setElementKey: (NSString *)elementKey { 77 | #if ! __has_feature(objc_arc) 78 | [elementKey retain]; 79 | [myElementKey release]; 80 | #endif 81 | 82 | myElementKey = elementKey; 83 | } 84 | 85 | - (NSString *)elementKey { 86 | return myElementKey; 87 | } 88 | 89 | #pragma mark - 90 | 91 | - (void)setElementValue: (id)elementValue { 92 | #if ! __has_feature(objc_arc) 93 | [elementValue retain]; 94 | [myElementValue release]; 95 | #endif 96 | 97 | myElementValue = elementValue; 98 | } 99 | 100 | - (id)elementValue { 101 | return myElementValue; 102 | } 103 | 104 | #pragma mark - 105 | 106 | - (void)dealloc { 107 | #if ! __has_feature(objc_arc) 108 | [myChildren release]; 109 | [myElementKey release]; 110 | [myElementValue release]; 111 | 112 | [super dealloc]; 113 | #endif 114 | } 115 | 116 | @end 117 | 118 | #pragma mark - 119 | 120 | @implementation XMLRPCEventBasedParserDelegate (NSXMLParserDelegate) 121 | 122 | - (void)parser: (NSXMLParser *)parser didStartElement: (NSString *)element namespaceURI: (NSString *)namespaceURI qualifiedName: (NSString *)qualifiedName attributes: (NSDictionary *)attributes { 123 | if ([element isEqualToString: @"value"] || [element isEqualToString: @"member"] || [element isEqualToString: @"name"]) { 124 | XMLRPCEventBasedParserDelegate *parserDelegate = [[XMLRPCEventBasedParserDelegate alloc] initWithParent: self]; 125 | 126 | if ([element isEqualToString: @"member"]) { 127 | [parserDelegate setElementType: XMLRPCElementTypeMember]; 128 | } else if ([element isEqualToString: @"name"]) { 129 | [parserDelegate setElementType: XMLRPCElementTypeName]; 130 | } 131 | 132 | [myChildren addObject: parserDelegate]; 133 | 134 | [parser setDelegate: parserDelegate]; 135 | #if ! __has_feature(objc_arc) 136 | [parserDelegate release]; 137 | #endif 138 | return; 139 | } 140 | 141 | if ([element isEqualToString: @"array"]) { 142 | NSMutableArray *array = [[NSMutableArray alloc] init]; 143 | 144 | [self setElementValue: array]; 145 | #if ! __has_feature(objc_arc) 146 | [array release]; 147 | #endif 148 | [self setElementType: XMLRPCElementTypeArray]; 149 | } else if ([element isEqualToString: @"struct"]) { 150 | NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; 151 | 152 | [self setElementValue: dictionary]; 153 | #if ! __has_feature(objc_arc) 154 | [dictionary release]; 155 | #endif 156 | [self setElementType: XMLRPCElementTypeDictionary]; 157 | } else if ([element isEqualToString: @"int"] || [element isEqualToString: @"i4"]) { 158 | [self setElementType: XMLRPCElementTypeInteger]; 159 | } else if ([element isEqualToString: @"double"]) { 160 | [self setElementType: XMLRPCElementTypeDouble]; 161 | } else if ([element isEqualToString: @"boolean"]) { 162 | [self setElementType: XMLRPCElementTypeBoolean]; 163 | } else if ([element isEqualToString: @"string"]) { 164 | [self setElementType: XMLRPCElementTypeString]; 165 | } else if ([element isEqualToString: @"dateTime.iso8601"]) { 166 | [self setElementType: XMLRPCElementTypeDate]; 167 | } else if ([element isEqualToString: @"base64"]) { 168 | [self setElementType: XMLRPCElementTypeData]; 169 | } 170 | } 171 | 172 | - (void)parser: (NSXMLParser *)parser didEndElement: (NSString *)element namespaceURI: (NSString *)namespaceURI qualifiedName: (NSString *)qualifiedName { 173 | if ([element isEqualToString: @"value"] || [element isEqualToString: @"member"] || [element isEqualToString: @"name"]) { 174 | NSString *elementValue = nil; 175 | 176 | if ((myElementType != XMLRPCElementTypeArray) && ![self isDictionaryElementType: myElementType]) { 177 | elementValue = [self parseString: myElementValue]; 178 | #if ! __has_feature(objc_arc) 179 | [myElementValue release]; 180 | #endif 181 | myElementValue = nil; 182 | } 183 | 184 | switch (myElementType) { 185 | case XMLRPCElementTypeInteger: 186 | myElementValue = [self parseInteger: elementValue]; 187 | #if ! __has_feature(objc_arc) 188 | [myElementValue retain]; 189 | #endif 190 | break; 191 | case XMLRPCElementTypeDouble: 192 | myElementValue = [self parseDouble: elementValue]; 193 | #if ! __has_feature(objc_arc) 194 | [myElementValue retain]; 195 | #endif 196 | break; 197 | case XMLRPCElementTypeBoolean: 198 | myElementValue = [self parseBoolean: elementValue]; 199 | #if ! __has_feature(objc_arc) 200 | [myElementValue retain]; 201 | #endif 202 | break; 203 | case XMLRPCElementTypeString: 204 | case XMLRPCElementTypeName: 205 | myElementValue = elementValue; 206 | #if ! __has_feature(objc_arc) 207 | [myElementValue retain]; 208 | #endif 209 | break; 210 | case XMLRPCElementTypeDate: 211 | myElementValue = [self parseDate: elementValue]; 212 | #if ! __has_feature(objc_arc) 213 | [myElementValue retain]; 214 | #endif 215 | break; 216 | case XMLRPCElementTypeData: 217 | myElementValue = [self parseData: elementValue]; 218 | #if ! __has_feature(objc_arc) 219 | [myElementValue retain]; 220 | #endif 221 | break; 222 | default: 223 | break; 224 | } 225 | 226 | if (myParent && myElementValue) { 227 | [self addElementValueToParent]; 228 | } 229 | 230 | [parser setDelegate: myParent]; 231 | 232 | if (myParent) { 233 | XMLRPCEventBasedParserDelegate *parent = myParent; 234 | 235 | // Set it to nil explicitly since it's not __weak but __unsafe_unretained. 236 | // We're doing it here because if we'll do it after removal from myChildren 237 | // self can already be deallocated, and accessing field of deallocated object 238 | // causes memory corruption. 239 | myParent = nil; 240 | 241 | [parent->myChildren removeObject: self]; 242 | } 243 | } 244 | } 245 | 246 | - (void)parser: (NSXMLParser *)parser foundCharacters: (NSString *)string { 247 | if ((myElementType == XMLRPCElementTypeArray) || [self isDictionaryElementType: myElementType]) { 248 | return; 249 | } 250 | 251 | if (!myElementValue) { 252 | myElementValue = [[NSMutableString alloc] initWithString: string]; 253 | } else { 254 | [myElementValue appendString: string]; 255 | } 256 | } 257 | 258 | - (void)parser: (NSXMLParser *)parser parseErrorOccurred: (NSError *)parseError { 259 | [parser abortParsing]; 260 | } 261 | 262 | @end 263 | 264 | #pragma mark - 265 | 266 | @implementation XMLRPCEventBasedParserDelegate (XMLRPCEventBasedParserDelegatePrivate) 267 | 268 | - (BOOL)isDictionaryElementType: (XMLRPCElementType)elementType { 269 | if ((myElementType == XMLRPCElementTypeDictionary) || (myElementType == XMLRPCElementTypeMember)) { 270 | return YES; 271 | } 272 | 273 | return NO; 274 | } 275 | 276 | #pragma mark - 277 | 278 | - (void)addElementValueToParent { 279 | id parentElementValue = [myParent elementValue]; 280 | 281 | switch ([myParent elementType]) { 282 | case XMLRPCElementTypeArray: 283 | [parentElementValue addObject: myElementValue]; 284 | 285 | break; 286 | case XMLRPCElementTypeDictionary: 287 | if ([myElementValue isEqual:[NSNull null]]) { 288 | [parentElementValue removeObjectForKey:myElementKey]; 289 | } else { 290 | [parentElementValue setObject: myElementValue forKey: myElementKey]; 291 | } 292 | 293 | break; 294 | case XMLRPCElementTypeMember: 295 | if (myElementType == XMLRPCElementTypeName) { 296 | [myParent setElementKey: myElementValue]; 297 | } else { 298 | [myParent setElementValue: myElementValue]; 299 | } 300 | 301 | break; 302 | default: 303 | break; 304 | } 305 | } 306 | 307 | #pragma mark - 308 | 309 | - (NSDate *)parseDateString: (NSString *)dateString withFormat: (NSString *)format { 310 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 311 | NSDate *result = nil; 312 | 313 | [dateFormatter setDateFormat: format]; 314 | 315 | result = [dateFormatter dateFromString: dateString]; 316 | #if ! __has_feature(objc_arc) 317 | [dateFormatter release]; 318 | #endif 319 | return result; 320 | } 321 | 322 | #pragma mark - 323 | 324 | - (NSNumber *)parseInteger: (NSString *)value { 325 | return [NSNumber numberWithInteger: [value integerValue]]; 326 | } 327 | 328 | - (NSNumber *)parseDouble: (NSString *)value { 329 | return [NSNumber numberWithDouble: [value doubleValue]]; 330 | } 331 | 332 | - (NSNumber *)parseBoolean: (NSString *)value { 333 | if ([value isEqualToString: @"1"]) { 334 | return [NSNumber numberWithBool: YES]; 335 | } 336 | 337 | return [NSNumber numberWithBool: NO]; 338 | } 339 | 340 | - (NSString *)parseString: (NSString *)value { 341 | return [value stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; 342 | } 343 | 344 | - (NSDate *)parseDate: (NSString *)value { 345 | NSDate *result = nil; 346 | 347 | result = [self parseDateString: value withFormat: @"yyyyMMdd'T'HH:mm:ss"]; 348 | 349 | if (!result) { 350 | result = [self parseDateString: value withFormat: @"yyyy'-'MM'-'dd'T'HH:mm:ss"]; 351 | } 352 | 353 | if (!result) { 354 | result = [self parseDateString: value withFormat: @"yyyy'-'MM'-'dd'T'HH:mm:ssZ"]; 355 | } 356 | 357 | if (!result) { 358 | result = (NSDate *)[NSNull null]; 359 | } 360 | 361 | return result; 362 | } 363 | 364 | - (NSData *)parseData: (NSString *)value { 365 | return [NSData dataFromBase64String: value]; 366 | } 367 | 368 | @end 369 | -------------------------------------------------------------------------------- /XMLRPCRequest.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "XMLRPCEncoder.h" 4 | 5 | @interface XMLRPCRequest : NSObject { 6 | NSMutableURLRequest *myRequest; 7 | id myXMLEncoder; 8 | NSTimeInterval myTimeout; 9 | 10 | id extra; 11 | } 12 | 13 | - (id)initWithURL: (NSURL *)URL; 14 | 15 | #pragma mark - 16 | 17 | - (void)setURL: (NSURL *)URL; 18 | 19 | - (NSURL *)URL; 20 | 21 | #pragma mark - 22 | 23 | - (void)setUserAgent: (NSString *)userAgent; 24 | 25 | - (NSString *)userAgent; 26 | 27 | #pragma mark - 28 | 29 | - (void)setEncoder: (id) encoder; 30 | 31 | - (void)setMethod: (NSString *)method; 32 | 33 | - (void)setMethod: (NSString *)method withParameter: (id)parameter; 34 | 35 | - (void)setMethod: (NSString *)method withParameters: (NSArray *)parameters; 36 | 37 | - (void)setTimeoutInterval: (NSTimeInterval)timeout; 38 | 39 | #pragma mark - 40 | 41 | - (NSString *)method; 42 | 43 | - (NSArray *)parameters; 44 | 45 | - (NSTimeInterval)timeout; 46 | 47 | #pragma mark - 48 | 49 | - (NSString *)body; 50 | 51 | #pragma mark - 52 | 53 | - (NSURLRequest *)request; 54 | 55 | #pragma mark - 56 | 57 | - (void)setValue: (NSString *)value forHTTPHeaderField: (NSString *)header; 58 | 59 | #pragma mark - 60 | 61 | - (id) extra; 62 | - (void) setExtra:(id) extraObject; 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /XMLRPCRequest.m: -------------------------------------------------------------------------------- 1 | #import "XMLRPCRequest.h" 2 | #import "XMLRPCEncoder.h" 3 | #import "XMLRPCDefaultEncoder.h" 4 | 5 | static const NSTimeInterval DEFAULT_TIMEOUT = 240; 6 | 7 | @implementation XMLRPCRequest 8 | 9 | - (id)initWithURL: (NSURL *)URL withEncoder: (id)encoder { 10 | self = [super init]; 11 | if (self) { 12 | if (URL) { 13 | myRequest = [[NSMutableURLRequest alloc] initWithURL: URL]; 14 | } else { 15 | myRequest = [[NSMutableURLRequest alloc] init]; 16 | } 17 | 18 | myXMLEncoder = encoder; 19 | #if ! __has_feature(objc_arc) 20 | [myXMLEncoder retain]; 21 | #endif 22 | 23 | myTimeout = DEFAULT_TIMEOUT; 24 | } 25 | 26 | return self; 27 | } 28 | 29 | - (id)initWithURL: (NSURL *)URL { 30 | #if ! __has_feature(objc_arc) 31 | return [self initWithURL:URL withEncoder:[[[XMLRPCDefaultEncoder alloc] init] autorelease]]; 32 | #else 33 | return [self initWithURL:URL withEncoder:[[XMLRPCDefaultEncoder alloc] init]]; 34 | #endif 35 | } 36 | 37 | #pragma mark - 38 | 39 | - (void)setURL: (NSURL *)URL { 40 | [myRequest setURL: URL]; 41 | } 42 | 43 | - (NSURL *)URL { 44 | return [myRequest URL]; 45 | } 46 | 47 | #pragma mark - 48 | 49 | - (void)setUserAgent: (NSString *)userAgent { 50 | if (![self userAgent]) { 51 | [myRequest addValue: userAgent forHTTPHeaderField: @"User-Agent"]; 52 | } else { 53 | [myRequest setValue: userAgent forHTTPHeaderField: @"User-Agent"]; 54 | } 55 | } 56 | 57 | - (NSString *)userAgent { 58 | return [myRequest valueForHTTPHeaderField: @"User-Agent"]; 59 | } 60 | 61 | #pragma mark - 62 | 63 | - (void)setEncoder:(id)encoder { 64 | NSString *method = [myXMLEncoder method]; 65 | NSArray *parameters = [myXMLEncoder parameters]; 66 | #if ! __has_feature(objc_arc) 67 | [myXMLEncoder release]; 68 | 69 | myXMLEncoder = [encoder retain]; 70 | #else 71 | myXMLEncoder = encoder; 72 | #endif 73 | 74 | [myXMLEncoder setMethod: method withParameters: parameters]; 75 | } 76 | 77 | - (void)setMethod: (NSString *)method { 78 | [myXMLEncoder setMethod: method withParameters: nil]; 79 | } 80 | 81 | - (void)setMethod: (NSString *)method withParameter: (id)parameter { 82 | NSArray *parameters = nil; 83 | 84 | if (parameter) { 85 | parameters = [NSArray arrayWithObject: parameter]; 86 | } 87 | 88 | [myXMLEncoder setMethod: method withParameters: parameters]; 89 | } 90 | 91 | - (void)setMethod: (NSString *)method withParameters: (NSArray *)parameters { 92 | [myXMLEncoder setMethod: method withParameters: parameters]; 93 | } 94 | 95 | - (void)setTimeoutInterval: (NSTimeInterval)timeout 96 | { 97 | myTimeout = timeout; 98 | } 99 | 100 | #pragma mark - 101 | 102 | - (NSString *)method { 103 | return [myXMLEncoder method]; 104 | } 105 | 106 | - (NSArray *)parameters { 107 | return [myXMLEncoder parameters]; 108 | } 109 | 110 | - (NSTimeInterval)timeout 111 | { 112 | return myTimeout; 113 | } 114 | 115 | #pragma mark - 116 | 117 | - (NSString *)body { 118 | return [myXMLEncoder encode]; 119 | } 120 | 121 | #pragma mark - 122 | 123 | - (NSURLRequest *)request { 124 | NSData *content = [[self body] dataUsingEncoding: NSUTF8StringEncoding]; 125 | NSNumber *contentLength = [NSNumber numberWithUnsignedInteger:[content length]]; 126 | 127 | if (!myRequest) { 128 | return nil; 129 | } 130 | 131 | [myRequest setHTTPMethod: @"POST"]; 132 | 133 | if (![myRequest valueForHTTPHeaderField: @"Content-Type"]) { 134 | [myRequest addValue: @"text/xml" forHTTPHeaderField: @"Content-Type"]; 135 | } else { 136 | [myRequest setValue: @"text/xml" forHTTPHeaderField: @"Content-Type"]; 137 | } 138 | 139 | if (![myRequest valueForHTTPHeaderField: @"Content-Length"]) { 140 | [myRequest addValue: [contentLength stringValue] forHTTPHeaderField: @"Content-Length"]; 141 | } else { 142 | [myRequest setValue: [contentLength stringValue] forHTTPHeaderField: @"Content-Length"]; 143 | } 144 | 145 | if (![myRequest valueForHTTPHeaderField: @"Accept"]) { 146 | [myRequest addValue: @"text/xml" forHTTPHeaderField: @"Accept"]; 147 | } else { 148 | [myRequest setValue: @"text/xml" forHTTPHeaderField: @"Accept"]; 149 | } 150 | 151 | if (![self userAgent]) { 152 | NSString *userAgent = [[NSUserDefaults standardUserDefaults] objectForKey:@"UserAgent"]; 153 | 154 | if (userAgent) { 155 | [self setUserAgent: userAgent]; 156 | } 157 | } 158 | 159 | [myRequest setHTTPBody: content]; 160 | 161 | return (NSURLRequest *)myRequest; 162 | } 163 | 164 | #pragma mark - 165 | 166 | - (void)setValue: (NSString *)value forHTTPHeaderField: (NSString *)header { 167 | [myRequest setValue: value forHTTPHeaderField: header]; 168 | } 169 | #pragma mark - 170 | 171 | - (id) extra { 172 | return extra; 173 | } 174 | 175 | - (void) setExtra:(id) extraObject { 176 | #if ! __has_feature(objc_arc) 177 | [extra release]; 178 | extra = [extraObject retain]; 179 | #else 180 | extra = extraObject; 181 | #endif 182 | } 183 | 184 | #pragma mark - 185 | 186 | - (void)dealloc { 187 | #if ! __has_feature(objc_arc) 188 | [myRequest release]; 189 | [myXMLEncoder release]; 190 | 191 | [super dealloc]; 192 | #endif 193 | } 194 | 195 | @end 196 | -------------------------------------------------------------------------------- /XMLRPCResponse.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class XMLRPCDecoder; 4 | 5 | @interface XMLRPCResponse : NSObject { 6 | NSString *myBody; 7 | id myObject; 8 | BOOL isFault; 9 | } 10 | 11 | - (id)initWithData: (NSData *)data; 12 | 13 | #pragma mark - 14 | 15 | - (BOOL)isFault; 16 | 17 | - (NSNumber *)faultCode; 18 | 19 | - (NSString *)faultString; 20 | 21 | #pragma mark - 22 | 23 | - (id)object; 24 | 25 | #pragma mark - 26 | 27 | - (NSString *)body; 28 | 29 | #pragma mark - 30 | 31 | - (NSString *)description; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /XMLRPCResponse.m: -------------------------------------------------------------------------------- 1 | #import "XMLRPCResponse.h" 2 | #import "XMLRPCEventBasedParser.h" 3 | 4 | @implementation XMLRPCResponse 5 | 6 | - (id)initWithData: (NSData *)data { 7 | if (!data) { 8 | return nil; 9 | } 10 | 11 | self = [super init]; 12 | if (self) { 13 | XMLRPCEventBasedParser *parser = [[XMLRPCEventBasedParser alloc] initWithData: data]; 14 | 15 | if (!parser) { 16 | #if ! __has_feature(objc_arc) 17 | [self release]; 18 | #endif 19 | return nil; 20 | } 21 | 22 | myBody = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]; 23 | myObject = [parser parse]; 24 | #if ! __has_feature(objc_arc) 25 | [myObject retain]; 26 | #endif 27 | 28 | isFault = [parser isFault]; 29 | 30 | #if ! __has_feature(objc_arc) 31 | [parser release]; 32 | #endif 33 | } 34 | 35 | return self; 36 | } 37 | 38 | #pragma mark - 39 | 40 | - (BOOL)isFault { 41 | return isFault; 42 | } 43 | 44 | - (NSNumber *)faultCode { 45 | if (isFault) { 46 | return [myObject objectForKey: @"faultCode"]; 47 | } 48 | 49 | return nil; 50 | } 51 | 52 | - (NSString *)faultString { 53 | if (isFault) { 54 | return [myObject objectForKey: @"faultString"]; 55 | } 56 | 57 | return nil; 58 | } 59 | 60 | #pragma mark - 61 | 62 | - (id)object { 63 | return myObject; 64 | } 65 | 66 | #pragma mark - 67 | 68 | - (NSString *)body { 69 | return myBody; 70 | } 71 | 72 | #pragma mark - 73 | 74 | - (NSString *)description { 75 | NSMutableString *result = [NSMutableString stringWithCapacity:128]; 76 | 77 | [result appendFormat:@"[body=%@", myBody]; 78 | 79 | if (isFault) { 80 | [result appendFormat:@", fault[%@]='%@'", [self faultCode], [self faultString]]; 81 | } else { 82 | [result appendFormat:@", object=%@", myObject]; 83 | } 84 | 85 | [result appendString:@"]"]; 86 | 87 | return result; 88 | } 89 | 90 | #pragma mark - 91 | 92 | - (void)dealloc { 93 | #if ! __has_feature(objc_arc) 94 | [myBody release]; 95 | [myObject release]; 96 | 97 | [super dealloc]; 98 | #endif 99 | } 100 | 101 | @end 102 | --------------------------------------------------------------------------------