[libgxps] Add missing files
- From: Carlos Garcia Campos <carlosgc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgxps] Add missing files
- Date: Sun, 5 Sep 2010 15:12:05 +0000 (UTC)
commit 5813b44653cfb0dbcdf302d150ff88b66448c0d0
Author: Carlos Garcia Campos <carlosgc gnome org>
Date: Sun Sep 5 17:11:18 2010 +0200
Add missing files
I forgot to git add gxps-document-structure.[ch]. Thanks chpe!
libgxps/gxps-document-structure.c | 436 +++++++++++++++++++++++++++++++++++++
libgxps/gxps-document-structure.h | 73 ++++++
2 files changed, 509 insertions(+), 0 deletions(-)
---
diff --git a/libgxps/gxps-document-structure.c b/libgxps/gxps-document-structure.c
new file mode 100644
index 0000000..5de7c70
--- /dev/null
+++ b/libgxps/gxps-document-structure.c
@@ -0,0 +1,436 @@
+/* GXPSDocumentStructure
+ *
+ * Copyright (C) 2010 Carlos Garcia Campos <carlosgc gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include "gxps-archive.h"
+#include "gxps-private.h"
+#include "gxps-error.h"
+
+enum {
+ PROP_0,
+ PROP_ARCHIVE,
+ PROP_SOURCE
+};
+
+struct _GXPSDocumentStructurePrivate {
+ GXPSArchive *zip;
+ gchar *source;
+
+ /* Outline */
+ GList *outline;
+};
+
+typedef struct _OutlineNode OutlineNode;
+struct _OutlineNode {
+ gchar *desc;
+ gchar *target;
+ guint level;
+
+ OutlineNode *parent;
+ GList *children;
+};
+
+G_DEFINE_TYPE (GXPSDocumentStructure, gxps_document_structure, G_TYPE_OBJECT)
+
+static void
+outline_node_free (OutlineNode *node)
+{
+ if (G_UNLIKELY (!node))
+ return;
+
+ g_free (node->desc);
+ g_free (node->target);
+
+ if (node->children)
+ g_list_foreach (node->children, (GFunc)outline_node_free, NULL);
+
+ g_slice_free (OutlineNode, node);
+}
+
+static void
+gxps_document_structure_finalize (GObject *object)
+{
+ GXPSDocumentStructure *structure = GXPS_DOCUMENT_STRUCTURE (object);
+
+ if (structure->priv->zip) {
+ g_object_unref (structure->priv->zip);
+ structure->priv->zip = NULL;
+ }
+
+ if (structure->priv->source) {
+ g_free (structure->priv->source);
+ structure->priv->source = NULL;
+ }
+
+ if (structure->priv->outline) {
+ g_list_foreach (structure->priv->outline, (GFunc)outline_node_free, NULL);
+ structure->priv->outline = NULL;
+ }
+
+ G_OBJECT_CLASS (gxps_document_structure_parent_class)->finalize (object);
+}
+
+static void
+gxps_document_structure_init (GXPSDocumentStructure *structure)
+{
+ structure->priv = G_TYPE_INSTANCE_GET_PRIVATE (structure,
+ GXPS_TYPE_DOCUMENT_STRUCTURE,
+ GXPSDocumentStructurePrivate);
+}
+
+static void
+gxps_document_structure_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GXPSDocumentStructure *structure = GXPS_DOCUMENT_STRUCTURE (object);
+
+ switch (prop_id) {
+ case PROP_ARCHIVE:
+ structure->priv->zip = g_value_dup_object (value);
+ break;
+ case PROP_SOURCE:
+ structure->priv->source = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gxps_document_structure_class_init (GXPSDocumentStructureClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->set_property = gxps_document_structure_set_property;
+ object_class->finalize = gxps_document_structure_finalize;
+
+ g_object_class_install_property (object_class,
+ PROP_ARCHIVE,
+ g_param_spec_object ("archive",
+ "Archive",
+ "The document archive",
+ GXPS_TYPE_ARCHIVE,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (object_class,
+ PROP_SOURCE,
+ g_param_spec_string ("source",
+ "Source",
+ "The DocStructure Source File",
+ NULL,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_type_class_add_private (klass, sizeof (GXPSDocumentStructurePrivate));
+}
+
+GXPSDocumentStructure *
+_gxps_document_structure_new (GXPSArchive *zip,
+ const gchar *source)
+{
+ GXPSDocumentStructure *structure;
+
+ structure = g_object_new (GXPS_TYPE_DOCUMENT_STRUCTURE,
+ "archive", zip,
+ "source", source,
+ NULL);
+ return GXPS_DOCUMENT_STRUCTURE (structure);
+}
+
+/* Document Outline */
+typedef struct {
+ GXPSDocumentStructure *structure;
+ guint level;
+ GList *prevs;
+ GList *outline;
+} GXPSOutlineContext;
+
+static void
+outline_start_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **names,
+ const gchar **values,
+ gpointer user_data,
+ GError **error)
+{
+ GXPSOutlineContext *ctx = (GXPSOutlineContext *)user_data;
+
+ if (strcmp (element_name, "DocumentOutline") == 0) {
+ } else if (strcmp (element_name, "OutlineEntry") == 0) {
+ gint i;
+ gint level = 1;
+ const gchar *desc = NULL;
+ const gchar *target = NULL;
+ OutlineNode *node;
+
+ for (i = 0; names[i] != NULL; i++) {
+ if (strcmp (names[i], "OutlineLevel") == 0) {
+ if (!gxps_value_get_int (values[i], &level))
+ level = 1;
+ } else if (strcmp (names[i], "Description") == 0) {
+ desc = values[i];
+ } else if (strcmp (names[i], "OutlineTarget") == 0) {
+ target = values[i];
+ } else if (strcmp (names[i], "xml:lang") == 0) {
+ /* TODO */
+ }
+ }
+
+ if (!desc || !target) {
+ gxps_parse_error (context,
+ ctx->structure->priv->source,
+ G_MARKUP_ERROR_MISSING_ATTRIBUTE,
+ element_name,
+ !desc ? "Description" : "OutlineTarget",
+ NULL, error);
+ return;
+ }
+
+ node = g_slice_new0 (OutlineNode);
+ node->desc = g_strdup (desc);
+ node->level = level;
+ node->target = gxps_resolve_relative_path (ctx->structure->priv->source, target);
+
+ if (ctx->level < level) {
+ /* Higher level, make previous the parent of current one */
+ node->parent = ctx->prevs ? (OutlineNode *)ctx->prevs->data : NULL;
+ } else if (ctx->level > level) {
+ /* Lower level, pop previous nodes, reordering children list,
+ * until previous node of the same level is found
+ */
+ while (ctx->prevs) {
+ OutlineNode *prev = (OutlineNode *)ctx->prevs->data;
+
+ ctx->prevs = g_list_delete_link (ctx->prevs, ctx->prevs);
+ prev->children = g_list_reverse (prev->children);
+ if (prev->level == level) {
+ node->parent = prev->parent;
+ break;
+ }
+ }
+ g_assert (level > 1 && node->parent != NULL);
+ } else if (ctx->level == level) {
+ /* Same level, parent must be the same as the previous node */
+ node->parent = (ctx->prevs) ? ((OutlineNode *)ctx->prevs->data)->parent : NULL;
+ ctx->prevs = g_list_delete_link (ctx->prevs, ctx->prevs);
+ }
+
+ if (level == 1)
+ ctx->outline = g_list_prepend (ctx->outline, node);
+ else
+ node->parent->children = g_list_prepend (node->parent->children, node);
+
+ ctx->prevs = g_list_prepend (ctx->prevs, node);
+ ctx->level = level;
+ }
+}
+
+static void
+outline_end_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ gpointer user_data,
+ GError **error)
+{
+ GXPSOutlineContext *ctx = (GXPSOutlineContext *)user_data;
+
+ if (strcmp (element_name, "DocumentOutline") == 0) {
+ /* Reorder children of pending node and remove them */
+ while (ctx->prevs) {
+ OutlineNode *prev = (OutlineNode *)ctx->prevs->data;
+
+ ctx->prevs = g_list_delete_link (ctx->prevs, ctx->prevs);
+ prev->children = g_list_reverse (prev->children);
+ }
+ ctx->outline = g_list_reverse (ctx->outline);
+ } else if (strcmp (element_name, "OutlineEntry") == 0) {
+ }
+}
+
+static const GMarkupParser outline_parser = {
+ outline_start_element,
+ outline_end_element,
+ NULL,
+ NULL,
+ NULL
+};
+
+static GList *
+gxps_document_structure_parse_outline (GXPSDocumentStructure *structure,
+ GError **error)
+{
+ GInputStream *stream;
+ GXPSOutlineContext ctx;
+ GMarkupParseContext *context;
+
+ stream = gxps_archive_open (structure->priv->zip,
+ structure->priv->source);
+ if (!stream) {
+ g_set_error (error,
+ GXPS_ERROR,
+ GXPS_ERROR_SOURCE_NOT_FOUND,
+ "Document Structure source %s not found in archive",
+ structure->priv->source);
+ return NULL;
+ }
+
+ ctx.structure = structure;
+ ctx.prevs = NULL;
+ ctx.level = 0;
+ ctx.outline = NULL;
+
+ context = g_markup_parse_context_new (&outline_parser, 0, &ctx, NULL);
+ gxps_parse_stream (context, stream, error);
+ g_object_unref (stream);
+ g_markup_parse_context_free (context);
+
+ return ctx.outline;
+}
+
+/* Try to know ASAP whether document has an outline */
+static void
+check_outline_start_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **names,
+ const gchar **values,
+ gpointer user_data,
+ GError **error)
+{
+ gboolean *has_outline = (gboolean *)user_data;
+
+ if (*has_outline == TRUE)
+ return;
+
+ if (strcmp (element_name, "DocumentStructure.Outline") == 0)
+ *has_outline = TRUE;
+}
+
+static const GMarkupParser check_outline_parser = {
+ check_outline_start_element,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+gboolean
+gxps_document_structure_has_outline (GXPSDocumentStructure *structure)
+{
+ GInputStream *stream;
+ GMarkupParseContext *context;
+ gboolean retval = FALSE;
+
+ stream = gxps_archive_open (structure->priv->zip,
+ structure->priv->source);
+ if (!stream)
+ return FALSE;
+
+ context = g_markup_parse_context_new (&check_outline_parser, 0, &retval, NULL);
+ gxps_parse_stream (context, stream, NULL);
+ g_object_unref (stream);
+ g_markup_parse_context_free (context);
+
+ return retval;
+}
+
+typedef struct {
+ GXPSDocumentStructure *structure;
+ GList *current;
+} OutlineIter;
+
+gboolean
+gxps_document_structure_outline_iter_init (GXPSOutlineIter *iter,
+ GXPSDocumentStructure *structure)
+{
+ OutlineIter *oi = (OutlineIter *)iter;
+
+ g_return_val_if_fail (iter != NULL, FALSE);
+ g_return_val_if_fail (GXPS_IS_DOCUMENT_STRUCTURE (structure), FALSE);
+
+ oi->structure = structure;
+ if (!structure->priv->outline)
+ structure->priv->outline = gxps_document_structure_parse_outline (structure, NULL);
+ oi->current = structure->priv->outline;
+
+ return oi->current != NULL;
+}
+
+gboolean
+gxps_outline_iter_next (GXPSOutlineIter *iter)
+{
+ OutlineIter *oi = (OutlineIter *)iter;
+
+ if (!oi->current)
+ return FALSE;
+
+ oi->current = g_list_next (oi->current);
+ return oi->current != NULL;
+}
+
+gboolean
+gxps_outline_iter_children (GXPSOutlineIter *iter,
+ GXPSOutlineIter *parent)
+{
+ OutlineIter *oi = (OutlineIter *)parent;
+ OutlineIter *retval = (OutlineIter *)iter;
+ OutlineNode *node;
+
+ g_assert (oi->current != NULL);
+
+ node = (OutlineNode *)oi->current->data;
+ if (!node->children)
+ return FALSE;
+
+ retval->structure = oi->structure;
+ retval->current = node->children;
+
+ return TRUE;
+}
+
+const gchar *
+gxps_outline_iter_get_description (GXPSOutlineIter *iter)
+{
+ OutlineIter *oi = (OutlineIter *)iter;
+ OutlineNode *node;
+
+ g_assert (oi->current != NULL);
+
+ node = (OutlineNode *)oi->current->data;
+
+ return node->desc;
+}
+
+GXPSLinkTarget *
+gxps_outline_iter_get_target (GXPSOutlineIter *iter)
+{
+ OutlineIter *oi = (OutlineIter *)iter;
+ OutlineNode *node;
+
+ g_assert (oi->current != NULL);
+
+ node = (OutlineNode *)oi->current->data;
+
+ return _gxps_link_target_new (oi->structure->priv->zip, node->target);
+}
+
diff --git a/libgxps/gxps-document-structure.h b/libgxps/gxps-document-structure.h
new file mode 100644
index 0000000..8db1a4c
--- /dev/null
+++ b/libgxps/gxps-document-structure.h
@@ -0,0 +1,73 @@
+/* GXPSDocumentStructure
+ *
+ * Copyright (C) 2010 Carlos Garcia Campos <carlosgc gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if !defined (__GXPS_H_INSIDE__) && !defined (GXPS_COMPILATION)
+#error "Only <libgxps/gxps.h> can be included directly."
+#endif
+
+#ifndef __GXPS_DOCUMENT_STRUCTURE_H__
+#define __GXPS_DOCUMENT_STRUCTURE_H__
+
+#include <glib-object.h>
+#include "gxps-links.h"
+
+G_BEGIN_DECLS
+
+#define GXPS_TYPE_DOCUMENT_STRUCTURE (gxps_document_structure_get_type ())
+#define GXPS_DOCUMENT_STRUCTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GXPS_TYPE_DOCUMENT_STRUCTURE, GXPSDocumentStructure))
+#define GXPS_DOCUMENT_STRUCTURE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GXPS_TYPE_DOCUMENT_STRUCTURE, GXPSDocumentClassStructure))
+#define GXPS_IS_DOCUMENT_STRUCTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GXPS_TYPE_DOCUMENT_STRUCTURE))
+#define GXPS_IS_DOCUMENT_STRUCTURE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GXPS_TYPE_DOCUMENT_STRUCTURE))
+#define GXPS_DOCUMENT_STRUCTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GXPS_TYPE_DOCUMENT_STRUCTURE, GXPSDocumentStructureClass))
+
+typedef struct _GXPSDocumentStructure GXPSDocumentStructure;
+typedef struct _GXPSDocumentStructureClass GXPSDocumentStructureClass;
+typedef struct _GXPSDocumentStructurePrivate GXPSDocumentStructurePrivate;
+
+struct _GXPSDocumentStructure {
+ GObject parent;
+
+ GXPSDocumentStructurePrivate *priv;
+};
+
+struct _GXPSDocumentStructureClass {
+ GObjectClass parent_class;
+};
+
+typedef struct _GXPSOutlineIter GXPSOutlineIter;
+struct _GXPSOutlineIter {
+ /*< private >*/
+ gpointer dummy1;
+ gpointer dummy2;
+};
+
+GType gxps_document_structure_get_type (void) G_GNUC_CONST;
+
+gboolean gxps_document_structure_has_outline (GXPSDocumentStructure *structure);
+gboolean gxps_document_structure_outline_iter_init (GXPSOutlineIter *iter,
+ GXPSDocumentStructure *structure);
+gboolean gxps_outline_iter_next (GXPSOutlineIter *iter);
+gboolean gxps_outline_iter_children (GXPSOutlineIter *iter,
+ GXPSOutlineIter *parent);
+const gchar *gxps_outline_iter_get_description (GXPSOutlineIter *iter);
+GXPSLinkTarget *gxps_outline_iter_get_target (GXPSOutlineIter *iter);
+
+G_END_DECLS
+
+#endif /* __GXPS_DOCUMENT_STRUCTURE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]