Changeset 5314

Show
Ignore:
Timestamp:
02/25/08 10:03:48 (5 months ago)
Author:
morris
Message:

Support new section with broadcasts sent by the server

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • libwired/trunk/libwired/p7/wi-p7-spec.c

    r5299 r5314  
    5757typedef struct _wi_p7_spec_parameter            _wi_p7_spec_parameter_t; 
    5858typedef struct _wi_p7_spec_transaction          _wi_p7_spec_transaction_t; 
     59typedef struct _wi_p7_spec_broadcast            _wi_p7_spec_broadcast_t; 
    5960typedef struct _wi_p7_spec_andor                        _wi_p7_spec_andor_t; 
    6061typedef struct _wi_p7_spec_reply                        _wi_p7_spec_reply_t; 
     
    185186 
    186187 
     188struct _wi_p7_spec_broadcast { 
     189        wi_runtime_base_t                                               base; 
     190 
     191        _wi_p7_spec_message_t                                   *message; 
     192        wi_boolean_t                                                    required; 
     193}; 
     194 
     195static _wi_p7_spec_broadcast_t *                        _wi_p7_spec_broadcast_with_node(wi_p7_spec_t *, xmlNodePtr); 
     196static void                                                                     _wi_p7_spec_broadcast_dealloc(wi_runtime_instance_t *); 
     197static wi_string_t *                                            _wi_p7_spec_broadcast_description(wi_runtime_instance_t *); 
     198 
     199static wi_runtime_id_t                                          _wi_p7_spec_broadcast_runtime_id = WI_RUNTIME_ID_NULL; 
     200static wi_runtime_class_t                                       _wi_p7_spec_broadcast_runtime_class = { 
     201    "_wi_p7_spec_broadcast_t", 
     202    _wi_p7_spec_broadcast_dealloc, 
     203    NULL, 
     204    NULL, 
     205    _wi_p7_spec_broadcast_description, 
     206    NULL 
     207}; 
     208 
     209 
     210 
    187211enum _wi_p7_spec_andor_type { 
    188212        _WI_P7_SPEC_AND, 
     
    261285        wi_hash_t                                                               *types_name, *types_id; 
    262286        wi_hash_t                                                               *transactions_name; 
     287        wi_hash_t                                                               *broadcasts_name; 
    263288}; 
    264289 
     
    279304static wi_boolean_t                                                     _wi_p7_spec_load_messages(wi_p7_spec_t *, xmlNodePtr); 
    280305static wi_boolean_t                                                     _wi_p7_spec_load_transactions(wi_p7_spec_t *, xmlNodePtr); 
     306static wi_boolean_t                                                     _wi_p7_spec_load_broadcasts(wi_p7_spec_t *, xmlNodePtr); 
    281307 
    282308static wi_boolean_t                                                     _wi_p7_spec_is_compatible(wi_p7_spec_t *, wi_p7_spec_t *); 
    283309static wi_boolean_t                                                     _wi_p7_spec_transaction_is_compatible(wi_p7_spec_t *, _wi_p7_spec_transaction_t *, _wi_p7_spec_transaction_t *); 
     310static wi_boolean_t                                                     _wi_p7_spec_broadcast_is_compatible(wi_p7_spec_t *, _wi_p7_spec_broadcast_t *, _wi_p7_spec_broadcast_t *); 
    284311static wi_boolean_t                                                     _wi_p7_spec_andor_is_compatible(wi_p7_spec_t *, _wi_p7_spec_transaction_t *, _wi_p7_spec_andor_t *, _wi_p7_spec_andor_t *); 
    285312static wi_boolean_t                                                     _wi_p7_spec_replies_are_compatible(wi_p7_spec_t *, _wi_p7_spec_transaction_t *, _wi_p7_spec_andor_t *, _wi_p7_spec_andor_t *, wi_boolean_t); 
    286313static wi_boolean_t                                                     _wi_p7_spec_reply_is_compatible(wi_p7_spec_t *, _wi_p7_spec_transaction_t *, _wi_p7_spec_reply_t *, _wi_p7_spec_reply_t *, wi_boolean_t); 
    287 static wi_boolean_t                                                     _wi_p7_spec_message_is_compatible(wi_p7_spec_t *, _wi_p7_spec_transaction_t *, _wi_p7_spec_message_t *, _wi_p7_spec_message_t *); 
     314static wi_boolean_t                                                     _wi_p7_spec_message_is_compatible(wi_p7_spec_t *, _wi_p7_spec_message_t *, _wi_p7_spec_message_t *); 
    288315 
    289316static wi_p7_spec_t                                                     *_wi_p7_spec_builtin_spec; 
     
    435462    _wi_p7_spec_parameter_runtime_id = wi_runtime_register_class(&_wi_p7_spec_parameter_runtime_class); 
    436463    _wi_p7_spec_transaction_runtime_id = wi_runtime_register_class(&_wi_p7_spec_transaction_runtime_class); 
     464    _wi_p7_spec_broadcast_runtime_id = wi_runtime_register_class(&_wi_p7_spec_broadcast_runtime_class); 
    437465    _wi_p7_spec_andor_runtime_id = wi_runtime_register_class(&_wi_p7_spec_andor_runtime_class); 
    438466    _wi_p7_spec_reply_runtime_id = wi_runtime_register_class(&_wi_p7_spec_reply_runtime_class); 
     
    515543 
    516544        p7_spec->transactions_name              = wi_hash_init_with_capacity(wi_hash_alloc(), 20); 
     545        p7_spec->broadcasts_name                = wi_hash_init_with_capacity(wi_hash_alloc(), 20); 
    517546 
    518547        return p7_spec; 
     
    588617 
    589618        wi_release(p7_spec->transactions_name); 
     619        wi_release(p7_spec->broadcasts_name); 
    590620} 
    591621 
     
    739769                                        return false; 
    740770                        } 
     771                        else if(strcmp((const char *) node->name, "broadcasts") == 0) { 
     772                                if(!_wi_p7_spec_load_broadcasts(p7_spec, node)) 
     773                                        return false; 
     774                        } 
    741775                } 
    742776        } 
     
    886920 
    887921 
     922static wi_boolean_t _wi_p7_spec_load_broadcasts(wi_p7_spec_t *p7_spec, xmlNodePtr node) { 
     923        _wi_p7_spec_broadcast_t         *broadcast; 
     924        xmlNodePtr                                      broadcast_node; 
     925         
     926        for(broadcast_node = node->children; broadcast_node != NULL; broadcast_node = broadcast_node->next) { 
     927                if(broadcast_node->type == XML_ELEMENT_NODE) { 
     928                        broadcast = _wi_p7_spec_broadcast_with_node(p7_spec, broadcast_node); 
     929                         
     930                        if(!broadcast) 
     931                                return false; 
     932                         
     933                        if(wi_hash_data_for_key(p7_spec->broadcasts_name, broadcast->message->name)) { 
     934                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     935                                        WI_STR("Broadcast with message \"%@\" already exists"), 
     936                                        broadcast->message->name); 
     937                                 
     938                                return false; 
     939                        } 
     940 
     941                        wi_hash_set_data_for_key(p7_spec->broadcasts_name, broadcast, broadcast->message->name); 
     942                } 
     943        } 
     944         
     945        return true; 
     946} 
     947 
     948 
     949 
    888950#pragma mark - 
    889951 
     
    914976        wi_string_t                                     *key; 
    915977        _wi_p7_spec_transaction_t       *transaction, *other_transaction; 
     978        _wi_p7_spec_broadcast_t         *broadcast, *other_broadcast; 
    916979         
    917980        enumerator = wi_hash_key_enumerator(p7_spec->transactions_name); 
     
    922985                 
    923986                if(!_wi_p7_spec_transaction_is_compatible(p7_spec, transaction, other_transaction)) 
     987                        return false; 
     988        } 
     989         
     990        enumerator = wi_hash_key_enumerator(p7_spec->broadcasts_name); 
     991         
     992        while((key = wi_enumerator_next_data(enumerator))) { 
     993                broadcast                       = wi_hash_data_for_key(p7_spec->broadcasts_name, key); 
     994                other_broadcast         = wi_hash_data_for_key(other_p7_spec->broadcasts_name, key); 
     995                 
     996                if(!_wi_p7_spec_broadcast_is_compatible(p7_spec, broadcast, other_broadcast)) 
    924997                        return false; 
    925998        } 
     
    9581031                } 
    9591032                 
    960                 if(!_wi_p7_spec_message_is_compatible(p7_spec, transaction, transaction->message, other_transaction->message)) 
     1033                if(!_wi_p7_spec_message_is_compatible(p7_spec, transaction->message, other_transaction->message)) 
    9611034                        return false; 
    9621035                 
    9631036                if(!_wi_p7_spec_andor_is_compatible(p7_spec, transaction, transaction->andor, other_transaction->andor)) 
     1037                        return false; 
     1038        } 
     1039         
     1040        return true; 
     1041} 
     1042 
     1043 
     1044 
     1045static wi_boolean_t _wi_p7_spec_broadcast_is_compatible(wi_p7_spec_t *p7_spec, _wi_p7_spec_broadcast_t *broadcast, _wi_p7_spec_broadcast_t *other_broadcast) { 
     1046        if(broadcast->required) { 
     1047                if(!other_broadcast || !other_broadcast->required) { 
     1048                        if(!other_broadcast) { 
     1049                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     1050                                        WI_STR("Broadcast \"%@\" is required, but peer lacks it"), 
     1051                                        broadcast->message->name); 
     1052                        } else { 
     1053                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     1054                                        WI_STR("Broadcast \"%@\" is required, but peer has it optional"), 
     1055                                        broadcast->message->name); 
     1056                        } 
     1057                         
     1058                        return false; 
     1059                } 
     1060        } 
     1061         
     1062        if(other_broadcast) { 
     1063                if(!_wi_p7_spec_message_is_compatible(p7_spec, broadcast->message, other_broadcast->message)) 
    9641064                        return false; 
    9651065        } 
     
    10901190                        } 
    10911191                         
    1092                         if(!_wi_p7_spec_message_is_compatible(p7_spec, transaction, reply->message, other_reply->message)) 
     1192                        if(!_wi_p7_spec_message_is_compatible(p7_spec, reply->message, other_reply->message)) 
    10931193                                return false; 
    10941194                } 
     
    11001200         
    11011201         
    1102 static wi_boolean_t _wi_p7_spec_message_is_compatible(wi_p7_spec_t *p7_spec, _wi_p7_spec_transaction_t *transaction, _wi_p7_spec_message_t *message, _wi_p7_spec_message_t *other_message) { 
     1202static wi_boolean_t _wi_p7_spec_message_is_compatible(wi_p7_spec_t *p7_spec, _wi_p7_spec_message_t *message, _wi_p7_spec_message_t *other_message) { 
    11031203        wi_enumerator_t                 *enumerator; 
    11041204        wi_string_t                             *key; 
     
    11081208        if(!wi_is_equal(message->name, other_message->name)) { 
    11091209                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
    1110                         WI_STR("Reply in transaction \"%@\" should be \"%@\", but peer has \"%@\""), 
    1111                                 transaction->message->name, message->name, other_message->name); 
     1210                        WI_STR("Message should be \"%@\", but peer has \"%@\""), 
     1211                                message->name, other_message->name); 
    11121212                 
    11131213                return false; 
     
    11161216        if(message->id != other_message->id) { 
    11171217                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
    1118                         WI_STR("Message in reply \"%@\" in transaction \"%@\" should have id %lu, but peer has id %lu"), 
    1119                         message->name, transaction->message->name, message->id, other_message->id); 
     1218                        WI_STR("Message should have id %lu, but peer has id %lu"), 
     1219                        message->id, other_message->id); 
    11201220                 
    11211221                return false; 
     
    11321232                                if(!other_parameter) { 
    11331233                                        wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
    1134                                                 WI_STR("Parameter \"%@\" in reply \"%@\" in transaction \"%@\" is required, but peer lacks it"), 
    1135                                                 parameter->field->name, message->name, transaction->message->name); 
     1234                                                WI_STR("Parameter \"%@\" in message \"%@\" is required, but peer lacks it"), 
     1235                                                parameter->field->name, message->name); 
    11361236                                } else { 
    11371237                                        wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
    1138                                                 WI_STR("Parameter \"%@\" in reply \"%@\" in transaction \"%@\" is required, but peer has it optional"), 
    1139                                                 parameter->field->name, message->name, transaction->message->name); 
     1238                                                WI_STR("Parameter \"%@\" in message \"%@\" is required, but peer has it optional"), 
     1239                                                parameter->field->name, message->name); 
    11401240                                } 
    11411241                                 
     
    11501250                        if(field->id != other_field->id) { 
    11511251                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
    1152                                         WI_STR("Field in parameter \"%@\" in reply \"%@\" in transaction \"%@\" should have id %lu, but peer has id %lu"), 
    1153                                         parameter->field->name, message->name, transaction->message->name, field->id, other_field->id); 
     1252                                        WI_STR("Field in parameter \"%@\" in message \"%@\" should have id %lu, but peer has id %lu"), 
     1253                                        parameter->field->name, message->name, field->id, other_field->id); 
    11541254                                 
    11551255                                return false; 
     
    11581258                        if(field->type->id != other_field->type->id) { 
    11591259                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
    1160                                         WI_STR("Parameter \"%@\" in reply \"%@\" in transaction \"%@\" should be of type \"%@\", but peer has it as \"%@\""), 
    1161                                         parameter->field->name, message->name, transaction->message->name, field->type->name, other_field->type->name); 
     1260                                        WI_STR("Parameter \"%@\" in message \"%@\" should be of type \"%@\", but peer has it as \"%@\""), 
     1261                                        parameter->field->name, message->name, field->type->name, other_field->type->name); 
    11621262 
    11631263                                return false; 
     
    11671267                                if(!wi_is_equal(field->enums_name, other_field->enums_name)) { 
    11681268                                        wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
    1169                                                 WI_STR("Parameter \"%@\" in reply \"%@\" in transaction \"%@\" have enumerations that differ with those of peer"), 
    1170                                                 parameter->field->name, message->name, transaction->message->name); 
     1269                                                WI_STR("Parameter \"%@\" in message \"%@\" have enumerations that differ with those of peer"), 
     1270                                                parameter->field->name, message->name); 
    11711271                                         
    11721272                                        return false; 
     
    19002000                transaction->required ? WI_STR("true") : WI_STR("false"), 
    19012001                transaction->andor); 
     2002} 
     2003 
     2004 
     2005 
     2006#pragma mark - 
     2007 
     2008static _wi_p7_spec_broadcast_t * _wi_p7_spec_broadcast_with_node(wi_p7_spec_t *p7_spec, xmlNodePtr node) { 
     2009        wi_string_t                                     *message; 
     2010        _wi_p7_spec_broadcast_t         *broadcast; 
     2011 
     2012    broadcast = wi_autorelease(wi_runtime_create_instance(_wi_p7_spec_broadcast_runtime_id, sizeof(_wi_p7_spec_broadcast_t))); 
     2013        message = wi_autorelease(wi_p7_xml_copy_string_for_attribute(node, WI_STR("message"))); 
     2014         
     2015        if(!message) { 
     2016                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     2017                        WI_STR("Broadcast has no \"message\"")); 
     2018                 
     2019                return NULL; 
     2020        } 
     2021 
     2022        broadcast->message = wi_retain(wi_hash_data_for_key(p7_spec->messages_name, message)); 
     2023 
     2024        if(!broadcast->message && _wi_p7_spec_builtin_spec) 
     2025                broadcast->message = wi_retain(wi_hash_data_for_key(_wi_p7_spec_builtin_spec->messages_name, message)); 
     2026         
     2027        if(!broadcast->message) { 
     2028                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     2029                        WI_STR("Broadcast has an invalid \"message\" (\"%@\")"), 
     2030                        message); 
     2031                 
     2032                return NULL; 
     2033        } 
     2034         
     2035        return broadcast; 
     2036} 
     2037 
     2038 
     2039 
     2040static void _wi_p7_spec_broadcast_dealloc(wi_runtime_instance_t *instance) { 
     2041        _wi_p7_spec_broadcast_t         *broadcast = instance; 
     2042         
     2043        wi_release(broadcast->message); 
     2044} 
     2045 
     2046 
     2047 
     2048static wi_string_t * _wi_p7_spec_broadcast_description(wi_runtime_instance_t *instance) { 
     2049        _wi_p7_spec_broadcast_t         *broadcast = instance; 
     2050         
     2051        return wi_string_with_format(WI_STR("<%@ %p>{message = %@}"), 
     2052        wi_runtime_class_name(broadcast), 
     2053                broadcast, 
     2054                broadcast->message ? broadcast->message->name : NULL); 
    19022055} 
    19032056