aboutsummaryrefslogblamecommitdiffstats
path: root/autoarchive/autoar-create.c
blob: 4b946bd430bc44c643f2fba185f2e78766c12ec6 (plain) (tree)































                                                                             
                   












                                                                              
                                                    


























                             
                                                    































                                                        

                                             





























                                                                     


                                                                    






































                                                                              






                                                        




















                                                          







                                                 





















































































































                                                                                                                    









                                                                               





































































































                                                                                         


                                        
 
                         











                                                 










































                                                                              
/* vim: set sw=2 ts=2 sts=2 et: */
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * autoar-create.c
 * Automatically create archives in some GNOME programs
 *
 * Copyright (C) 2013  Ting-Wei Lan
 *
 * This program 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 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 *
 */

#include "config.h"

#include "autoar-create.h"
#include "autoar-pref.h"

#include <gio/gio.h>
#include <glib.h>
#include <stdarg.h>

G_DEFINE_TYPE (AutoarCreate, autoar_create, G_TYPE_OBJECT)

#define AUTOAR_CREATE_GET_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE ((o), AUTOAR_TYPE_CREATE, AutoarCreatePrivate))

#define BUFFER_SIZE (64 * 1024)

struct _AutoarCreatePrivate
{
  char **source;
  char  *output;

  guint64 size; /* This field is currently unused */
  guint64 completed_size;

  guint files;
  guint completed_files;

  AutoarPref *arpref;

  GOutputStream *ostream;
  void          *buffer;
  gssize         buffer_size;
  GError        *error;
};

enum
{
  DECIDE_DEST,
  PROGRESS,
  COMPLETED,
  ERROR,
  LAST_SIGNAL
};

enum
{
  PROP_0,
  PROP_SOURCE,
  PROP_OUTPUT,
  PROP_SIZE, /* This property is currently unused */
  PROP_COMPLETED_SIZE,
  PROP_FILES,
  PROP_COMPLETED_FILES
};

static guint autoar_create_signals[LAST_SIGNAL] = { 0 };
static GQuark autoar_create_quark;

