[libgepub/wip/cosimoc/api-rework: 8/13] Rework API to be based on GBytes



commit b764421fcfccf315e0e880fe43490c118e2f0738
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Sat Jun 18 13:01:52 2016 -0700

    Rework API to be based on GBytes
    
    This is more convenient to use, and the format ultimately expected by
    the WebView widget.

 libgepub/gepub-archive.c |   27 ++++++------
 libgepub/gepub-archive.h |    6 +--
 libgepub/gepub-doc.c     |  105 +++++++++++++++++++++++-----------------------
 libgepub/gepub-doc.h     |   10 ++--
 libgepub/gepub-utils.c   |   13 ++++--
 libgepub/gepub-utils.h   |    2 +-
 libgepub/gepub-widget.c  |   16 +++----
 tests/test-gepub.c       |   39 ++++++++++-------
 8 files changed, 113 insertions(+), 105 deletions(-)
---
diff --git a/libgepub/gepub-archive.c b/libgepub/gepub-archive.c
index 20c9e80..ad246a4 100644
--- a/libgepub/gepub-archive.c
+++ b/libgepub/gepub-archive.c
@@ -128,17 +128,16 @@ gepub_archive_list_files (GepubArchive *archive)
     return file_list;
 }
 
-gboolean
+GBytes *
 gepub_archive_read_entry (GepubArchive *archive,
-                          const gchar *path,
-                          guchar **buffer,
-                          gsize *bufsize)
+                          const gchar *path)
 {
     struct archive_entry *entry;
+    guchar *buffer;
     gint size;
 
     if (!gepub_archive_open (archive))
-        return FALSE;
+        return NULL;
 
     while (archive_read_next_header (archive->archive, &entry) == ARCHIVE_OK) {
         if (g_ascii_strcasecmp (path, archive_entry_pathname (entry)) == 0)
@@ -146,13 +145,12 @@ gepub_archive_read_entry (GepubArchive *archive,
         archive_read_data_skip (archive->archive);
     }
 
-    *bufsize = archive_entry_size (entry);
-    size = *bufsize;
-    *buffer = g_malloc0 (*bufsize);
-    archive_read_data (archive->archive, *buffer, size);
+    size = archive_entry_size (entry);
+    buffer = g_malloc0 (size);
+    archive_read_data (archive->archive, buffer, size);
 
     gepub_archive_close (archive);
-    return TRUE;
+    return g_bytes_new_take (buffer, size);
 }
 
 gchar *
@@ -161,21 +159,24 @@ gepub_archive_get_root_file (GepubArchive *archive)
     xmlDoc *doc = NULL;
     xmlNode *root_element = NULL;
     xmlNode *root_node = NULL;
-    guchar *buffer;
+    GBytes *bytes;
+    const guchar *buffer;
     gsize bufsize;
     gchar *root_file = NULL;
 
     // root file is in META-INF/container.xml
-    if (!gepub_archive_read_entry (archive, "META-INF/container.xml", &buffer, &bufsize))
+    bytes = gepub_archive_read_entry (archive, "META-INF/container.xml");
+    if (!bytes)
         return NULL;
 
+    buffer = g_bytes_get_data (bytes, &bufsize);
     doc = xmlRecoverMemory (buffer, bufsize);
     root_element = xmlDocGetRootElement (doc);
     root_node = gepub_utils_get_element_by_tag (root_element, "rootfile");
     root_file = xmlGetProp (root_node, "full-path");
 
     xmlFreeDoc (doc);
-    g_free (buffer);
+    g_bytes_unref (bytes);
 
     return root_file;
 }
diff --git a/libgepub/gepub-archive.h b/libgepub/gepub-archive.h
index b707617..ee4ce9d 100644
--- a/libgepub/gepub-archive.h
+++ b/libgepub/gepub-archive.h
@@ -40,10 +40,8 @@ GType             gepub_archive_get_type       (void) G_GNUC_CONST;
 
 GepubArchive     *gepub_archive_new            (const gchar  *path);
 GList            *gepub_archive_list_files     (GepubArchive *archive);
