[libgepub/rust] Using rust epub lib instead C code



commit 2461ac86dc90f29fb787655747a1f8908983567d
Author: Daniel GarcĂ­a Moreno <danigm wadobo com>
Date:   Mon Feb 13 18:21:37 2017 +0100

    Using rust epub lib instead C code

 .gitignore                  |    3 +
 configure.ac                |   30 +++-
 libgepub/Makefile.am        |   36 +++-
 libgepub/gepub-archive.c    |  182 -------------------
 libgepub/gepub-archive.h    |   49 -----
 libgepub/gepub-doc.c        |  416 +++++++------------------------------------
 libgepub/gepub-doc.h        |   10 -
 libgepub/gepub-text-chunk.c |  111 ------------
 libgepub/gepub-text-chunk.h |   64 -------
 libgepub/gepub-utils.c      |  249 --------------------------
 libgepub/gepub-utils.h      |   30 ---
 libgepub/gepub.h            |    2 -
 libgepub/rust/Cargo.lock    |  289 ++++++++++++++++++++++++++++++
 libgepub/rust/Cargo.toml    |   16 ++
 libgepub/rust/src/lib.rs    |  214 ++++++++++++++++++++++
 tests/test-gepub.c          |  197 ++-------------------
 16 files changed, 653 insertions(+), 1245 deletions(-)
---
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d549197
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+*.o
+*.lo
+*.swp
diff --git a/configure.ac b/configure.ac
index 9f62ece..4e563dc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
 AC_PREREQ(2.60)
 AC_INIT([libgepub],[0.4],[danigm wadobo com])
 AC_CONFIG_AUX_DIR([build])
-AM_INIT_AUTOMAKE([1.10 -Wall -Werror dist-bzip2])
+AM_INIT_AUTOMAKE([1.10 dist-bzip2])
 AM_SILENT_RULES([yes])
 
 GNOME_COMMON_INIT
@@ -16,6 +16,34 @@ AM_PROG_CC_C_O
 AC_PROG_INSTALL
 AC_PROG_LIBTOOL
 
