[libgit2-glib] Implemented branch enumerator



commit 5c2b9ce5132ad92081d2a63c8a37816578f79715
Author: Jesse van den Kieboom <jessevdk gmail com>
Date:   Fri Nov 22 20:38:42 2013 +0100

    Implemented branch enumerator

 libgit2-glib/Makefile.am              |    2 +
 libgit2-glib/ggit-branch-enumerator.c |  111 +++++++++++++++++++++++++++++++++
 libgit2-glib/ggit-branch-enumerator.h |   45 +++++++++++++
 libgit2-glib/ggit-repository.c        |   40 ++++++------
 libgit2-glib/ggit-repository.h        |    8 +--
 libgit2-glib/ggit-types.h             |   23 ++-----
 6 files changed, 187 insertions(+), 42 deletions(-)
---
diff --git a/libgit2-glib/Makefile.am b/libgit2-glib/Makefile.am
index 8de0bd9..26378e1 100644
--- a/libgit2-glib/Makefile.am
+++ b/libgit2-glib/Makefile.am
@@ -21,6 +21,7 @@ INST_H_FILES =                                \
        ggit-blob.h                     \
        ggit-blob-output-stream.h       \
        ggit-branch.h                   \
+       ggit-branch-enumerator.h        \
        ggit-clone-options.h            \
        ggit-commit.h                   \
        ggit-config.h                   \
@@ -75,6 +76,7 @@ C_FILES =                             \
        ggit-blob.c                     \
        ggit-blob-output-stream.c       \
        ggit-branch.c                   \
+       ggit-branch-enumerator.c        \
        ggit-clone-options.c            \
        ggit-commit.c                   \
        ggit-config.c                   \