-gboolean          gepub_archive_read_entry     (GepubArchive *archive,
-                                                const gchar *path,
-                                                guchar **buffer,
-                                                gsize *bufsize);
+GBytes           *gepub_archive_read_entry     (GepubArchive *archive,
+                                                const gchar *path);
 gchar            *gepub_archive_get_root_file  (GepubArchive *archive);
 
 G_END_DECLS
diff --git a/libgepub/gepub-doc.c b/libgepub/gepub-doc.c
index bdaef5a..55af87e 100644
--- a/libgepub/gepub-doc.c
+++ b/libgepub/gepub-doc.c
@@ -35,8 +35,7 @@ struct _GepubDoc {
     GObject parent;
 
     GepubArchive *archive;
-    guchar *content;
-    gsize content_len;
+    GBytes *content;
     gchar *content_base;
     gchar *path;
     GHashTable *resources;
@@ -72,8 +71,7 @@ gepub_doc_finalize (GObject *object)
     GepubDoc *doc = GEPUB_DOC (object);
 
     g_clear_object (&doc->archive);
-    g_clear_pointer (&doc->content, g_free);
-    g_clear_pointer (&doc->content_base, g_free);
+    g_clear_pointer (&doc->content, g_bytes_unref);
     g_clear_pointer (&doc->path, g_free);
     g_clear_pointer (&doc->resources, g_hash_table_destroy);
 
@@ -170,7 +168,8 @@ gepub_doc_initable_init (GInitable     *initable,
     file = gepub_archive_get_root_file (doc->archive);
     if (!file)
         return FALSE;
-    if (!gepub_archive_read_entry (doc->archive, file, &doc->content, &doc->content_len))
+    doc->content = gepub_archive_read_entry (doc->archive, file);
+    if (!doc->content)
         return FALSE;
 
     len = strlen (file);
@@ -221,8 +220,11 @@ gepub_doc_fill_resources (GepubDoc *doc)
     xmlNode *item = NULL;
     gchar *id, *tmpuri, *uri;
     GepubResource *res;
+    const char *data;
+    gsize size;
 
-    xdoc = xmlRecoverMemory (doc->content, doc->content_len);
+    data = g_bytes_get_data (doc->content, &size);
+    xdoc = xmlRecoverMemory (data, size);
     root_element = xmlDocGetRootElement (xdoc);
     mnode = gepub_utils_get_element_by_tag (root_element, "manifest");
 
@@ -256,8 +258,11 @@ gepub_doc_fill_spine (GepubDoc *doc)
     xmlNode *snode = NULL;
     xmlNode *item = NULL;
     gchar *id;
+    const char *data;
+    gsize size;
 
-    xdoc = xmlRecoverMemory (doc->content, doc->content_len);
+    data = g_bytes_get_data (doc->content, &size);
+    xdoc = xmlRecoverMemory (data, size);
     root_element = xmlDocGetRootElement (xdoc);
     snode = gepub_utils_get_element_by_tag (root_element, "spine");
 
@@ -283,7 +288,7 @@ gepub_doc_fill_spine (GepubDoc *doc)
  *
  * Returns: (transfer none): the document content
  */
-gchar *
+GBytes *
 gepub_doc_get_content (GepubDoc *doc)
 {
     return doc->content;
@@ -305,8 +310,11 @@ gepub_doc_get_metadata (GepubDoc *doc, gchar *mdata)
     xmlNode *mdata_node = NULL;
     gchar *ret;
     xmlChar *text;
+    const char *data;
+    gsize size;
 
-    xdoc = xmlRecoverMemory (doc->content, doc->content_len);
+    data = g_bytes_get_data (doc->content, &size);
+    xdoc = xmlRecoverMemory (data, size);
     root_element = xmlDocGetRootElement (xdoc);
     mnode = gepub_utils_get_element_by_tag (root_element, "metadata");
     mdata_node = gepub_utils_get_element_by_tag (mnode, mdata);
@@ -336,43 +344,32 @@ gepub_doc_get_resources (GepubDoc *doc)
  * gepub_doc_get_resource_by_id:
  * @doc: a #GepubDoc
  * @id: the resource id
- * @bufsize: (out): location to store the length in bytes of the contents
  *
- * Returns: (array length=bufsize) (transfer full): the resource content
+ * Returns: (transfer full): the resource content
  */
-guchar *
-gepub_doc_get_resource_by_id (GepubDoc *doc, gchar *id, gsize *bufsize)
+GBytes *
+gepub_doc_get_resource_by_id (GepubDoc *doc, gchar *id)
 {
-    guchar *res = NULL;
     GepubResource *gres = g_hash_table_lookup (doc->resources, id);
     if (!gres) {
         // not found
         return NULL;
     }
-    if (!gepub_archive_read_entry (doc->archive, gres->uri, &res, bufsize))
-        return NULL;
 
-    return res;
+    return gepub_archive_read_entry (doc->archive, gres->uri);
 }
 
 /**
  * gepub_doc_get_resource:
  * @doc: a #GepubDoc
  * @path: the resource path
- * @bufsize: (out): location to store length in bytes of the contents
  *
- * Returns: (array length=bufsize) (transfer full): the resource content
+ * Returns: (transfer full): the resource content
  */
-guchar *
-gepub_doc_get_resource (GepubDoc *doc, gchar *path, gsize *bufsize)
+GBytes *
+gepub_doc_get_resource (GepubDoc *doc, gchar *path)
 {
-    guchar *res = NULL;
-
-    if (!gepub_archive_read_entry (doc->archive, path, &res, bufsize)) {
-        return NULL;
-    }
-
-    return res;
+    return gepub_archive_read_entry (doc->archive, path);
 }
 
 /**
@@ -451,38 +448,35 @@ gepub_doc_get_spine (GepubDoc *doc)
 /**
  * gepub_doc_get_current:
  * @doc: a #GepubDoc
- * @bufsize: (out): location to store the length in bytes of the contents
  *
- * Returns: (array length=bufsize) (transfer full): the current chapter data
+ * Returns: (transfer full): the current chapter data
  */
-guchar *
-gepub_doc_get_current (GepubDoc *doc, gsize *bufsize)
+GBytes *
+gepub_doc_get_current (GepubDoc *doc)
 {
-    return gepub_doc_get_resource_by_id (doc, doc->spine->data, bufsize);
+    return gepub_doc_get_resource_by_id (doc, doc->spine->data);
 }
 
 /**
  * gepub_doc_get_current_with_epub_uris:
  * @doc: a #GepubDoc
- * @bufsize: (out): location to store the length in bytes of the contents
  *
- * Returns: (array length=bufsize) (transfer full): the current chapter
+ * Returns: (transfer full): the current chapter
  * data, with resource uris renamed so they have the epub:// prefix and all
  * are relative to the root file
  */
-guchar *
-gepub_doc_get_current_with_epub_uris (GepubDoc *doc, gsize *bufsize)
+GBytes *
+gepub_doc_get_current_with_epub_uris (GepubDoc *doc)
 {
-    guchar *content = gepub_doc_get_current (doc, bufsize);
-    guchar *replaced = NULL;
+    GBytes *content = gepub_doc_get_current (doc);
     gchar *path = gepub_doc_get_current_path (doc);
     // getting the basepath of the current xhtml loaded
     gchar *base = g_path_get_dirname (path);
 
-    replaced = gepub_utils_replace_resources (content, bufsize, base);
+    GBytes *replaced = gepub_utils_replace_resources (content, base);
 
     g_free (path);
-    g_free (content);
+    g_bytes_unref (content);
 
     return replaced;
 }
@@ -498,20 +492,22 @@ gepub_doc_get_text (GepubDoc *doc)
 {
     xmlDoc *xdoc = NULL;
     xmlNode *root_element = NULL;
-    guchar *res = NULL;
-    gsize size = 0;
+    GBytes *current;
+    const guchar *data;
+    gsize size;
 
     GList *texts = NULL;
 
-    res = gepub_doc_get_current (doc, &size);
-    if (!res) {
+    current = gepub_doc_get_current (doc);
+    if (!current) {
         return NULL;
     }
-    xdoc = htmlReadMemory (res, size, "", NULL, HTML_PARSE_NOWARNING | HTML_PARSE_NOERROR);
+    data = g_bytes_get_data (current, &size);
+    xdoc = htmlReadMemory (data, size, "", NULL, HTML_PARSE_NOWARNING | HTML_PARSE_NOERROR);
     root_element = xmlDocGetRootElement (xdoc);
     texts = gepub_utils_get_text_elements (root_element);
 
-    g_free (res);
+    g_bytes_unref (current);
     xmlFreeDoc (xdoc);
 
     return texts;
@@ -529,21 +525,23 @@ gepub_doc_get_text_by_id (GepubDoc *doc, gchar *id)
 {
     xmlDoc *xdoc = NULL;
     xmlNode *root_element = NULL;
-    gsize size = 0;
-    guchar *res = NULL;
+    gsize size;
+    const guchar *res;
+    GBytes *contents;
 
     GList *texts = NULL;
 
-    res = gepub_doc_get_resource_by_id (doc, id, &size);
+    contents = gepub_doc_get_resource_by_id (doc, id);
     if (!res) {
         return NULL;
     }
 
+    res = g_bytes_get_data (contents, &size);
     xdoc = htmlReadMemory (res, size, "", NULL, HTML_PARSE_NOWARNING | HTML_PARSE_NOERROR);
     root_element = xmlDocGetRootElement (xdoc);
     texts = gepub_utils_get_text_elements (root_element);
 
-    g_free (res);
+    g_bytes_unref (contents);
     xmlFreeDoc (xdoc);
 
     return texts;
@@ -595,8 +593,11 @@ gepub_doc_get_cover (GepubDoc *doc)
     xmlNode *mnode = NULL;
     gchar *ret;
     xmlChar *text;
+    const char *data;
+    gsize size;
 
-    xdoc = xmlRecoverMemory (doc->content, doc->content_len);
+    data = g_bytes_get_data (doc->content, &size);
+    xdoc = xmlRecoverMemory (data, size);
     root_element = xmlDocGetRootElement (xdoc);
     mnode = gepub_utils_get_element_by_attr (root_element, "name", "cover");
     text = xmlGetProp(mnode, "content");
diff --git a/libgepub/gepub-doc.h b/libgepub/gepub-doc.h
index b28afd4..304ec91 100644
--- a/libgepub/gepub-doc.h
+++ b/libgepub/gepub-doc.h
@@ -45,10 +45,10 @@ typedef struct _GepubResource GepubResource;
 GType             gepub_doc_get_type                        (void) G_GNUC_CONST;
 
 GepubDoc         *gepub_doc_new                             (const gchar *path);
-gchar            *gepub_doc_get_content                     (GepubDoc *doc);
+GBytes           *gepub_doc_get_content                     (GepubDoc *doc);
 gchar            *gepub_doc_get_metadata                    (GepubDoc *doc, gchar *mdata);
-guchar           *gepub_doc_get_resource                    (GepubDoc *doc, gchar *path, gsize *bufsize);
-guchar           *gepub_doc_get_resource_by_id              (GepubDoc *doc, gchar *id, gsize *bufsize);
+GBytes           *gepub_doc_get_resource                    (GepubDoc *doc, gchar *path);
+GBytes           *gepub_doc_get_resource_by_id              (GepubDoc *doc, gchar *id);
 GHashTable       *gepub_doc_get_resources                   (GepubDoc *doc);
 gchar            *gepub_doc_get_resource_mime               (GepubDoc *doc, gchar *path);
 gchar            *gepub_doc_get_resource_mime_by_id         (GepubDoc *doc, gchar *id);
@@ -56,8 +56,8 @@ gchar            *gepub_doc_get_current_mime                (GepubDoc *doc);
 GList            *gepub_doc_get_spine                       (GepubDoc *doc);
 GList            *gepub_doc_get_text                        (GepubDoc *doc);
 GList            *gepub_doc_get_text_by_id                  (GepubDoc *doc, gchar *id);
-guchar           *gepub_doc_get_current                     (GepubDoc *doc, gsize *bufsize);
-guchar           *gepub_doc_get_current_with_epub_uris      (GepubDoc *doc, gsize *bufsize);
+GBytes           *gepub_doc_get_current                     (GepubDoc *doc);
+GBytes           *gepub_doc_get_current_with_epub_uris      (GepubDoc *doc);
 gboolean          gepub_doc_go_next                         (GepubDoc *doc);
 gboolean          gepub_doc_go_prev                         (GepubDoc *doc);
 gchar            *gepub_doc_get_cover                       (GepubDoc *doc);
diff --git a/libgepub/gepub-utils.c b/libgepub/gepub-utils.c
index a0c23b6..f907e05 100644
--- a/libgepub/gepub-utils.c
+++ b/libgepub/gepub-utils.c
@@ -220,14 +220,17 @@ gepub_utils_get_text_elements (xmlNode *node)
 /* Replacing epub media paths, for css, image and svg files, to be
  * able to provide these files to webkit from the epub file
  */
-guchar *
-gepub_utils_replace_resources (guchar *content, gsize *bufsize, gchar *path)
+GBytes *
+gepub_utils_replace_resources (GBytes *content, gchar *path)
 {
     xmlDoc *doc = NULL;
     xmlNode *root_element = NULL;
     guchar *buffer;
+    const guchar *data;
+    gsize bufsize;
 
-    doc = xmlRecoverMemory (content, *bufsize);
+    data = g_bytes_get_data (content, &bufsize);
+    doc = xmlRecoverMemory (data, bufsize);
     root_element = xmlDocGetRootElement (doc);
 
     // replacing css resources
@@ -239,8 +242,8 @@ gepub_utils_replace_resources (guchar *content, gsize *bufsize, gchar *path)
     // replacing crosslinks
     set_epub_uri (root_element, path, "a", "href");
 
-    xmlDocDumpFormatMemory (doc, (xmlChar**)&buffer, (int*)bufsize, 1);
+    xmlDocDumpFormatMemory (doc, (xmlChar**)&buffer, (int*)&bufsize, 1);
     xmlFreeDoc (doc);
 
-    return buffer;
+    return g_bytes_new_take (buffer, bufsize);
 }
diff --git a/libgepub/gepub-utils.h b/libgepub/gepub-utils.h
index 1d51607..4fc548b 100644
--- a/libgepub/gepub-utils.h
+++ b/libgepub/gepub-utils.h
@@ -25,6 +25,6 @@
 xmlNode * gepub_utils_get_element_by_tag  (xmlNode *node, gchar *name);
 xmlNode * gepub_utils_get_element_by_attr (xmlNode *node, gchar *attr, gchar *value);
 GList *   gepub_utils_get_text_elements   (xmlNode *node);
-guchar *  gepub_utils_replace_resources   (guchar *content, gsize *bufsize, gchar *path);
+GBytes *  gepub_utils_replace_resources   (GBytes *content, gchar *path);
 
 #endif
diff --git a/libgepub/gepub-widget.c b/libgepub/gepub-widget.c
index bba8a62..9a3dfaa 100644
--- a/libgepub/gepub-widget.c
+++ b/libgepub/gepub-widget.c
@@ -46,12 +46,11 @@ static void
 resource_callback (WebKitURISchemeRequest *request, gpointer user_data)
 {
     GInputStream *stream;
-    gsize stream_length;
     gchar *path;
     gchar *uri;
-    guchar *contents;
     gchar *mime;
     GepubWidget *widget = user_data;
+    GBytes *contents;
 
     if (!widget->doc)
       return;
@@ -59,7 +58,7 @@ resource_callback (WebKitURISchemeRequest *request, gpointer user_data)
     uri = g_strdup (webkit_uri_scheme_request_get_uri (request));
     // removing "epub://"
     path = uri + 7;
-    contents = gepub_doc_get_resource (widget->doc, path, &stream_length);
+    contents = gepub_doc_get_resource (widget->doc, path);
     mime = gepub_doc_get_resource_mime (widget->doc, path);
 
     if (!mime) {
@@ -67,10 +66,11 @@ resource_callback (WebKitURISchemeRequest *request, gpointer user_data)
         return;
     }
 
-    stream = g_memory_input_stream_new_from_data (contents, stream_length, g_free);
-    webkit_uri_scheme_request_finish (request, stream, stream_length, mime);
+    stream = g_memory_input_stream_new_from_bytes (contents);
+    webkit_uri_scheme_request_finish (request, stream, g_bytes_get_size (contents), mime);
 
     g_object_unref (stream);
+    g_bytes_unref (contents);
     g_free (mime);
     g_free (uri);
 }
@@ -209,16 +209,12 @@ gepub_widget_set_doc (GepubWidget *widget,
 void
 gepub_widget_reload (GepubWidget *widget)
 {
-    gsize bufsize = 0;
-    guchar *buffer = NULL;
     GBytes *current;
 
     if (!widget->doc)
       return;
 
-    buffer = gepub_doc_get_current_with_epub_uris (widget->doc, &bufsize);
-    current = g_bytes_new_take (buffer, bufsize);
-
+    current = gepub_doc_get_current_with_epub_uris (widget->doc);
     webkit_web_view_load_bytes (WEBKIT_WEB_VIEW (widget),
                                 current,
                                 gepub_doc_get_current_mime (widget->doc),
diff --git a/tests/test-gepub.c b/tests/test-gepub.c
index be893a0..2e64767 100644
--- a/tests/test-gepub.c
+++ b/tests/test-gepub.c
@@ -55,12 +55,14 @@ update_text (GepubDoc *doc)
 void
 print_replaced_text (GepubDoc *doc)
 {
-    gsize s = 0;
-    guchar *content = NULL;
-    content = gepub_doc_get_current_with_epub_uris (doc, &s);
-
-    printf ("\n\nREPLACED:\n%s\n", content);
-    g_free (content);
+    GBytes *content;
+    gsize s;
+    const guchar *data;
+    content = gepub_doc_get_current_with_epub_uris (doc);
+
+    data = g_bytes_get_data (content, &s);
+    printf ("\n\nREPLACED:\n%s\n", data);
+    g_bytes_unref (content);
 }
 
 void
@@ -121,9 +123,10 @@ test_read (const char *path)
 {
     GepubArchive *a;
     GList *list_files = NULL;
-    guchar *buffer;
+    const guchar *buffer;
     guchar *file = NULL;
     gsize bufsize;
+    GBytes *bytes;
 
     a = gepub_archive_new (path);
 
@@ -131,11 +134,15 @@ test_read (const char *path)
     GHashTable *ht = (GHashTable*)gepub_doc_get_resources (doc);
     g_hash_table_foreach (ht, (GHFunc)find_xhtml, &file);
 
-    gepub_archive_read_entry (a, file, &buffer, &bufsize);
-    if (bufsize)
-        PTEST ("doc:%s\n----\n%s\n-----\n", file, buffer);
+    bytes = gepub_archive_read_entry (a, file);
+    if (bytes) {
+        const char *data;
+        gsize size;
 
-    g_free (buffer);
+        buffer = g_bytes_get_data (bytes, &bufsize);
+        PTEST ("doc:%s\n----\n%s\n-----\n", file, buffer);
+        g_bytes_unref (bytes);
+    }
 
     g_list_foreach (list_files, (GFunc)g_free, NULL);
     g_list_free (list_files);
@@ -200,12 +207,14 @@ test_doc_resources (const char *path)
     GepubDoc *doc = gepub_doc_new (path);
     GHashTable *ht = (GHashTable*)gepub_doc_get_resources (doc);
     g_hash_table_foreach (ht, (GHFunc)pk, NULL);
-    guchar *ncx;
+    GBytes *ncx;
+    const guchar *data;
     gsize size;
 
-    ncx = gepub_doc_get_resource_by_id (doc, "ncx", &size);
-    PTEST ("ncx:\n%s\n", ncx);
-    g_free (ncx);
+    ncx = gepub_doc_get_resource_by_id (doc, "ncx");
+    data = g_bytes_get_data (ncx, &size);
+    PTEST ("ncx:\n%s\n", data);
+    g_bytes_unref (ncx);
 
     g_object_unref (G_OBJECT (doc));
 }


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