+AC_CHECK_PROG(CARGO, [cargo], [yes], [no])
+AS_IF(test x$CARGO = xno,
+    AC_MSG_ERROR([cargo is required.  Please install the Rust toolchain from https://www.rust-lang.org/])
+)
+AC_CHECK_PROG(RUSTC, [rustc], [yes], [no])
+AS_IF(test x$RUSTC = xno,
+    AC_MSG_ERROR([rustc is required.  Please install the Rust toolchain from https://www.rust-lang.org/])
+)
+
+AC_ARG_ENABLE(debug,
+              AC_HELP_STRING([--enable-debug],
+                             [Build Rust code with debugging information [default=no]]),
+              [debug_release=$enableval],
+             [debug_release=no])
+
+AC_MSG_CHECKING(whether to build Rust code with debugging information)
+if test "x$debug_release" = "xyes" ; then
+       AC_MSG_RESULT(yes)
+       RUST_TARGET_SUBDIR=debug
+else
+       AC_MSG_RESULT(no)
+       RUST_TARGET_SUBDIR=release
+fi
+AM_CONDITIONAL([DEBUG_RELEASE], [test "x$debug_release" = "xyes"])
+
+AC_SUBST([RUST_TARGET_SUBDIR])
+
+
 PKG_CHECK_MODULES(GEPUB,
                   webkit2gtk-4.0
                   libsoup-2.4
diff --git a/libgepub/Makefile.am b/libgepub/Makefile.am
index 1ae6339..a8047c2 100644
--- a/libgepub/Makefile.am
+++ b/libgepub/Makefile.am
@@ -1,12 +1,7 @@
 lib_LTLIBRARIES = libgepub.la
 
-NOINST_H_FILES = \
-       gepub-utils.h
-
 INST_H_FILES = \
        gepub-widget.h          \
-       gepub-archive.h         \
-       gepub-text-chunk.h      \
        gepub-doc.h             \
        gepub.h
 
@@ -15,13 +10,35 @@ libgepubinclude_HEADERS = $(INST_H_FILES)
 
 libgepub_la_SOURCES = \
        gepub-widget.c                  \
-       gepub-archive.c                 \
-       gepub-text-chunk.c              \
        gepub-doc.c                             \
-       gepub-utils.c                   \
        $(NOINST_H_FILES)               \
        $(INST_H_FILES)
 
+
+RUST_SOURCES =                                 \
+       rust/Cargo.toml                         \
+       rust/src/lib.rs
+
+if DEBUG_RELEASE
+CARGO_RELEASE_ARGS=
+else
+CARGO_RELEASE_ARGS=--release
+endif
+
+RUST_LIB=@abs_top_builddir@/target/@RUST_TARGET_SUBDIR@/libepub_internals.a
+
+check-local:
+       cd $(srcdir)/rust && \
+       CARGO_TARGET_DIR=@abs_top_builddir@/target cargo test
+
+clean-local:
+       cd $(top_srcdir)/rust && \
+       CARGO_TARGET_DIR=@abs_top_builddir@/target cargo clean
+
+@abs_top_builddir@/target/@RUST_TARGET_SUBDIR@/libepub_internals.a: $(RUST_SOURCES)
+       cd $(top_srcdir)/libgepub/rust && \
+       CARGO_TARGET_DIR=@abs_top_builddir@/target cargo build --verbose $(CARGO_RELEASE_ARGS)
+
 libgepub_la_CPPFLAGS = \
        -I$(top_builddir)       \
        -I$(srcdir)                     \
@@ -39,7 +56,8 @@ libgepub_la_LDFLAGS = \
        $(AM_LDFLAGS)
 
 libgepub_la_LIBADD = \
-       $(GEPUB_LIBS)
+       $(GEPUB_LIBS)    \
+       $(RUST_LIB)
 
 -include $(INTROSPECTION_MAKEFILE)
 INTROSPECTION_GIRS =
diff --git a/libgepub/gepub-doc.c b/libgepub/gepub-doc.c
index 2273aef..51e8a95 100644
--- a/libgepub/gepub-doc.c
+++ b/libgepub/gepub-doc.c
@@ -18,30 +18,42 @@
  */
 
 #include <config.h>
+#include <gio/gio.h>
 #include <libxml/tree.h>
 #include <libxml/HTMLparser.h>
 #include <string.h>
 
-#include "gepub-utils.h"
 #include "gepub-doc.h"
-#include "gepub-archive.h"
-#include "gepub-text-chunk.h"
 
-static void gepub_doc_fill_resources (GepubDoc *doc);
-static void gepub_doc_fill_spine (GepubDoc *doc);
+
+// Rust
+void      *epub_new(char *path);
+void       epub_destroy(void *doc);
+void      *epub_get_resource(void *doc, const char *path, int *size);
+void      *epub_get_resource_by_id(void *doc, const char *id, int *size);
+void      *epub_get_metadata(void *doc, const char *mdata);
+void      *epub_get_resource_mime(void *doc, const char *path);
+void      *epub_get_resource_mime_by_id(void *doc, const char *id);
+void      *epub_get_current_mime(void *doc);
+void      *epub_get_current(void *doc, int *size);
+void      *epub_get_current_with_epub_uris(void *doc, int *size);
+void       epub_set_page(void *doc, guint page);
+guint      epub_get_num_pages(void *doc);
+guint      epub_get_page(void *doc);
+gboolean   epub_next_page(void *doc);
+gboolean   epub_prev_page(void *doc);
+void      *epub_get_cover(void *doc);
+void      *epub_resource_path(void *doc, const char *id);
+void      *epub_current_path(void *doc);
+void      *epub_current_id(void *doc);
+
+
 static void gepub_doc_initable_iface_init (GInitableIface *iface);
 
 struct _GepubDoc {
     GObject parent;
-
-    GepubArchive *archive;
-    GBytes *content;
-    gchar *content_base;
     gchar *path;
-    GHashTable *resources;
-
-    GList *spine;
-    GList *page;
+    void *rust_epub_doc;
 };
 
 struct _GepubDocClass {
@@ -61,27 +73,11 @@ G_DEFINE_TYPE_WITH_CODE (GepubDoc, gepub_doc, G_TYPE_OBJECT,
                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, gepub_doc_initable_iface_init))
 
 static void
-gepub_resource_free (GepubResource *res)
-{
-    g_free (res->mime);
-    g_free (res->uri);
-    g_free (res);
-}
-
-static void
 gepub_doc_finalize (GObject *object)
 {
     GepubDoc *doc = GEPUB_DOC (object);
 
-    g_clear_object (&doc->archive);
-    g_clear_pointer (&doc->content, g_bytes_unref);
-    g_clear_pointer (&doc->path, g_free);
-    g_clear_pointer (&doc->resources, g_hash_table_destroy);
-
-    if (doc->spine) {
-        g_list_foreach (doc->spine, (GFunc)g_free, NULL);
-        g_clear_pointer (&doc->spine, g_list_free);
-    }
+    epub_destroy (doc->rust_epub_doc);
 
     G_OBJECT_CLASS (gepub_doc_parent_class)->finalize (object);
 }
@@ -98,9 +94,9 @@ gepub_doc_set_property (GObject      *object,
     case PROP_PATH:
         doc->path = g_value_dup_string (value);
         break;
-    case PROP_PAGE:
-        gepub_doc_set_page (doc, g_value_get_int (value));
-        break;
+    //case PROP_PAGE:
+    //    gepub_doc_set_page (doc, g_value_get_int (value));
+    //    break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
         break;
@@ -119,9 +115,9 @@ gepub_doc_get_property (GObject    *object,
     case PROP_PATH:
         g_value_set_string (value, doc->path);
         break;
-    case PROP_PAGE:
-        g_value_set_int (value, gepub_doc_get_page (doc));
-        break;
+    //case PROP_PAGE:
+    //    g_value_set_int (value, gepub_doc_get_page (doc));
+    //    break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
         break;
@@ -131,13 +127,6 @@ gepub_doc_get_property (GObject    *object,
 static void
 gepub_doc_init (GepubDoc *doc)
 {
-    /* doc resources hashtable:
-     * id : (mime, path)
-     */
-    doc->resources = g_hash_table_new_full (g_str_hash,
-                                            g_str_equal,
-                                            (GDestroyNotify)g_free,
-                                            (GDestroyNotify)gepub_resource_free);
 }
 
 static void
@@ -174,35 +163,12 @@ gepub_doc_initable_init (GInitable     *initable,
                          GError       **error)
 {
     GepubDoc *doc = GEPUB_DOC (initable);
-    gchar *file;
-    gsize bufsize = 0;
-    gint i = 0, len;
 
-    g_assert (doc->path != NULL);
-
-    doc->archive = gepub_archive_new (doc->path);
-    file = gepub_archive_get_root_file (doc->archive);
-    if (!file)
-        return FALSE;
-    doc->content = gepub_archive_read_entry (doc->archive, file);
-    if (!doc->content)
+    doc->rust_epub_doc = epub_new (doc->path);
+    if (!doc->rust_epub_doc) {
         return FALSE;
-
-    len = strlen (file);
-    doc->content_base = g_strdup ("");
-    for (i=0; i<len; i++) {
-        if (file[i] == '/') {
-            g_free (doc->content_base);
-            doc->content_base = g_strndup (file, i+1);
-            break;
-        }
     }
 
-    gepub_doc_fill_resources (doc);
-    gepub_doc_fill_spine (doc);
-
-    g_free (file);
-
     return TRUE;
 }
 
@@ -227,93 +193,6 @@ gepub_doc_new (const gchar *path)
                            NULL);
 }
 
-static void
-gepub_doc_fill_resources (GepubDoc *doc)
-{
-    xmlDoc *xdoc = NULL;
-    xmlNode *root_element = NULL;
-    xmlNode *mnode = NULL;
-    xmlNode *item = NULL;
-    gchar *id, *tmpuri, *uri;
-    GepubResource *res;
-    const char *data;
-    gsize size;
-
-    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");
-
-    item = mnode->children;
-    while (item) {
-        if (item->type != XML_ELEMENT_NODE ) {
-            item = item->next;
-            continue;
-        }
-
-        id = xmlGetProp (item, "id");
-        tmpuri = xmlGetProp (item, "href");
-        uri = g_strdup_printf ("%s%s", doc->content_base, tmpuri);
-        g_free (tmpuri);
-
-        res = g_malloc (sizeof (GepubResource));
-        res->mime = xmlGetProp (item, "media-type");
-        res->uri = uri;
-        g_hash_table_insert (doc->resources, id, res);
-        item = item->next;
-    }
-
-    xmlFreeDoc (xdoc);
-}
-
-static void
-gepub_doc_fill_spine (GepubDoc *doc)
-{
-    xmlDoc *xdoc = NULL;
-    xmlNode *root_element = NULL;
-    xmlNode *snode = NULL;
-    xmlNode *item = NULL;
-    gchar *id;
-    const char *data;
-    gsize size;
-    GList *spine = NULL;
-
-    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");
-
-    item = snode->children;
-    while (item) {
-        if (item->type != XML_ELEMENT_NODE ) {
-            item = item->next;
-            continue;
-        }
-
-        id = xmlGetProp (item, "idref");
-
-        spine = g_list_prepend (spine, id);
-        item = item->next;
-    }
-
-    doc->spine = g_list_reverse (spine);
-    doc->page = doc->spine;
-
-    xmlFreeDoc (xdoc);
-}
-
-/**
- * gepub_doc_get_content:
- * @doc: a #GepubDoc
- *
- * Returns: (transfer none): the document content
- */
-GBytes *
-gepub_doc_get_content (GepubDoc *doc)
-{
-    return doc->content;
-}
-
 /**
  * gepub_doc_get_metadata:
  * @doc: a #GepubDoc
@@ -324,40 +203,7 @@ gepub_doc_get_content (GepubDoc *doc)
 gchar *
 gepub_doc_get_metadata (GepubDoc *doc, const gchar *mdata)
 {
-    xmlDoc *xdoc = NULL;
-    xmlNode *root_element = NULL;
-    xmlNode *mnode = NULL;
-    xmlNode *mdata_node = NULL;
-    gchar *ret;
-    xmlChar *text;
-    const char *data;
-    gsize size;
-
-    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);
-
-    text = xmlNodeGetContent (mdata_node);
-    ret = g_strdup (text);
-    xmlFree (text);
-
-    xmlFreeDoc (xdoc);
-
-    return ret;
-}
-
-/**
- * gepub_doc_get_resources:
- * @doc: a #GepubDoc
- *
- * Returns: (element-type utf8 Gepub.Resource) (transfer none): doc resource table
- */
-GHashTable *
-gepub_doc_get_resources (GepubDoc *doc)
-{
-    return doc->resources;
+    return epub_get_metadata (doc->rust_epub_doc, mdata);
 }
 
 /**
@@ -370,13 +216,9 @@ gepub_doc_get_resources (GepubDoc *doc)
 GBytes *
 gepub_doc_get_resource_by_id (GepubDoc *doc, const gchar *id)
 {
-    GepubResource *gres = g_hash_table_lookup (doc->resources, id);
-    if (!gres) {
-        // not found
-        return NULL;
-    }
-
-    return gepub_archive_read_entry (doc->archive, gres->uri);
+    int size = 0;
+    guint8 *data = epub_get_resource_by_id (doc->rust_epub_doc, id, &size);
+    return g_bytes_new_take (data, size);
 }
 
 /**
@@ -389,7 +231,9 @@ gepub_doc_get_resource_by_id (GepubDoc *doc, const gchar *id)
 GBytes *
 gepub_doc_get_resource (GepubDoc *doc, const gchar *path)
 {
-    return gepub_archive_read_entry (doc->archive, path);
+    int size = 0;
+    guint8 *data = epub_get_resource (doc->rust_epub_doc, path, &size);
+    return g_bytes_new_take (data, size);
 }
 
 /**
@@ -402,17 +246,7 @@ gepub_doc_get_resource (GepubDoc *doc, const gchar *path)
 gchar *
 gepub_doc_get_resource_mime_by_id (GepubDoc *doc, const gchar *id)
 {
-    GepubResource *gres;
-
-    g_return_val_if_fail (id != NULL, NULL);
-
-    gres = g_hash_table_lookup (doc->resources, id);
-    if (!gres) {
-        // not found
-        return NULL;
-    }
-
-    return g_strdup (gres->mime);
+    return epub_get_resource_mime_by_id (doc->rust_epub_doc, id);
 }
 
 /**
@@ -425,20 +259,7 @@ gepub_doc_get_resource_mime_by_id (GepubDoc *doc, const gchar *id)
 gchar *
 gepub_doc_get_resource_mime (GepubDoc *doc, const gchar *path)
 {
-    GepubResource *gres;
-    GList *keys = g_hash_table_get_keys (doc->resources);
-
-    while (keys) {
-        gres = ((GepubResource*)g_hash_table_lookup (doc->resources, keys->data));
-        if (!strcmp (gres->uri, path))
-            break;
-        keys = keys->next;
-    }
-
-    if (keys)
-        return g_strdup (gres->mime);
-    else
-        return NULL;
+    return epub_get_resource_mime (doc->rust_epub_doc, path);
 }
 
 /**
@@ -450,7 +271,7 @@ gepub_doc_get_resource_mime (GepubDoc *doc, const gchar *path)
 gchar *
 gepub_doc_get_current_mime (GepubDoc *doc)
 {
-    return gepub_doc_get_resource_mime_by_id (doc, doc->page->data);
+    return epub_get_current_mime (doc->rust_epub_doc);
 }
 
 /**
@@ -462,7 +283,9 @@ gepub_doc_get_current_mime (GepubDoc *doc)
 GBytes *
 gepub_doc_get_current (GepubDoc *doc)
 {
-    return gepub_doc_get_resource_by_id (doc, doc->page->data);
+    int size = 0;
+    guint8 *data = epub_get_current (doc->rust_epub_doc, &size);
+    return g_bytes_new_take (data, size);
 }
 
 /**
@@ -476,96 +299,9 @@ gepub_doc_get_current (GepubDoc *doc)
 GBytes *
 gepub_doc_get_current_with_epub_uris (GepubDoc *doc)
 {
-    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);
-
-    GBytes *replaced = gepub_utils_replace_resources (content, base);
-
-    g_free (path);
-    g_bytes_unref (content);
-
-    return replaced;
-}
-
-/**
- * gepub_doc_get_text:
- * @doc: a #GepubDoc
- *
- * Returns: (element-type Gepub.TextChunk) (transfer full): the list of text in the current chapter.
- */
-GList *
-gepub_doc_get_text (GepubDoc *doc)
-{
-    xmlDoc *xdoc = NULL;
-    xmlNode *root_element = NULL;
-    GBytes *current;
-    const guchar *data;
-    gsize size;
-
-    GList *texts = NULL;
-
-    current = gepub_doc_get_current (doc);
-    if (!current) {
-        return NULL;
-    }
-    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_bytes_unref (current);
-    xmlFreeDoc (xdoc);
-
-    return texts;
-}
-
-/**
- * gepub_doc_get_text_by_id:
- * @doc: a #GepubDoc
- * @id: the resource id
- *
- * Returns: (element-type Gepub.TextChunk) (transfer full): the list of text in the current chapter.
- */
-GList *
-gepub_doc_get_text_by_id (GepubDoc *doc, const gchar *id)
-{
-    xmlDoc *xdoc = NULL;
-    xmlNode *root_element = NULL;
-    gsize size;
-    const guchar *res;
-    GBytes *contents;
-
-    GList *texts = NULL;
-
-    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_bytes_unref (contents);
-    xmlFreeDoc (xdoc);
-
-    return texts;
-}
-
-static gboolean
-gepub_doc_set_page_internal (GepubDoc *doc,
-                             GList    *page)
-{
-    if (!page || doc->page == page)
-        return FALSE;
-
-    doc->page = page;
-    g_object_notify_by_pspec (G_OBJECT (doc), properties[PROP_PAGE]);
-
-    return TRUE;
+    int size = 0;
+    guint8 *data = epub_get_current_with_epub_uris (doc->rust_epub_doc, &size);
+    return g_bytes_new_take (data, size);
 }
 
 /**
@@ -577,7 +313,8 @@ gepub_doc_set_page_internal (GepubDoc *doc,
 gboolean
 gepub_doc_go_next (GepubDoc *doc)
 {
-    return gepub_doc_set_page_internal (doc, doc->page->next);
+    g_object_notify_by_pspec (G_OBJECT (doc), properties[PROP_PAGE]);
+    return epub_next_page (doc->rust_epub_doc);
 }
 
 /**
@@ -589,7 +326,8 @@ gepub_doc_go_next (GepubDoc *doc)
 gboolean
 gepub_doc_go_prev (GepubDoc *doc)
 {
-    return gepub_doc_set_page_internal (doc, doc->page->prev);
+    g_object_notify_by_pspec (G_OBJECT (doc), properties[PROP_PAGE]);
+    return epub_prev_page (doc->rust_epub_doc);
 }
 
 /**
@@ -601,7 +339,7 @@ gepub_doc_go_prev (GepubDoc *doc)
 int
 gepub_doc_get_n_pages (GepubDoc *doc)
 {
-    return g_list_length (doc->spine);
+    return epub_get_num_pages (doc->rust_epub_doc);
 }
 
 /**
@@ -613,7 +351,7 @@ gepub_doc_get_n_pages (GepubDoc *doc)
 int
 gepub_doc_get_page (GepubDoc *doc)
 {
-    return g_list_position (doc->spine, doc->page);
+    return epub_get_page (doc->rust_epub_doc);
 }
 
 /**
@@ -627,12 +365,9 @@ void
 gepub_doc_set_page (GepubDoc *doc,
                     gint      index)
 {
-    GList *page;
-
     g_return_if_fail (index >= 0 && index <= gepub_doc_get_n_pages (doc));
-
-    page = g_list_nth (doc->spine, index);
-    gepub_doc_set_page_internal (doc, page);
+    g_object_notify_by_pspec (G_OBJECT (doc), properties[PROP_PAGE]);
+    epub_set_page (doc->rust_epub_doc, index);
 }
 
 /**
@@ -645,26 +380,7 @@ gepub_doc_set_page (GepubDoc *doc,
 gchar *
 gepub_doc_get_cover (GepubDoc *doc)
 {
-    xmlDoc *xdoc = NULL;
-    xmlNode *root_element = NULL;
-    xmlNode *mnode = NULL;
-    gchar *ret;
-    xmlChar *text;
-    const char *data;
-    gsize size;
-
-    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");
-
-    ret = g_strdup (text);
-    xmlFree (text);
-
-    xmlFreeDoc (xdoc);
-
-    return ret;
+    return epub_get_cover (doc->rust_epub_doc);
 }
 
 /**
@@ -677,13 +393,7 @@ gepub_doc_get_cover (GepubDoc *doc)
 gchar *
 gepub_doc_get_resource_path (GepubDoc *doc, const gchar *id)
 {
-    GepubResource *gres = g_hash_table_lookup (doc->resources, id);
-    if (!gres) {
-        // not found
-        return NULL;
-    }
-
-    return g_strdup (gres->uri);
+    return epub_resource_path(doc->rust_epub_doc, id);
 }
 
 /**
@@ -695,7 +405,7 @@ gepub_doc_get_resource_path (GepubDoc *doc, const gchar *id)
 gchar *
 gepub_doc_get_current_path (GepubDoc *doc)
 {
-    return gepub_doc_get_resource_path (doc, doc->page->data);
+    return epub_current_path (doc->rust_epub_doc);
 }
 
 /**
@@ -703,10 +413,10 @@ gepub_doc_get_current_path (GepubDoc *doc)
  * @doc: a #GepubDoc
  *
 
- * Returns: (transfer none): the current resource id
+ * Returns: (transfer full): the current resource id
  */
 const gchar *
 gepub_doc_get_current_id (GepubDoc *doc)
 {
-    return doc->page->data;
+    return epub_current_id (doc->rust_epub_doc);
 }
diff --git a/libgepub/gepub-doc.h b/libgepub/gepub-doc.h
index 68c2a93..ccc8f66 100644
--- a/libgepub/gepub-doc.h
+++ b/libgepub/gepub-doc.h
@@ -35,26 +35,16 @@ G_BEGIN_DECLS
 typedef struct _GepubDoc      GepubDoc;
 typedef struct _GepubDocClass GepubDocClass;
 
-struct _GepubResource {
-    gchar *mime;
-    gchar *uri;
-};
-
-typedef struct _GepubResource GepubResource;
 
 GType             gepub_doc_get_type                        (void) G_GNUC_CONST;
 
 GepubDoc         *gepub_doc_new                             (const gchar *path);
-GBytes           *gepub_doc_get_content                     (GepubDoc *doc);
 gchar            *gepub_doc_get_metadata                    (GepubDoc *doc, const gchar *mdata);
 GBytes           *gepub_doc_get_resource                    (GepubDoc *doc, const gchar *path);
 GBytes           *gepub_doc_get_resource_by_id              (GepubDoc *doc, const gchar *id);
-GHashTable       *gepub_doc_get_resources                   (GepubDoc *doc);
 gchar            *gepub_doc_get_resource_mime               (GepubDoc *doc, const gchar *path);
 gchar            *gepub_doc_get_resource_mime_by_id         (GepubDoc *doc, const gchar *id);
 gchar            *gepub_doc_get_current_mime                (GepubDoc *doc);
-GList            *gepub_doc_get_text                        (GepubDoc *doc);
-GList            *gepub_doc_get_text_by_id                  (GepubDoc *doc, const gchar *id);
 GBytes           *gepub_doc_get_current                     (GepubDoc *doc);
 GBytes           *gepub_doc_get_current_with_epub_uris      (GepubDoc *doc);
 gchar            *gepub_doc_get_cover                       (GepubDoc *doc);
diff --git a/libgepub/gepub.h b/libgepub/gepub.h
index a8f7fd2..cdc1c3c 100644
--- a/libgepub/gepub.h
+++ b/libgepub/gepub.h
@@ -1,8 +1,6 @@
 #ifndef _GEPUB__H_
 #define _GEPUB__H_
 
-#include "gepub-archive.h"
-#include "gepub-text-chunk.h"
 #include "gepub-doc.h"
 #include "gepub-widget.h"
 
diff --git a/libgepub/rust/Cargo.lock b/libgepub/rust/Cargo.lock
new file mode 100644
index 0000000..47617ff
--- /dev/null
+++ b/libgepub/rust/Cargo.lock
@@ -0,0 +1,289 @@
+[root]
+name = "epub_internals"
+version = "0.0.1"
+dependencies = [
+ "epub 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib 0.1.1 (git+https://github.com/gtk-rs/glib)",
+ "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "aho-corasick"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "bitflags"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "bitflags"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "bitflags"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "bzip2"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "bzip2-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "bzip2-sys"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "epub"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "zip 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "flate2"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "gcc"
+version = "0.3.43"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "glib"
+version = "0.1.1"
+source = "git+https://github.com/gtk-rs/glib#389afe445563e84def1410fac3f06bdec3566834";
+dependencies = [
+ "bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib-sys 0.3.2 (git+https://github.com/gtk-rs/sys)",
+ "gobject-sys 0.3.2 (git+https://github.com/gtk-rs/sys)",
+ "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "glib-sys"
+version = "0.3.2"
+source = "git+https://github.com/gtk-rs/sys#9ae84c22d72d588536368204fbb337b550988443";
+dependencies = [
+ "bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "gobject-sys"
+version = "0.3.2"
+source = "git+https://github.com/gtk-rs/sys#9ae84c22d72d588536368204fbb337b550988443";
+dependencies = [
+ "bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib-sys 0.3.2 (git+https://github.com/gtk-rs/sys)",
+ "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "kernel32-sys"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.20"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "memchr"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "miniz-sys"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "msdos_time"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "pkg-config"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "podio"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "redox_syscall"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "regex"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "thread_local 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "thread-id"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "thread_local"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "time"
+version = "0.1.36"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unreachable"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "utf8-ranges"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "void"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "winapi"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "winapi-build"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "xml-rs"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "bitflags 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "zip"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "bzip2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flate2 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "msdos_time 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "podio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[metadata]
+"checksum aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = 
"0638fd549427caa90c499814196d1b9e3725eb4d15d7339d6de073a680ed0ca2"
+"checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3"
+"checksum bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23"
+"checksum bitflags 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"ab1c7dc97f39523ffa63f3096291612e630cf3ed75aa6b9fad436bac4c700274"
+"checksum bzip2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"e39c71fcff507b547240346a894c5df38e6fd42fb02590a5d5b3f2dae9173ad2"
+"checksum bzip2-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = 
"98ce3fff84d4e90011f464bbdf48e3428f04270439f703868fd489d2aaedfc30"
+"checksum epub 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"455f3e6ebc08988413b6155884f58aa247f8e3e7b408f64f6532d5a27b368ddd"
+"checksum flate2 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = 
"d4e4d0c15ef829cbc1b7cda651746be19cceeb238be7b1049227b14891df9e25"
+"checksum gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)" = 
"c07c758b972368e703a562686adb39125707cc1ef3399da8c019fc6c2498a75d"
+"checksum glib 0.1.1 (git+https://github.com/gtk-rs/glib)" = "<none>"
+"checksum glib-sys 0.3.2 (git+https://github.com/gtk-rs/sys)" = "<none>"
+"checksum gobject-sys 0.3.2 (git+https://github.com/gtk-rs/sys)" = "<none>"
+"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = 
"7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
+"checksum libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = 
"684f330624d8c3784fb9558ca46c4ce488073a8d22450415c5eb4f4cfb0d11b5"
+"checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4"
+"checksum miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = 
"28eaee17666671fa872e567547e8428e83308ebe5808cdf6a0e28397dbe2c726"
+"checksum msdos_time 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = 
"c04b68cc63a8480fb2550343695f7be72effdec953a9d4508161c3e69041c7d8"
+"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = 
"3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
+"checksum podio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = 
"e5422a1ee1bc57cc47ae717b0137314258138f38fd5f3cea083f43a9725383a0"
+"checksum redox_syscall 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = 
"8dd35cc9a8bdec562c757e3d43c1526b5c6d2653e23e2315065bc25556550753"
+"checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01"
+"checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457"
+"checksum thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"4437c97558c70d129e40629a5b385b3fb1ffac301e63941335e4d354081ec14a"
+"checksum thread_local 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = 
"7793b722f0f77ce716e7f1acf416359ca32ff24d04ffbac4269f44a4a83be05d"
+"checksum time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = 
"211b63c112206356ef1ff9b19355f43740fc3f85960c598a93d3a3d3ba7beade"
+"checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91"
+"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
+"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = 
"6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
+"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = 
"167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
+"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
+"checksum xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = 
"7ec6c39eaa68382c8e31e35239402c0a9489d4141a8ceb0c716099a0b515b562"
+"checksum zip 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"54fa1f34fd0d00e851e31dd84dd89a67e0f279ad898ffaa7176ed5c616c1a457"
diff --git a/libgepub/rust/Cargo.toml b/libgepub/rust/Cargo.toml
new file mode 100644
index 0000000..5ff7d78
--- /dev/null
+++ b/libgepub/rust/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "epub_internals"
+version = "0.0.1"
+authors = ["Daniel Garcia Moreno <danigm wadobo com>"]
+
+[dependencies]
+libc = "0.2"
+epub = "1.0.2"
+
+[dependencies.glib]
+git = "https://github.com/gtk-rs/glib";
+version = "0.1.1"
+
+[lib]
+name = "epub_internals"
+crate-type = ["staticlib"]
diff --git a/libgepub/rust/src/lib.rs b/libgepub/rust/src/lib.rs
new file mode 100644
index 0000000..06f2f84
--- /dev/null
+++ b/libgepub/rust/src/lib.rs
@@ -0,0 +1,214 @@
+// TODO: manage errors, remove all unwraps
+
+extern crate glib;
+extern crate libc;
+extern crate epub;
+
+use std::mem;
+use epub::doc::EpubDoc;
+use self::glib::translate::*;
+
+
+#[no_mangle]
+pub extern fn epub_new(path: *const libc::c_char) -> *mut EpubDoc {
+    let my_path = unsafe { &String::from_glib_none(path) };
+    let doc = EpubDoc::new(my_path);
+    let doc = doc.unwrap();
+    Box::into_raw(Box::new(doc))
+}
+
+#[no_mangle]
+pub unsafe extern fn epub_destroy(raw_doc: *mut EpubDoc) {
+    assert!(!raw_doc.is_null());
+    let _ = Box::from_raw(raw_doc);
+}
+
+#[no_mangle]
+pub unsafe extern fn epub_get_resource(doc: *mut EpubDoc,
+                                       path: *const libc::c_char,
+                                       size: *mut i32)
+                                       -> *mut u8 {
+    assert!(!doc.is_null());
+    let my_path = &String::from_glib_none(path);
+
+    let mut v = (*doc).get_resource_by_path(my_path).unwrap();
+
+    *size = v.len() as i32;
+
+    v.shrink_to_fit();
+    let ptr = v.as_mut_ptr();
+    mem::forget(v);
+
+    ptr
+}
+
+#[no_mangle]
+pub unsafe extern fn epub_get_resource_by_id(doc: *mut EpubDoc,
+                                             id: *const libc::c_char,
+                                             size: *mut i32)
+                                             -> *mut u8 {
+    assert!(!doc.is_null());
+    let my_id = &String::from_glib_none(id);
+
+    let mut v = (*doc).get_resource(my_id).unwrap();
+    *size = v.len() as i32;
+
+    v.shrink_to_fit();
+    let ptr = v.as_mut_ptr();
+    mem::forget(v);
+
+    ptr
+}
+
+#[no_mangle]
+pub unsafe extern fn epub_get_metadata(doc: *mut EpubDoc,
+                                mdata: *const libc::c_char)
+                                -> *const libc::c_char {
+    assert!(!doc.is_null());
+    let mut ret = String::from("");
+    let my_mdata = &String::from_glib_none(mdata);
+    if let Some(mdata) = (*doc).metadata.get(my_mdata) {
+        ret = mdata.clone();
+    }
+
+    ret.to_glib_full()
+}
+
+#[no_mangle]
+pub unsafe extern fn epub_get_resource_mime(doc: *mut EpubDoc,
+                                            path: *const libc::c_char)
+                                            -> *const libc::c_char {
+    assert!(!doc.is_null());
+    let mut ret = String::from("");
+    let my_path = &String::from_glib_none(path);
+    if let Ok(m) = (*doc).get_resource_mime_by_path(my_path) {
+        ret = m.clone();
+    }
+    ret.to_glib_full()
+}
+
+#[no_mangle]
+pub unsafe extern fn epub_get_resource_mime_by_id(doc: *mut EpubDoc,
+                                                  id: *const libc::c_char)
+                                                  -> *const libc::c_char {
+    assert!(!doc.is_null());
+    let mut ret = String::from("");
+    let my_id = &String::from_glib_none(id);
+    if let Ok(m) = (*doc).get_resource_mime(my_id) {
+        ret = m.clone();
+    }
+    ret.to_glib_full()
+}
+
+#[no_mangle]
+pub unsafe extern fn epub_get_current_mime(doc: *mut EpubDoc)
+                                           -> *const libc::c_char {
+    assert!(!doc.is_null());
+    let mut ret = String::from("");
+    if let Ok(m) = (*doc).get_current_mime() {
+        ret = m.clone();
+    }
+    ret.to_glib_full()
+}
+
+#[no_mangle]
+pub unsafe extern fn epub_get_current(doc: *mut EpubDoc,
+                                      size: *mut i32)
+                                      -> *mut u8 {
+    assert!(!doc.is_null());
+    let mut v = (*doc).get_current().unwrap();
+    *size = v.len() as i32;
+
+    v.shrink_to_fit();
+    let ptr = v.as_mut_ptr();
+    mem::forget(v);
+
+    ptr
+}
+
+#[no_mangle]
+pub unsafe extern fn epub_get_current_with_epub_uris(doc: *mut EpubDoc,
+                                                     size: *mut i32)
+                                                     -> *mut u8 {
+    assert!(!doc.is_null());
+    let mut v = (*doc).get_current_with_epub_uris().unwrap();
+    *size = v.len() as i32;
+
+    v.shrink_to_fit();
+    let ptr = v.as_mut_ptr();
+    mem::forget(v);
+
+    ptr
+}
+
+#[no_mangle]
+pub unsafe extern fn epub_set_page(doc: *mut EpubDoc, n: usize) {
+    (*doc).set_current_page(n);
+}
+
+#[no_mangle]
+pub unsafe extern fn epub_get_num_pages(doc: *mut EpubDoc) -> usize {
+    (*doc).get_num_pages()
+}
+
+#[no_mangle]
+pub unsafe extern fn epub_get_page(doc: *mut EpubDoc) -> usize {
+    (*doc).get_current_page()
+}
+
+#[no_mangle]
+pub unsafe extern fn epub_next_page(doc: *mut EpubDoc) -> bool {
+    match (*doc).go_next() {
+        Ok(_) => return true,
+        Err(_) => return false,
+    }
+}
+
+#[no_mangle]
+pub unsafe extern fn epub_prev_page(doc: *mut EpubDoc) -> bool {
+    match (*doc).go_prev() {
+        Ok(_) => return true,
+        Err(_) => return false,
+    }
+}
+
+#[no_mangle]
+pub unsafe extern fn epub_get_cover(doc: *mut EpubDoc) -> *const libc::c_char {
+    let mut ret = String::from("");
+    if let Ok(cid) = (*doc).get_cover_id() {
+        if let Some(m) = (*doc).resources.get(&cid) {
+            ret = m.0.clone();
+        }
+    }
+
+    ret.to_glib_full()
+}
+
+#[no_mangle]
+pub unsafe extern fn epub_resource_path(doc: *mut EpubDoc,
+                                        id: *const libc::c_char) -> *const libc::c_char {
+    let my_id = &String::from_glib_none(id);
+    let mut ret = String::from("");
+    if let Some(m) = (*doc).resources.get(my_id) {
+        ret = m.0.clone();
+    }
+    ret.to_glib_full()
+}
+
+#[no_mangle]
+pub unsafe extern fn epub_current_path(doc: *mut EpubDoc) -> *const libc::c_char {
+    let mut ret = String::from("");
+    if let Ok(m) = (*doc).get_current_path() {
+        ret = m.clone();
+    }
+    ret.to_glib_full()
+}
+
+#[no_mangle]
+pub unsafe extern fn epub_current_id(doc: *mut EpubDoc) -> *const libc::c_char {
+    let mut ret = String::from("");
+    if let Ok(m) = (*doc).get_current_id() {
+        ret = m.clone();
+    }
+    ret.to_glib_full()
+}
diff --git a/tests/test-gepub.c b/tests/test-gepub.c
index 20048d4..028a5f8 100644
--- a/tests/test-gepub.c
+++ b/tests/test-gepub.c
@@ -20,39 +20,6 @@ GtkTextBuffer *page_buffer;
 #define TEST(f,arg...) PTEST ("\n### TESTING " #f " ###\n\n"); f (arg); PTEST ("\n\n");
 
 void
-update_text (GepubDoc *doc)
-{
-    GList *l, *chunks;
-    GtkTextIter start, end;
-
-    gtk_text_buffer_get_start_iter (page_buffer, &start);
-    gtk_text_buffer_get_end_iter (page_buffer, &end);
-    gtk_text_buffer_delete (page_buffer, &start, &end);
-
-    chunks = gepub_doc_get_text (doc);
-
-    for (l=chunks; l; l = l->next) {
-        GepubTextChunk *chunk = GEPUB_TEXT_CHUNK (l->data);
-        if (chunk->type == GEPUBTextHeader) {
-            gtk_text_buffer_insert_at_cursor (page_buffer, "\n", -1);
-            gtk_text_buffer_get_end_iter (page_buffer, &end);
-            gtk_text_buffer_insert_with_tags_by_name (page_buffer, &end, chunk->text, -1, "head",  NULL);
-            gtk_text_buffer_insert_at_cursor (page_buffer, "\n", -1);
-        } else if (chunk->type == GEPUBTextNormal) {
-            gtk_text_buffer_insert_at_cursor (page_buffer, "\n", -1);
-            gtk_text_buffer_insert_at_cursor (page_buffer, chunk->text, -1);
-            gtk_text_buffer_insert_at_cursor (page_buffer, "\n", -1);
-        } else if (chunk->type == GEPUBTextItalic) {
-            gtk_text_buffer_get_end_iter (page_buffer, &end);
-            gtk_text_buffer_insert_with_tags_by_name (page_buffer, &end, chunk->text, -1, "italic",  NULL);
-        } else if (chunk->type == GEPUBTextBold) {
-            gtk_text_buffer_get_end_iter (page_buffer, &end);
-            gtk_text_buffer_insert_with_tags_by_name (page_buffer, &end, chunk->text, -1, "bold",  NULL);
-        }
-    }
-}
-
-void
 print_replaced_text (GepubDoc *doc)
 {
     GBytes *content;
@@ -66,105 +33,20 @@ print_replaced_text (GepubDoc *doc)
 }
 
 void
-button_pressed (GtkButton *button, GepubWidget *widget)
+button_pressed (GtkButton *button, GepubDoc *doc)
 {
-    GepubDoc *doc = gepub_widget_get_doc (widget);
-
     if (!strcmp (gtk_button_get_label (button), "prev")) {
         gepub_doc_go_prev (doc);
     } else {
         gepub_doc_go_next (doc);
     }
-    update_text (doc);
+    printf ("CURRENT: %d\n", gepub_doc_get_page (doc));
+    printf ("CURRENT: %s\n", gepub_doc_get_current_id (doc));
+    printf ("CURRENT: %s\n", gepub_doc_get_current_path (doc));
     print_replaced_text (doc);
 }
 
 void
-test_open (const char *path)
-{
-    GepubArchive *a;
-    GList *list_files;
-    gint i;
-    gint size;
-
-    a = gepub_archive_new (path);
-    list_files = gepub_archive_list_files (a);
-    if (!list_files) {
-        PTEST ("ERROR: BAD epub file");
-        g_object_unref (a);
-        return;
-    }
-
-    size = g_list_length (list_files);
-    PTEST ("%d\n", size);
-    for (i = 0; i < size; i++) {
-        PTEST ("file: %s\n", (char *)g_list_nth_data (list_files, i));
-        g_free (g_list_nth_data (list_files, i));
-    }
-
-    g_list_free (list_files);
-
-    g_object_unref (a);
-}
-
-void
-find_xhtml (gchar *key, GepubResource *value, gpointer data)
-{
-    guchar **d = (guchar **)data;
-    if (g_strcmp0 (value->mime, "application/xhtml+xml") == 0) {
-        *d = value->uri;
-    }
-}
-
-void
-test_read (const char *path)
-{
-    GepubArchive *a;
-    GList *list_files = NULL;
-    const guchar *buffer;
-    guchar *file = NULL;
-    gsize bufsize;
-    GBytes *bytes;
-
-    a = gepub_archive_new (path);
-
-    GepubDoc *doc = gepub_doc_new (path);
-    GHashTable *ht = (GHashTable*)gepub_doc_get_resources (doc);
-    g_hash_table_foreach (ht, (GHFunc)find_xhtml, &file);
-
-    bytes = gepub_archive_read_entry (a, file);
-    if (bytes) {
-        const char *data;
-        gsize size;
-
-        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);
-
-    g_object_unref (a);
-}
-
-void
-test_root_file (const char *path)
-{
-    GepubArchive *a;
-    gchar *root_file = NULL;
-
-    a = gepub_archive_new (path);
-
-    root_file = gepub_archive_get_root_file (a);
-    PTEST ("root file: %s\n", root_file);
-    if (root_file)
-        g_free (root_file);
-
-    g_object_unref (a);
-}
-
-void
 test_doc_name (const char *path)
 {
     GepubDoc *doc = gepub_doc_new (path);
@@ -173,60 +55,24 @@ test_doc_name (const char *path)
     gchar *id = gepub_doc_get_metadata (doc, GEPUB_META_ID);
     gchar *author = gepub_doc_get_metadata (doc, GEPUB_META_AUTHOR);
     gchar *description = gepub_doc_get_metadata (doc, GEPUB_META_DESC);
-    gchar *cover = gepub_doc_get_cover (doc);
-    gchar *cover_mime = gepub_doc_get_resource_mime_by_id (doc, cover);
+    //gchar *cover = gepub_doc_get_cover (doc);
+    //gchar *cover_mime = gepub_doc_get_resource_mime_by_id (doc, cover);
 
     PTEST ("title: %s\n", title);
     PTEST ("author: %s\n", author);
     PTEST ("id: %s\n", id);
     PTEST ("lang: %s\n", lang);
     PTEST ("desc: %s\n", description);
-    PTEST ("cover: %s\n", cover);
-    PTEST ("cover mime: %s\n", cover_mime);
+    //PTEST ("cover: %s\n", cover);
+    //PTEST ("cover mime: %s\n", cover_mime);
 
     g_free (title);
     g_free (lang);
     g_free (id);
     g_free (author);
     g_free (description);
-    g_free (cover);
-    g_object_unref (G_OBJECT (doc));
-}
-
-void
-pk (gchar *key, GepubResource *value, gpointer data)
-{
-    PTEST ("%s: %s, %s\n", key, value->mime, value->uri);
-}
-
-void
-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);
-    GBytes *ncx;
-    const guchar *data;
-    gsize size;
-
-    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));
-}
-
-void
-test_doc_spine (const char *path)
-{
-    GepubDoc *doc = gepub_doc_new (path);
-    int id = 0;
-
-    do {
-        PTEST ("%d: %s\n", id++, gepub_doc_get_current_id (doc));
-    } while (gepub_doc_go_next (doc));
-
+    //g_free (cover);
+    //g_free (cover_mime);
     g_object_unref (G_OBJECT (doc));
 }
 
@@ -248,7 +94,6 @@ main (int argc, char **argv)
     GtkTextBuffer *buffer;
 
     GepubDoc *doc;
-    GtkWidget *textview2;
     GtkWidget *widget = gepub_widget_new ();
 
     if (argc < 2) {
@@ -271,28 +116,15 @@ main (int argc, char **argv)
 
     gepub_widget_set_doc (GEPUB_WIDGET (widget), doc);
 
-    scrolled = gtk_scrolled_window_new (NULL, NULL);
-    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, 
GTK_POLICY_AUTOMATIC);
-    textview2 = gtk_text_view_new ();
-    gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (textview2), GTK_WRAP_WORD_CHAR);
-    page_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview2));
-    gtk_text_buffer_create_tag (page_buffer, "bold", "weight", PANGO_WEIGHT_BOLD, "foreground", "#ff0000", 
NULL);
-    gtk_text_buffer_create_tag (page_buffer, "italic", "style", PANGO_STYLE_ITALIC, "foreground", "#005500", 
NULL);
-    gtk_text_buffer_create_tag (page_buffer, "head", "size-points", 20.0, NULL);
-    update_text (doc);
-    gtk_container_add (GTK_CONTAINER (scrolled), GTK_WIDGET (textview2));
-    gtk_widget_set_size_request (GTK_WIDGET (textview2), 500, 300);
-
     vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
     hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
     b_prev = gtk_button_new_with_label ("prev");
-    g_signal_connect (b_prev, "clicked", (GCallback)button_pressed, GEPUB_WIDGET (widget));
+    g_signal_connect (b_prev, "clicked", (GCallback)button_pressed, GEPUB_DOC (doc));
     b_next = gtk_button_new_with_label ("next");
-    g_signal_connect (b_next, "clicked", (GCallback)button_pressed, GEPUB_WIDGET (widget));
+    g_signal_connect (b_next, "clicked", (GCallback)button_pressed, GEPUB_DOC (doc));
     gtk_container_add (GTK_CONTAINER (hbox), b_prev);
     gtk_container_add (GTK_CONTAINER (hbox), b_next);
     gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5);
-    gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 5);
 
     textview = gtk_text_view_new ();
     scrolled = gtk_scrolled_window_new (NULL, NULL);
@@ -308,12 +140,7 @@ main (int argc, char **argv)
 
 
     // Testing all
-    TEST(test_open, argv[1])
-    TEST(test_read, argv[1])
-    TEST(test_root_file, argv[1])
     TEST(test_doc_name, argv[1])
-    TEST(test_doc_resources, argv[1])
-    TEST(test_doc_spine, argv[1])
 
     // Freeing the mallocs :P
     if (buf2) {


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