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); } }
/** * 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; }