From 3c095487e3a6c14f2900762c18c6e2170d22a283 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C4=90o=C3=A0n=20Tr=E1=BA=A7n=20C=C3=B4ng=20Danh?=
 <congdanhqx@gmail.com>
Date: Fri, 1 Mar 2024 21:56:34 +0700
Subject: [PATCH 2/5] parsers: Generalise input to array of gchar

In a later change, we will move to libsoup-3.0, which doesn't expose
`response_body' in SoupMessage.

Prepare for that move.

Upstream-Status: Backport [https://github.com/xfce-mirror/xfce4-weather-plugin/commit/3c095487e3a6c14f2900762c18c6e2170d22a283]
Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
 panel-plugin/weather-config.c  | 18 +++++++++++++++--
 panel-plugin/weather-parsers.c | 36 ++++++++++++++++++----------------
 panel-plugin/weather-parsers.h |  7 +++----
 panel-plugin/weather-search.c  | 18 +++++++++++++++--
 panel-plugin/weather.c         | 26 ++++++++++++++++++++----
 5 files changed, 76 insertions(+), 29 deletions(-)

diff --git a/panel-plugin/weather-config.c b/panel-plugin/weather-config.c
index 2645408..19fa1d8 100644
--- a/panel-plugin/weather-config.c
+++ b/panel-plugin/weather-config.c
@@ -245,6 +245,13 @@ cb_lookup_altitude(SoupSession *session,
     xfceweather_dialog *dialog = (xfceweather_dialog *) user_data;
     xml_altitude *altitude;
     gdouble alt = 0;
+    const gchar *body = NULL;
+    gsize len = 0;
+
+    if (G_LIKELY(msg->response_body && msg->response_body->data)) {
+        body = msg->response_body->data;
+        len = msg->response_body->length;
+    }
 
     if (global_dialog == NULL) {
         weather_debug("%s called after dialog was destroyed", G_STRFUNC);
@@ -252,7 +259,7 @@ cb_lookup_altitude(SoupSession *session,
     }
 
     altitude = (xml_altitude *)
-        parse_xml_document(msg, (XmlParseFunc) parse_altitude);
+        parse_xml_document(body, len, (XmlParseFunc) parse_altitude);
 
     if (altitude) {
         alt = string_to_double(altitude->altitude, -9999);
@@ -274,6 +281,13 @@ cb_lookup_timezone(SoupSession *session,
 {
     xfceweather_dialog *dialog = (xfceweather_dialog *) user_data;
     xml_timezone *xml_tz;
+    const gchar *body = NULL;
+    gsize len = 0;
+
+    if (G_LIKELY(msg->response_body && msg->response_body->data)) {
+        body = msg->response_body->data;
+        len = msg->response_body->length;
+    }
 
     if (global_dialog == NULL) {
         weather_debug("%s called after dialog was destroyed", G_STRFUNC);
@@ -281,7 +295,7 @@ cb_lookup_timezone(SoupSession *session,
     }
 
     xml_tz = (xml_timezone *)
-        parse_xml_document(msg, (XmlParseFunc) parse_timezone);
+        parse_xml_document(body, len, (XmlParseFunc) parse_timezone);
     weather_dump(weather_dump_timezone, xml_tz);
 
     if (xml_tz) {
diff --git a/panel-plugin/weather-parsers.c b/panel-plugin/weather-parsers.c
index d53a2bc..28934c4 100644
--- a/panel-plugin/weather-parsers.c
+++ b/panel-plugin/weather-parsers.c
@@ -791,49 +791,51 @@ parse_timezone(xmlNode *cur_node)
 
 
 xmlDoc *
-get_xml_document(SoupMessage *msg)
+get_xml_document(const gchar *data, gsize len)
 {
-    if (G_LIKELY(msg && msg->response_body && msg->response_body->data)) {
-        if (g_utf8_validate(msg->response_body->data, -1, NULL)) {
+    if (G_LIKELY(data && len)) {
+        if (g_utf8_validate(data, len, NULL)) {
             /* force parsing as UTF-8, the XML encoding header may lie */
-            return xmlReadMemory(msg->response_body->data,
-                                 strlen(msg->response_body->data),
+            return xmlReadMemory(data, len,
                                  NULL, "UTF-8", 0);
         } else {
-            return xmlParseMemory(msg->response_body->data,
-                                  strlen(msg->response_body->data));
+            return xmlParseMemory(data, len);
         }
     }
     return NULL;
 }
 
 json_object *
-get_json_tree(SoupMessage *msg)
+get_json_tree(const gchar *data, gsize len)
 {
     json_object *res=NULL;
-    enum json_tokener_error err;
+    struct json_tokener *tok = json_tokener_new();
 
-    if (G_LIKELY(msg && msg->response_body && msg->response_body->data)) {
-        res =  json_tokener_parse_verbose(msg->response_body->data, &err);
-        if (err != json_tokener_success)
-            g_warning("get_json_tree: error =%d",err);
+    if (G_UNLIKELY(tok == NULL)) {
+        return NULL;
+    } else if (G_LIKELY(data && len)) {
+        res =  json_tokener_parse_ex(tok, data, len);
+        if (res == NULL)
+            g_warning("get_json_tree: error =%d",
+                      json_tokener_get_error(tok));
     }
+    json_tokener_free(tok);
     return res;
 }
 
 gpointer
-parse_xml_document(SoupMessage *msg,
+parse_xml_document(const gchar *data, gsize len,
                    XmlParseFunc parse_func)
 {
     xmlDoc *doc;
     xmlNode *root_node;
     gpointer user_data = NULL;
 
-    g_assert(msg != NULL);
-    if (G_UNLIKELY(msg == NULL))
+    g_assert(data != NULL);
+    if (G_UNLIKELY(data == NULL || len == 0))
         return NULL;
 
-    doc = get_xml_document(msg);
+    doc = get_xml_document(data, len);
     if (G_LIKELY(doc)) {
         root_node = xmlDocGetRootElement(doc);
         if (G_LIKELY(root_node))
diff --git a/panel-plugin/weather-parsers.h b/panel-plugin/weather-parsers.h
index a9d019d..09b9c02 100644
--- a/panel-plugin/weather-parsers.h
+++ b/panel-plugin/weather-parsers.h
@@ -22,7 +22,6 @@
 #include <glib.h>
 #include <gtk/gtk.h>
 #include <libxml/parser.h>
-#include <libsoup/soup.h>
 #include <json-c/json_tokener.h>
 
 #define DATA_EXPIRY_TIME (24 * 3600)
@@ -157,11 +156,11 @@ xml_astro *get_astro(const GArray *astrodata,
                      const time_t day_t,
                      guint *index);
 
-xmlDoc *get_xml_document(SoupMessage *msg);
+xmlDoc *get_xml_document(const gchar *data, gsize len);
 
-json_object *get_json_tree(SoupMessage *msg);
+json_object *get_json_tree(const gchar *data, gsize len);
 
-gpointer parse_xml_document(SoupMessage *msg,
+gpointer parse_xml_document(const gchar *data, gsize len,
                             XmlParseFunc parse_func);
 
 xml_astro *xml_astro_copy(const xml_astro *src);
diff --git a/panel-plugin/weather-search.c b/panel-plugin/weather-search.c
index 7e87ae8..6a2ba1f 100644
--- a/panel-plugin/weather-search.c
+++ b/panel-plugin/weather-search.c
@@ -89,6 +89,13 @@ cb_searchdone(SoupSession *session,
     gint found = 0;
     GtkTreeIter iter;
     GtkTreeSelection *selection;
+    const gchar *body = NULL;
+    gsize len = 0;
+
+    if (G_LIKELY(msg->response_body && msg->response_body->data)) {
+        body = msg->response_body->data;
+        len = msg->response_body->length;
+    }
 
     if (global_dialog == NULL) {
         weather_debug("%s called after dialog was destroyed", G_STRFUNC);
@@ -97,7 +104,7 @@ cb_searchdone(SoupSession *session,
 
     gtk_widget_set_sensitive(dialog->find_button, TRUE);
 
-    doc = get_xml_document(msg);
+    doc = get_xml_document(body, len);
     if (!doc)
         return;
 
@@ -385,6 +392,13 @@ cb_geolocation(SoupSession *session,
     xml_geolocation *geo;
     gchar *full_loc;
     units_config *units;
+    const gchar *body = NULL;
+    gsize len = 0;
+
+    if (G_LIKELY(msg->response_body && msg->response_body->data)) {
+        body = msg->response_body->data;
+        len = msg->response_body->length;
+    }
 
     if (global_dialog == NULL) {
         weather_debug("%s called after dialog was destroyed", G_STRFUNC);
@@ -392,7 +406,7 @@ cb_geolocation(SoupSession *session,
     }
 
     geo = (xml_geolocation *)
-        parse_xml_document(msg, (XmlParseFunc) parse_geolocation);
+        parse_xml_document(body, len, (XmlParseFunc) parse_geolocation);
     weather_dump(weather_dump_geolocation, geo);
 
     if (!geo) {
diff --git a/panel-plugin/weather.c b/panel-plugin/weather.c
index 0a92b4e..b75c633 100644
--- a/panel-plugin/weather.c
+++ b/panel-plugin/weather.c
@@ -489,11 +489,17 @@ cb_astro_update_sun(SoupSession *session,
     json_object *json_tree;
     time_t now_t;
     guint astro_forecast_days;
+    const gchar *body = NULL;
+    gsize len = 0;
 
     data->msg_parse->sun_msg_processed++;
     data->astro_update->http_status_code = msg->status_code;
     if ((msg->status_code == 200 || msg->status_code == 203)) {
-        json_tree = get_json_tree(msg);
+        if (G_LIKELY(msg->response_body && msg->response_body->data)) {
+            body = msg->response_body->data;
+            len = msg->response_body->length;
+        }
+        json_tree = get_json_tree(body, len);
         if (G_LIKELY(json_tree)) {
             if (!parse_astrodata_sun(json_tree, data->astrodata))  {
                 data->msg_parse->sun_msg_parse_error++;
@@ -545,11 +551,17 @@ cb_astro_update_moon(SoupSession *session,
     json_object *json_tree;
     time_t now_t;
     guint astro_forecast_days;
+    const gchar *body = NULL;
+    gsize len = 0;
 
     data->msg_parse->moon_msg_processed++;
     data->astro_update->http_status_code = msg->status_code;
     if ((msg->status_code == 200 || msg->status_code == 203)) {
-        json_tree = get_json_tree(msg);
+        if (G_LIKELY(msg->response_body && msg->response_body->data)) {
+            body = msg->response_body->data;
+            len = msg->response_body->length;
+        }
+        json_tree = get_json_tree(body, len);
         if (G_LIKELY(json_tree)) {
             if (!parse_astrodata_moon(json_tree, data->astrodata))  {
                 data->msg_parse->moon_msg_parse_error++;
@@ -606,17 +618,23 @@ cb_weather_update(SoupSession *session,
                   gpointer user_data)
 {
     plugin_data *data = user_data;
-    xmlDoc *doc;
+    xmlDoc *doc = NULL;
     xmlNode *root_node;
     time_t now_t;
     gboolean parsing_error = TRUE;
+    const gchar *body = NULL;
+    gsize len = 0;
 
     weather_debug("Processing downloaded weather data.");
     time(&now_t);
     data->weather_update->attempt++;
     data->weather_update->http_status_code = msg->status_code;
     if (msg->status_code == 200 || msg->status_code == 203) {
-        doc = get_xml_document(msg);
+        if (G_LIKELY(msg->response_body && msg->response_body->data)) {
+            body = msg->response_body->data;
+            len = msg->response_body->length;
+        }
+        doc = get_xml_document(body, len);
         if (G_LIKELY(doc)) {
             root_node = xmlDocGetRootElement(doc);
             if (G_LIKELY(root_node))
