[libgdata] core: Add JSON support to GDataUploadStream



commit d8a40c6e4172ba26f57e65041667b5266f88fed1
Author: Philip Withnall <philip tecnocode co uk>
Date:   Sun Apr 19 18:34:16 2015 +0100

    core: Add JSON support to GDataUploadStream
    
    Add support for JSON to the non-resumable and resumable code paths, so
    that GDataEntrys which specify application/json as their content type
    have JSON generated and uploaded, rather than XML.
    
    This will be useful for the upcoming port to v3 of the YouTube API.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=687597

 gdata/gdata-upload-stream.c |   79 +++++++++++++++++++++++++++++++++----------
 1 files changed, 61 insertions(+), 18 deletions(-)
---
diff --git a/gdata/gdata-upload-stream.c b/gdata/gdata-upload-stream.c
index 87d8a31..0fe054e 100644
--- a/gdata/gdata-upload-stream.c
+++ b/gdata/gdata-upload-stream.c
@@ -427,7 +427,7 @@ static GObject *
 gdata_upload_stream_constructor (GType type, guint n_construct_params, GObjectConstructParam 
*construct_params)
 {
        GDataUploadStreamPrivate *priv;
-       GDataServiceClass *klass;
+       GDataServiceClass *service_klass;
        GObject *object;
 
        /* Chain up to the parent class */
@@ -451,22 +451,47 @@ gdata_upload_stream_constructor (GType type, guint n_construct_params, GObjectCo
                /* The Content-Type should be multipart/related if we're also uploading the metadata (entry 
!= NULL),
                 * and the given content_type otherwise. */
                if (priv->entry != NULL) {
-                       const gchar *first_part_header;
-                       gchar *entry_xml, *second_part_header;
+                       gchar *first_part_header, *upload_data;
+                       gchar *second_part_header;
+                       GDataParsableClass *parsable_klass;
+
+                       parsable_klass = GDATA_PARSABLE_GET_CLASS (priv->entry);
+                       g_assert (parsable_klass->get_content_type != NULL);
 
                        soup_message_headers_set_content_type (priv->message->request_headers, 
"multipart/related; boundary=" BOUNDARY_STRING, NULL);
 
+                       if (g_strcmp0 (parsable_klass->get_content_type (), "application/json") == 0) {
+                               upload_data = gdata_parsable_get_json (GDATA_PARSABLE (priv->entry));
+                       } else {
+                               upload_data = gdata_parsable_get_xml (GDATA_PARSABLE (priv->entry));
+                       }
+
                        /* Start by writing out the entry; then the thread has something to write to the 
network when it's created */
-                       first_part_header = "--" BOUNDARY_STRING "\nContent-Type: application/atom+xml; 
charset=UTF-8\n\n";
-                       entry_xml = gdata_parsable_get_xml (GDATA_PARSABLE (priv->entry));
-                       second_part_header = g_strdup_printf ("\n--" BOUNDARY_STRING "\nContent-Type: 
%s\nContent-Transfer-Encoding: binary\n\n",
+                       first_part_header = g_strdup_printf ("--" BOUNDARY_STRING "\n"
+                                                            "Content-Type: %s; charset=UTF-8\n\n",
+                                                            parsable_klass->get_content_type ());
+                       second_part_header = g_strdup_printf ("\n--" BOUNDARY_STRING "\n"
+                                                             "Content-Type: %s\n"
+                                                             "Content-Transfer-Encoding: binary\n\n",
                                                              priv->content_type);
 
                        /* Push the message parts onto the message body; we can skip the buffer, since the 
network thread hasn't yet been created,
                         * so we're the sole thread accessing the SoupMessage. */
-                       soup_message_body_append (priv->message->request_body, SOUP_MEMORY_STATIC, 
first_part_header, strlen (first_part_header));
-                       soup_message_body_append (priv->message->request_body, SOUP_MEMORY_TAKE, entry_xml, 
strlen (entry_xml));
-                       soup_message_body_append (priv->message->request_body, SOUP_MEMORY_TAKE, 
second_part_header, strlen (second_part_header));
+                       soup_message_body_append (priv->message->request_body,
+                                                 SOUP_MEMORY_TAKE,
+                                                 first_part_header,
+                                                 strlen (first_part_header));
+                       soup_message_body_append (priv->message->request_body,
+                                                 SOUP_MEMORY_TAKE, upload_data,
+                                                 strlen (upload_data));
+                       soup_message_body_append (priv->message->request_body,
+                                                 SOUP_MEMORY_TAKE,
+                                                 second_part_header,
+                                                 strlen (second_part_header));
+
+                       first_part_header = NULL;
+                       upload_data = NULL;
+                       second_part_header = NULL;
 
                        priv->network_bytes_outstanding = priv->message->request_body->length;
                } else {
@@ -487,12 +512,30 @@ gdata_upload_stream_constructor (GType type, guint n_construct_params, GObjectCo
                g_free (content_length_str);
 
                if (priv->entry != NULL) {
-                       const gchar *entry_xml;
-
-                       soup_message_headers_set_content_type (priv->message->request_headers, 
"application/atom+xml; charset=UTF-8", NULL);
-
-                       entry_xml = gdata_parsable_get_xml (GDATA_PARSABLE (priv->entry));
-                       soup_message_body_append (priv->message->request_body, SOUP_MEMORY_TAKE, entry_xml, 
strlen (entry_xml));
+                       GDataParsableClass *parsable_klass;
+                       gchar *content_type, *upload_data;
+
+                       parsable_klass = GDATA_PARSABLE_GET_CLASS (priv->entry);
+                       g_assert (parsable_klass->get_content_type != NULL);
+
+                       if (g_strcmp0 (parsable_klass->get_content_type (), "application/json") == 0) {
+                               upload_data = gdata_parsable_get_json (GDATA_PARSABLE (priv->entry));
+                       } else {
+                               upload_data = gdata_parsable_get_xml (GDATA_PARSABLE (priv->entry));
+                       }
+
+                       content_type = g_strdup_printf ("%s; charset=UTF-8",
+                                                       parsable_klass->get_content_type ());
+                       soup_message_headers_set_content_type (priv->message->request_headers,
+                                                              content_type,
+                                                              NULL);
+                       g_free (content_type);
+
+                       soup_message_body_append (priv->message->request_body,
+                                                 SOUP_MEMORY_TAKE,
+                                                 upload_data,
+                                                 strlen (upload_data));
+                       upload_data = NULL;
 
                        priv->network_bytes_outstanding = priv->message->request_body->length;
                } else {
@@ -506,9 +549,9 @@ gdata_upload_stream_constructor (GType type, guint n_construct_params, GObjectCo
 
        /* Make sure the headers are set. HACK: This should actually be in build_message(), but we have to 
work around
         * http://code.google.com/a/google.com/p/apps-api-issues/issues/detail?id=3033 in 
GDataDocumentsService's append_query_headers(). */
-       klass = GDATA_SERVICE_GET_CLASS (priv->service);
-       if (klass->append_query_headers != NULL) {
-               klass->append_query_headers (priv->service, priv->authorization_domain, priv->message);
+       service_klass = GDATA_SERVICE_GET_CLASS (priv->service);
+       if (service_klass->append_query_headers != NULL) {
+               service_klass->append_query_headers (priv->service, priv->authorization_domain, 
priv->message);
        }
 
        /* If the entry exists and has an ETag, we assume we're updating the entry, so we can set the 
If-Match header */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]