Changeset 5326

Show
Ignore:
Timestamp:
02/28/08 15:20:16 (5 months ago)
Author:
morris
Message:

Add a new list type, for lists of other base types

The implementation only supports string lists for now

Files:

Legend:

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

    r5325 r5326  
    416416        wi_string_t                             *string; 
    417417        wi_data_t                               *data; 
     418        wi_array_t                              *list; 
    418419         
    419420        switch(type_id) { 
     
    485486                                field_value = wi_string_with_format(WI_STR("%llu"), p7_oobdata); 
    486487                        break; 
     488                 
     489                case WI_P7_LIST: 
     490                        list = wi_p7_message_list_for_name(p7_message, field_name); 
     491                         
     492                        if(list) 
     493                                field_value = wi_array_components_joined_by_string(list, WI_STR(", ")); 
     494                        break; 
    487495        } 
    488496         
     
    622630 
    623631static xmlNodePtr _wi_p7_message_xml_node_for_name(wi_p7_message_t *p7_message, const char *field_name) { 
    624         xmlNodePtr              node, foundNode = NULL; 
     632        xmlNodePtr              node, found_node = NULL; 
    625633        xmlChar                 *prop; 
    626634         
     
    631639                        if(prop) { 
    632640                                if(strcmp((const char *) prop, field_name) == 0) 
    633                                         foundNode = node; 
     641                                        found_node = node; 
    634642 
    635643                                xmlFree(prop); 
    636644                        } 
    637645                         
    638                         if(foundNode) 
    639                                 return foundNode; 
     646                        if(found_node) 
     647                                return found_node; 
    640648                } 
    641649        } 
     
    693701 
    694702void wi_p7_message_serialize(wi_p7_message_t *p7_message, wi_p7_serialization_t serialization) { 
     703        xmlNodePtr                              listnode, itemnode; 
     704        wi_runtime_instance_t   *instance; 
    695705        wi_string_t                             *field_name, *field_value; 
    696706        unsigned char                   *buffer, *start; 
     
    707717        wi_string_t                             *string; 
    708718        wi_data_t                               *data; 
    709         wi_p7_type_t                    type_id; 
     719        wi_array_t                              *list; 
     720        wi_p7_type_t                    type_id, listtype_id; 
     721        wi_uinteger_t                   i, count; 
    710722        uint32_t                                message_size, field_id, field_size; 
    711723 
     
    817829                                                        field_value = wi_string_with_format(WI_STR("%llu"), p7_oobdata); 
    818830                                                break; 
     831                                                 
     832                                        case WI_P7_LIST: 
     833                                                list = wi_p7_message_list_for_name(p7_message, field_name); 
     834                                                 
     835                                                if(list) { 
     836                                                        listnode = _wi_p7_message_xml_node_for_name(p7_message, wi_string_cstring(field_name)); 
     837                                                         
     838                                                        if(!listnode) { 
     839                                                                listtype_id = wi_p7_spec_field_listtype(p7_message->spec, wi_p7_spec_field_id(p7_message->spec, field_name)); 
     840                                                                listnode = xmlNewNode(p7_message->xml_ns, (xmlChar *) "field"); 
     841                                                                xmlSetProp(listnode, (xmlChar *) "name", (xmlChar *) wi_string_cstring(field_name)); 
     842                                                                xmlSetProp(listnode, (xmlChar *) "type", (xmlChar *) wi_string_cstring(wi_p7_spec_type_name(p7_message->spec, type_id))); 
     843                                                                xmlSetProp(listnode, (xmlChar *) "listtype", (xmlChar *) wi_string_cstring(wi_p7_spec_type_name(p7_message->spec, listtype_id))); 
     844                                                                xmlAddChild(p7_message->xml_root_node, listnode); 
     845                                                        } 
     846                                                         
     847                                                        count = wi_array_count(list); 
     848                                                         
     849                                                        for(i = 0; i < count; i++) { 
     850                                                                itemnode = xmlNewNode(p7_message->xml_ns, (xmlChar *) "item"); 
     851                                                                instance = WI_ARRAY(list, i); 
     852 
     853                                                                if(wi_runtime_id(instance) == wi_string_runtime_id()) 
     854                                                                        xmlNodeSetContent(itemnode, (xmlChar *) wi_string_cstring(instance)); 
     855                                                                 
     856                                                                xmlAddChild(listnode, itemnode); 
     857                                                        } 
     858                                                } 
     859                                                break; 
    819860                                } 
    820861                                 
     
    15151556 
    15161557 
     1558wi_boolean_t wi_p7_message_set_list_for_name(wi_p7_message_t *p7_message, wi_array_t *list, wi_string_t *field_name) { 
     1559        wi_runtime_instance_t   *instance; 
     1560        unsigned char                   *binary; 
     1561        wi_uinteger_t                   i, count, offset; 
     1562        uint32_t                                field_id, field_size, string_size; 
     1563         
     1564        WI_ASSERT(p7_message->serialization == WI_P7_BINARY, "Message is not editable"); 
     1565         
     1566        count = wi_array_count(list); 
     1567        field_size = 0; 
     1568         
     1569        for(i = 0; i < count; i++) { 
     1570                instance = WI_ARRAY(list, i); 
     1571                 
     1572                if(wi_runtime_id(instance) == wi_string_runtime_id()) { 
     1573                        field_size += 4 + wi_string_length(instance) + 1; 
     1574                } else { 
     1575                        wi_error_set_libwired_p7_error(WI_ERROR_P7_UNKNOWNFIELD, 
     1576                                WI_STR("Unhandled type %@ in list"), wi_runtime_class_name(instance)); 
     1577                         
     1578                        return false; 
     1579                } 
     1580        } 
     1581         
     1582        if(!_wi_p7_message_get_binary_buffer_for_writing_for_name(p7_message, field_name, field_size, &binary, &field_id)) 
     1583                return false; 
     1584         
     1585        wi_write_swap_host_to_big_int32(binary, 0, field_id); 
     1586        wi_write_swap_host_to_big_int32(binary, 4, field_size); 
     1587         
     1588        offset = 8; 
     1589         
     1590        for(i = 0; i < count; i++) { 
     1591                instance = WI_ARRAY(list, i); 
     1592                 
     1593                if(wi_runtime_id(instance) == wi_string_runtime_id()) { 
     1594                        string_size = wi_string_length(instance) + 1; 
     1595                         
     1596                        wi_write_swap_host_to_big_int32(binary, offset, string_size); 
     1597                         
     1598                        offset += 4; 
     1599                         
     1600                        memcpy(binary + offset, wi_string_cstring(instance), string_size); 
     1601                         
     1602                        offset += string_size; 
     1603                } 
     1604        } 
     1605 
     1606        return true; 
     1607} 
     1608 
     1609 
     1610 
     1611wi_array_t * wi_p7_message_list_for_name(wi_p7_message_t *p7_message, wi_string_t *field_name) { 
     1612        xmlNodePtr                              listnode, itemnode; 
     1613        xmlChar                                 *content; 
     1614        wi_array_t                              *list; 
     1615        wi_runtime_instance_t   *instance; 
     1616        unsigned char                   *binary; 
     1617        wi_p7_type_t                    listtype; 
     1618        uint32_t                                field_size, list_size, string_size; 
     1619         
     1620        listtype = wi_p7_spec_field_listtype(p7_message->spec, wi_p7_spec_field_id(p7_message->spec, field_name)); 
     1621 
     1622        if(listtype != WI_P7_STRING) { 
     1623                wi_error_set_libwired_p7_error(WI_ERROR_P7_UNKNOWNFIELD, 
     1624                        WI_STR("Unhandled type %@ in list"), wi_p7_spec_type_name(p7_message->spec, listtype)); 
     1625                 
     1626                if(wi_p7_message_debug) 
     1627                        wi_log_debug(WI_STR("wi_p7_message_list_for_name: %m")); 
     1628                 
     1629                return NULL; 
     1630        } 
     1631         
     1632        list = wi_array(); 
     1633                 
     1634        if(p7_message->serialization == WI_P7_BINARY) { 
     1635                if(!_wi_p7_message_get_binary_buffer_for_reading_for_name(p7_message, field_name, &binary, &field_size)) 
     1636                        return NULL; 
     1637                 
     1638                list_size = 0; 
     1639                 
     1640                while(list_size < field_size) { 
     1641                        if(listtype == WI_P7_STRING) { 
     1642                                string_size = wi_read_swap_big_to_host_int32(binary, list_size); 
     1643                                 
     1644                                list_size += 4; 
     1645                                 
     1646                                instance = wi_string_with_bytes(binary + list_size, string_size - 1); 
     1647                                 
     1648                                list_size += string_size; 
     1649                        } 
     1650                         
     1651                        wi_array_add_data(list, instance); 
     1652                } 
     1653        } else { 
     1654                listnode = _wi_p7_message_xml_node_for_name(p7_message, wi_string_cstring(field_name)); 
     1655                 
     1656                for(itemnode = listnode->children; itemnode != NULL; itemnode = itemnode->next) { 
     1657                        if(itemnode->type == XML_ELEMENT_NODE) { 
     1658                                content = xmlNodeGetContent(itemnode); 
     1659                                 
     1660                                if(!content) 
     1661                                        continue; 
     1662                                 
     1663                                if(listtype == WI_P7_STRING) 
     1664                                        instance = wi_string_with_cstring_no_copy((char *) content, true); 
     1665                                 
     1666                                wi_array_add_data(list, instance); 
     1667                        } 
     1668                } 
     1669        } 
     1670         
     1671        return list; 
     1672} 
     1673 
     1674 
     1675 
    15171676#pragma mark - 
    15181677 
  • libwired/trunk/libwired/p7/wi-p7-message.h

    r5321 r5326  
    6060        WI_P7_DATE                                              = 10, 
    6161        WI_P7_DATA                                              = 11, 
    62         WI_P7_OOBDATA                                   = 12 
     62        WI_P7_OOBDATA                                   = 12, 
     63        WI_P7_LIST                                              = 13 
    6364}; 
    6465typedef enum _wi_p7_type                        wi_p7_type_t; 
     
    112113WI_EXPORT wi_boolean_t                          wi_p7_message_set_date_for_name(wi_p7_message_t *, wi_date_t *, wi_string_t *); 
    113114WI_EXPORT wi_date_t *                           wi_p7_message_date_for_name(wi_p7_message_t *, wi_string_t *); 
     115WI_EXPORT wi_boolean_t                          wi_p7_message_set_list_for_name(wi_p7_message_t *, wi_array_t *, wi_string_t *); 
     116WI_EXPORT wi_array_t *                          wi_p7_message_list_for_name(wi_p7_message_t *, wi_string_t *); 
    114117 
    115118WI_EXPORT wi_boolean_t                          wi_p7_message_write_binary(wi_p7_message_t *, const void *, uint32_t, wi_uinteger_t); 
  • libwired/trunk/libwired/p7/wi-p7-spec.c

    r5314 r5326  
    9292        wi_uinteger_t                                                   id; 
    9393        _wi_p7_spec_type_t                                              *type; 
     94        _wi_p7_spec_type_t                                              *listtype; 
    9495        wi_hash_t                                                               *enums_name; 
    9596        wi_hash_t                                                               *enums_id; 
     
    335336        "               <p7:type name=\"data\" id=\"11\" />" 
    336337        "               <p7:type name=\"oobdata\" id=\"12\" size=\"8\" />" 
     338        "               <p7:type name=\"list\" id=\"13\" />" 
    337339        "       </p7:types>" 
    338340        "" 
     
    14121414 
    14131415 
     1416wi_p7_type_t wi_p7_spec_field_listtype(wi_p7_spec_t *p7_spec, wi_uinteger_t field_id) { 
     1417        _wi_p7_spec_field_t             *field; 
     1418         
     1419        field = wi_hash_data_for_key(p7_spec->fields_id, (void *) field_id); 
     1420         
     1421        if(!field && _wi_p7_spec_builtin_spec) 
     1422                field = wi_hash_data_for_key(_wi_p7_spec_builtin_spec->fields_id, (void *) field_id); 
     1423         
     1424        if(!field || !field->listtype) 
     1425                return WI_P7_SPEC_TYPE_ID_NULL; 
     1426         
     1427        return field->listtype->id; 
     1428} 
     1429 
     1430 
     1431 
    14141432wi_uinteger_t wi_p7_spec_field_size(wi_p7_spec_t *p7_spec, wi_uinteger_t field_id) { 
    14151433        _wi_p7_spec_field_t             *field; 
     
    16481666        xmlNodePtr                                      enum_node; 
    16491667        _wi_p7_spec_field_t                     *field; 
    1650         wi_string_t                                     *type, *name; 
     1668        wi_string_t                                     *type, *listtype, *name; 
    16511669        wi_integer_t                            value; 
    16521670         
     
    16821700 
    16831701                return NULL; 
     1702        } 
     1703         
     1704        listtype = wi_autorelease(wi_p7_xml_copy_string_for_attribute(node, WI_STR("listtype"))); 
     1705         
     1706        if(listtype) { 
     1707                field->listtype = wi_retain(wi_hash_data_for_key(p7_spec->types_name, listtype)); 
     1708                 
     1709                if(!field->listtype && _wi_p7_spec_builtin_spec) 
     1710                        field->listtype = wi_retain(wi_hash_data_for_key(_wi_p7_spec_builtin_spec->types_name, listtype)); 
     1711                 
     1712                if(!field->listtype) { 
     1713                        wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     1714                                WI_STR("Field \"%@\" has an invalid \"listtype\" (\"%@\")"), 
     1715                                field->name, listtype); 
     1716 
     1717                        return NULL; 
     1718                } 
    16841719        } 
    16851720         
  • libwired/trunk/libwired/p7/wi-p7-spec.h

    r5254 r5326  
    6868WI_EXPORT wi_hash_t *                                   wi_p7_spec_field_names_for_ids(wi_p7_spec_t *); 
    6969WI_EXPORT wi_p7_type_t                                  wi_p7_spec_field_type(wi_p7_spec_t *, wi_uinteger_t); 
     70WI_EXPORT wi_p7_type_t                                  wi_p7_spec_field_listtype(wi_p7_spec_t *, wi_uinteger_t); 
    7071WI_EXPORT wi_uinteger_t                                 wi_p7_spec_field_size(wi_p7_spec_t *, wi_uinteger_t); 
    7172WI_EXPORT wi_p7_type_t                                  wi_p7_spec_type_id(wi_p7_spec_t *, wi_string_t *); 
  • libwired/trunk/p7/p7-message.xsd

    r4649 r5326  
    77        <xs:element name="field" type="p7:field" /> 
    88 
     9        <xs:element name="item" type="p7:item" /> 
     10 
    911        <xs:element name="message"> 
    1012                <xs:complexType> 
     
    1416                                        <xs:complexType> 
    1517                                                <xs:sequence> 
    16                                                         <xs:element ref="p7:field" minOccurs="0" maxOccurs="unbounded" /> 
     18                                                        <xs:element ref="p7:field" minOccurs="0" maxOccurs="unbounded"> 
     19                                                                <xs:complexType> 
     20                                                                        <xs:element ref="p7:item" minOccurs="0" maxOccurs="unbounded"> 
     21                                                                </xs:complexType> 
     22                                                        </xs:element> 
    1723                                                </xs:sequence> 
    1824                                        </xs:complexType> 
     
    2531                <xs:attribute name="name" type="xs:string" use="required" /> 
    2632        </xs:complexType> 
     33 
     34        <xs:simpleType name="item" /> 
    2735</xs:schema> 
  • libwired/trunk/p7/p7-specification.xsd

    r4649 r5326  
    101101                                        <xs:enumeration value="data" /> 
    102102                                        <xs:enumeration value="oobdata" /> 
     103                                        <xs:enumeration value="list" /> 
     104                                </xs:restriction> 
     105                        </xs:simpleType> 
     106                </xs:attribute> 
     107                <xs:attribute name="listtype" use="optional"> 
     108                        <xs:simpleType> 
     109                                <xs:restriction base="xs:string"> 
     110                                        <xs:enumeration value="bool" /> 
     111                                        <xs:enumeration value="enum" /> 
     112                                        <xs:enumeration value="int32" /> 
     113                                        <xs:enumeration value="uint32" /> 
     114                                        <xs:enumeration value="int64" /> 
     115                                        <xs:enumeration value="uint64" /> 
     116                                        <xs:enumeration value="double" /> 
     117                                        <xs:enumeration value="string" /> 
     118                                        <xs:enumeration value="uuid" /> 
     119                                        <xs:enumeration value="date" /> 
     120                                        <xs:enumeration value="data" /> 
     121                                        <xs:enumeration value="oobdata" /> 
     122                                        <xs:enumeration value="list" /> 
    103123                                </xs:restriction> 
    104124                        </xs:simpleType>