/soc/2015/jgeboski/facebook: 1fedb5e19577: facebook: refactored ...

James Geboski jgeboski at gmail.com
Mon Aug 3 22:34:31 EDT 2015


Changeset: 1fedb5e195779907b7c121b46189301c1486129a
Author:	 James Geboski <jgeboski at gmail.com>
Date:	 2015-08-03 22:34 -0400
Branch:	 facebook
URL: https://hg.pidgin.im/soc/2015/jgeboski/facebook/rev/1fedb5e19577

Description:

facebook: refactored the parsing of JSON values

diffstat:

 libpurple/protocols/facebook/api.c  |  408 +++++++++++++++++++----------------
 libpurple/protocols/facebook/api.h  |    2 +-
 libpurple/protocols/facebook/http.c |   79 ------
 libpurple/protocols/facebook/http.h |   16 -
 libpurple/protocols/facebook/json.c |  279 +++++++++++++++++++-----
 libpurple/protocols/facebook/json.h |   60 ++++-
 6 files changed, 488 insertions(+), 356 deletions(-)

diffs (truncated from 1210 to 300 lines):

diff --git a/libpurple/protocols/facebook/api.c b/libpurple/protocols/facebook/api.c
--- a/libpurple/protocols/facebook/api.c
+++ b/libpurple/protocols/facebook/api.c
@@ -308,11 +308,12 @@ fb_api_error_quark(void)
 static gboolean
 fb_api_json_chk(FbApi *api, gconstpointer data, gsize size, JsonNode **node)
 {
+	const gchar *str;
 	FbApiError errc = FB_API_ERROR_GENERAL;
 	FbApiPrivate *priv;
+	FbJsonValues *values;
 	gboolean success = TRUE;
-	gchar *msg = NULL;
-	gchar *str;
+	gchar *msg;
 	GError *err = NULL;
 	gint64 code;
 	guint i;
@@ -337,9 +338,16 @@ fb_api_json_chk(FbApi *api, gconstpointe
 	root = fb_json_node_new(data, size, &err);
 	FB_API_ERROR_CHK(api, err, return FALSE);
 
-	if (fb_json_node_chk_int(root, "$.error_code", &code) &&
-	    (code == 401))
-	{
+	values = fb_json_values_new(root);
+	fb_json_values_add(values, FALSE, "$.error_code");
+	fb_json_values_add(values, FALSE, "$.error.type");
+	fb_json_values_add(values, FALSE, "$.errorCode");
+
+	fb_json_values_update(values, NULL);
+	code = fb_json_values_next_int(values, 0);
+	str = fb_json_values_next_str(values, 0);
+
+	if (purple_strequal(str, "OAuthException") || (code == 401)) {
 		errc = FB_API_ERROR_AUTH;
 		success = FALSE;
 
@@ -350,35 +358,24 @@ fb_api_json_chk(FbApi *api, gconstpointe
 		priv->token = NULL;
 	}
 
-	if (fb_json_node_chk_str(root, "$.error.type", &str) &&
-	    (g_ascii_strcasecmp(str, "OAuthException") == 0))
+	str = fb_json_values_next_str(values, 0);
+
+	if (purple_strequal(str, "ERROR_QUEUE_NOT_FOUND") ||
+	    purple_strequal(str, "ERROR_QUEUE_LOST"))
 	{
 		errc = FB_API_ERROR_AUTH;
 		success = FALSE;
-		g_free(str);
-
-		g_free(priv->stoken);
-		priv->stoken = NULL;
-
-		g_free(priv->token);
-		priv->token = NULL;
-
-	}
-
-	if (fb_json_node_chk_str(root, "$.errorCode", &str) && (
-		(g_ascii_strcasecmp(str, "ERROR_QUEUE_NOT_FOUND") == 0) ||
-		(g_ascii_strcasecmp(str, "ERROR_QUEUE_LOST") == 0)))
-	{
-		errc = FB_API_ERROR_AUTH;
-		success = FALSE;
-		g_free(str);
 
 		g_free(priv->stoken);
 		priv->stoken = NULL;
 	}
 
-	for (i = 0; i < G_N_ELEMENTS(exprs); i++) {
-		if (fb_json_node_chk_str(root, exprs[i], &msg)) {
+	fb_json_values_free(values);
+
+	for (msg = NULL, i = 0; i < G_N_ELEMENTS(exprs); i++) {
+		msg = fb_json_node_get_str(root, exprs[i], NULL);
+
+		if (msg != NULL) {
 			success = FALSE;
 			break;
 		}
@@ -603,26 +600,34 @@ static void
 fb_api_cb_seqid(PurpleHttpConnection *con, PurpleHttpResponse *res,
                 gpointer data)
 {
+	const gchar *str;
 	FbApi *api = data;
 	FbApiPrivate *priv = api->priv;
+	FbJsonValues *values;
 	gchar *json;
-	gchar *str;
 	GError *err = NULL;
 	JsonBuilder *bldr;
 	JsonNode *root;
 
-	static const gchar *expr =
-		"$.viewer.message_threads.sync_sequence_id";
-
 	if (!fb_api_http_chk(api, con, res, &root)) {
 		return;
 	}
 
-	str = fb_json_node_get_str(root, expr, &err);
+	values = fb_json_values_new(root);
+	fb_json_values_add(values, TRUE, "$.viewer.message_threads"
+	                                  ".sync_sequence_id");
+	fb_json_values_update(values, &err);
+
+	FB_API_ERROR_CHK(api, err,
+		fb_json_values_free(values);
+		json_node_free(root);
+		return;
+	);
+
+	str = fb_json_values_next_str(values, "0");
+	priv->sid = g_ascii_strtoll(str, NULL, 10);
+	fb_json_values_free(values);
 	json_node_free(root);
-	FB_API_ERROR_CHK(api, err, return);
-	priv->sid = g_ascii_strtoll(str, NULL, 10);
-	g_free(str);
 
 	bldr = fb_json_bldr_new(JSON_NODE_OBJECT);
 	fb_json_bldr_add_int(bldr, "delta_batch_size", 125);
@@ -702,72 +707,86 @@ fb_api_cb_mqtt_connect(FbMqtt *mqtt, gpo
 static void
 fb_api_cb_publish_mark(FbApi *api, const GByteArray *pload)
 {
-	gboolean res;
+	FbJsonValues *values;
+	GError *err = NULL;
 	JsonNode *root;
 
 	if (!fb_api_json_chk(api, pload->data, pload->len, &root)) {
 		return;
 	}
 
-	if (fb_json_node_chk_bool(root, "$.succeeded", &res) && !res) {
+	values = fb_json_values_new(root);
+	fb_json_values_add(values, FALSE, "$.succeeded");
+	fb_json_values_update(values, &err);
+
+	FB_API_ERROR_CHK(api, err,
+		fb_json_values_free(values);
+		json_node_free(root);
+		return;
+	);
+
+	if (!fb_json_values_next_bool(values, TRUE)) {
 		fb_api_error(api, FB_API_ERROR_GENERAL,
 		             _("Failed to mark thread as read"));
 	}
 
+	fb_json_values_free(values);
 	json_node_free(root);
 }
 
 static void
 fb_api_cb_publish_typing(FbApi *api, const GByteArray *pload)
 {
+	const gchar *str;
 	FbApiTyping typg;
-	gboolean res;
-	gchar *str;
+	FbJsonValues *values;
+	GError *err = NULL;
 	JsonNode *root;
 
 	if (!fb_api_json_chk(api, pload->data, pload->len, &root)) {
 		return;
 	}
 
-	if (fb_json_node_chk_str(root, "$.type", &str)) {
-		res = g_ascii_strcasecmp(str, "typ") == 0;
-		g_free(str);
+	values = fb_json_values_new(root);
+	fb_json_values_add(values, TRUE, "$.type");
+	fb_json_values_add(values, TRUE, "$.sender_fbid");
+	fb_json_values_add(values, TRUE, "$.state");
+	fb_json_values_update(values, &err);
 
-		if (!res) {
-			goto finish;
-		}
-	} else {
-		goto finish;
+	FB_API_ERROR_CHK(api, err,
+		fb_json_values_free(values);
+		json_node_free(root);
+		return;
+	);
+
+	str = fb_json_values_next_str(values, NULL);
+
+	if (g_ascii_strcasecmp(str, "typ") == 0) {
+		typg.uid = fb_json_values_next_int(values, 0);
+		typg.state = fb_json_values_next_int(values, 0);
+		g_signal_emit_by_name(api, "typing", &typg);
 	}
 
-	typg.uid = fb_json_node_get_int(root, "$.sender_fbid", NULL);
-	typg.state = fb_json_node_get_int(root, "$.state", NULL);
-
-	g_signal_emit_by_name(api, "typing", &typg);
-
-finish:
+	fb_json_values_free(values);
 	json_node_free(root);
 }
 
 static void
 fb_api_cb_publish_ms(FbApi *api, const GByteArray *pload)
 {
-	const gchar *strc;
+	const gchar *str;
 	FbApiMessage msg;
 	FbApiPrivate *priv = api->priv;
+	FbJsonValues *values;
 	FbThrift *thft;
-	gchar *str;
+	gchar *stoken;
 	GError *err = NULL;
-	GList *elms = NULL;
-	GList *l;
 	gpointer mptr;
 	GSList *msgs = NULL;
 	guint i;
-	JsonArray *arr = NULL;
-	JsonArray *arr2;
-	JsonNode *mode;
+	JsonArray *arr;
+	JsonNode *root;
 	JsonNode *node;
-	JsonNode *root;
 
 	thft = fb_thrift_new((GByteArray*) pload, 0, TRUE);
 	fb_thrift_read_str(thft, NULL);
@@ -780,70 +799,86 @@ fb_api_cb_publish_ms(FbApi *api, const G
 		return;
 	}
 
-	if (fb_json_node_chk_str(root, "$.syncToken", &str)) {
+	values = fb_json_values_new(root);
+	fb_json_values_add(values, FALSE, "$.lastIssuedSeqId");
+	fb_json_values_add(values, FALSE, "$.syncToken");
+	fb_json_values_update(values, &err);
+
+	FB_API_ERROR_CHK(api, err,
+		fb_json_values_free(values);
+		json_node_free(root);
+		return;
+	);
+
+	priv->sid = fb_json_values_next_int(values, 0);
+	stoken = fb_json_values_next_str_dup(values, NULL);
+	fb_json_values_free(values);
+
+	if (G_UNLIKELY(stoken != NULL)) {
 		g_free(priv->stoken);
-		priv->stoken = str;
+		priv->stoken = stoken;
 		g_signal_emit_by_name(api, "connect");
-		goto finish;
+		json_node_free(root);
+		return;
 	}
 
-	fb_json_node_chk_int(root, "$.lastIssuedSeqId", &priv->sid);
+	values = fb_json_values_new(root);
+	fb_json_values_add(values, FALSE, "$.deltaNewMessage.messageMetadata"
+	                                  ".actorFbId");
+	fb_json_values_add(values, FALSE, "$.deltaNewMessage.messageMetadata"
+	                                   ".threadKey.threadFbId");
+	fb_json_values_add(values, FALSE, "$.deltaNewMessage.body");
+	fb_json_values_set_array(values, "$.deltas", &err);
 
-	arr = fb_json_node_get_arr(root, "$.deltas", &err);
-	FB_API_ERROR_CHK(api, err, goto finish);
-	elms = json_array_get_elements(arr);
+	FB_API_ERROR_CHK(api, err,
+		fb_json_values_free(values);
+		json_node_free(root);
+		return;
+	);
 
-	for (l = elms; l != NULL; l = l->next) {
-		node = l->data;
-		fb_api_message_reset(&msg, FALSE);
-
-		if (!fb_json_node_chk(node, "$.deltaNewMessage", &node)) {
+	while (fb_json_values_update(values, NULL)) {
+		if (!fb_json_values_successful(values)) {
 			continue;
 		}
 
-		mode = fb_json_node_get(node, "$.messageMetadata", &err);
-		FB_API_ERROR_CHK(api, err, goto next);



More information about the Commits mailing list