1 /*
2 * ggit-index-entry-resolve_undo.c
3 * This file is part of libgit2-glib
4 *
5 * Copyright (C) 2012 - Jesse van den Kieboom
6 *
7 * libgit2-glib is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * libgit2-glib is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with libgit2-glib. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "ggit-index-entry-resolve-undo.h"
22 #include "ggit-index.h"
23 #include <git2/sys/index.h>
24
25 struct _GgitIndexEntriesResolveUndo
26 {
27 GgitIndex *owner;
28 gint ref_count;
29 };
30
31 struct _GgitIndexEntryResolveUndo
32 {
33 git_index_reuc_entry *entry;
34 gint ref_count;
35 };
36
G_DEFINE_BOXED_TYPE(GgitIndexEntriesResolveUndo,ggit_index_entries_resolve_undo,ggit_index_entries_resolve_undo_ref,ggit_index_entries_resolve_undo_unref)37 G_DEFINE_BOXED_TYPE (GgitIndexEntriesResolveUndo,
38 ggit_index_entries_resolve_undo,
39 ggit_index_entries_resolve_undo_ref,
40 ggit_index_entries_resolve_undo_unref)
41
42 G_DEFINE_BOXED_TYPE (GgitIndexEntryResolveUndo,
43 ggit_index_entry_resolve_undo,
44 ggit_index_entry_resolve_undo_ref,
45 ggit_index_entry_resolve_undo_unref)
46
47 static GgitIndexEntryResolveUndo *
48 ggit_index_entry_resolve_undo_wrap (git_index_reuc_entry *entry)
49 {
50 GgitIndexEntryResolveUndo *ret;
51
52 ret = g_slice_new (GgitIndexEntryResolveUndo);
53 ret->entry = entry;
54 ret->ref_count = 1;
55
56 return ret;
57 }
58
59 GgitIndexEntriesResolveUndo *
_ggit_index_entries_resolve_undo_wrap(GgitIndex * owner)60 _ggit_index_entries_resolve_undo_wrap (GgitIndex *owner)
61 {
62 GgitIndexEntriesResolveUndo *ret;
63
64 ret = g_slice_new (GgitIndexEntriesResolveUndo);
65 ret->owner = g_object_ref (owner);
66 ret->ref_count = 1;
67
68 return ret;
69 }
70
71 /**
72 * ggit_index_entry_resolve_undo_ref:
73 * @entry: a #GgitIndexEntryResolveUndo.
74 *
75 * Atomically increments the reference count of @entry by one.
76 * This function is MT-safe and may be called from any thread.
77 *
78 * Returns: (transfer none) (nullable): a #GgitIndexEntryResolveUndo or %NULL.
79 **/
80 GgitIndexEntryResolveUndo *
ggit_index_entry_resolve_undo_ref(GgitIndexEntryResolveUndo * entry)81 ggit_index_entry_resolve_undo_ref (GgitIndexEntryResolveUndo *entry)
82 {
83 g_return_val_if_fail (entry != NULL, NULL);
84
85 g_atomic_int_inc (&entry->ref_count);
86
87 return entry;
88 }
89
90 /**
91 * ggit_index_entry_resolve_undo_unref:
92 * @entry: a #GgitIndexEntryResolveUndo.
93 *
94 * Atomically decrements the reference count of @entry by one.
95 * If the reference count drops to 0, @entry is freed.
96 **/
97 void
ggit_index_entry_resolve_undo_unref(GgitIndexEntryResolveUndo * entry)98 ggit_index_entry_resolve_undo_unref (GgitIndexEntryResolveUndo *entry)
99 {
100 g_return_if_fail (entry != NULL);
101
102 if (g_atomic_int_dec_and_test (&entry->ref_count))
103 {
104 g_slice_free (GgitIndexEntryResolveUndo, entry);
105 }
106 }
107
108 /**
109 * ggit_index_entries_resolve_undo_ref:
110 * @entries: a #GgitIndexEntriesResolveUndo.
111 *
112 * Atomically increments the reference count of @entries by one.
113 * This function is MT-safe and may be called from any thread.
114 *
115 * Returns: (transfer none) (nullable): a #GgitIndexEntriesResolveUndo or %NULL.
116 *
117 **/
118 GgitIndexEntriesResolveUndo *
ggit_index_entries_resolve_undo_ref(GgitIndexEntriesResolveUndo * entries)119 ggit_index_entries_resolve_undo_ref (GgitIndexEntriesResolveUndo *entries)
120 {
121 g_return_val_if_fail (entries != NULL, NULL);
122
123 g_atomic_int_inc (&entries->ref_count);
124
125 return entries;
126 }
127
128 /**
129 * ggit_index_entries_resolve_undo_unref:
130 * @entries: a #GgitIndexEntriesResolveUndo.
131 *
132 * Atomically decrements the reference count of @entries by one.
133 * If the reference count drops to 0, @entries is freed.
134 **/
135 void
ggit_index_entries_resolve_undo_unref(GgitIndexEntriesResolveUndo * entries)136 ggit_index_entries_resolve_undo_unref (GgitIndexEntriesResolveUndo *entries)
137 {
138 g_return_if_fail (entries != NULL);
139
140 if (g_atomic_int_dec_and_test (&entries->ref_count))
141 {
142 g_clear_object (&entries->owner);
143 g_slice_free (GgitIndexEntriesResolveUndo, entries);
144 }
145 }
146
147 /**
148 * ggit_index_entries_resolve_undo_get:
149 * @entries: a #GgitIndexEntriesResolveUndo.
150 * @idx: the index of the entry.
151 *
152 * Get a #GgitIndexEntryResolveUndo by index. Note that the returned
153 * #GgitIndexEntryResolveUndo is _only_ valid as long as:
154 *
155 * 1) The associated index has been closed
156 * 2) The entry has not been removed (see ggit_index_remove())
157 * 3) The index has not been refreshed (see ggit_index_read())
158 *
159 * Returns: (transfer full) (nullable): a #GgitIndexEntryResolveUndo or %NULL.
160 *
161 **/
162 GgitIndexEntryResolveUndo *
ggit_index_entries_resolve_undo_get(GgitIndexEntriesResolveUndo * entries,guint idx)163 ggit_index_entries_resolve_undo_get (GgitIndexEntriesResolveUndo *entries,
164 guint idx)
165 {
166 git_index *gidx;
167 const git_index_reuc_entry *ret;
168
169 g_return_val_if_fail (entries != NULL, NULL);
170
171 gidx = _ggit_index_get_index (entries->owner);
172 ret = git_index_reuc_get_byindex (gidx, idx);
173
174 return ggit_index_entry_resolve_undo_wrap ((git_index_reuc_entry *)ret);
175 }
176
177 /**
178 * ggit_index_entries_resolve_undo_size:
179 * @entries: a #GgitIndexEntriesResolveUndo.
180 *
181 * Get the number of #GgitIndexEntryResolveUndo entries.
182 *
183 * Returns: the number of entries.
184 *
185 **/
186 guint
ggit_index_entries_resolve_undo_size(GgitIndexEntriesResolveUndo * entries)187 ggit_index_entries_resolve_undo_size (GgitIndexEntriesResolveUndo *entries)
188 {
189 git_index *gidx;
190
191 g_return_val_if_fail (entries != NULL, 0);
192
193 gidx = _ggit_index_get_index (entries->owner);
194
195 return git_index_reuc_entrycount (gidx);
196 }
197
198 /**
199 * ggit_index_entries_resolve_undo_get_by_file:
200 * @entries: a #GgitIndexEntriesResolveUndo.
201 * @file: a #GFile.
202 *
203 * Get an resolve_undo entry specified by path. The returned entry is read
204 * only and should not be modified by the caller. If the entry could not be
205 * found, %NULL is returned.
206 *
207 * Returns: (transfer full) (nullable): a #GgitIndexEntryResolveUndo or %NULL.
208 *
209 **/
210 GgitIndexEntryResolveUndo *
ggit_index_entries_resolve_undo_get_by_file(GgitIndexEntriesResolveUndo * entries,GFile * file)211 ggit_index_entries_resolve_undo_get_by_file (GgitIndexEntriesResolveUndo *entries,
212 GFile *file)
213 {
214 git_index *gidx;
215 const git_index_reuc_entry *ret;
216 gchar *path;
217
218 g_return_val_if_fail (entries != NULL, NULL);
219 g_return_val_if_fail (G_IS_FILE (file), NULL);
220
221 gidx = _ggit_index_get_index (entries->owner);
222 path = g_file_get_path (file);
223
224 g_return_val_if_fail (path != NULL, NULL);
225
226 ret = git_index_reuc_get_bypath (gidx, path);
227 g_free (path);
228
229 if (ret)
230 {
231 return ggit_index_entry_resolve_undo_wrap ((git_index_reuc_entry *)ret);
232 }
233 else
234 {
235 return NULL;
236 }
237 }
238
239 /**
240 * ggit_index_entry_resolve_undo_get_mode:
241 * @entry: a #GgitIndexEntryResolveUndo.
242 * @stage: the stage (0, 1 or 2).
243 *
244 * Get the mode of the index entry. The returned mode contains the modes from
245 * stage 1, 2 and 3.
246 *
247 * Returns: the mode.
248 *
249 **/
250 guint
ggit_index_entry_resolve_undo_get_mode(GgitIndexEntryResolveUndo * entry,gint stage)251 ggit_index_entry_resolve_undo_get_mode (GgitIndexEntryResolveUndo *entry,
252 gint stage)
253 {
254 g_return_val_if_fail (entry != NULL, 0);
255 g_return_val_if_fail (stage >= 0 && stage <= 3, 0);
256
257 return entry->entry->mode[stage];
258 }
259
260 /**
261 * ggit_index_entry_resolve_undo_get_id:
262 * @entry: a #GgitIndexEntryResolveUndo.
263 * @stage: the stage (0, 1 or 2).
264 *
265 * Get the oid of the index entry.
266 *
267 * Returns: (transfer full) (nullable): the oid or %NULL.
268 *
269 **/
270 GgitOId *
ggit_index_entry_resolve_undo_get_id(GgitIndexEntryResolveUndo * entry,gint stage)271 ggit_index_entry_resolve_undo_get_id (GgitIndexEntryResolveUndo *entry,
272 gint stage)
273 {
274 g_return_val_if_fail (entry != NULL, NULL);
275 g_return_val_if_fail (stage >= 0 && stage <= 3, NULL);
276
277 return _ggit_oid_wrap (&entry->entry->oid[stage]);
278 }
279
280 /**
281 * ggit_index_entry_resolve_undo_get_file:
282 * @entry: a #GgitIndexEntryResolveUndo.
283 *
284 * Get the file of the index entry.
285 *
286 * Returns: (transfer full) (nullable): a #GFile or %NULL.
287 *
288 **/
289 GFile *
ggit_index_entry_resolve_undo_get_file(GgitIndexEntryResolveUndo * entry)290 ggit_index_entry_resolve_undo_get_file (GgitIndexEntryResolveUndo *entry)
291 {
292 g_return_val_if_fail (entry != NULL, 0);
293
294 if (entry->entry->path == NULL)
295 {
296 return NULL;
297 }
298
299 return g_file_new_for_path (entry->entry->path);
300 }
301
302 /* ex:set ts=8 noet: */
303