diff --git a/libgit2-glib/ggit-branch-enumerator.c b/libgit2-glib/ggit-branch-enumerator.c
new file mode 100644
index 0000000..b10208c
--- /dev/null
+++ b/libgit2-glib/ggit-branch-enumerator.c
@@ -0,0 +1,111 @@
+#include "ggit-branch-enumerator.h"
+
+struct _GgitBranchEnumerator
+{
+       git_branch_iterator *iterator;
+       GgitRef *ref;
+       gint ref_count;
+};
+
+G_DEFINE_BOXED_TYPE (GgitBranchEnumerator, ggit_branch_enumerator, ggit_branch_enumerator_ref, 
ggit_branch_enumerator_unref)
+
+GgitBranchEnumerator *
+_ggit_branch_enumerator_wrap (git_branch_iterator *iter)
+{
+       GgitBranchEnumerator *ret;
+
+       g_return_val_if_fail (iter != NULL, NULL);
+
+       ret = g_slice_new (GgitBranchEnumerator);
+       ret->ref_count = 1;
+       ret->iterator = iter;
+
+       return ret;
+}
+
+/**
+ * ggit_branch_enumerator_ref:
+ * @enumerator: a #GgitBranchEnumerator.
+ *
+ * Returns: (transfer full): @enumerator
+ */
+GgitBranchEnumerator *
+ggit_branch_enumerator_ref (GgitBranchEnumerator *enumerator)
+{
+       g_atomic_int_inc (&enumerator->ref_count);
+       return enumerator;
+}
+
+/**
+ * ggit_branch_enumerator_unref:
+ * @enumerator: a #GgitBranchEnumerator.
+ */
+void
+ggit_branch_enumerator_unref (GgitBranchEnumerator *enumerator)
+{
+       if (g_atomic_int_dec_and_test (&enumerator->ref_count))
+       {
+               g_clear_object (&enumerator->ref);
+
+               git_branch_iterator_free (enumerator->iterator);
+               g_slice_free (GgitBranchEnumerator, enumerator);
+       }
+}
+
+/**
+ * ggit_branch_enumerator_next:
+ * @enumerator: a #GgitBranchEnumerator.
+ *
+ * Move the enumerator to the next branch.
+ *
+ * Returns: %TRUE if there is a next branch, %FALSE otherwise.
+ */
+gboolean
+ggit_branch_enumerator_next (GgitBranchEnumerator *enumerator)
+{
+       git_reference *ref;
+       git_branch_t branch_type;
+
+       g_return_val_if_fail (enumerator != NULL, FALSE);
+
+       g_clear_object (&enumerator->ref);
+
+       if (git_branch_next (&ref, &branch_type, enumerator->iterator) != GIT_OK)
+       {
+               return FALSE;
+       }
+
+       if (branch_type == GIT_BRANCH_LOCAL)
+       {
+               enumerator->ref = GGIT_REF (_ggit_branch_wrap (ref));
+       }
+       else
+       {
+               enumerator->ref = _ggit_ref_wrap (ref);
+       }
+
+       return TRUE;
+}
+
+/**
+ * ggit_branch_enumerator_get:
+ * @enumerator: a #GgitBranchEnumerator.
+ *
+ * Returns the currently being enumerated branch, or %NULL. Note that the
+ * returned GgitRef will be of type GgitBranch if the ref represents a local
+ * branch.
+ *
+ * Returns: (transfer full): the branch ref.
+ */
+GgitRef *
+ggit_branch_enumerator_get (GgitBranchEnumerator *enumerator)
+{
+       g_return_val_if_fail (enumerator != NULL, NULL);
+
+       if (enumerator->ref != NULL)
+       {
+               return g_object_ref (enumerator->ref);
+       }
+
+       return NULL;
+}
diff --git a/libgit2-glib/ggit-branch-enumerator.h b/libgit2-glib/ggit-branch-enumerator.h
new file mode 100644
index 0000000..5d5aee3
--- /dev/null
+++ b/libgit2-glib/ggit-branch-enumerator.h
@@ -0,0 +1,45 @@
+/*
+ * ggit-branc-enumeratir.h
+ * This file is part of libgit2-glib
+ *
+ * Copyright (C) 2013 - Jesse van den Kieboom
+ *
+ * libgit2-glib 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.
+ *
+ * libgit2-glib 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 libgit2-glib. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GGIT_BRANCH_ENUMERATOR_H__
+#define __GGIT_BRANCH_ENUMERATOR_H__
+
+#include <glib-object.h>
+#include <git2.h>
+
+#include <libgit2-glib/ggit-types.h>
+#include <libgit2-glib/ggit-branch.h>
+
+G_BEGIN_DECLS
+
+#define GGIT_TYPE_BRANCH_ENUMERATOR (ggit_branch_enumerator_get_type ())
+#define GGIT_BRANCH_ENUMERATOR(obj) ((GgitBranchEnumerator *)obj)
+
+GType                 ggit_branch_enumerator_get_type   (void) G_GNUC_CONST;
+
+GgitBranchEnumerator *_ggit_branch_enumerator_wrap      (git_branch_iterator *iter);
+
+GgitBranchEnumerator *ggit_branch_enumerator_ref        (GgitBranchEnumerator *enumerator);
+void                  ggit_branch_enumerator_unref      (GgitBranchEnumerator *enumerator);
+
+gboolean              ggit_branch_enumerator_next       (GgitBranchEnumerator *enumerator);
+GgitRef              *ggit_branch_enumerator_get        (GgitBranchEnumerator *enumerator);
+
+#endif /* __GGIT_BRANCH_ENUMERATOR_H__ */
diff --git a/libgit2-glib/ggit-repository.c b/libgit2-glib/ggit-repository.c
index 6153b7e..a34c2c6 100644
--- a/libgit2-glib/ggit-repository.c
+++ b/libgit2-glib/ggit-repository.c
@@ -33,6 +33,7 @@
 #include "ggit-clone-options.h"
 #include "ggit-status-options.h"
 #include "ggit-tree-builder.h"
+#include "ggit-branch-enumerator.h"
 
 #define GGIT_REPOSITORY_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GGIT_TYPE_REPOSITORY, 
GgitRepositoryPrivate))
 
@@ -1393,42 +1394,39 @@ ggit_repository_create_branch (GgitRepository   *repository,
        return _ggit_branch_wrap (reference);
 }
 
