--- a/libpurple/protocols/facebook/json.c Thu Nov 03 22:51:47 2022 -0500
+++ b/libpurple/protocols/facebook/json.c Thu Nov 03 22:52:46 2022 -0500
@@ -37,8 +37,15 @@
+ * Represents a JSON value handler. @@ -48,46 +55,30 @@
- * Represents a JSON value handler.
- FbJsonValuesPrivate *priv;
-G_DEFINE_TYPE_WITH_PRIVATE(FbJsonValues, fb_json_values, G_TYPE_OBJECT);
+G_DEFINE_TYPE(FbJsonValues, fb_json_values, G_TYPE_OBJECT); fb_json_values_dispose(GObject *obj)
- FbJsonValuesPrivate *priv = FB_JSON_VALUES(obj)->priv;
+ FbJsonValues *values = FB_JSON_VALUES(obj); - while (!g_queue_is_empty(priv->queue)) {
- value = g_queue_pop_head(priv->queue);
+ if(values->queue != NULL) { + while(!g_queue_is_empty(values->queue)) { + FbJsonValue *value = g_queue_pop_head(values->queue); - if (G_IS_VALUE(&value->value)) {
- g_value_unset(&value->value);
+ if(G_IS_VALUE(&value->value)) { + g_value_unset(&value->value);
- if (priv->array != NULL) {
- json_array_unref(priv->array);
- if (priv->error != NULL) {
- g_error_free(priv->error);
- g_queue_free(priv->queue);
+ g_clear_pointer(&values->array, json_array_unref); + g_clear_error(&values->error); + g_clear_pointer(&values->queue, g_queue_free); @@ -101,11 +92,7 @@
fb_json_values_init(FbJsonValues *values)
- FbJsonValuesPrivate *priv = fb_json_values_get_instance_private(values);
- priv->queue = g_queue_new();
+ values->queue = g_queue_new(); @@ -449,13 +436,11 @@
fb_json_values_new(JsonNode *root)
- FbJsonValuesPrivate *priv;
g_return_val_if_fail(root != NULL, NULL);
values = g_object_new(FB_TYPE_JSON_VALUES, NULL);
@@ -465,57 +450,50 @@
- FbJsonValuesPrivate *priv;
g_return_if_fail(values != NULL);
g_return_if_fail(expr != NULL);
value = g_new0(FbJsonValue, 1);
value->required = required;
- g_queue_push_tail(priv->queue, value);
+ g_queue_push_tail(values->queue, value); fb_json_values_get_root(FbJsonValues *values)
- FbJsonValuesPrivate *priv;
g_return_val_if_fail(values != NULL, NULL);
- if (priv->array == NULL) {
+ if(values->array == NULL) { - g_return_val_if_fail(priv->index > 0, NULL);
- index = priv->index - 1;
+ g_return_val_if_fail(values->index > 0, NULL); + index = values->index - 1; - if (json_array_get_length(priv->array) <= index) {
+ if(json_array_get_length(values->array) <= index) { - return json_array_get_element(priv->array, index);
+ return json_array_get_element(values->array, index); fb_json_values_set_array(FbJsonValues *values, gboolean required,
- FbJsonValuesPrivate *priv;
g_return_if_fail(values != NULL);
- priv->array = fb_json_node_get_arr(priv->root, expr, &priv->error);
+ values->array = fb_json_node_get_arr(values->root, expr, &values->error); + values->isarray = TRUE; - if ((priv->error != NULL) && !required) {
- g_clear_error(&priv->error);
+ g_clear_error(&values->error); @@ -523,7 +501,6 @@
fb_json_values_update(FbJsonValues *values, GError **error)
- FbJsonValuesPrivate *priv;
@@ -531,29 +508,28 @@
g_return_val_if_fail(values != NULL, FALSE);
- if (G_UNLIKELY(priv->error != NULL)) {
- g_propagate_error(error, priv->error);
+ if(G_UNLIKELY(values->error != NULL)) { + g_propagate_error(error, values->error);
- if ((priv->array == NULL) ||
- (json_array_get_length(priv->array) <= priv->index))
+ if(values->array == NULL || + json_array_get_length(values->array) <= values->index) - root = json_array_get_element(priv->array, priv->index++);
+ root = json_array_get_element(values->array, values->index++);
g_return_val_if_fail(root != NULL, FALSE);
- for (l = priv->queue->head; l != NULL; l = l->next) {
+ for(l = values->queue->head; l != NULL; l = l->next) { node = fb_json_node_get(root, value->expr, &err);
@@ -589,7 +565,7 @@
- priv->next = priv->queue->head;
+ values->next = values->queue->head; @@ -597,14 +573,12 @@
fb_json_values_next(FbJsonValues *values)
- FbJsonValuesPrivate *priv;
g_return_val_if_fail(values != NULL, NULL);
- g_return_val_if_fail(priv->next != NULL, NULL);
- value = priv->next->data;
- priv->next = priv->next->next;
+ g_return_val_if_fail(values->next != NULL, NULL); + value = values->next->data; + values->next = values->next->next; if (!G_IS_VALUE(&value->value)) {
--- a/libpurple/protocols/facebook/mqtt.c Thu Nov 03 22:51:47 2022 -0500
+++ b/libpurple/protocols/facebook/mqtt.c Thu Nov 03 22:52:46 2022 -0500
@@ -30,8 +30,15 @@
+ * Represents an MQTT connection. GBufferedInputStream *input;
@@ -44,32 +51,9 @@
- * Represents an MQTT connection.
-G_DEFINE_TYPE_WITH_PRIVATE(FbMqtt, fb_mqtt, G_TYPE_OBJECT);
- FbMqttMessageType type;
- FbMqttMessageFlags flags;
+G_DEFINE_TYPE(FbMqtt, fb_mqtt, G_TYPE_OBJECT); @@ -79,10 +63,18 @@
- FbMqttMessagePrivate *priv;
+ FbMqttMessageType type; + FbMqttMessageFlags flags; -G_DEFINE_TYPE_WITH_PRIVATE(FbMqttMessage, fb_mqtt_message, G_TYPE_OBJECT);
+G_DEFINE_TYPE(FbMqttMessage, fb_mqtt_message, G_TYPE_OBJECT); static void fb_mqtt_read_packet(FbMqtt *mqtt);
@@ -90,10 +82,9 @@
fb_mqtt_dispose(GObject *obj)
FbMqtt *mqtt = FB_MQTT(obj);
- FbMqttPrivate *priv = mqtt->priv;
- g_byte_array_free(priv->rbuf, TRUE);
+ g_byte_array_free(mqtt->rbuf, TRUE); @@ -169,20 +160,17 @@
fb_mqtt_init(FbMqtt *mqtt)
- FbMqttPrivate *priv = fb_mqtt_get_instance_private(mqtt);
- priv->rbuf = g_byte_array_new();
+ mqtt->rbuf = g_byte_array_new(); fb_mqtt_message_dispose(GObject *obj)
- FbMqttMessagePrivate *priv = FB_MQTT_MESSAGE(obj)->priv;
+ FbMqttMessage *msg = FB_MQTT_MESSAGE(obj); - if ((priv->bytes != NULL) && priv->local) {
- g_byte_array_free(priv->bytes, TRUE);
+ if(msg->bytes != NULL && msg->local) { + g_byte_array_free(msg->bytes, TRUE); @@ -197,9 +185,6 @@
fb_mqtt_message_init(FbMqttMessage *msg)
- FbMqttMessagePrivate *priv = fb_mqtt_message_get_instance_private(msg);
@@ -218,13 +203,11 @@
fb_mqtt_new(PurpleConnection *gc)
g_return_val_if_fail(PURPLE_IS_CONNECTION(gc), NULL);
mqtt = g_object_new(FB_TYPE_MQTT, NULL);
@@ -232,32 +215,29 @@
fb_mqtt_close(FbMqtt *mqtt)
+ g_return_if_fail(FB_IS_MQTT(mqtt)); - g_return_if_fail(FB_IS_MQTT(mqtt));
+ g_source_remove(mqtt->tev);
- g_source_remove(priv->tev);
+ if(mqtt->cancellable != NULL) { + g_cancellable_cancel(mqtt->cancellable); + g_clear_object(&mqtt->cancellable); - if (priv->cancellable != NULL) {
- g_cancellable_cancel(priv->cancellable);
- g_clear_object(&priv->cancellable);
+ if(mqtt->conn != NULL) { + purple_gio_graceful_close(mqtt->conn, + G_INPUT_STREAM(mqtt->input), + G_OUTPUT_STREAM(mqtt->output)); + g_clear_object(&mqtt->input); + g_clear_object(&mqtt->output); + g_clear_object(&mqtt->conn); - if (priv->conn != NULL) {
- purple_gio_graceful_close(priv->conn,
- G_INPUT_STREAM(priv->input),
- G_OUTPUT_STREAM(priv->output));
- g_clear_object(&priv->input);
- g_clear_object(&priv->output);
- g_clear_object(&priv->conn);
- priv->connected = FALSE;
- g_byte_array_set_size(priv->rbuf, 0);
+ mqtt->connected = FALSE; + g_byte_array_set_size(mqtt->rbuf, 0); @@ -313,9 +293,8 @@
fb_mqtt_cb_timeout(gpointer data)
- FbMqttPrivate *priv = mqtt->priv;
fb_mqtt_error_literal(mqtt, FB_MQTT_ERROR_GENERAL,
_("Connection timed out"));
@@ -324,21 +303,17 @@
fb_mqtt_timeout_clear(FbMqtt *mqtt)
- FbMqttPrivate *priv = mqtt->priv;
- g_source_remove(priv->tev);
+ g_source_remove(mqtt->tev); fb_mqtt_timeout(FbMqtt *mqtt)
- FbMqttPrivate *priv = mqtt->priv;
fb_mqtt_timeout_clear(mqtt);
- priv->tev = g_timeout_add_seconds(FB_MQTT_TIMEOUT_CONN, fb_mqtt_cb_timeout,
+ mqtt->tev = g_timeout_add_seconds(FB_MQTT_TIMEOUT_CONN, fb_mqtt_cb_timeout, @@ -347,13 +322,12 @@
- FbMqttPrivate *priv = mqtt->priv;
msg = fb_mqtt_message_new(FB_MQTT_MESSAGE_TYPE_PINGREQ, 0);
fb_mqtt_write(mqtt, msg);
@@ -361,11 +335,9 @@
fb_mqtt_ping(FbMqtt *mqtt)
- FbMqttPrivate *priv = mqtt->priv;
fb_mqtt_timeout_clear(mqtt);
- g_timeout_add_seconds(FB_MQTT_TIMEOUT_PING, fb_mqtt_cb_ping, mqtt);
+ mqtt->tev = g_timeout_add_seconds(FB_MQTT_TIMEOUT_PING, fb_mqtt_cb_ping, @@ -396,7 +368,6 @@
fb_mqtt_cb_read_packet(GObject *source, GAsyncResult *res, gpointer data)
@@ -414,19 +385,18 @@
g_input_stream_read_async(G_INPUT_STREAM(source),
- priv->rbuf->len - priv->remz, priv->remz,
- G_PRIORITY_DEFAULT, priv->cancellable,
- fb_mqtt_cb_read_packet, mqtt);
+ mqtt->rbuf->data + mqtt->rbuf->len - mqtt->remz, + mqtt->remz, G_PRIORITY_DEFAULT, + mqtt->cancellable, fb_mqtt_cb_read_packet, - msg = fb_mqtt_message_new_bytes(priv->rbuf);
+ msg = fb_mqtt_message_new_bytes(mqtt->rbuf); if (G_UNLIKELY(msg == NULL)) {
fb_mqtt_error_literal(mqtt, FB_MQTT_ERROR_GENERAL,
@@ -446,7 +416,6 @@
fb_mqtt_read_packet(FbMqtt *mqtt)
- FbMqttPrivate *priv = mqtt->priv;
@@ -454,7 +423,7 @@
- buf = g_buffered_input_stream_peek_buffer(priv->input, &count);
+ buf = g_buffered_input_stream_peek_buffer(mqtt->input, &count); /* Start at 1 to skip the first byte */
@@ -462,9 +431,10 @@
/* Not enough data yet, try again later */
- g_buffered_input_stream_fill_async(priv->input, -1,
- G_PRIORITY_DEFAULT, priv->cancellable,
- fb_mqtt_cb_fill, mqtt);
+ g_buffered_input_stream_fill_async(mqtt->input, -1, + fb_mqtt_cb_fill, mqtt); @@ -477,8 +447,8 @@
- g_byte_array_set_size(priv->rbuf, size);
+ g_byte_array_set_size(mqtt->rbuf, size); /* TODO: Use g_input_stream_read_all_async() when available. */
/* TODO: Alternately, it would be nice to let the
@@ -486,33 +456,27 @@
* buffer instead of copying it, provided it's consumed
- g_input_stream_read_async(G_INPUT_STREAM(priv->input),
- priv->rbuf->data, priv->rbuf->len,
- G_PRIORITY_DEFAULT, priv->cancellable,
- fb_mqtt_cb_read_packet, mqtt);
+ g_input_stream_read_async(G_INPUT_STREAM(mqtt->input), mqtt->rbuf->data, + mqtt->rbuf->len, G_PRIORITY_DEFAULT, + mqtt->cancellable, fb_mqtt_cb_read_packet, mqtt); fb_mqtt_read(FbMqtt *mqtt, FbMqttMessage *msg)
- FbMqttMessagePrivate *mriv;
g_return_if_fail(FB_IS_MQTT(mqtt));
- g_return_if_fail(FB_IS_MQTT_MESSAGE(msg));
- fb_util_debug_hexdump(FB_UTIL_DEBUG_INFO, mriv->bytes,
+ fb_util_debug_hexdump(FB_UTIL_DEBUG_INFO, msg->bytes, "Reading %d (flags: 0x%0X)",
- mriv->type, mriv->flags);
+ msg->type, msg->flags);
case FB_MQTT_MESSAGE_TYPE_CONNACK:
if (!fb_mqtt_message_read_byte(msg, NULL) ||
!fb_mqtt_message_read_byte(msg, &chr))
@@ -526,7 +490,7 @@
- priv->connected = TRUE;
+ mqtt->connected = TRUE; g_signal_emit_by_name(mqtt, "connect");
@@ -536,10 +500,10 @@
- if ((mriv->flags & FB_MQTT_MESSAGE_FLAG_QOS1) ||
- (mriv->flags & FB_MQTT_MESSAGE_FLAG_QOS2))
+ if((msg->flags & FB_MQTT_MESSAGE_FLAG_QOS1) || + (msg->flags & FB_MQTT_MESSAGE_FLAG_QOS2)) - if (mriv->flags & FB_MQTT_MESSAGE_FLAG_QOS1) {
+ if(msg->flags & FB_MQTT_MESSAGE_FLAG_QOS1) { chr = FB_MQTT_MESSAGE_TYPE_PUBACK;
chr = FB_MQTT_MESSAGE_TYPE_PUBREC;
@@ -586,7 +550,7 @@
fb_mqtt_error(mqtt, FB_MQTT_ERROR_GENERAL,
- _("Unknown packet (%u)"), mriv->type);
+ _("Unknown packet (%u)"), msg->type); @@ -615,14 +579,10 @@
fb_mqtt_write(FbMqtt *mqtt, FbMqttMessage *msg)
- FbMqttMessagePrivate *mriv;
g_return_if_fail(FB_IS_MQTT(mqtt));
g_return_if_fail(FB_IS_MQTT_MESSAGE(msg));
bytes = fb_mqtt_message_bytes(msg);
@@ -632,15 +592,16 @@
- fb_util_debug_hexdump(FB_UTIL_DEBUG_INFO, mriv->bytes,
+ fb_util_debug_hexdump(FB_UTIL_DEBUG_INFO, msg->bytes, "Writing %d (flags: 0x%0X)",
- mriv->type, mriv->flags);
+ msg->type, msg->flags); /* TODO: Would be nice to refactor this to not require copying bytes */
gbytes = g_bytes_new(bytes->data, bytes->len);
- purple_queued_output_stream_push_bytes_async(priv->output, gbytes,
- G_PRIORITY_DEFAULT, priv->cancellable,
- fb_mqtt_cb_push_bytes, mqtt);
+ purple_queued_output_stream_push_bytes_async(mqtt->output, gbytes, + fb_mqtt_cb_push_bytes, mqtt); @@ -648,7 +609,6 @@
fb_mqtt_cb_open(GObject *source, GAsyncResult *res, gpointer data)
@@ -662,12 +622,11 @@
fb_mqtt_timeout_clear(mqtt);
- priv->conn = G_IO_STREAM(conn);
- priv->input = G_BUFFERED_INPUT_STREAM(g_buffered_input_stream_new(
- g_io_stream_get_input_stream(priv->conn)));
- priv->output = purple_queued_output_stream_new(
- g_io_stream_get_output_stream(priv->conn));
+ mqtt->conn = G_IO_STREAM(conn); + mqtt->input = G_BUFFERED_INPUT_STREAM(g_buffered_input_stream_new( + g_io_stream_get_input_stream(mqtt->conn))); + mqtt->output = purple_queued_output_stream_new( + g_io_stream_get_output_stream(mqtt->conn)); fb_mqtt_read_packet(mqtt);
@@ -677,15 +636,13 @@
fb_mqtt_open(FbMqtt *mqtt, const gchar *host, gint port)
g_return_if_fail(FB_IS_MQTT(mqtt));
- acc = purple_connection_get_account(priv->gc);
+ acc = purple_connection_get_account(mqtt->gc); client = purple_gio_socket_client_new(acc, &err);
@@ -695,11 +652,12 @@
- priv->cancellable = g_cancellable_new();
+ mqtt->cancellable = g_cancellable_new(); g_socket_client_set_tls(client, TRUE);
g_socket_client_connect_to_host_async(client, host, port,
- priv->cancellable, fb_mqtt_cb_open, mqtt);
+ mqtt->cancellable, fb_mqtt_cb_open, @@ -732,12 +690,10 @@
fb_mqtt_connected(FbMqtt *mqtt, gboolean error)
g_return_val_if_fail(FB_IS_MQTT(mqtt), FALSE);
- connected = (priv->conn != NULL) && priv->connected;
+ connected = (mqtt->conn != NULL) && mqtt->connected; if (!connected && error) {
fb_mqtt_error_literal(mqtt, FB_MQTT_ERROR_GENERAL, _("Not connected"));
@@ -765,18 +721,16 @@
fb_mqtt_publish(FbMqtt *mqtt, const gchar *topic, const GByteArray *pload)
g_return_if_fail(FB_IS_MQTT(mqtt));
g_return_if_fail(fb_mqtt_connected(mqtt, FALSE));
/* Message identifier not required, but for consistency use QoS1 */
msg = fb_mqtt_message_new(FB_MQTT_MESSAGE_TYPE_PUBLISH,
FB_MQTT_MESSAGE_FLAG_QOS1);
fb_mqtt_message_write_str(msg, topic); /* Message topic */
- fb_mqtt_message_write_mid(msg, &priv->mid); /* Message identifier */
+ fb_mqtt_message_write_mid(msg, &mqtt->mid); /* Message identifier */ fb_mqtt_message_write(msg, pload->data, pload->len);
@@ -791,19 +745,17 @@
g_return_if_fail(FB_IS_MQTT(mqtt));
g_return_if_fail(fb_mqtt_connected(mqtt, FALSE));
/* Facebook requires a message identifier, use QoS1 */
msg = fb_mqtt_message_new(FB_MQTT_MESSAGE_TYPE_SUBSCRIBE,
FB_MQTT_MESSAGE_FLAG_QOS1);
- fb_mqtt_message_write_mid(msg, &priv->mid); /* Message identifier */
+ fb_mqtt_message_write_mid(msg, &mqtt->mid); /* Message identifier */ @@ -824,18 +776,16 @@
g_return_if_fail(FB_IS_MQTT(mqtt));
g_return_if_fail(fb_mqtt_connected(mqtt, FALSE));
/* Facebook requires a message identifier, use QoS1 */
msg = fb_mqtt_message_new(FB_MQTT_MESSAGE_TYPE_UNSUBSCRIBE,
FB_MQTT_MESSAGE_FLAG_QOS1);
- fb_mqtt_message_write_mid(msg, &priv->mid); /* Message identifier */
+ fb_mqtt_message_write_mid(msg, &mqtt->mid); /* Message identifier */ fb_mqtt_message_write_str(msg, topic1); /* First topic */
@@ -854,15 +804,13 @@
fb_mqtt_message_new(FbMqttMessageType type, FbMqttMessageFlags flags)
- FbMqttMessagePrivate *priv;
msg = g_object_new(FB_TYPE_MQTT_MESSAGE, NULL);
- priv->bytes = g_byte_array_new();
+ msg->bytes = g_byte_array_new(); @@ -871,24 +819,26 @@
fb_mqtt_message_new_bytes(GByteArray *bytes)
- FbMqttMessagePrivate *priv;
g_return_val_if_fail(bytes != NULL, NULL);
g_return_val_if_fail(bytes->len >= 2, NULL);
msg = g_object_new(FB_TYPE_MQTT_MESSAGE, NULL);
- priv->type = (*bytes->data & 0xF0) >> 4;
- priv->flags = *bytes->data & 0x0F;
+ msg->type = (*bytes->data & 0xF0) >> 4; + msg->flags = *bytes->data & 0x0F; /* Skip the fixed header */
- for (byte = priv->bytes->data + 1; (*(byte++) & 128) != 0; );
- priv->offset = byte - bytes->data;
- priv->pos = priv->offset;
+ byte = msg->bytes->data + 1; + while((*byte & 128) != 0) { + msg->offset = byte - bytes->data; + msg->pos = msg->offset; @@ -896,32 +846,27 @@
fb_mqtt_message_reset(FbMqttMessage *msg)
- FbMqttMessagePrivate *priv;
g_return_if_fail(FB_IS_MQTT_MESSAGE(msg));
- if (priv->offset > 0) {
- g_byte_array_remove_range(priv->bytes, 0, priv->offset);
+ g_byte_array_remove_range(msg->bytes, 0, msg->offset); fb_mqtt_message_bytes(FbMqttMessage *msg)
- FbMqttMessagePrivate *priv;
g_return_val_if_fail(FB_IS_MQTT_MESSAGE(msg), NULL);
- size = priv->bytes->len - priv->offset;
+ size = msg->bytes->len - msg->offset; if (G_UNLIKELY(i >= G_N_ELEMENTS(sbuf))) {
@@ -939,48 +884,42 @@
fb_mqtt_message_reset(msg);
- g_byte_array_prepend(priv->bytes, sbuf, i);
+ g_byte_array_prepend(msg->bytes, sbuf, i); - byte = ((priv->type & 0x0F) << 4) | (priv->flags & 0x0F);
- g_byte_array_prepend(priv->bytes, &byte, sizeof byte);
+ byte = ((msg->type & 0x0F) << 4) | (msg->flags & 0x0F); + g_byte_array_prepend(msg->bytes, &byte, sizeof byte); - priv->pos = (i + 1) * (sizeof byte);
+ msg->pos = (i + 1) * (sizeof byte); fb_mqtt_message_read(FbMqttMessage *msg, gpointer data, guint size)
- FbMqttMessagePrivate *priv;
+ g_return_val_if_fail(FB_IS_MQTT_MESSAGE(msg), FALSE); - g_return_val_if_fail(FB_IS_MQTT_MESSAGE(msg), FALSE);
- if ((priv->pos + size) > priv->bytes->len) {
+ if((msg->pos + size) > msg->bytes->len) { if ((data != NULL) && (size > 0)) {
- memcpy(data, priv->bytes->data + priv->pos, size);
+ memcpy(data, msg->bytes->data + msg->pos, size);
fb_mqtt_message_read_r(FbMqttMessage *msg, GByteArray *bytes)
- FbMqttMessagePrivate *priv;
g_return_val_if_fail(FB_IS_MQTT_MESSAGE(msg), FALSE);
- size = priv->bytes->len - priv->pos;
+ size = msg->bytes->len - msg->pos; if (G_LIKELY(size > 0)) {
- g_byte_array_append(bytes, priv->bytes->data + priv->pos,
+ g_byte_array_append(bytes, msg->bytes->data + msg->pos, size); @@ -1044,13 +983,10 @@
fb_mqtt_message_write(FbMqttMessage *msg, gconstpointer data, guint size)
- FbMqttMessagePrivate *priv;
+ g_return_if_fail(FB_IS_MQTT_MESSAGE(msg)); - g_return_if_fail(FB_IS_MQTT_MESSAGE(msg));
- g_byte_array_append(priv->bytes, data, size);
+ g_byte_array_append(msg->bytes, data, size);