/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Pix
*
* Copyright (C) 2009 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include
#include
#include "gth-search.h"
#include "gth-search-source.h"
#define SEARCH_FORMAT "1.0"
static void gth_search_dom_domizable_interface_init (DomDomizableInterface *iface);
static void gth_search_gth_duplicable_interface_init (GthDuplicableInterface *iface);
struct _GthSearchPrivate {
GList *sources;
GthTestChain *test;
};
G_DEFINE_TYPE_WITH_CODE (GthSearch,
gth_search,
GTH_TYPE_CATALOG,
G_ADD_PRIVATE (GthSearch)
G_IMPLEMENT_INTERFACE (DOM_TYPE_DOMIZABLE,
gth_search_dom_domizable_interface_init)
G_IMPLEMENT_INTERFACE (GTH_TYPE_DUPLICABLE,
gth_search_gth_duplicable_interface_init))
static DomDomizableInterface *dom_domizable_parent_iface = NULL;
static GthDuplicableInterface *gth_duplicable_parent_iface = NULL;
static DomElement *
gth_search_create_root (GthCatalog *catalog,
DomDocument *doc)
{
return dom_document_create_element (doc, "search",
"version", SEARCH_FORMAT,
NULL);
}
static void
gth_search_read_from_doc (GthCatalog *base,
DomElement *root)
{
GthSearch *self;
DomElement *node;
g_return_if_fail (DOM_IS_ELEMENT (root));
self = GTH_SEARCH (base);
GTH_CATALOG_CLASS (gth_search_parent_class)->read_from_doc (GTH_CATALOG (self), root);
_g_object_list_unref (self->priv->sources);
self->priv->sources = NULL;
gth_search_set_test (self, NULL);
for (node = root->first_child; node; node = node->next_sibling) {
if (g_strcmp0 (node->tag_name, "folder") == 0) {
GthSearchSource *source;
GFile *folder;
source = gth_search_source_new ();
folder = g_file_new_for_uri (dom_element_get_attribute (node, "uri"));
gth_search_source_set_folder (source, folder);
g_object_unref (folder);
gth_search_source_set_recursive (source, (g_strcmp0 (dom_element_get_attribute (node, "recursive"), "true") == 0));
self->priv->sources = g_list_prepend (self->priv->sources, source);
}
else if (g_strcmp0 (node->tag_name, "tests") == 0) {
GthTest *test;
test = gth_test_chain_new (GTH_MATCH_TYPE_NONE, NULL);
dom_domizable_load_from_element (DOM_DOMIZABLE (test), node);
gth_search_set_test (self, GTH_TEST_CHAIN (test));
}
else if (g_strcmp0 (node->tag_name, "sources") == 0) {
DomElement *source_node;
for (source_node = node->first_child; source_node; source_node = source_node->next_sibling) {
if (g_strcmp0 (source_node->tag_name, "source") == 0) {
GthSearchSource *source;
source = gth_search_source_new ();
dom_domizable_load_from_element (DOM_DOMIZABLE (source), source_node);
self->priv->sources = g_list_prepend (self->priv->sources, source);
}
}
}
}
self->priv->sources = g_list_reverse (self->priv->sources);
}
static void
_gth_search_write_to_doc (GthSearch *self,
DomDocument *doc,
DomElement *root)
{
DomElement *sources;
GList *scan;
sources = dom_document_create_element (doc, "sources", NULL);
for (scan = self->priv->sources; scan; scan = scan->next) {
GthSearchSource *source = scan->data;
dom_element_append_child (sources, dom_domizable_create_element (DOM_DOMIZABLE (source), doc));
}
dom_element_append_child (root, sources);
dom_element_append_child (root, dom_domizable_create_element (DOM_DOMIZABLE (self->priv->test), doc));
}
static void
gth_search_write_to_doc (GthCatalog *catalog,
DomDocument *doc,
DomElement *root)
{
GTH_CATALOG_CLASS (gth_search_parent_class)->write_to_doc (catalog, doc, root);
_gth_search_write_to_doc (GTH_SEARCH (catalog), doc, root);
}
static DomElement*
gth_search_real_create_element (DomDomizable *base,
DomDocument *doc)
{
GthSearch *self;
DomElement *element;
g_return_val_if_fail (DOM_IS_DOCUMENT (doc), NULL);
self = GTH_SEARCH (base);
element = gth_search_create_root (GTH_CATALOG (self), doc);
gth_search_write_to_doc (GTH_CATALOG (self), doc, element);
return element;
}
static void
gth_search_real_load_from_element (DomDomizable *base,
DomElement *element)
{
gth_search_read_from_doc (GTH_CATALOG (base), element);
}
static GObject *
gth_search_real_duplicate (GthDuplicable *duplicable)
{
GthSearch *search = GTH_SEARCH (duplicable);
GthSearch *new_search;
GList *file_list;
GList *new_file_list = NULL;
GList *scan;
new_search = gth_search_new ();
gth_search_set_sources (new_search, gth_search_get_sources (search));
if (search->priv->test != NULL)
new_search->priv->test = (GthTestChain*) gth_duplicable_duplicate (GTH_DUPLICABLE (search->priv->test));
file_list = gth_catalog_get_file_list (GTH_CATALOG (search));
for (scan = file_list; scan; scan = scan->next) {
GFile *file = scan->data;
new_file_list = g_list_prepend (new_file_list, g_file_dup (file));
}
gth_catalog_set_file_list (GTH_CATALOG (new_search), new_file_list);
_g_object_list_unref (new_file_list);
return (GObject *) new_search;
}
static void
gth_search_finalize (GObject *object)
{
GthSearch *search;
search = GTH_SEARCH (object);
_g_object_list_unref (search->priv->sources);
if (search->priv->test != NULL)
g_object_unref (search->priv->test);
G_OBJECT_CLASS (gth_search_parent_class)->finalize (object);
}
static void
gth_search_class_init (GthSearchClass *class)
{
GObjectClass *object_class;
GthCatalogClass *catalog_class;
object_class = G_OBJECT_CLASS (class);
object_class->finalize = gth_search_finalize;
catalog_class = GTH_CATALOG_CLASS (class);
catalog_class->create_root = gth_search_create_root;
catalog_class->read_from_doc = gth_search_read_from_doc;
catalog_class->write_to_doc = gth_search_write_to_doc;
}
static void
gth_search_dom_domizable_interface_init (DomDomizableInterface *iface)
{
dom_domizable_parent_iface = g_type_interface_peek_parent (iface);
iface->create_element = gth_search_real_create_element;
iface->load_from_element = gth_search_real_load_from_element;
}
static void
gth_search_gth_duplicable_interface_init (GthDuplicableInterface *iface)
{
gth_duplicable_parent_iface = g_type_interface_peek_parent (iface);
iface->duplicate = gth_search_real_duplicate;
}
static void
gth_search_init (GthSearch *search)
{
search->priv = gth_search_get_instance_private (search);
search->priv->sources = NULL;
search->priv->test = NULL;
}
GthSearch *
gth_search_new (void)
{
return (GthSearch *) g_object_new (GTH_TYPE_SEARCH, NULL);
}
GthSearch*
gth_search_new_from_data (void *buffer,
gsize count,
GError **error)
{
DomDocument *doc;
DomElement *root;
GthSearch *search;
doc = dom_document_new ();
if (! dom_document_load (doc, (const char *) buffer, count, error))
return NULL;
root = DOM_ELEMENT (doc)->first_child;
if (g_strcmp0 (root->tag_name, "search") != 0) {
*error = g_error_new_literal (DOM_ERROR, DOM_ERROR_INVALID_FORMAT, _("Invalid file format"));
return NULL;
}
search = gth_search_new ();
dom_domizable_load_from_element (DOM_DOMIZABLE (search), root);
g_object_unref (doc);
return search;
}
void
gth_search_set_sources (GthSearch *search,
GList *sources /* GthSearchSource list */)
{
_g_object_list_unref (search->priv->sources);
search->priv->sources = _g_object_list_ref (sources);
}
void
gth_search_set_source (GthSearch *search,
GFile *folder,
gboolean recursive)
{
GthSearchSource *source;
_g_object_list_unref (search->priv->sources);
search->priv->sources = NULL;
source = gth_search_source_new ();
gth_search_source_set_folder (source, folder);
gth_search_source_set_recursive (source, recursive);
search->priv->sources = g_list_prepend (search->priv->sources, source);
}
GList *
gth_search_get_sources (GthSearch *search)
{
return search->priv->sources;
}
void
gth_search_set_test (GthSearch *search,
GthTestChain *test)
{
if (test == search->priv->test)
return;
if (search->priv->test != NULL) {
g_object_unref (search->priv->test);
search->priv->test = NULL;
}
if (test != NULL)
search->priv->test = g_object_ref (test);
}
GthTestChain *
gth_search_get_test (GthSearch *search)
{
if (search->priv->test != NULL)
return search->priv->test;
else
return NULL;
}
static DomDocument *
_create_fake_document (GthSearch *self)
{
DomDocument *doc;
DomElement *root;
doc = dom_document_new ();
root = dom_document_create_element (doc, "search", NULL);
dom_element_append_child (DOM_ELEMENT (doc), root);
_gth_search_write_to_doc (self, doc, root);
return doc;
}
gboolean
gth_search_equal (GthSearch *a,
GthSearch *b)
{
DomDocument *doc_a;
DomDocument *doc_b;
char *xml_a;
gsize size_a;
char *xml_b;
gsize size_b;
gboolean equal;
doc_a = _create_fake_document (a);
doc_b = _create_fake_document (b);
xml_a = dom_document_dump (doc_a, &size_a);
xml_b = dom_document_dump (doc_b, &size_b);
equal = (size_a == size_b) && (g_strcmp0 (xml_a, xml_b) == 0);
g_free (xml_a);
g_free (xml_b);
return equal;
}