static void
autoar_create_get_property (GObject    *object,
                            guint       property_id,
                            GValue     *value,
                            GParamSpec *pspec)
{
  AutoarCreate *arcreate;
  AutoarCreatePrivate *priv;

  GVariant *variant;
  const char* const* strv;

  arcreate = AUTOAR_CREATE (object);
  priv = arcreate->priv;

  switch (property_id) {
    case PROP_SOURCE:
      strv = (const char* const*)(priv->source);
      variant = g_variant_new_strv (strv, -1);
      g_value_take_variant (value, variant);
      break;
    case PROP_OUTPUT:
      g_value_set_string (value, priv->output);
      break;
    case PROP_SIZE:
      g_value_set_uint64 (value, priv->size);
    case PROP_COMPLETED_SIZE:
      g_value_set_uint64 (value, priv->completed_size);
      break;
    case PROP_FILES:
      g_value_set_uint (value, priv->files);
      break;
    case PROP_COMPLETED_FILES:
      g_value_set_uint (value, priv->completed_files);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

static void
autoar_create_set_property (GObject      *object,
                            guint         property_id,
                            const GValue *value,
                            GParamSpec   *pspec)
{
  AutoarCreate *arcreate;
  AutoarCreatePrivate *priv;

  const char **strv;

  arcreate = AUTOAR_CREATE (object);
  priv = arcreate->priv;

  switch (property_id) {
    case PROP_SIZE:
      autoar_create_set_size (arcreate, g_value_get_uint64 (value));
      break;
    case PROP_COMPLETED_SIZE:
      autoar_create_set_completed_size (arcreate, g_value_get_uint64 (value));
      break;
    case PROP_FILES:
      autoar_create_set_files (arcreate, g_value_get_uint (value));
      break;
    case PROP_COMPLETED_FILES:
      autoar_create_set_completed_files (arcreate, g_value_get_uint (value));
      break;
    case PROP_SOURCE:
      strv = g_variant_get_strv (g_value_get_variant (value), NULL);
      g_strfreev (arcreate->priv->source);
      arcreate->priv->source = g_strdupv ((char**)strv);
      break;
    case PROP_OUTPUT:
      g_free (priv->output);
      priv->output = g_value_dup_string (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

char**
autoar_create_get_source (AutoarCreate *arcreate)
{
  g_return_val_if_fail (AUTOAR_IS_CREATE (arcreate), NULL);
  return arcreate->priv->source;
}

char*
autoar_create_get_output (AutoarCreate *arcreate)
{
  g_return_val_if_fail (AUTOAR_IS_CREATE (arcreate), NULL);
  return arcreate->priv->output;
}

guint64
autoar_create_get_size (AutoarCreate *arcreate)
{
  g_return_val_if_fail (AUTOAR_IS_CREATE (arcreate), 0);
  return arcreate->priv->size;
}

guint64
autoar_create_get_completed_size (AutoarCreate *arcreate)
{
  g_return_val_if_fail (AUTOAR_IS_CREATE (arcreate), 0);
  return arcreate->priv->completed_size;
}

guint
autoar_create_get_files (AutoarCreate *arcreate)
{
  g_return_val_if_fail (AUTOAR_IS_CREATE (arcreate), 0);
  return arcreate->priv->files;
}

guint
autoar_create_get_completed_files (AutoarCreate *arcreate)
{
  g_return_val_if_fail (AUTOAR_IS_CREATE (arcreate), 0);
  return arcreate->priv->completed_files;
}

void
autoar_create_set_size (AutoarCreate *arcreate,
                        guint64 size)
{
  g_return_if_fail (AUTOAR_IS_CREATE (arcreate));
  arcreate->priv->size = size;
}

void
autoar_create_set_completed_size (AutoarCreate *arcreate,
                                  guint64 completed_size)
{
  g_return_if_fail (AUTOAR_IS_CREATE (arcreate));
  g_return_if_fail (completed_size <= arcreate->priv->completed_size);
  arcreate->priv->completed_size = completed_size;
}

void
autoar_create_set_files (AutoarCreate *arcreate,
                         guint files)
{
  g_return_if_fail (AUTOAR_IS_CREATE (arcreate));
  arcreate->priv->files = files;
}

void
autoar_create_set_completed_files (AutoarCreate *arcreate,
                                   guint completed_files)
{
  g_return_if_fail (AUTOAR_IS_CREATE (arcreate));
  g_return_if_fail (completed_files <= arcreate->priv->completed_files);
  arcreate->priv->completed_files = completed_files;
}

static void
autoar_create_dispose (GObject *object)
{
  AutoarCreate *arcreate;
  arcreate = AUTOAR_CREATE (object);

  g_debug ("AutoarCreate: dispose");

  g_clear_object (&(arcreate->priv->arpref));

  G_OBJECT_CLASS (autoar_create_parent_class)->dispose (object);
}

static void
autoar_create_finalize (GObject *object)
{
  AutoarCreate *arcreate;
  AutoarCreatePrivate *priv;

  arcreate = AUTOAR_CREATE (object);
  priv = arcreate->priv;

  g_debug ("AutoarCreate: finalize");

  g_strfreev (priv->source);
  priv->source = NULL;

  g_free (priv->output);
  priv->output = NULL;

  if (priv->ostream != NULL) {
    if (!g_output_stream_is_closed (priv->ostream)) {
      g_output_stream_close (priv->ostream, NULL, NULL);
    }
    g_object_unref (priv->ostream);
  }

  g_free (priv->buffer);
  priv->buffer = NULL;

  if (priv->error != NULL) {
    g_error_free (priv->error);
    priv->error = NULL;
  }

  G_OBJECT_CLASS (autoar_create_parent_class)->finalize (object);
}

static void
autoar_create_class_init (AutoarCreateClass *klass)
{
  GObjectClass *object_class;
  GType type;
  GPtrArray *tmparr;

  object_class = G_OBJECT_CLASS (klass);
  type = G_TYPE_FROM_CLASS (klass);

  g_type_class_add_private (klass, sizeof (AutoarCreatePrivate));

  autoar_create_quark = g_quark_from_static_string ("autoar-create");

  object_class->get_property = autoar_create_get_property;
  object_class->set_property = autoar_create_set_property;
  object_class->dispose = autoar_create_dispose;
  object_class->finalize = autoar_create_finalize;

  tmparr = g_ptr_array_new ();
  g_ptr_array_add (tmparr, NULL);

  g_object_class_install_property (object_class, PROP_SOURCE,
                                   g_param_spec_variant ("source",
                                                         "Source archive",
                                                         "The source files and directories to be compressed",
                                                         G_VARIANT_TYPE_STRING_ARRAY,
                                                         g_variant_new_strv ((const char* const*)tmparr->pdata, -1),
                                                         G_PARAM_READWRITE |
                                                         G_PARAM_CONSTRUCT_ONLY |
                                                         G_PARAM_STATIC_NAME |
                                                         G_PARAM_STATIC_NICK |
                                                         G_PARAM_STATIC_BLURB));

  g_object_class_install_property (object_class, PROP_OUTPUT,
                                   g_param_spec_string ("output",
                                                        "Output directory",
                                                        "Output directory of created archive",
                                                        NULL,
                                                        G_PARAM_READWRITE |
                                                        G_PARAM_CONSTRUCT_ONLY |
                                                        G_PARAM_STATIC_NAME |
                                                        G_PARAM_STATIC_NICK |
                                                        G_PARAM_STATIC_BLURB));

  g_object_class_install_property (object_class, PROP_SIZE,
                                   g_param_spec_uint64 ("size",
                                                        "Size",
                                                        "Unused property",
                                                        0, G_MAXUINT64, 0,
                                                        G_PARAM_READWRITE |
                                                        G_PARAM_STATIC_NAME |
                                                        G_PARAM_STATIC_NICK |
                                                        G_PARAM_STATIC_BLURB));

  g_object_class_install_property (object_class, PROP_COMPLETED_SIZE,
                                   g_param_spec_uint64 ("completed-size",
                                                        "Read file size",
                                                        "Bytes written to the archive",
                                                        0, G_MAXUINT64, 0,
                                                        G_PARAM_READWRITE |
                                                        G_PARAM_STATIC_NAME |
                                                        G_PARAM_STATIC_NICK |
                                                        G_PARAM_STATIC_BLURB));

  g_object_class_install_property (object_class, PROP_FILES,
                                   g_param_spec_uint ("files",
                                                      "Files",
                                                      "Number of files to be compressed",
                                                      0, G_MAXUINT32, 0,
                                                      G_PARAM_READWRITE |
                                                      G_PARAM_STATIC_NAME |
                                                      G_PARAM_STATIC_NICK |
                                                      G_PARAM_STATIC_BLURB));

  g_object_class_install_property (object_class, PROP_COMPLETED_FILES,
                                   g_param_spec_uint ("completed-files",
                                                      "Read files",
                                                      "Number of files has been read",
                                                      0, G_MAXUINT32, 0,
                                                      G_PARAM_READWRITE |
                                                      G_PARAM_STATIC_NAME |
                                                      G_PARAM_STATIC_NICK |
                                                      G_PARAM_STATIC_BLURB));

  autoar_create_signals[DECIDE_DEST] =
    g_signal_new ("decide-dest",
                  type,
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (AutoarCreateClass, decide_dest),
                  NULL, NULL,
                  g_cclosure_marshal_generic,
                  G_TYPE_NONE,
                  1,
                  G_TYPE_FILE);

  autoar_create_signals[PROGRESS] =
    g_signal_new ("progress",
                  type,
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (AutoarCreateClass, progress),
                  NULL, NULL,
                  g_cclosure_marshal_generic,
                  G_TYPE_NONE,
                  2,
                  G_TYPE_UINT64,
                  G_TYPE_UINT);

  autoar_create_signals[COMPLETED] =
    g_signal_new ("completed",
                  type,
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (AutoarCreateClass, completed),
                  NULL, NULL,
                  g_cclosure_marshal_VOID__VOID,
                  G_TYPE_NONE,
                  0);

  autoar_create_signals[ERROR] =
    g_signal_new ("error",
                  type,
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (AutoarCreateClass, error),
                  NULL, NULL,
                  g_cclosure_marshal_VOID__POINTER,
                  G_TYPE_NONE,
                  1,
                  G_TYPE_POINTER);

  g_ptr_array_unref (tmparr);
}

static void
autoar_create_init (AutoarCreate *arcreate)
{
  AutoarCreatePrivate *priv;

  priv = AUTOAR_CREATE_GET_PRIVATE (arcreate);
  arcreate->priv = priv;

  priv->source = NULL;
  priv->output = NULL;

  priv->completed_size = 0;

  priv->files = 0;
  priv->completed_files = 0;

  priv->arpref = NULL;

  priv->ostream = NULL;
  priv->buffer_size = BUFFER_SIZE;
  priv->buffer = g_new (char, priv->buffer_size);
  priv->error = NULL;
}

AutoarCreate*
autoar_create_newv (AutoarPref  *arpref,
                    const char  *output,
                    const char **source)
{
  AutoarCreate *arcreate;

  g_return_val_if_fail (source != NULL, NULL);
  g_return_val_if_fail (output != NULL, NULL);

  arcreate = g_object_new (AUTOAR_TYPE_CREATE,
                           "source", source,
                           "output", output,
                           NULL);
  arcreate->priv->arpref = g_object_ref (arpref);

  return arcreate;
}

AutoarCreate*
autoar_create_new (AutoarPref *arpref,
                   const char *output,
                   ...)
{
  AutoarCreate *arcreate;
  char *str;
  va_list ap;
  GPtrArray *strv;

  va_start (ap, output);
  strv = g_ptr_array_new_with_free_func (g_free);
  while ((str = va_arg (ap, char*)) != NULL) {
    g_ptr_array_add (strv, str);
  }
  g_ptr_array_add (strv, NULL);
  va_end (ap);

  arcreate = autoar_create_newv (arpref, output, (const char**)(strv->pdata));
  g_ptr_array_unref (strv);
  return arcreate;
}

static void
autoar_create_run (AutoarCreate *arcreate,
                   gboolean in_thread)
{
  struct archive *a;
  struct archive_entry *entry;

}

void
autoar_create_start (AutoarCreate *arcreate)
{
  autoar_create_run (arcreate, FALSE);
}

void
autoar_create_start_async (AutoarCreate *arcreate)
{
}