Wired Networking  2.0
Objective-C implementation of the Wired 2.0 protocol
WIP7Spec.m
00001 /* $Id$ */
00002 
00003 /*
00004  *  Copyright (c) 2008-2009 Axel Andersson
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *  1. Redistributions of source code must retain the above copyright
00011  *     notice, this list of conditions and the following disclaimer.
00012  *  2. Redistributions in binary form must reproduce the above copyright
00013  *     notice, this list of conditions and the following disclaimer in the
00014  *     documentation and/or other materials provided with the distribution.
00015  *
00016  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00017  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
00020  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00021  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00022  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00023  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00024  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00025  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00026  * POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00029 #import <WiredNetworking/NSString-WINetworking.h>
00030 #import <WiredNetworking/WIError.h>
00031 #import <WiredNetworking/WIP7Message.h>
00032 #import <WiredNetworking/WIP7Spec.h>
00033 
00034 @interface WIP7Spec(Private)
00035 
00036 - (void)_setSpec:(wi_p7_spec_t *)spec;
00037 
00038 @end
00039 
00040 
00041 @interface WIP7SpecType(Private)
00042 
00043 - (id)_initWithType:(wi_p7_spec_type_t *)type;
00044 
00045 @end
00046 
00047 
00048 @interface WIP7SpecField(Private)
00049 
00050 - (id)_initWithField:(wi_p7_spec_field_t *)field;
00051 
00052 @end
00053 
00054 
00055 @interface WIP7SpecMessage(Private)
00056 
00057 - (id)_initWithMessage:(wi_p7_spec_message_t *)message;
00058 
00059 @end
00060 
00061 
00062 @interface WIP7SpecParameter(Private)
00063 
00064 - (id)_initWithParameter:(wi_p7_spec_parameter_t *)parameter;
00065 
00066 @end
00067 
00068 
00069 
00070 @implementation WIP7Spec(Private)
00071 
00072 - (void)_setSpec:(wi_p7_spec_t *)spec {
00073                 NSString                                        *name;
00074                 wi_enumerator_t                 *enumerator;
00075                 wi_array_t                                      *array;
00076                 wi_p7_spec_field_t              *field;
00077                 
00078                 _spec                                           = wi_retain(spec);
00079                 
00080                 array                                           = wi_p7_spec_fields(_spec);
00081                 enumerator                      = wi_array_data_enumerator(array);
00082                 
00083                 _fieldNames                     = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, NULL);
00084                 _fieldIDs                       = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, NULL);
00085                 
00086                 while((field = wi_enumerator_next_data(enumerator))) {
00087                                 name = [NSString stringWithWiredString:wi_p7_spec_field_name(field)];
00088                                 
00089                                 CFDictionarySetValue(_fieldNames, name, wi_p7_spec_field_name(field));
00090                                 CFDictionarySetValue(_fieldIDs, name, (void *) wi_p7_spec_field_id(field));
00091                 }
00092 }
00093 
00094 @end
00095 
00096 
00097 
00098 @implementation WIP7Spec
00099 
00100 - (id)initWithPath:(NSString *)path originator:(WIP7Originator)originator error:(WIError **)error {
00101                 wi_p7_spec_t                    *spec;
00102                 wi_pool_t                                       *pool;
00103                 wi_string_t                                     *string;
00104                 
00105                 self = [super init];
00106                 
00107                 pool            = wi_pool_init(wi_pool_alloc());
00108                 string          = wi_string_with_cstring([path fileSystemRepresentation]);
00109                 spec            = wi_p7_spec_init_with_file(wi_p7_spec_alloc(), string, originator);
00110                 
00111                 if(!spec) {
00112                                 if(error) {
00113                                                 *error = [WIError errorWithDomain:WIWiredNetworkingErrorDomain
00114                                                                                                                                                                  code:WIP7SpecLoadFailed
00115                                                                                                                                                  userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
00116                                                                                                                                                                  [WIError errorWithDomain:WILibWiredErrorDomain],
00117                                                                                                                                                                                  WILibWiredErrorKey,
00118                                                                                                                                                                  path,
00119                                                                                                                                                                                  WIArgumentErrorKey,
00120                                                                                                                                                                  NULL]];
00121                                 }
00122                                 
00123                                 wi_release(pool);
00124 
00125                                 [self release];
00126                                 
00127                                 return NULL;
00128                 }
00129                 
00130                 [self _setSpec:spec];
00131                 
00132                 wi_release(spec);
00133                 wi_release(pool);
00134 
00135                 return self;
00136 }
00137 
00138 
00139 
00140 - (id)initWithString:(NSString *)string originator:(WIP7Originator)originator error:(WIError **)error {
00141                 wi_p7_spec_t                    *spec;
00142                 wi_pool_t                                       *pool;
00143                 
00144                 self = [super init];
00145                 
00146                 pool = wi_pool_init(wi_pool_alloc());
00147                 spec = wi_p7_spec_init_with_string(wi_p7_spec_alloc(), [string wiredString], originator);
00148                 
00149                 if(!spec) {
00150                                 if(error) {
00151                                                 *error = [WIError errorWithDomain:WIWiredNetworkingErrorDomain
00152                                                                                                                                                                  code:WIP7SpecLoadFailed
00153                                                                                                                                                  userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
00154                                                                                                                                                                  [WIError errorWithDomain:WILibWiredErrorDomain],
00155                                                                                                                                                                                  WILibWiredErrorKey,
00156                                                                                                                                                                  NULL]];
00157                                 }
00158                                 
00159                                 wi_release(pool);
00160 
00161                                 [self release];
00162                                 
00163                                 return NULL;
00164                 }
00165                 
00166                 [self _setSpec:spec];
00167                 
00168                 wi_release(spec);
00169                 wi_release(pool);
00170 
00171                 return self;
00172 }
00173 
00174 
00175 
00176 - (void)dealloc {
00177                 wi_release(_spec);
00178                 
00179                 if(_fieldNames)
00180                                 CFRelease(_fieldNames);
00181                 
00182                 if(_fieldIDs)
00183                                 CFRelease(_fieldIDs);
00184                 
00185                 [_fields release];
00186                 [_messages release];
00187                 [_parameters release];
00188                 
00189                 [super dealloc];
00190 }
00191 
00192 
00193 
00194 #pragma mark -
00195 
00196 - (wi_p7_spec_t *)spec {
00197                 return _spec;
00198 }
00199 
00200 
00201 
00202 - (NSString *)protocolName {
00203                 return [NSString stringWithWiredString:wi_p7_spec_name(_spec)];
00204 }
00205 
00206 
00207 
00208 - (NSString *)protocolVersion {
00209                 return [NSString stringWithWiredString:wi_p7_spec_version(_spec)];
00210 }
00211 
00212 
00213 
00214 #pragma mark -
00215 
00216 - (wi_string_t *)fieldNameForName:(NSString *)name {
00217                 return (wi_string_t *) CFDictionaryGetValue(_fieldNames, name);
00218 }
00219 
00220 
00221 
00222 - (NSUInteger)fieldIDForName:(NSString *)name {
00223                 return (NSUInteger) CFDictionaryGetValue(_fieldIDs, name);
00224 }
00225 
00226 
00227 
00228 #pragma mark -
00229 
00230 - (NSArray *)fields {
00231                 wi_pool_t                                                       *pool;
00232                 wi_enumerator_t                                 *enumerator;
00233                 wi_p7_spec_field_t                              *field;
00234                 wi_array_t                                                      *array;
00235                 
00236                 if(!_fields) {
00237                                 pool = wi_pool_init(wi_pool_alloc());
00238                                 
00239                                 array = wi_p7_spec_fields(_spec);
00240                                 enumerator = wi_array_data_enumerator(array);
00241                                 
00242                                 _fields = [[NSMutableArray alloc] initWithCapacity:wi_array_count(array)];
00243                                 
00244                                 while((field = wi_enumerator_next_data(enumerator)))
00245                                                 [_fields addObject:[[[WIP7SpecField alloc] _initWithField:field] autorelease]];
00246                                 
00247                                 [_fields sortUsingSelector:@selector(compare:)];
00248                                 
00249                                 wi_release(pool);
00250                 }
00251                 
00252                 return _fields;
00253 }
00254 
00255 
00256 
00257 - (NSArray *)messages {
00258                 wi_pool_t                                                       *pool;
00259                 wi_enumerator_t                                 *enumerator;
00260                 wi_p7_spec_message_t            *message;
00261                 wi_array_t                                                      *array;
00262                 
00263                 if(!_messages) {
00264                                 pool = wi_pool_init(wi_pool_alloc());
00265                                 
00266                                 array = wi_p7_spec_messages(_spec);
00267                                 enumerator = wi_array_data_enumerator(array);
00268                                 
00269                                 _messages = [[NSMutableArray alloc] initWithCapacity:wi_array_count(array)];
00270                                 
00271                                 while((message = wi_enumerator_next_data(enumerator)))
00272                                                 [_messages addObject:[[[WIP7SpecMessage alloc] _initWithMessage:message] autorelease]];
00273                                 
00274                                 [_messages sortUsingSelector:@selector(compare:)];
00275                                 
00276                                 wi_release(pool);
00277                 }
00278                 
00279                 return _messages;
00280 }
00281 
00282 
00283 
00284 - (WIP7SpecMessage *)messageWithName:(NSString *)name {
00285                 NSEnumerator                    *enumerator;
00286                 WIP7SpecMessage                 *message;
00287                 
00288                 enumerator = [[self messages] objectEnumerator];
00289                 
00290                 while((message = [enumerator nextObject])) {
00291                                 if([name isEqualToString:[message name]])
00292                                                 return message;
00293                 }
00294                 
00295                 return NULL;
00296 }
00297 
00298 
00299 
00300 #pragma mark -
00301 
00302 - (BOOL)verifyMessage:(WIP7Message *)message error:(WIError **)error {
00303                 wi_pool_t                       *pool;
00304                 wi_boolean_t    result;
00305                 
00306                 pool = wi_pool_init(wi_pool_alloc());
00307                 result = wi_p7_spec_verify_message(_spec, [message message]);
00308                 wi_release(pool);
00309                 
00310                 if(!result) {
00311                                 if(error)
00312                                                 *error = [WIError errorWithDomain:WILibWiredErrorDomain];
00313                                 
00314                                 return NO;
00315                 }
00316                 
00317                 return YES;
00318 }
00319 
00320 @end
00321 
00322 
00323 
00324 @implementation WIP7SpecType(Private)
00325 
00326 - (id)_initWithType:(wi_p7_spec_type_t *)type {
00327                 self = [super init];
00328                 
00329                 _type                           = wi_retain(type);
00330                 _name                           = [[NSString alloc] initWithWiredString:wi_p7_spec_type_name(_type)];
00331                 _id                                             = wi_p7_spec_type_id(_type);
00332                 
00333                 return self;
00334 }
00335 
00336 @end
00337 
00338 
00339 
00340 @implementation WIP7SpecType
00341 
00342 - (void)dealloc {
00343                 [_name release];
00344                 
00345                 wi_release(_type);
00346                 
00347                 [super dealloc];
00348 }
00349 
00350 
00351 
00352 #pragma mark -
00353 
00354 - (NSComparisonResult)compare:(WIP7SpecType *)type {
00355                 if([self ID] < [type ID])
00356                                 return NSOrderedAscending;
00357     else if([self ID] > [type ID])
00358         return NSOrderedDescending;
00359                 
00360     return NSOrderedSame;
00361 }
00362 
00363 
00364 
00365 #pragma mark -
00366 
00367 - (wi_p7_spec_type_t *)type {
00368                 return _type;
00369 }
00370 
00371 
00372 
00373 - (NSString *)name {
00374                 return _name;
00375 }
00376 
00377 
00378 
00379 - (WIP7Type)ID {
00380                 return _id;
00381 }
00382 
00383 @end
00384 
00385 
00386 
00387 @implementation WIP7SpecField(Private)
00388 
00389 - (id)_initWithField:(wi_p7_spec_field_t *)field {
00390                 NSString                                        *name;
00391                 NSNumber                                        *value;
00392                 wi_enumerator_t                 *enumerator;
00393                 wi_dictionary_t                 *dictionary;
00394                 void                                                            *key;
00395 
00396                 self = [self init];
00397                 
00398                 _field                                          = wi_retain(field);
00399                 _name                                           = [[NSString alloc] initWithWiredString:wi_p7_spec_field_name(_field)];
00400                 _id                                                             = wi_p7_spec_field_id(_field);
00401                 _type                                           = [[WIP7SpecType alloc] _initWithType:wi_p7_spec_field_type(_field)];
00402                 
00403                 if([_type ID] == WIP7EnumType) {
00404                                 _enumsByName    = [[NSMutableDictionary alloc] init];
00405                                 _enumsByValue   = [[NSMutableDictionary alloc] init];
00406                                 dictionary                      = wi_p7_spec_field_enums_by_name(_field);
00407                                 enumerator                      = wi_dictionary_key_enumerator(dictionary);
00408                                 
00409                                 while((key = wi_enumerator_next_data(enumerator))) {
00410                                                 name                            = [NSString stringWithWiredString:key];
00411                                                 value                           = [NSNumber numberWithUnsignedInteger:(wi_uinteger_t) wi_dictionary_data_for_key(dictionary, key)];
00412                                                 
00413                                                 [_enumsByName setObject:value forKey:name];
00414                                                 [_enumsByValue setObject:name forKey:value];
00415                                 }
00416                 }
00417                 
00418                 return self;
00419 }
00420 
00421 @end
00422 
00423 
00424 
00425 @implementation WIP7SpecField
00426 
00427 - (void)dealloc {
00428                 [_name release];
00429                 [_type release];
00430                 [_enumsByName release];
00431                 [_enumsByValue release];
00432                 
00433                 wi_release(_field);
00434                 
00435                 [super dealloc];
00436 }
00437 
00438 
00439 
00440 #pragma mark -
00441 
00442 - (NSComparisonResult)compare:(WIP7SpecField *)field {
00443                 if([self ID] < [field ID])
00444                                 return NSOrderedAscending;
00445     else if([self ID] > [field ID])
00446         return NSOrderedDescending;
00447                 
00448     return NSOrderedSame;
00449 }
00450 
00451 
00452 
00453 #pragma mark -
00454 
00455 - (wi_p7_spec_field_t *)field {
00456                 return _field;
00457 }
00458 
00459 
00460 
00461 - (NSString *)name {
00462                 return _name;
00463 }
00464 
00465 
00466 
00467 - (NSUInteger)ID {
00468                 return _id;
00469 }
00470 
00471 
00472 
00473 - (WIP7SpecType *)type {
00474                 return _type;
00475 }
00476 
00477 
00478 
00479 - (NSDictionary *)enumsByName {
00480                 return _enumsByName;
00481 }
00482 
00483 
00484 
00485 - (NSDictionary *)enumsByValue {
00486                 return _enumsByValue;
00487 }
00488 
00489 @end
00490 
00491 
00492 
00493 @implementation WIP7SpecMessage(Private)
00494 
00495 - (id)_initWithMessage:(wi_p7_spec_message_t *)message {
00496                 wi_enumerator_t                                 *enumerator;
00497                 wi_p7_spec_parameter_t          *parameter;
00498                 
00499                 self = [self init];
00500                 
00501                 _message        = wi_retain(message);
00502                 _name                           = [[NSString alloc] initWithWiredString:wi_p7_spec_message_name(_message)];
00503                 _id                                             = wi_p7_spec_message_id(_message);
00504                 _parameters     = [[NSMutableArray alloc] init];
00505                 
00506                 enumerator = wi_array_data_enumerator(wi_p7_spec_message_parameters(_message));
00507                 
00508                 while((parameter = wi_enumerator_next_data(enumerator)))
00509                                 [_parameters addObject:[[[WIP7SpecParameter alloc] _initWithParameter:parameter] autorelease]];
00510                 
00511                 [_parameters sortUsingSelector:@selector(compare:)];
00512 
00513                 return self;
00514 }
00515 
00516 @end
00517 
00518 
00519 
00520 @implementation WIP7SpecMessage
00521 
00522 - (void)dealloc {
00523                 [_name release];
00524                 [_parameters release];
00525                 
00526                 wi_release(_message);
00527                 
00528                 [super dealloc];
00529 }
00530 
00531 
00532 
00533 #pragma mark -
00534 
00535 - (NSComparisonResult)compare:(WIP7SpecMessage *)message {
00536                 if([self ID] < [message ID])
00537                                 return NSOrderedAscending;
00538     else if([self ID] > [message ID])
00539         return NSOrderedDescending;
00540                 
00541     return NSOrderedSame;
00542 }
00543 
00544 
00545 
00546 #pragma mark -
00547 
00548 - (wi_p7_spec_message_t *)message {
00549                 return _message;
00550 }
00551 
00552 
00553 
00554 - (NSString *)name {
00555                 return _name;
00556 }
00557 
00558 
00559 
00560 - (NSUInteger)ID {
00561                 return _id;
00562 }
00563 
00564 
00565 
00566 - (NSArray *)parameters {
00567                 return _parameters;
00568 }
00569 
00570 @end
00571 
00572 
00573 
00574 @implementation WIP7SpecParameter(Private)
00575 
00576 - (id)_initWithParameter:(wi_p7_spec_parameter_t *)parameter {
00577                 self = [self init];
00578                 
00579                 _parameter      = wi_retain(parameter);
00580                 _field                          = [[WIP7SpecField alloc] _initWithField:wi_p7_spec_parameter_field(parameter)]; 
00581                 _required       = wi_p7_spec_parameter_required(parameter);
00582                 
00583                 return self;
00584 }
00585 
00586 @end
00587 
00588 
00589 
00590 @implementation WIP7SpecParameter
00591 
00592 - (void)dealloc {
00593                 [_field release];
00594                 
00595                 wi_release(_parameter);
00596                 
00597                 [super dealloc];
00598 }
00599 
00600 
00601 
00602 #pragma mark -
00603 
00604 - (NSComparisonResult)compare:(WIP7SpecParameter *)parameter {
00605                 if([self isRequired] && ![parameter isRequired])
00606                                 return NSOrderedAscending;
00607                 else if(![self isRequired] && [parameter isRequired])
00608         return NSOrderedDescending;
00609                 
00610                 return [[[self field] name] caseInsensitiveCompare:[[parameter field] name]];
00611 }
00612 
00613 
00614 
00615 #pragma mark -
00616 
00617 - (wi_p7_spec_parameter_t *)parameter {
00618                 return _parameter;
00619 }
00620 
00621 
00622 
00623 - (WIP7SpecField *)field {
00624                 return _field;
00625 }
00626 
00627 
00628 
00629 - (BOOL)isRequired {
00630                 return _required;
00631 }
00632 
00633 @end
 All Classes