-typedef gint (* _GitBranchesCallback) (const gchar  *branch_name,
-                                       git_branch_t  branch_type,
-                                       gpointer      payload);
-
 /**
  * ggit_repository_branches_foreach:
  * @repository: a #GgitRepository.
- * @branch_type: a GgitBranchType.
- * @callback: (scope call): a #GgitBranchesCallback.
- * @user_data: callback user data.
+ * @list_type: a GgitBranchType.
  * @error: a #GError for error reporting, or %NULL.
  *
- * Foreach branch of type @branch_type the callback @callback is called.
+ * Get a branch enumerator to enumerate over all branches of the specified
+ * @list_type in @repository.
+ *
+ * Returns: (transfer full): a branch enumerator.
  **/
-void
-ggit_repository_branches_foreach (GgitRepository        *repository,
-                                  GgitBranchType         branch_type,
-                                  GgitBranchesCallback   callback,
-                                  gpointer               user_data,
-                                  GError               **error)
+GgitBranchEnumerator *
+ggit_repository_enumerate_branches (GgitRepository  *repository,
+                                    GgitBranchType   list_type,
+                                    GError         **error)
 {
+       git_branch_iterator *iter;
        gint ret;
 
-       g_return_if_fail (GGIT_IS_REPOSITORY (repository));
-       g_return_if_fail (callback != NULL);
-       g_return_if_fail (error == NULL || *error == NULL);
+       g_return_val_if_fail (GGIT_IS_REPOSITORY (repository), NULL);
+       g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
-       ret = git_branch_foreach (_ggit_native_get (repository),
-                                 branch_type,
-                                 (_GitBranchesCallback) callback,
-                                 user_data);
+       ret = git_branch_iterator_new (&iter,
+                                      _ggit_native_get (repository),
+                                      (git_branch_t)list_type);
 
        if (ret != GIT_OK)
        {
                _ggit_error_set (error, ret);
+               return NULL;
        }
+
+       return _ggit_branch_enumerator_wrap (iter);
 }
 
 /**
diff --git a/libgit2-glib/ggit-repository.h b/libgit2-glib/ggit-repository.h
index ac18618..4b86bd6 100644
--- a/libgit2-glib/ggit-repository.h
+++ b/libgit2-glib/ggit-repository.h
@@ -198,11 +198,9 @@ GgitBranch         *ggit_repository_create_branch     (GgitRepository        *re
                                                        GgitCreateFlags        flags,
                                                        GError               **error);
 
-void                ggit_repository_branches_foreach  (GgitRepository        *repository,
-                                                       GgitBranchType         branch_type,
-                                                       GgitBranchesCallback   callback,
-                                                       gpointer               user_data,
-                                                       GError               **error);
+GgitBranchEnumerator *ggit_repository_enumerate_branches (GgitRepository        *repository,
+                                                          GgitBranchType         list_flags,
+                                                          GError               **error);
 
 GgitBranch         *ggit_repository_lookup_branch     (GgitRepository        *repository,
                                                        const gchar           *branch_name,
diff --git a/libgit2-glib/ggit-types.h b/libgit2-glib/ggit-types.h
index da21e67..a658f7a 100644
--- a/libgit2-glib/ggit-types.h
+++ b/libgit2-glib/ggit-types.h
@@ -47,6 +47,13 @@ typedef struct _GgitBlobOutputStream GgitBlobOutputStream;
 typedef struct _GgitBranch GgitBranch;
 
 /**
+ * GgitBranchEnumerator:
+ *
+ * Represents a branch enumerator.
+ */
+typedef struct _GgitBranchEnumerator GgitBranchEnumerator;
+
+/**
  * GgitCloneOptions:
  *
  * Represents the options used when cloning.
@@ -848,22 +855,6 @@ typedef enum {
 } GgitStatusShow;
 
 /**
- * GgitBranchesCallback:
- * @branch_name: the branch name.
- * @branch_type: a #GgitBranchType.
- * @user_data: (closure): user-supplied data.
- *
- * The type of the callback functions for retrieving the branches
- * in a #GgitRepository. See ggit_repository_branches_foreach().
- *
- * Returns: 0 to go for the next branch or a #GgitError in case there was an error.
- *
- */
-typedef gint (* GgitBranchesCallback) (const gchar    *branch_name,
-                                       GgitBranchType  branch_type,
-                                       gpointer        user_data);
-
-/**
  * GgitConfigCallback:
  * @entry: a #GgitConfigEntry.
  * @user_data: (closure): user-supplied data.


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