SHA1Digest.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "SHA1Digest.H"
27 #include "IOstreams.H"
28 
29 #include <cstring>
30 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
34 
36 static const char hexChars[] = "0123456789abcdef";
38 
39 
40 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
41 
42 unsigned char Foam::SHA1Digest::readHexDigit(Istream& is)
43 {
44  // Takes into account that 'a' (or 'A') is 10
45  static const int alphaOffset = toupper('A') - 10;
46  // Takes into account that '0' is 0
47  static const int zeroOffset = int('0');
48 
49 
50  // silently ignore leading or intermediate '_'
51  char c = 0;
52  do
53  {
54  is.read(c);
55  }
56  while (c == '_');
57 
58  if (!isxdigit(c))
59  {
60  FatalIOErrorIn("SHA1Digest::readHexDigit(Istream&)", is)
61  << "Illegal hex digit: '" << c << "'"
62  << exit(FatalIOError);
63  }
64 
65  if (isdigit(c))
66  {
67  return int(c) - zeroOffset;
68  }
69  else
70  {
71  return toupper(c) - alphaOffset;
72  }
73 }
74 
75 
76 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
77 
79 {
80  clear();
81 }
82 
83 
85 {
86  is >> *this;
87 }
88 
89 
90 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
91 
93 {
94  memset(v_, 0, length);
95 }
96 
97 
99 {
100  for (unsigned i = 0; i < length; ++i)
101  {
102  if (v_[i])
103  {
104  return false;
105  }
106  }
107 
108  return true;
109 }
110 
111 
112 std::string Foam::SHA1Digest::str(const bool prefixed) const
113 {
114  std::string buf;
115  unsigned nChar = 0;
116 
117  if (prefixed)
118  {
119  buf.resize(1 + length*2);
120  buf[nChar++] = '_';
121  }
122  else
123  {
124  buf.resize(length*2);
125  }
126 
127  for (unsigned i = 0; i < length; ++i)
128  {
129  buf[nChar++] = hexChars[((v_[i] >> 4) & 0xF)];
130  buf[nChar++] = hexChars[(v_[i] & 0xF)];
131  }
132 
133  return buf;
134 }
135 
136 
137 Foam::Ostream& Foam::SHA1Digest::write(Ostream& os, const bool prefixed) const
138 {
139  if (prefixed)
140  {
141  os.write('_');
142  }
143 
144  for (unsigned i = 0; i < length; ++i)
145  {
146  os.write(hexChars[((v_[i] >> 4) & 0xF)]);
147  os.write(hexChars[(v_[i] & 0xF)]);
148  }
149 
150  os.check("SHA1Digest::write(Ostream&, const bool)");
151  return os;
152 }
153 
154 
155 // * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
156 
158 {
159  for (unsigned i = 0; i < length; ++i)
160  {
161  if (v_[i] != rhs.v_[i])
162  {
163  return false;
164  }
165  }
166 
167  return true;
168 }
169 
170 
171 bool Foam::SHA1Digest::operator==(const std::string& hexdigits) const
172 {
173  // null or empty string is not an error - interpret as '0000..'
174  if (hexdigits.empty())
175  {
176  return empty();
177  }
178 
179  // skip possible '_' prefix
180  unsigned charI = 0;
181  if (hexdigits[0] == '_')
182  {
183  ++charI;
184  }
185 
186  // incorrect length - can never match
187  if (hexdigits.size() != charI + length*2)
188  {
189  return false;
190  }
191 
192  for (unsigned i = 0; i < length; ++i)
193  {
194  const char c1 = hexChars[((v_[i] >> 4) & 0xF)];
195  const char c2 = hexChars[(v_[i] & 0xF)];
196 
197  if (c1 != hexdigits[charI++]) return false;
198  if (c2 != hexdigits[charI++]) return false;
199  }
200 
201  return true;
202 }
203 
204 
205 bool Foam::SHA1Digest::operator==(const char* hexdigits) const
206 {
207  // null or empty string is not an error - interpret as '0000..'
208  if (!hexdigits || !*hexdigits)
209  {
210  return empty();
211  }
212 
213  // skip possible '_' prefix
214  unsigned charI = 0;
215  if (hexdigits[0] == '_')
216  {
217  ++charI;
218  }
219 
220  // incorrect length - can never match
221  if (strlen(hexdigits) != charI + length*2)
222  {
223  return false;
224  }
225 
226  for (unsigned i = 0; i < length; ++i)
227  {
228  const char c1 = hexChars[((v_[i] >> 4) & 0xF)];
229  const char c2 = hexChars[(v_[i] & 0xF)];
230 
231  if (c1 != hexdigits[charI++]) return false;
232  if (c2 != hexdigits[charI++]) return false;
233  }
234 
235  return true;
236 }
237 
238 
240 {
241  return !operator==(rhs);
242 }
243 
244 
245 bool Foam::SHA1Digest::operator!=(const std::string& rhs) const
246 {
247  return !operator==(rhs);
248 }
249 
250 
251 bool Foam::SHA1Digest::operator!=(const char* rhs) const
252 {
253  return !operator==(rhs);
254 }
255 
256 
257 // * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
258 
260 {
261  unsigned char *v = dig.v_;
262 
263  for (unsigned i = 0; i < dig.length; ++i)
264  {
265  unsigned char c1 = SHA1Digest::readHexDigit(is);
266  unsigned char c2 = SHA1Digest::readHexDigit(is);
267 
268  v[i] = (c1 << 4) + c2;
269  }
270 
271  is.check("Istream& operator>>(Istream&, SHA1Digest&)");
272  return is;
273 }
274 
275 
277 {
278  return dig.write(os);
279 }
280 
281 
282 // ************************************************************************* //
Ostream & write(Ostream &, const bool prefixed=false) const
Write (40-byte) text representation, optionally with &#39;_&#39; prefix.
Definition: SHA1Digest.C:137
void clear()
Reset the digest to zero.
Definition: SHA1Digest.C:92
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
static const unsigned length
The length of the (uncoded) digest contents.
Definition: SHA1Digest.H:70
Ostream & operator<<(Ostream &, const edgeMesh &)
Definition: edgeMeshIO.C:133
static const SHA1Digest null
A null digest (ie, all zero)
Definition: SHA1Digest.H:73
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:92
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
IOerror FatalIOError
bool operator==(const SHA1Digest &) const
Equality operator.
Definition: SHA1Digest.C:157
virtual Ostream & write(const token &)=0
Write next token to stream.
const dimensionedScalar c1
First radiation constant: default SI units: [W/m2].
Istream & operator>>(Istream &, edgeMesh &)
Definition: edgeMeshIO.C:144
bool operator!=(const SHA1Digest &) const
Inequality operator.
Definition: SHA1Digest.C:239
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:53
SHA1Digest()
Construct a zero digest.
Definition: SHA1Digest.C:78
bool empty() const
Return true if the digest is empty (ie, all zero).
Definition: SHA1Digest.C:98
The SHA1 message digest.
Definition: SHA1Digest.H:62
#define FatalIOErrorIn(functionName, ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:325
std::string str(const bool prefixed=false) const
Return (40-byte) text representation, optionally with &#39;_&#39; prefix.
Definition: SHA1Digest.C:112
const dimensionedScalar c2
Second radiation constant: default SI units: [m.K].