static void
add_dlna_info (GString           *str,
               GUPnPProtocolInfo *info)
{
        const char *dlna_profile;
        const char **speeds;
        GUPnPDLNAConversion conversion;
        GUPnPDLNAFlags flags;

        dlna_profile = gupnp_protocol_info_get_dlna_profile (info);
        if (dlna_profile == NULL) {
                g_string_append_printf (str, ":*");
                return;
        }

        g_string_append_printf (str, ":DLNA.ORG_PN=%s", dlna_profile);

        /* the OP parameter is only allowed for the "http-get"
         * and "rtsp-rtp-udp" protocols
         */
        if (strcmp (gupnp_protocol_info_get_protocol (info),
                    "http-get") == 0 ||
            strcmp (gupnp_protocol_info_get_protocol (info),
                    "rtsp-rtp-udp") == 0)
                g_string_append_printf
                        (str,
                         ";DLNA.ORG_OP=%.2x",
                         gupnp_protocol_info_get_dlna_operation (info));

        /* Specify PS parameter if list of play speeds is provided */
        speeds = gupnp_protocol_info_get_play_speeds (info);
        if (speeds != NULL) {
                int i;

                g_string_append_printf (str, ";DLNA.ORG_PS=");

                for (i = 0; speeds[i]; i++) {
                        g_string_append (str, speeds[i]);

                        if (speeds[i + 1])
                                g_string_append_c (str, ',');
                }
        }

        conversion = gupnp_protocol_info_get_dlna_conversion (info);
        /* omit the CI parameter for non-converted content */
        if (conversion != GUPNP_DLNA_CONVERSION_NONE)
                g_string_append_printf (str, ";DLNA.ORG_CI=%d", conversion);

        flags = gupnp_protocol_info_get_dlna_flags (info);
        /* Omit the FLAGS parameter if no flags set */
        if (flags != GUPNP_DLNA_FLAGS_NONE) {
                g_string_append_printf (str, ";DLNA.ORG_FLAGS=%.8x", flags);
                /*  append 24 reserved hex-digits */
                g_string_append_printf (str,
                                        "0000" "0000" "0000"
                                        "0000" "0000" "0000");
        }
}
/**
 * gupnp_protocol_info_to_string:
 * @info: The #GUPnPProtocolInfo
 *
 * Provides the string representation of @info.
 *
 * Return value: String representation of @info. #g_free after usage.
 **/
