1
// TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2018 - TortoiseGit
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #define GIT_HASH_SIZE 20
23 /* also see gitdll.c */
24 static_assert(GIT_HASH_SIZE
== GIT_OID_RAWSZ
, "hash size needs to be the same as in libgit2");
25 static_assert(sizeof(git_oid::id
) == GIT_HASH_SIZE
, "hash size needs to be the same as in libgit2");
27 #define GIT_REV_ZERO_C "0000000000000000000000000000000000000000"
28 #define GIT_REV_ZERO _T(GIT_REV_ZERO_C)
32 struct std::hash
<CGitHash
>;
37 unsigned char m_hash
[GIT_HASH_SIZE
];
41 memset(m_hash
,0, GIT_HASH_SIZE
);
43 CGitHash(const unsigned char* p
)
45 memcpy(m_hash
,p
,GIT_HASH_SIZE
);
47 CGitHash(const git_oid
* oid
)
49 git_oid_cpy((git_oid
*)m_hash
, oid
);
51 CGitHash(const git_oid oid
)
53 git_oid_cpy((git_oid
*)m_hash
, &oid
);
55 CGitHash
& operator = (const CString
& str
)
61 CGitHash
& operator = (const unsigned char *p
)
63 memcpy(m_hash
, p
, GIT_HASH_SIZE
);
66 CGitHash
& operator = (const git_oid
* oid
)
68 git_oid_cpy((git_oid
*)m_hash
, oid
);
71 CGitHash
& operator = (const git_oid oid
)
73 git_oid_cpy((git_oid
*)m_hash
, &oid
);
76 CGitHash(const CString
&str
)
78 if (!IsValidSHA1(str
))
81 //ASSERT(FALSE); // TODO problematic
83 memset(m_hash
, 0, GIT_HASH_SIZE
);
87 for (int i
= 0; i
< GIT_HASH_SIZE
; ++i
)
91 for (int j
= 2 * i
; j
<= 2 * i
+ 1; ++j
)
96 if (ch
>= L
'0' && ch
<= L
'9')
97 a
|= (ch
- L
'0') & 0xF;
98 else if (ch
>=L
'A' && ch
<= L
'F')
99 a
|= ((ch
- L
'A') & 0xF) + 10 ;
100 else if (ch
>=L
'a' && ch
<= L
'f')
101 a
|= ((ch
- L
'a') & 0xF) + 10;
108 void ConvertFromStrA(const char *str
)
110 for (int i
= 0; i
< GIT_HASH_SIZE
; ++i
)
114 for (int j
= 2 * i
; j
<= 2 * i
+ 1; ++j
)
119 if (ch
>= '0' && ch
<= '9')
120 a
|= (ch
- '0') & 0xF;
121 else if (ch
>= 'A' && ch
<= 'F')
122 a
|= ((ch
- 'A') & 0xF) + 10 ;
123 else if (ch
>= 'a' && ch
<= 'f')
124 a
|= ((ch
- 'a') & 0xF) + 10;
132 memset(m_hash
,0, GIT_HASH_SIZE
);
136 for (int i
= 0; i
< GIT_HASH_SIZE
; ++i
)
144 CString
ToString() const
147 str
.Preallocate(GIT_HASH_SIZE
* 2);
148 for (int i
= 0; i
< GIT_HASH_SIZE
; ++i
)
149 str
.AppendFormat(L
"%02x", m_hash
[i
]);
153 operator const git_oid
*() const
155 return (const git_oid
*)m_hash
;
158 operator const unsigned char*() const
163 bool operator == (const CGitHash
&hash
) const
165 return memcmp(m_hash
,hash
.m_hash
,GIT_HASH_SIZE
) == 0;
168 static friend bool operator<(const CGitHash
& left
, const CGitHash
& right
)
170 return memcmp(left
.m_hash
,right
.m_hash
,GIT_HASH_SIZE
) < 0;
173 static friend bool operator>(const CGitHash
& left
, const CGitHash
& right
)
175 return memcmp(left
.m_hash
, right
.m_hash
, GIT_HASH_SIZE
) > 0;
178 static friend bool operator != (const CGitHash
& left
, const CGitHash
& right
)
180 return memcmp(left
.m_hash
, right
.m_hash
, GIT_HASH_SIZE
) != 0;
183 bool MatchesPrefix(const CGitHash
& hash
, const CString
& hashString
, size_t prefixLen
) const
185 if (memcmp(m_hash
, hash
.m_hash
, prefixLen
>> 1))
187 return prefixLen
== 2 * GIT_HASH_SIZE
|| wcsncmp(ToString(), hashString
, prefixLen
) == 0;
190 static bool IsValidSHA1(const CString
&possibleSHA1
)
192 if (possibleSHA1
.GetLength() != 2 * GIT_HASH_SIZE
)
194 for (int i
= 0; i
< possibleSHA1
.GetLength(); ++i
)
196 if (!((possibleSHA1
[i
] >= '0' && possibleSHA1
[i
] <= '9') || (possibleSHA1
[i
] >= 'a' && possibleSHA1
[i
] <= 'f') || (possibleSHA1
[i
] >= 'A' && possibleSHA1
[i
] <= 'F')))
202 friend struct std::hash
<CGitHash
>;
208 struct hash
<CGitHash
>
210 std::size_t operator()(const CGitHash
& k
) const
212 return *(size_t*)k
.m_hash
;