Update some images for the documentation
[TortoiseGit.git] / src / Git / GitHash.h
blob6cef413cc680df02f1905511243291e3a0c7403d
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2017 - 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.
20 #pragma once
21 #define GIT_HASH_SIZE 20
23 #define GIT_REV_ZERO L"0000000000000000000000000000000000000000"
25 class CGitHash
27 public:
28 unsigned char m_hash[GIT_HASH_SIZE];
30 CGitHash()
32 memset(m_hash,0, GIT_HASH_SIZE);
34 CGitHash(const unsigned char* p)
36 memcpy(m_hash,p,GIT_HASH_SIZE);
38 CGitHash & operator = (const CString &str)
40 CGitHash hash(str);
41 *this = hash;
42 return *this;
44 CGitHash & operator = (const unsigned char *p)
46 memcpy(m_hash, p, GIT_HASH_SIZE);
47 return *this;
49 CGitHash(const CString &str)
51 if (!IsValidSHA1(str))
53 #ifdef ASSERT
54 //ASSERT(FALSE); // TODO problematic
55 #endif
56 memset(m_hash, 0, GIT_HASH_SIZE);
57 return;
60 for (int i = 0; i < GIT_HASH_SIZE; ++i)
62 unsigned char a;
63 a=0;
64 for (int j = 2 * i; j <= 2 * i + 1; ++j)
66 a =a<<4;
68 TCHAR ch = str[j];
69 if (ch >= L'0' && ch <= L'9')
70 a |= (ch - L'0') & 0xF;
71 else if (ch >=L'A' && ch <= L'F')
72 a |= ((ch - L'A') & 0xF) + 10 ;
73 else if (ch >=L'a' && ch <= L'f')
74 a |= ((ch - L'a') & 0xF) + 10;
77 m_hash[i]=a;
81 void ConvertFromStrA(const char *str)
83 for (int i = 0; i < GIT_HASH_SIZE; ++i)
85 unsigned char a;
86 a=0;
87 for (int j = 2 * i; j <= 2 * i + 1; ++j)
89 a =a<<4;
91 char ch = str[j];
92 if (ch >= '0' && ch <= '9')
93 a |= (ch - '0') & 0xF;
94 else if (ch >= 'A' && ch <= 'F')
95 a |= ((ch - 'A') & 0xF) + 10 ;
96 else if (ch >= 'a' && ch <= 'f')
97 a |= ((ch - 'a') & 0xF) + 10;
100 m_hash[i]=a;
103 void Empty()
105 memset(m_hash,0, GIT_HASH_SIZE);
107 bool IsEmpty() const
109 for (int i = 0; i < GIT_HASH_SIZE; ++i)
111 if(m_hash[i] != 0)
112 return false;
114 return true;
117 CString ToString() const
119 CString str;
120 for (int i = 0; i < GIT_HASH_SIZE; ++i)
121 str.AppendFormat(L"%02x", m_hash[i]);
122 return str;
124 operator CString () const
126 return ToString();
129 bool operator == (const CGitHash &hash) const
131 return memcmp(m_hash,hash.m_hash,GIT_HASH_SIZE) == 0;
134 static friend bool operator<(const CGitHash& left, const CGitHash& right)
136 return memcmp(left.m_hash,right.m_hash,GIT_HASH_SIZE) < 0;
139 static friend bool operator>(const CGitHash& left, const CGitHash& right)
141 return memcmp(left.m_hash, right.m_hash, GIT_HASH_SIZE) > 0;
144 static friend bool operator != (const CGitHash& left, const CGitHash& right)
146 return memcmp(left.m_hash, right.m_hash, GIT_HASH_SIZE) != 0;
149 bool MatchesPrefix(const CGitHash& hash, const CString& hashString, size_t prefixLen) const
151 if (memcmp(m_hash, hash.m_hash, prefixLen >> 1))
152 return false;
153 return prefixLen == 2 * GIT_HASH_SIZE || wcsncmp(ToString(), hashString, prefixLen) == 0;
156 static bool IsValidSHA1(const CString &possibleSHA1)
158 if (possibleSHA1.GetLength() != 2 * GIT_HASH_SIZE)
159 return false;
160 for (int i = 0; i < possibleSHA1.GetLength(); ++i)
162 if (!((possibleSHA1[i] >= '0' && possibleSHA1[i] <= '9') || (possibleSHA1[i] >= 'a' && possibleSHA1[i] <= 'f') || (possibleSHA1[i] >= 'A' && possibleSHA1[i] <= 'F')))
163 return false;
165 return true;
169 namespace std
171 template <>
172 struct hash<CGitHash>
174 std::size_t operator()(const CGitHash& k) const
176 return(size_t)*k.m_hash;