Changeset 5314
- Timestamp:
- 02/25/08 10:03:48 (5 months ago)
- Files:
-
- libwired/trunk/libwired/p7/wi-p7-spec.c (modified) (21 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
libwired/trunk/libwired/p7/wi-p7-spec.c
r5299 r5314 57 57 typedef struct _wi_p7_spec_parameter _wi_p7_spec_parameter_t; 58 58 typedef struct _wi_p7_spec_transaction _wi_p7_spec_transaction_t; 59 typedef struct _wi_p7_spec_broadcast _wi_p7_spec_broadcast_t; 59 60 typedef struct _wi_p7_spec_andor _wi_p7_spec_andor_t; 60 61 typedef struct _wi_p7_spec_reply _wi_p7_spec_reply_t; … … 185 186 186 187 188 struct _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 195 static _wi_p7_spec_broadcast_t * _wi_p7_spec_broadcast_with_node(wi_p7_spec_t *, xmlNodePtr); 196 static void _wi_p7_spec_broadcast_dealloc(wi_runtime_instance_t *); 197 static wi_string_t * _wi_p7_spec_broadcast_description(wi_runtime_instance_t *); 198 199 static wi_runtime_id_t _wi_p7_spec_broadcast_runtime_id = WI_RUNTIME_ID_NULL; 200 static 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 187 211 enum _wi_p7_spec_andor_type { 188 212 _WI_P7_SPEC_AND, … … 261 285 wi_hash_t *types_name, *types_id; 262 286 wi_hash_t *transactions_name; 287 wi_hash_t *broadcasts_name; 263 288 }; 264 289 … … 279 304 static wi_boolean_t _wi_p7_spec_load_messages(wi_p7_spec_t *, xmlNodePtr); 280 305 static wi_boolean_t _wi_p7_spec_load_transactions(wi_p7_spec_t *, xmlNodePtr); 306 static wi_boolean_t _wi_p7_spec_load_broadcasts(wi_p7_spec_t *, xmlNodePtr); 281 307 282 308 static wi_boolean_t _wi_p7_spec_is_compatible(wi_p7_spec_t *, wi_p7_spec_t *); 283 309 static wi_boolean_t _wi_p7_spec_transaction_is_compatible(wi_p7_spec_t *, _wi_p7_spec_transaction_t *, _wi_p7_spec_transaction_t *); 310 static wi_boolean_t _wi_p7_spec_broadcast_is_compatible(wi_p7_spec_t *, _wi_p7_spec_broadcast_t *, _wi_p7_spec_broadcast_t *); 284 311 static 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 *); 285 312 static 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); 286 313 static 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 *);314 static wi_boolean_t _wi_p7_spec_message_is_compatible(wi_p7_spec_t *, _wi_p7_spec_message_t *, _wi_p7_spec_message_t *); 288 315 289 316 static wi_p7_spec_t *_wi_p7_spec_builtin_spec; … … 435 462 _wi_p7_spec_parameter_runtime_id = wi_runtime_register_class(&_wi_p7_spec_parameter_runtime_class); 436 463 _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); 437 465 _wi_p7_spec_andor_runtime_id = wi_runtime_register_class(&_wi_p7_spec_andor_runtime_class); 438 466 _wi_p7_spec_reply_runtime_id = wi_runtime_register_class(&_wi_p7_spec_reply_runtime_class); … … 515 543 516 544 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); 517 546 518 547 return p7_spec; … … 588 617 589 618 wi_release(p7_spec->transactions_name); 619 wi_release(p7_spec->broadcasts_name); 590 620 } 591 621 … … 739 769 return false; 740 770 } 771 else if(strcmp((const char *) node->name, "broadcasts") == 0) { 772 if(!_wi_p7_spec_load_broadcasts(p7_spec, node)) 773 return false; 774 } 741 775 } 742 776 } … … 886 920 887 921 922 static 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 888 950 #pragma mark - 889 951 … … 914 976 wi_string_t *key; 915 977 _wi_p7_spec_transaction_t *transaction, *other_transaction; 978 _wi_p7_spec_broadcast_t *broadcast, *other_broadcast; 916 979 917 980 enumerator = wi_hash_key_enumerator(p7_spec->transactions_name); … … 922 985 923 986 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)) 924 997 return false; 925 998 } … … 958 1031 } 959 1032 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)) 961 1034 return false; 962 1035 963 1036 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 1045 static 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)) 964 1064 return false; 965 1065 } … … 1090 1190 } 1091 1191 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)) 1093 1193 return false; 1094 1194 } … … 1100 1200 1101 1201 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) {1202 static 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) { 1103 1203 wi_enumerator_t *enumerator; 1104 1204 wi_string_t *key; … … 1108 1208 if(!wi_is_equal(message->name, other_message->name)) { 1109 1209 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); 1112 1212 1113 1213 return false; … … 1116 1216 if(message->id != other_message->id) { 1117 1217 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); 1120 1220 1121 1221 return false; … … 1132 1232 if(!other_parameter) { 1133 1233 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); 1136 1236 } else { 1137 1237 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); 1140 1240 } 1141 1241 … … 1150 1250 if(field->id != other_field->id) { 1151 1251 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); 1154 1254 1155 1255 return false; … … 1158 1258 if(field->type->id != other_field->type->id) { 1159 1259 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); 1162 1262 1163 1263 return false; … … 1167 1267 if(!wi_is_equal(field->enums_name, other_field->enums_name)) { 1168 1268 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); 1171 1271 1172 1272 return false; … … 1900 2000 transaction->required ? WI_STR("true") : WI_STR("false"), 1901 2001 transaction->andor); 2002 } 2003 2004 2005 2006 #pragma mark - 2007 2008 static _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 2040 static 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 2048 static 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); 1902 2055 } 1903 2056
