Changeset 5379

Show
Ignore:
Timestamp:
03/13/08 18:57:55 (4 months ago)
Author:
morris
Message:

Keep collections as a separate item in protocol

Files:

Legend:

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

    r5371 r5379  
    5454typedef struct _wi_p7_spec_type                         _wi_p7_spec_type_t; 
    5555typedef struct _wi_p7_spec_field                        _wi_p7_spec_field_t; 
     56typedef struct _wi_p7_spec_collection           _wi_p7_spec_collection_t; 
    5657typedef struct _wi_p7_spec_message                      _wi_p7_spec_message_t; 
    5758typedef struct _wi_p7_spec_parameter            _wi_p7_spec_parameter_t; 
     
    113114 
    114115 
     116struct _wi_p7_spec_collection { 
     117        wi_runtime_base_t                                               base; 
     118         
     119        wi_string_t                                                             *name; 
     120        wi_array_t                                                              *fields; 
     121}; 
     122 
     123static _wi_p7_spec_collection_t *                       _wi_p7_spec_collection_with_node(wi_p7_spec_t *, xmlNodePtr); 
     124static void                                                                     _wi_p7_spec_collection_dealloc(wi_runtime_instance_t *); 
     125static wi_string_t *                                            _wi_p7_spec_collection_description(wi_runtime_instance_t *); 
     126 
     127static wi_runtime_id_t                                          _wi_p7_spec_collection_runtime_id = WI_RUNTIME_ID_NULL; 
     128static wi_runtime_class_t                                       _wi_p7_spec_collection_runtime_class = { 
     129    "_wi_p7_spec_collection_t", 
     130    _wi_p7_spec_collection_dealloc, 
     131    NULL, 
     132    NULL, 
     133    _wi_p7_spec_collection_description, 
     134    NULL 
     135}; 
     136 
     137 
     138 
    115139struct _wi_p7_spec_message { 
    116140        wi_runtime_base_t                                               base; 
     
    305329static wi_boolean_t                                                     _wi_p7_spec_load_types(wi_p7_spec_t *, xmlNodePtr); 
    306330static wi_boolean_t                                                     _wi_p7_spec_load_fields(wi_p7_spec_t *, xmlNodePtr); 
    307 static wi_boolean_t                                                     _wi_p7_spec_load_collection(wi_p7_spec_t *, xmlNodePtr); 
    308 static _wi_p7_spec_field_t *                            _wi_p7_spec_load_field(wi_p7_spec_t *, xmlNodePtr); 
     331static wi_boolean_t                                                     _wi_p7_spec_load_collections(wi_p7_spec_t *, xmlNodePtr); 
    309332static wi_boolean_t                                                     _wi_p7_spec_load_messages(wi_p7_spec_t *, xmlNodePtr); 
    310333static wi_boolean_t                                                     _wi_p7_spec_load_transactions(wi_p7_spec_t *, xmlNodePtr); 
     
    465488    _wi_p7_spec_type_runtime_id = wi_runtime_register_class(&_wi_p7_spec_type_runtime_class); 
    466489    _wi_p7_spec_field_runtime_id = wi_runtime_register_class(&_wi_p7_spec_field_runtime_class); 
     490    _wi_p7_spec_collection_runtime_id = wi_runtime_register_class(&_wi_p7_spec_collection_runtime_class); 
    467491    _wi_p7_spec_message_runtime_id = wi_runtime_register_class(&_wi_p7_spec_message_runtime_class); 
    468492    _wi_p7_spec_parameter_runtime_id = wi_runtime_register_class(&_wi_p7_spec_parameter_runtime_class); 
     
    769793                                        return false; 
    770794                        } 
     795                        else if(strcmp((const char *) node->name, "collections") == 0) { 
     796                                if(!_wi_p7_spec_load_collections(p7_spec, node)) 
     797                                        return false; 
     798                        } 
    771799                        else if(strcmp((const char *) node->name, "messages") == 0) { 
    772800                                if(!_wi_p7_spec_load_messages(p7_spec, node)) 
     
    795823        for(type_node = node->children; type_node != NULL; type_node = type_node->next) { 
    796824                if(type_node->type == XML_ELEMENT_NODE) { 
     825                        if(strcmp((const char *) type_node->name, "type") != 0) { 
     826                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     827                                        WI_STR("Expected \"type\" node but got \"%s\""), 
     828                                        type_node->name); 
     829                                 
     830                                return false; 
     831                        } 
     832                         
    797833                        type = _wi_p7_spec_type_with_node(p7_spec, type_node); 
    798834                         
     
    827863 
    828864static wi_boolean_t _wi_p7_spec_load_fields(wi_p7_spec_t *p7_spec, xmlNodePtr node) { 
    829         xmlNodePtr              field_node; 
     865        _wi_p7_spec_field_t             *field; 
     866        xmlNodePtr                              field_node; 
    830867         
    831868        for(field_node = node->children; field_node != NULL; field_node = field_node->next) { 
    832869                if(field_node->type == XML_ELEMENT_NODE) { 
    833                         if(strcmp((const char *) field_node->name, "field") == 0) { 
    834                                 if(!_wi_p7_spec_load_field(p7_spec, field_node)) 
    835                                         return false; 
    836                         } 
    837                         else if(strcmp((const char *) field_node->name, "collection") == 0) { 
    838                                 if(!_wi_p7_spec_load_collection(p7_spec, field_node)) 
    839                                         return false; 
    840                         } 
     870                        if(strcmp((const char *) field_node->name, "field") != 0) { 
     871                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     872                                        WI_STR("Expected \"field\" node but got \"%s\""), 
     873                                        field_node->name); 
     874                                 
     875                                return false; 
     876                        } 
     877                         
     878                        field = _wi_p7_spec_field_with_node(p7_spec, field_node); 
     879                         
     880                        if(!field) 
     881                                return false; 
     882                         
     883                        if(wi_hash_data_for_key(p7_spec->fields_name, field->name)) { 
     884                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     885                                        WI_STR("Field with name \"%@\" already exists"), 
     886                                        field->name); 
     887                                 
     888                                return false; 
     889                        } 
     890                         
     891                        if(wi_hash_data_for_key(p7_spec->fields_id, (void *) field->id)) { 
     892                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     893                                        WI_STR("Field with id %lu (name \"%@\") already exists"), 
     894                                        field->id, field->name); 
     895                                 
     896                                return false; 
     897                        } 
     898 
     899                        wi_hash_set_data_for_key(p7_spec->fields_name, field, field->name); 
     900                        wi_hash_set_data_for_key(p7_spec->fields_id, field, (void *) field->id); 
    841901                } 
    842902        } 
     
    847907 
    848908 
    849 static wi_boolean_t _wi_p7_spec_load_collection(wi_p7_spec_t *p7_spec, xmlNodePtr node) { 
    850         wi_array_t                              *collection; 
    851         wi_string_t                             *name; 
    852         _wi_p7_spec_field_t             *field; 
    853         xmlNodePtr                              field_node; 
    854          
    855         name = wi_autorelease(wi_p7_xml_copy_string_for_attribute(node, WI_STR("name"))); 
    856          
    857         if(!name) { 
    858                 wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
    859                         WI_STR("Collection has no \"name\"")); 
    860                  
    861                 return false; 
    862         } 
    863  
    864         if(wi_hash_data_for_key(p7_spec->collections_name, name)) { 
    865                 wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
    866                         WI_STR("Collection with name \"%@\" already exists"), 
    867                         name); 
    868                  
    869                 return false; 
    870         } 
    871          
    872         collection = wi_array(); 
    873          
    874         for(field_node = node->children; field_node != NULL; field_node = field_node->next) { 
    875                 if(field_node->type == XML_ELEMENT_NODE) { 
    876                         field = _wi_p7_spec_load_field(p7_spec, field_node); 
    877                          
    878                         if(!field) 
    879                                 return false; 
    880                          
    881                         wi_array_add_data(collection, field); 
    882                 } 
    883         } 
    884          
    885         if(wi_array_count(collection) == 0) { 
    886                 wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
    887                         WI_STR("Collection has no fields")); 
    888                  
    889                 return false; 
    890         } 
    891  
    892         wi_hash_set_data_for_key(p7_spec->collections_name, collection, name); 
     909static wi_boolean_t _wi_p7_spec_load_collections(wi_p7_spec_t *p7_spec, xmlNodePtr node) { 
     910        _wi_p7_spec_collection_t        *collection; 
     911        xmlNodePtr                                      collection_node; 
     912         
     913        for(collection_node = node->children; collection_node != NULL; collection_node = collection_node->next) { 
     914                if(collection_node->type == XML_ELEMENT_NODE) { 
     915                        if(strcmp((const char *) collection_node->name, "collection") != 0) { 
     916                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     917                                        WI_STR("Expected \"collection\" node but got \"%s\""), 
     918                                        collection_node->name); 
     919                                 
     920                                return false; 
     921                        } 
     922                         
     923                        collection = _wi_p7_spec_collection_with_node(p7_spec, collection_node); 
     924                         
     925                        if(!collection) 
     926                                return false; 
     927                         
     928                        if(wi_hash_data_for_key(p7_spec->collections_name, collection->name)) { 
     929                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     930                                        WI_STR("Collection with name \"%@\" already exists"), 
     931                                        collection->name); 
     932                                 
     933                                return false; 
     934                        } 
     935                         
     936                        wi_hash_set_data_for_key(p7_spec->collections_name, collection, collection->name); 
     937                } 
     938        } 
    893939         
    894940        return true; 
    895 } 
    896  
    897  
    898  
    899 static _wi_p7_spec_field_t * _wi_p7_spec_load_field(wi_p7_spec_t *p7_spec, xmlNodePtr node) { 
    900         _wi_p7_spec_field_t             *field; 
    901          
    902         field = _wi_p7_spec_field_with_node(p7_spec, node); 
    903          
    904         if(!field) 
    905                 return NULL; 
    906          
    907         if(wi_hash_data_for_key(p7_spec->fields_name, field->name)) { 
    908                 wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
    909                         WI_STR("Field with name \"%@\" already exists"), 
    910                         field->name); 
    911                  
    912                 return NULL; 
    913         } 
    914          
    915         if(wi_hash_data_for_key(p7_spec->fields_id, (void *) field->id)) { 
    916                 wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
    917                         WI_STR("Field with id %lu (name \"%@\") already exists"), 
    918                         field->id, field->name); 
    919                  
    920                 return NULL; 
    921         } 
    922  
    923         wi_hash_set_data_for_key(p7_spec->fields_name, field, field->name); 
    924         wi_hash_set_data_for_key(p7_spec->fields_id, field, (void *) field->id); 
    925          
    926         return field; 
    927941} 
    928942 
     
    935949        for(message_node = node->children; message_node != NULL; message_node = message_node->next) { 
    936950                if(message_node->type == XML_ELEMENT_NODE) { 
     951                        if(strcmp((const char *) message_node->name, "message") != 0) { 
     952                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     953                                        WI_STR("Expected \"message\" node but got \"%s\""), 
     954                                        message_node->name); 
     955                                 
     956                                return false; 
     957                        } 
     958                         
    937959                        message = _wi_p7_spec_message_with_node(p7_spec, message_node); 
    938960                         
     
    972994        for(transaction_node = node->children; transaction_node != NULL; transaction_node = transaction_node->next) { 
    973995                if(transaction_node->type == XML_ELEMENT_NODE) { 
     996                        if(strcmp((const char *) transaction_node->name, "transaction") != 0) { 
     997                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     998                                        WI_STR("Expected \"transaction\" node but got \"%s\""), 
     999                                        transaction_node->name); 
     1000                                 
     1001                                return false; 
     1002                        } 
     1003                         
    9741004                        transaction = _wi_p7_spec_transaction_with_node(p7_spec, transaction_node); 
    9751005                         
     
    10001030        for(broadcast_node = node->children; broadcast_node != NULL; broadcast_node = broadcast_node->next) { 
    10011031                if(broadcast_node->type == XML_ELEMENT_NODE) { 
     1032                        if(strcmp((const char *) broadcast_node->name, "broadcast") != 0) { 
     1033                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     1034                                        WI_STR("Expected \"broadcast\" node but got \"%s\""), 
     1035                                        broadcast_node->name); 
     1036                                 
     1037                                return false; 
     1038                        } 
     1039                         
    10021040                        broadcast = _wi_p7_spec_broadcast_with_node(p7_spec, broadcast_node); 
    10031041                         
     
    18091847                for(enum_node = node->children; enum_node != NULL; enum_node = enum_node->next) { 
    18101848                        if(enum_node->type == XML_ELEMENT_NODE) { 
     1849                                if(strcmp((const char *) enum_node->name, "enum") != 0) { 
     1850                                        wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     1851                                                WI_STR("Expected \"enum\" node but got \"%s\""), 
     1852                                                enum_node->name); 
     1853                                         
     1854                                        return false; 
     1855                                } 
     1856                                 
    18111857                                name = wi_autorelease(wi_p7_xml_copy_string_for_attribute(enum_node, WI_STR("name"))); 
    18121858                                 
     
    18581904#pragma mark - 
    18591905 
     1906static _wi_p7_spec_collection_t * _wi_p7_spec_collection_with_node(wi_p7_spec_t *p7_spec, xmlNodePtr node) { 
     1907        xmlNodePtr                                      member_node; 
     1908        _wi_p7_spec_collection_t        *collection; 
     1909        _wi_p7_spec_field_t                     *field; 
     1910        wi_string_t                                     *field_name; 
     1911         
     1912    collection = wi_autorelease(wi_runtime_create_instance(_wi_p7_spec_collection_runtime_id, sizeof(_wi_p7_spec_collection_t))); 
     1913        collection->name = wi_p7_xml_copy_string_for_attribute(node, WI_STR("name")); 
     1914 
     1915        if(!collection->name) { 
     1916                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     1917                        WI_STR("Collection has no \"name\"")); 
     1918 
     1919                return NULL; 
     1920        } 
     1921         
     1922        collection->fields = wi_array_init(wi_array_alloc()); 
     1923         
     1924        for(member_node = node->children; member_node != NULL; member_node = member_node->next) { 
     1925                if(member_node->type == XML_ELEMENT_NODE) { 
     1926                        if(strcmp((const char *) member_node->name, "member") != 0) { 
     1927                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     1928                                        WI_STR("Expected \"member\" node but got \"%s\""), 
     1929                                        member_node->name); 
     1930                                 
     1931                                return false; 
     1932                        } 
     1933                         
     1934                        field_name = wi_autorelease(wi_p7_xml_copy_string_for_attribute(member_node, WI_STR("field"))); 
     1935                         
     1936                        if(!field_name) { 
     1937                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     1938                                        WI_STR("Member in collection \"%@\" has no \"field\""), 
     1939                                        collection->name); 
     1940                                 
     1941                                return NULL; 
     1942                        } 
     1943                         
     1944                        field = wi_hash_data_for_key(p7_spec->fields_name, field_name); 
     1945                         
     1946                        if(!field && _wi_p7_spec_builtin_spec) 
     1947                                field = wi_hash_data_for_key(_wi_p7_spec_builtin_spec->fields_name, field_name); 
     1948                         
     1949                        if(!field) { 
     1950                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     1951                                        WI_STR("Member in collection \"%@\" has an invalid \"field\" (\"%@\")"), 
     1952                                        collection->name, field_name); 
     1953                                 
     1954                                return NULL; 
     1955                        } 
     1956                         
     1957                        wi_array_add_data(collection->fields, field); 
     1958                } 
     1959        } 
     1960         
     1961        return collection; 
     1962} 
     1963 
     1964 
     1965 
     1966static void _wi_p7_spec_collection_dealloc(wi_runtime_instance_t *instance) { 
     1967        _wi_p7_spec_collection_t                *collection = instance; 
     1968 
     1969        wi_release(collection->name); 
     1970        wi_release(collection->fields); 
     1971} 
     1972 
     1973 
     1974 
     1975static wi_string_t * _wi_p7_spec_collection_description(wi_runtime_instance_t *instance) { 
     1976        _wi_p7_spec_collection_t                *collection = instance; 
     1977         
     1978        return wi_string_with_format(WI_STR("<%@ %p>{name = %@, fields = %@}"), 
     1979        wi_runtime_class_name(collection), 
     1980                collection, 
     1981                collection->name, 
     1982                collection->fields); 
     1983} 
     1984 
     1985 
     1986 
     1987#pragma mark - 
     1988 
    18601989static _wi_p7_spec_message_t * _wi_p7_spec_message_with_node(wi_p7_spec_t *p7_spec, xmlNodePtr node) { 
    18611990        wi_enumerator_t                         *enumerator; 
    1862         wi_array_t                                      *fields; 
    18631991        wi_string_t                                     *field_name, *collection_name, *use; 
    18641992        xmlNodePtr                                      parameter_node; 
    18651993        _wi_p7_spec_message_t           *message; 
    18661994        _wi_p7_spec_parameter_t         *parameter; 
     1995        _wi_p7_spec_collection_t        *collection; 
    18671996        _wi_p7_spec_field_t                     *field; 
    18681997        wi_boolean_t                            required; 
     
    18942023        for(parameter_node = node->children; parameter_node != NULL; parameter_node = parameter_node->next) { 
    18952024                if(parameter_node->type == XML_ELEMENT_NODE) { 
     2025                        if(strcmp((const char *) parameter_node->name, "parameter") != 0) { 
     2026                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     2027                                        WI_STR("Expected \"parameter\" node but got \"%s\""), 
     2028                                        parameter_node->name); 
     2029                                 
     2030                                return false; 
     2031                        } 
     2032                         
    18962033                        field_name                      = wi_autorelease(wi_p7_xml_copy_string_for_attribute(parameter_node, WI_STR("field"))); 
    18972034                        collection_name         = wi_autorelease(wi_p7_xml_copy_string_for_attribute(parameter_node, WI_STR("collection"))); 
     
    19182055                        } 
    19192056                        else if(collection_name) { 
    1920                                 fields = wi_hash_data_for_key(p7_spec->collections_name, collection_name); 
    1921                                  
    1922                                 if(!fields) { 
     2057                                collection = wi_hash_data_for_key(p7_spec->collections_name, collection_name); 
     2058                                 
     2059                                if(!collection) { 
    19232060                                        wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
    19242061                                                WI_STR("Parameter in message \"%@\" has an invalid \"collection\" (\"%@\")"), 
    19252062                                                message->name, collection_name); 
     2063                                         
     2064                                        return NULL; 
    19262065                                } 
    19272066 
     
    19412080                                        required = (wi_string_case_insensitive_compare(use, WI_STR("required")) == 0); 
    19422081                                } 
    1943  
    1944                                 enumerator = wi_array_data_enumerator(fields); 
     2082                                 
     2083                                enumerator = wi_array_data_enumerator(collection->fields); 
    19452084                                 
    19462085                                while((field = wi_enumerator_next_data(enumerator))) { 
     
    22742413                                wi_hash_set_data_for_key(andor->replies_hash, reply, reply->message->name); 
    22752414                        } else { 
    2276                                 if(strcmp((const char *) andor_node->name, "and") == 0) 
     2415                                if(strcmp((const char *) andor_node->name, "and") == 0) { 
    22772416                                        child_andor = _wi_p7_spec_andor(_WI_P7_SPEC_AND, p7_spec, andor_node, transaction); 
    2278                                 else 
     2417                                } 
     2418                                else if(strcmp((const char *) andor_node->name, "or") == 0) { 
    22792419                                        child_andor = _wi_p7_spec_andor(_WI_P7_SPEC_OR, p7_spec, andor_node, transaction); 
     2420                                } 
     2421                                else { 
     2422                                        wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     2423                                                WI_STR("Expected \"and\" or \"or\" node but got \"%s\""), 
     2424                                                andor_node->name); 
     2425                                         
     2426                                        return false; 
     2427                                } 
    22802428                                 
    22812429                                if(!child_andor)