Пример #1
0
static void
fb_mqtt_cb_read(gpointer data, gint fd, PurpleInputCondition cond)
{
	FbMqtt *mqtt = data;
	FbMqttMessage *msg;
	FbMqttPrivate *priv = mqtt->priv;
	gint res;
	guint mult;
	guint8 buf[1024];
	guint8 byte;
	gsize size;
	gssize rize;

	if (priv->remz < 1) {
		/* Reset the read buffer */
		g_byte_array_set_size(priv->rbuf, 0);

		res = purple_ssl_read(priv->gsc, &byte, sizeof byte);
		g_byte_array_append(priv->rbuf, &byte, sizeof byte);

		if (res != sizeof byte) {
			fb_mqtt_error(mqtt, FB_MQTT_ERROR_GENERAL,
			              _("Failed to read fixed header"));
			return;
		}

		mult = 1;

		do {
			res = purple_ssl_read(priv->gsc, &byte, sizeof byte);
			g_byte_array_append(priv->rbuf, &byte, sizeof byte);

			if (res != sizeof byte) {
				fb_mqtt_error(mqtt, FB_MQTT_ERROR_GENERAL,
				              _("Failed to read packet size"));
				return;
			}

			priv->remz += (byte & 127) * mult;
			mult *= 128;
		} while ((byte & 128) != 0);
	}

	if (priv->remz > 0) {
		size = MIN(priv->remz, sizeof buf);
		rize = purple_ssl_read(priv->gsc, buf, size);

		if (rize < 1) {
			fb_mqtt_error(mqtt, FB_MQTT_ERROR_GENERAL,
			              _("Failed to read packet data"));
			return;
		}

		g_byte_array_append(priv->rbuf, buf, rize);
		priv->remz -= rize;
	}

	if (priv->remz < 1) {
		msg = fb_mqtt_message_new_bytes(priv->rbuf);
		priv->remz = 0;

		if (G_UNLIKELY(msg == NULL)) {
			fb_mqtt_error(mqtt, FB_MQTT_ERROR_GENERAL,
			              _("Failed to parse message"));
			return;
		}

		fb_mqtt_read(mqtt, msg);
		g_object_unref(msg);
	}
}
Пример #2
0
/**
 * Implemented #b_event_handler for the read of #fb_mqtt->fd.
 *
 * @param data The user defined data, which is #fb_mqtt.
 * @param fd   The event file descriptor.
 * @param cond The #b_input_condition.
 *
 * @return TRUE for continued event handling, otherwise FALSE.
 **/
static gboolean fb_mqtt_cb_read(gpointer data, gint fd,
                                b_input_condition cond)
{
    fb_mqtt_t     *mqtt = data;
    fb_mqtt_msg_t *msg;
    gchar          buf[1024];
    guint8         byte;
    guint          mult;
    gssize         rize;
    gint           res;

    if (mqtt->remz < 1) {
        /* Reset the read buffer */
        g_byte_array_set_size(mqtt->rbuf, 0);

        res = ssl_read(mqtt->ssl, (gchar*) &byte, sizeof byte);
        g_byte_array_append(mqtt->rbuf, &byte, sizeof byte);

        if (res != sizeof byte)
            goto error;

        mult = 1;

        do {
            res = ssl_read(mqtt->ssl, (gchar*) &byte, sizeof byte);
            g_byte_array_append(mqtt->rbuf, &byte, sizeof byte);

            if (res != sizeof byte)
                goto error;

            mqtt->remz += (byte & 127) * mult;
            mult *= 128;
        } while ((byte & 128) != 0);
    }

    if (mqtt->remz > 0) {
        rize = ssl_read(mqtt->ssl, buf, MIN(mqtt->remz, sizeof buf));

        if (rize < 1)
            goto error;

        g_byte_array_append(mqtt->rbuf, (guint8*) buf, rize);
        mqtt->remz -= rize;
    }

    if (mqtt->remz < 1) {
        msg = fb_mqtt_msg_new_bytes(mqtt->rbuf);
        mqtt->remz = 0;

        if (G_UNLIKELY(msg == NULL))
            goto error;

        fb_mqtt_read(mqtt, msg);
        fb_mqtt_msg_free(msg);
    }

    return TRUE;

error:
    fb_mqtt_error(mqtt, FB_MQTT_ERROR_GENERAL, "Short read");
    return FALSE;
}