char *
gupnp_protocol_info_to_string (GUPnPProtocolInfo *info)
{
        GString *str;
        const char *protocol;
        const char *mime_type;
        const char *network;

        g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), NULL);

        protocol = gupnp_protocol_info_get_protocol (info);
        mime_type = gupnp_protocol_info_get_mime_type (info);
        network = gupnp_protocol_info_get_network (info);

        g_return_val_if_fail (protocol != NULL, NULL);
        g_return_val_if_fail (mime_type != NULL, NULL);

        str = g_string_new ("");

        g_string_append (str, protocol);
        g_string_append_c (str, ':');
        if (network != NULL)
                g_string_append (str, network);
        else
                g_string_append_c (str, '*');
        g_string_append_c (str, ':');
        g_string_append (str, mime_type);

        add_dlna_info (str, info);

        return g_string_free (str, FALSE);
}
static void
gupnp_protocol_info_get_property (GObject    *object,
                                  guint       property_id,
                                  GValue     *value,
                                  GParamSpec *pspec)
{
        GUPnPProtocolInfo *info;

        info = GUPNP_PROTOCOL_INFO (object);

        switch (property_id) {
        case PROP_PROTOCOL:
                g_value_set_string (value,
                                    gupnp_protocol_info_get_protocol (info));
                break;
        case PROP_NETWORK:
                g_value_set_string (value,
                                    gupnp_protocol_info_get_network (info));
                break;
        case PROP_MIME_TYPE:
                g_value_set_string (value,
                                    gupnp_protocol_info_get_mime_type (info));
                break;
        case PROP_DLNA_PROFILE:
                g_value_set_string
                              (value,
                               gupnp_protocol_info_get_dlna_profile (info));
                break;
        case PROP_PLAY_SPEEDS:
                g_value_set_boxed (value,
                                   gupnp_protocol_info_get_play_speeds (info));
                break;
        case PROP_DLNA_CONVERSION:
                g_value_set_flags
                                (value,
                                 gupnp_protocol_info_get_dlna_conversion
                                                                (info));
                break;
        case PROP_DLNA_OPERATION:
                g_value_set_flags
                                (value,
                                 gupnp_protocol_info_get_dlna_operation (info));
                break;
        case PROP_DLNA_FLAGS:
                g_value_set_flags (value,
                                   gupnp_protocol_info_get_dlna_flags (info));
                break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
                break;
        }
}
static gboolean
is_transport_compat (GUPnPProtocolInfo *info1,
                     GUPnPProtocolInfo *info2)
{
        const char *protocol1;
        const char *protocol2;

        protocol1 = gupnp_protocol_info_get_protocol (info1);
        protocol2 = gupnp_protocol_info_get_protocol (info2);

        if (protocol1[0] != '*' &&
            protocol2[0] != '*' &&
            g_ascii_strcasecmp (protocol1, protocol2) != 0)
                return FALSE;
        else if (g_ascii_strcasecmp ("internal", protocol1) == 0 &&
                 strcmp (gupnp_protocol_info_get_network (info1),
                         gupnp_protocol_info_get_network (info2)) != 0)
                /* Host must be the same in case of INTERNAL protocol */
                return FALSE;
        else
                return TRUE;
}
static void
add_dlna_info (GString           *str,
               GUPnPProtocolInfo *info)
{
        const char *dlna_profile;
        const char **speeds;
        GUPnPDLNAConversion conversion;
        GUPnPDLNAOperation operation;
        GUPnPDLNAFlags flags;

        dlna_profile = gupnp_protocol_info_get_dlna_profile (info);
        if (dlna_profile == NULL) {
                g_string_append_printf (str, ":");
        } else {
                g_string_append_printf (str, ":DLNA.ORG_PN=%s;", dlna_profile);
        }

        operation = gupnp_protocol_info_get_dlna_operation (info);
        if (operation != GUPNP_DLNA_OPERATION_NONE &&
            /* the OP parameter is only allowed for the "http-get"
             * and "rtsp-rtp-udp" protocols
             */
            (strcmp (gupnp_protocol_info_get_protocol (info),
                     "http-get") == 0 ||
             strcmp (gupnp_protocol_info_get_protocol (info),
                     "rtsp-rtp-udp") == 0))
                g_string_append_printf (str, "DLNA.ORG_OP=%.2x;", operation);

        /* Specify PS parameter if list of play speeds is provided */
        speeds = gupnp_protocol_info_get_play_speeds (info);
        if (speeds != NULL) {
                int i;

                g_string_append (str, "DLNA.ORG_PS=");

                for (i = 0; speeds[i]; i++) {
                        g_string_append (str, speeds[i]);

                        if (speeds[i + 1])
                                g_string_append_c (str, ',');
                }
                g_string_append_c (str, ';');
        }

        conversion = gupnp_protocol_info_get_dlna_conversion (info);
        /* omit the CI parameter for non-converted content */
        if (conversion != GUPNP_DLNA_CONVERSION_NONE)
                g_string_append_printf (str, "DLNA.ORG_CI=%d;", conversion);

        flags = gupnp_protocol_info_get_dlna_flags (info);
        /* Omit the FLAGS parameter if no or DLNA profile are set */
        if (flags != GUPNP_DLNA_FLAGS_NONE && dlna_profile != NULL) {
                g_string_append_printf (str, "DLNA.ORG_FLAGS=%.8x", flags);
                /*  append 24 reserved hex-digits */
                g_string_append_printf (str,
                                        "0000" "0000" "0000"
                                        "0000" "0000" "0000");
        }

        /* if nothing of the above was set, use the "match all" rule */
        switch (str->str[str->len - 1]) {
                case ':':
                        g_string_append_c (str, '*');
                        break;
                case ';':
                        g_string_erase (str, str->len - 1, 1);
                        break;
                default:
                        break;
        }
}