Fix possible resource leak
[TortoiseGit.git] / src / Utils / SmartLibgit2Ref.h
blob731a1a0cbda8b6e3dfd64da4911c035c0caa030b
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2014-2015 - TortoiseGit
4 // based on SmartHandle of TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #pragma once
21 #include "UnicodeUtils.h"
23 /**
24 * \ingroup Utils
25 * Helper classes for libgit2 references.
27 template <typename HandleType, class FreeFunction>
28 class CSmartBuffer : public FreeFunction
30 public:
31 CSmartBuffer()
33 HandleType tmp = { 0 };
34 m_Ref = tmp;
37 operator HandleType*()
39 return &m_Ref;
42 HandleType* operator->()
44 return &m_Ref;
47 ~CSmartBuffer()
49 Free(&m_Ref);
52 private:
53 CSmartBuffer(const CSmartBuffer& that);
54 CSmartBuffer& operator=(const CSmartBuffer& that);
56 protected:
57 HandleType m_Ref;
60 struct CFreeBuf
62 protected:
63 void Free(git_buf* ref)
65 git_buf_free(ref);
68 ~CFreeBuf()
73 struct CFreeStrArray
75 protected:
76 void Free(git_strarray* ref)
78 git_strarray_free(ref);
81 ~CFreeStrArray()
86 typedef CSmartBuffer<git_buf, CFreeBuf> CAutoBuf;
87 typedef CSmartBuffer<git_strarray, CFreeStrArray> CAutoStrArray;
89 template <typename ReferenceType>
90 class CSmartLibgit2Ref
92 public:
93 CSmartLibgit2Ref()
95 m_Ref = nullptr;
98 void Swap(CSmartLibgit2Ref& tmp)
100 ReferenceType* p;
102 p = m_Ref;
103 m_Ref = tmp.m_Ref;
104 tmp.m_Ref = p;
107 void Free()
109 CleanUp();
112 ReferenceType* Detach()
114 ReferenceType* p;
116 p = m_Ref;
117 m_Ref = nullptr;
119 return p;
122 operator ReferenceType*()
124 return m_Ref;
128 * Free the wrapped object and return a pointer to the wrapped object ReferenceType*
130 ReferenceType** GetPointer()
132 CleanUp();
133 return &m_Ref;
136 operator bool()
138 return IsValid();
141 bool IsValid() const
143 return m_Ref != nullptr;
146 private:
147 CSmartLibgit2Ref(const CSmartLibgit2Ref& that);
148 CSmartLibgit2Ref& operator=(const CSmartLibgit2Ref& that);
150 protected:
151 virtual void FreeRef() = 0;
153 void CleanUp()
155 if (IsValid())
157 FreeRef();
158 m_Ref = nullptr;
162 ReferenceType* m_Ref;
165 class CAutoRepository : public CSmartLibgit2Ref<git_repository>
167 public:
168 CAutoRepository() {};
170 CAutoRepository(git_repository* h)
172 m_Ref = h;
175 CAutoRepository(const CString& gitDir)
177 Open(gitDir);
180 CAutoRepository(const CStringA& gitDirA)
182 Open(gitDirA);
185 int Open(const CString& gitDir)
187 return Open(CUnicodeUtils::GetUTF8(gitDir));
190 int Open(const CStringA& gitDirA)
192 CleanUp();
193 return git_repository_open(GetPointer(), gitDirA);
196 ~CAutoRepository()
198 CleanUp();
201 protected:
202 virtual void FreeRef()
204 git_repository_free(m_Ref);
208 class CAutoSubmodule : public CSmartLibgit2Ref<git_submodule>
210 public:
211 ~CAutoSubmodule()
213 CleanUp();
216 protected:
217 virtual void FreeRef()
219 git_submodule_free(m_Ref);
223 class CAutoCommit : public CSmartLibgit2Ref<git_commit>
225 public:
226 CAutoCommit() {}
228 CAutoCommit(git_commit* h)
230 m_Ref = h;
233 ~CAutoCommit()
235 CleanUp();
237 protected:
238 virtual void FreeRef()
240 git_commit_free(m_Ref);
244 class CAutoTree : public CSmartLibgit2Ref<git_tree>
246 public:
247 git_tree* operator=(git_tree* h)
249 if (m_Ref != h)
251 CleanUp();
252 m_Ref = h;
254 return (*this);
257 ~CAutoTree()
259 CleanUp();
262 protected:
263 virtual void FreeRef()
265 git_tree_free(m_Ref);
269 class CAutoObject : public CSmartLibgit2Ref<git_object>
271 public:
272 ~CAutoObject()
274 CleanUp();
277 protected:
278 virtual void FreeRef()
280 git_object_free(m_Ref);
284 class CAutoBlob : public CSmartLibgit2Ref<git_blob>
286 public:
287 ~CAutoBlob()
289 CleanUp();
292 protected:
293 virtual void FreeRef()
295 git_blob_free(m_Ref);
299 class CAutoConfig : public CSmartLibgit2Ref<git_config>
301 public:
302 CAutoConfig() {}
304 CAutoConfig(CAutoRepository &repo)
306 git_repository_config(&m_Ref, repo);
309 CAutoConfig(bool init)
311 if (init)
312 New();
315 void New()
317 CleanUp();
318 git_config_new(&m_Ref);
321 ~CAutoConfig()
323 CleanUp();
326 int GetString(const CString &key, CString &value) const
328 if (!IsValid())
329 return -1;
331 CAutoBuf buf;
332 int ret = 0;
333 if ((ret = git_config_get_string_buf(buf, m_Ref, CUnicodeUtils::GetUTF8(key))))
335 value.Empty();
336 return ret;
339 value = CUnicodeUtils::GetUnicode((CStringA)buf->ptr);
341 return ret;
344 int GetBOOL(const CString &key, BOOL &b) const
346 if (!IsValid())
347 return -1;
349 return git_config_get_bool(&b, m_Ref, CUnicodeUtils::GetUTF8(key));
352 int GetBool(const CString &key, bool &b) const
354 if (!IsValid())
355 return -1;
357 int value = FALSE;
358 int ret = 0;
359 if ((ret = GetBOOL(key, value)) < 0)
360 return ret;
362 b = (value == TRUE);
364 return ret;
367 protected:
368 virtual void FreeRef()
370 git_config_free(m_Ref);
374 class CAutoReference : public CSmartLibgit2Ref<git_reference>
376 public:
377 CAutoReference() {}
379 CAutoReference(git_reference* h)
381 m_Ref = h;
384 ~CAutoReference()
386 CleanUp();
389 protected:
390 virtual void FreeRef()
392 git_reference_free(m_Ref);
396 class CAutoTreeEntry : public CSmartLibgit2Ref<git_tree_entry>
398 public:
399 ~CAutoTreeEntry()
401 CleanUp();
404 protected:
405 virtual void FreeRef()
407 git_tree_entry_free(m_Ref);
411 class CAutoDiff : public CSmartLibgit2Ref<git_diff>
413 public:
414 ~CAutoDiff()
416 CleanUp();
419 protected:
420 virtual void FreeRef()
422 git_diff_free(m_Ref);
426 class CAutoPatch : public CSmartLibgit2Ref<git_patch>
428 public:
429 ~CAutoPatch()
431 CleanUp();
434 protected:
435 virtual void FreeRef()
437 git_patch_free(m_Ref);
441 class CAutoDiffStats : public CSmartLibgit2Ref<git_diff_stats>
443 public:
444 ~CAutoDiffStats()
446 CleanUp();
449 protected:
450 virtual void FreeRef()
452 git_diff_stats_free(m_Ref);
456 class CAutoIndex : public CSmartLibgit2Ref<git_index>
458 public:
459 ~CAutoIndex()
461 CleanUp();
464 protected:
465 virtual void FreeRef()
467 git_index_free(m_Ref);
471 class CAutoRemote : public CSmartLibgit2Ref<git_remote>
473 public:
474 ~CAutoRemote()
476 CleanUp();
479 protected:
480 virtual void FreeRef()
482 git_remote_free(m_Ref);
486 class CAutoReflog : public CSmartLibgit2Ref<git_reflog>
488 public:
489 ~CAutoReflog()
491 CleanUp();
494 protected:
495 virtual void FreeRef()
497 git_reflog_free(m_Ref);
501 class CAutoRevwalk : public CSmartLibgit2Ref<git_revwalk>
503 public:
504 ~CAutoRevwalk()
506 CleanUp();
509 protected:
510 virtual void FreeRef()
512 git_revwalk_free(m_Ref);
516 class CAutoBranchIterator : public CSmartLibgit2Ref<git_branch_iterator>
518 public:
519 ~CAutoBranchIterator()
521 CleanUp();
524 protected:
525 virtual void FreeRef()
527 git_branch_iterator_free(m_Ref);
531 class CAutoDescribeResult : public CSmartLibgit2Ref<git_describe_result>
533 public:
534 ~CAutoDescribeResult()
536 CleanUp();
539 protected:
540 virtual void FreeRef()
542 git_describe_result_free(m_Ref);
546 class CAutoStatusList : public CSmartLibgit2Ref<git_status_list>
548 public:
549 ~CAutoStatusList()
551 CleanUp();
553 protected:
554 virtual void FreeRef()
556 git_status_list_free(m_Ref);