ENH: modernize SHA1 classes (#1301)

- localize some functionality, std::array for digest internals.
  Additional append sub-string methods, pass-through write of digest
  etc.
This commit is contained in:
Mark Olesen
2019-05-01 12:14:09 +02:00
parent 3e894bdef1
commit 879d280bb9
5 changed files with 241 additions and 200 deletions

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2009-2011 OpenCFD Ltd. \\ / A nd | Copyright (C) 2009-2011, 2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation | Copyright (C) 2011-2016 OpenFOAM Foundation
@ -36,9 +36,8 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "SHA1.H" #include "SHA1.H"
#include "IOstreams.H"
#include "endian.H" #include "endian.H"
#include "IOstreams.H"
#include <cstring> #include <cstring>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -77,17 +76,17 @@ static inline void set_uint32(unsigned char *dst, uint32_t v)
void Foam::SHA1::processBytes(const void *data, size_t len) void Foam::SHA1::processBytes(const void *data, size_t len)
{ {
// already finalized, thus need to restart from nothing // Already finalized, thus need to restart from nothing
if (finalized_) if (finalized_)
{ {
clear(); clear();
} }
// complete filling of internal buffer // Complete filling of internal buffer
if (bufLen_) if (bufLen_)
{ {
size_t remaining = bufLen_; const size_t remaining = bufLen_;
size_t add = const size_t add =
( (
sizeof(buffer_) - remaining > len sizeof(buffer_) - remaining > len
? len ? len
@ -158,10 +157,10 @@ void Foam::SHA1::processBytes(const void *data, size_t len)
void Foam::SHA1::processBlock(const void *data, size_t len) void Foam::SHA1::processBlock(const void *data, size_t len)
{ {
const uint32_t *words = reinterpret_cast<const uint32_t*>(data); const uint32_t *words = reinterpret_cast<const uint32_t*>(data);
size_t nwords = len / sizeof(uint32_t); const size_t nwords = len / sizeof(uint32_t);
const uint32_t *endp = words + nwords; const uint32_t *endp = words + nwords;
// calculate with sixteen words of 32-bits // Calculate with sixteen words of 32-bits
uint32_t x[16]; uint32_t x[16];
uint32_t a = hashsumA_; uint32_t a = hashsumA_;
uint32_t b = hashsumB_; uint32_t b = hashsumB_;
@ -295,7 +294,7 @@ void Foam::SHA1::calcDigest(SHA1Digest& dig) const
{ {
if (bufTotal_[0] || bufTotal_[1]) if (bufTotal_[0] || bufTotal_[1])
{ {
unsigned char *r = dig.v_; unsigned char *r = dig.data();
set_uint32(r + 0 * sizeof(uint32_t), swapBytes(hashsumA_)); set_uint32(r + 0 * sizeof(uint32_t), swapBytes(hashsumA_));
set_uint32(r + 1 * sizeof(uint32_t), swapBytes(hashsumB_)); set_uint32(r + 1 * sizeof(uint32_t), swapBytes(hashsumB_));
@ -305,8 +304,7 @@ void Foam::SHA1::calcDigest(SHA1Digest& dig) const
} }
else else
{ {
// no data! dig.clear(); // No data!
dig.clear();
} }
} }
@ -334,24 +332,24 @@ bool Foam::SHA1::finalize()
{ {
finalized_ = true; finalized_ = true;
// account for unprocessed bytes // Account for unprocessed bytes
uint32_t bytes = bufLen_; const uint32_t bytes = bufLen_;
size_t size = (bytes < 56 ? 64 : 128) / sizeof(uint32_t); const size_t size = (bytes < 56 ? 64 : 128) / sizeof(uint32_t);
// count remaining bytes. // Count remaining bytes.
bufTotal_[0] += bytes; bufTotal_[0] += bytes;
if (bufTotal_[0] < bytes) if (bufTotal_[0] < bytes)
{ {
++bufTotal_[1]; ++bufTotal_[1];
} }
// finalized, but no data! // Finalized, but no data!
if (!bufTotal_[0] && !bufTotal_[1]) if (!bufTotal_[0] && !bufTotal_[1])
{ {
return false; return false;
} }
// place the 64-bit file length in *bits* at the end of the buffer. // Place the 64-bit length in *bits* at the end of the buffer.
buffer_[size-2] = swapBytes((bufTotal_[1] << 3) | (bufTotal_[0] >> 29)); buffer_[size-2] = swapBytes((bufTotal_[1] << 3) | (bufTotal_[0] >> 29));
buffer_[size-1] = swapBytes(bufTotal_[0] << 3); buffer_[size-1] = swapBytes(bufTotal_[0] << 3);
@ -367,28 +365,6 @@ bool Foam::SHA1::finalize()
} }
Foam::SHA1Digest Foam::SHA1::digest() const
{
SHA1Digest dig;
if (finalized_)
{
calcDigest(dig);
}
else
{
// avoid disturbing our data - use a copy
SHA1 sha(*this);
if (sha.finalize())
{
sha.calcDigest(dig);
}
}
return dig;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#undef K1 #undef K1

View File

@ -45,9 +45,7 @@ SourceFiles
#define SHA1_H #define SHA1_H
#include <string> #include <string>
#include <cstddef> #include <cstdint>
#include "int.H"
#include "SHA1Digest.H" #include "SHA1Digest.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -61,7 +59,7 @@ namespace Foam
class SHA1 class SHA1
{ {
// Private data // Private Data
//- Track if the hashsum has been finalized (added count, etc) //- Track if the hashsum has been finalized (added count, etc)
bool finalized_; bool finalized_;
@ -91,8 +89,9 @@ class SHA1
//- Process for the next LEN bytes, LEN need not be a multiple of 64. //- Process for the next LEN bytes, LEN need not be a multiple of 64.
void processBytes(const void *data, size_t len); void processBytes(const void *data, size_t len);
//- Calculate current digest from appended data. //- Calculate digest from current data.
void calcDigest(SHA1Digest&) const; void calcDigest(SHA1Digest& dig) const;
public: public:
@ -101,41 +100,60 @@ public:
//- Construct null //- Construct null
inline SHA1(); inline SHA1();
//- Construct null and append initial std::string
inline explicit SHA1(const std::string&);
//- Construct null and append initial string //- Construct null and append initial string
inline explicit SHA1(const char*); inline explicit SHA1(const char* str);
//- Construct null and append initial std::string
inline explicit SHA1(const std::string& str);
// Member Functions // Member Functions
//- Reset the hashed data before appending more //- Reset the hashed data before appending more
void clear(); void clear();
//- Append data for processing
inline SHA1& append(const char* str);
//- Append data for processing //- Append data for processing
inline SHA1& append(const char* data, size_t len); inline SHA1& append(const char* data, size_t len);
//- Append string for processing //- Append string for processing
inline SHA1& append(const std::string&); inline SHA1& append(const std::string& str);
//- Append string for processing //- Append substring for processing
inline SHA1& append(const char* str); inline SHA1& append
(
const std::string& str,
size_t pos,
size_t len = std::string::npos
);
//- Finalized the calculations (normally not needed directly). //- Finalized the calculations (normally not needed directly).
// Returns false if no bytes were passed for processing // Returns false if no bytes were passed for processing
bool finalize(); bool finalize();
//- Calculate current digest from appended data. //- Calculate digest from current data.
SHA1Digest digest() const; inline SHA1Digest digest() const;
//- The digest (40-byte) text representation, optionally with '_' prefix
inline std::string str(const bool prefixed=false) const;
//- Write digest (40-byte) representation, optionally with '_' prefix
inline Ostream& write(Ostream& os, const bool prefixed=false) const;
// Member Operators // Member Operators
//- Cast conversion to a SHA1Digest,
// calculates the %digest from the current data
inline operator SHA1Digest() const;
//- Equality operator, compares %digests //- Equality operator, compares %digests
inline bool operator==(const SHA1&) const; inline bool operator==(const SHA1& rhs) const;
//- Compare %digest //- Compare %digest
inline bool operator==(const SHA1Digest&) const; inline bool operator==(const SHA1Digest& dig) const;
//- Compare %digest to (40-byte) text representation (eg, from sha1sum) //- Compare %digest to (40-byte) text representation (eg, from sha1sum)
// An %empty string is equivalent to // An %empty string is equivalent to
@ -147,7 +165,6 @@ public:
// "0000000000000000000000000000000000000000" // "0000000000000000000000000000000000000000"
inline bool operator==(const char* hexdigits) const; inline bool operator==(const char* hexdigits) const;
//- Inequality operator, compares %digests //- Inequality operator, compares %digests
inline bool operator!=(const SHA1&) const; inline bool operator!=(const SHA1&) const;
@ -159,11 +176,6 @@ public:
//- Inequality operator, compare %digest //- Inequality operator, compare %digest
inline bool operator!=(const char* hexdigits) const; inline bool operator!=(const char* hexdigits) const;
//- Convert to a SHA1Digest,
// calculate current %digest from appended data
inline operator SHA1Digest() const;
}; };

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2009-2011 OpenCFD Ltd. \\ / A nd | Copyright (C) 2009-2011, 2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
| Copyright (C) 2011-2015 OpenFOAM Foundation | Copyright (C) 2011-2015 OpenFOAM Foundation
@ -27,29 +27,30 @@ License
#include "SHA1Digest.H" #include "SHA1Digest.H"
#include "IOstreams.H" #include "IOstreams.H"
#include <cstring> #include <cstring>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const Foam::SHA1Digest Foam::SHA1Digest::null; const Foam::SHA1Digest Foam::SHA1Digest::null;
//! \cond fileScope
static const char hexChars[] = "0123456789abcdef"; static const char hexChars[] = "0123456789abcdef";
//! \endcond
// The char '0' == 0
static constexpr int offsetZero = int('0');
// The char 'A' (or 'a') == 10
static constexpr int offsetUpper = int('A') - 10;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
unsigned char Foam::SHA1Digest::readHexDigit(Istream& is) namespace Foam
{ {
// Takes into account that 'a' (or 'A') is 10
static const int alphaOffset = toupper('A') - 10;
// Takes into account that '0' is 0
static const int zeroOffset = int('0');
// Read hexadecimal value, ignoring leading or intermediate '_'
// silently ignore leading or intermediate '_' static unsigned char readHexDigit(Istream& is)
{
// Silently ignore leading or intermediate '_'
char c = 0; char c = 0;
do do
{ {
@ -57,23 +58,22 @@ unsigned char Foam::SHA1Digest::readHexDigit(Istream& is)
} }
while (c == '_'); while (c == '_');
if (!isxdigit(c)) if (isdigit(c))
{
return int(c) - offsetZero;
}
else if (!isxdigit(c))
{ {
FatalIOErrorInFunction(is) FatalIOErrorInFunction(is)
<< "Illegal hex digit: '" << c << "'" << "Illegal hex digit: '" << c << "'"
<< exit(FatalIOError); << exit(FatalIOError);
} }
if (isdigit(c)) return toupper(c) - offsetUpper;
{
return int(c) - zeroOffset;
}
else
{
return toupper(c) - alphaOffset;
}
} }
} // End namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -85,7 +85,8 @@ Foam::SHA1Digest::SHA1Digest()
Foam::SHA1Digest::SHA1Digest(Istream& is) Foam::SHA1Digest::SHA1Digest(Istream& is)
{ {
is >> *this; clear();
read(is);
} }
@ -93,15 +94,15 @@ Foam::SHA1Digest::SHA1Digest(Istream& is)
void Foam::SHA1Digest::clear() void Foam::SHA1Digest::clear()
{ {
memset(v_, 0, length); dig_.fill(0); // Same as memset(dig_.data(), 0, dig_.size());
} }
bool Foam::SHA1Digest::empty() const bool Foam::SHA1Digest::empty() const
{ {
for (unsigned i = 0; i < length; ++i) for (const auto& byteVal : dig_)
{ {
if (v_[i]) if (byteVal)
{ {
return false; return false;
} }
@ -118,24 +119,39 @@ std::string Foam::SHA1Digest::str(const bool prefixed) const
if (prefixed) if (prefixed)
{ {
buf.resize(1 + length*2); buf.resize(1 + 2*dig_.size());
buf[nChar++] = '_'; buf[nChar++] = '_';
} }
else else
{ {
buf.resize(length*2); buf.resize(2*dig_.size());
} }
for (unsigned i = 0; i < length; ++i) for (const auto& byteVal : dig_)
{ {
buf[nChar++] = hexChars[((v_[i] >> 4) & 0xF)]; buf[nChar++] = hexChars[((byteVal >> 4) & 0xF)]; // Upper nibble
buf[nChar++] = hexChars[(v_[i] & 0xF)]; buf[nChar++] = hexChars[(byteVal & 0xF)]; // Lower nibble
} }
return buf; return buf;
} }
Foam::Istream& Foam::SHA1Digest::read(Istream& is)
{
for (auto& byteVal : dig_)
{
const unsigned char upp = readHexDigit(is);
const unsigned char low = readHexDigit(is);
byteVal = (upp << 4) + low;
}
is.check(FUNCTION_NAME);
return is;
}
Foam::Ostream& Foam::SHA1Digest::write(Ostream& os, const bool prefixed) const Foam::Ostream& Foam::SHA1Digest::write(Ostream& os, const bool prefixed) const
{ {
if (prefixed) if (prefixed)
@ -143,10 +159,10 @@ Foam::Ostream& Foam::SHA1Digest::write(Ostream& os, const bool prefixed) const
os.write('_'); os.write('_');
} }
for (unsigned i = 0; i < length; ++i) for (const auto& byteVal : dig_)
{ {
os.write(hexChars[((v_[i] >> 4) & 0xF)]); os.write(hexChars[((byteVal >> 4) & 0xF)]); // Upper nibble
os.write(hexChars[(v_[i] & 0xF)]); os.write(hexChars[(byteVal & 0xF)]); // Lower nibble
} }
os.check(FUNCTION_NAME); os.check(FUNCTION_NAME);
@ -158,46 +174,38 @@ Foam::Ostream& Foam::SHA1Digest::write(Ostream& os, const bool prefixed) const
bool Foam::SHA1Digest::operator==(const SHA1Digest& rhs) const bool Foam::SHA1Digest::operator==(const SHA1Digest& rhs) const
{ {
for (unsigned i = 0; i < length; ++i) return (dig_ == rhs.dig_);
{
if (v_[i] != rhs.v_[i])
{
return false;
}
}
return true;
} }
bool Foam::SHA1Digest::operator==(const std::string& hexdigits) const bool Foam::SHA1Digest::operator==(const std::string& hexdigits) const
{ {
// null or empty string is not an error - interpret as '0000..' // Null or empty string is not an error - interpret as '0000..'
if (hexdigits.empty()) if (hexdigits.empty())
{ {
return empty(); return empty();
} }
// skip possible '_' prefix // Skip possible '_' prefix
unsigned charI = 0; unsigned nChar = 0;
if (hexdigits[0] == '_') if (hexdigits[0] == '_')
{ {
++charI; ++nChar;
} }
// incorrect length - can never match // Incorrect length - can never match
if (hexdigits.size() != charI + length*2) if (hexdigits.size() != nChar + 2*dig_.size())
{ {
return false; return false;
} }
for (unsigned i = 0; i < length; ++i) for (const auto& byteVal : dig_)
{ {
const char c1 = hexChars[((v_[i] >> 4) & 0xF)]; const char upp = hexChars[((byteVal >> 4) & 0xF)]; // Upper nibble
const char c2 = hexChars[(v_[i] & 0xF)]; const char low = hexChars[(byteVal & 0xF)]; // Lower nibble
if (c1 != hexdigits[charI++]) return false; if (upp != hexdigits[nChar++]) return false;
if (c2 != hexdigits[charI++]) return false; if (low != hexdigits[nChar++]) return false;
} }
return true; return true;
@ -206,32 +214,32 @@ bool Foam::SHA1Digest::operator==(const std::string& hexdigits) const
bool Foam::SHA1Digest::operator==(const char* hexdigits) const bool Foam::SHA1Digest::operator==(const char* hexdigits) const
{ {
// null or empty string is not an error - interpret as '0000..' // Null or empty string is not an error - interpret as '0000..'
if (!hexdigits || !*hexdigits) if (!hexdigits || !*hexdigits)
{ {
return empty(); return empty();
} }
// skip possible '_' prefix // Skip possible '_' prefix
unsigned charI = 0; unsigned nChar = 0;
if (hexdigits[0] == '_') if (hexdigits[0] == '_')
{ {
++charI; ++nChar;
} }
// incorrect length - can never match // Incorrect length - can never match
if (strlen(hexdigits) != charI + length*2) if (strlen(hexdigits) != nChar + 2*dig_.size())
{ {
return false; return false;
} }
for (unsigned i = 0; i < length; ++i) for (const auto& byteVal : dig_)
{ {
const char c1 = hexChars[((v_[i] >> 4) & 0xF)]; const char upp = hexChars[((byteVal >> 4) & 0xF)];
const char c2 = hexChars[(v_[i] & 0xF)]; const char low = hexChars[(byteVal & 0xF)];
if (c1 != hexdigits[charI++]) return false; if (upp != hexdigits[nChar++]) return false;
if (c2 != hexdigits[charI++]) return false; if (low != hexdigits[nChar++]) return false;
} }
return true; return true;
@ -256,22 +264,11 @@ bool Foam::SHA1Digest::operator!=(const char* rhs) const
} }
// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Istream& Foam::operator>>(Istream& is, SHA1Digest& dig) Foam::Istream& Foam::operator>>(Istream& is, SHA1Digest& dig)
{ {
unsigned char *v = dig.v_; return dig.read(is);
for (unsigned i = 0; i < dig.length; ++i)
{
unsigned char c1 = SHA1Digest::readHexDigit(is);
unsigned char c2 = SHA1Digest::readHexDigit(is);
v[i] = (c1 << 4) + c2;
}
is.check(FUNCTION_NAME);
return is;
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2009-2011 OpenCFD Ltd. \\ / A nd | Copyright (C) 2009-2011, 2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation | Copyright (C) 2011-2016 OpenFOAM Foundation
@ -40,6 +40,7 @@ SourceFiles
#ifndef SHA1Digest_H #ifndef SHA1Digest_H
#define SHA1Digest_H #define SHA1Digest_H
#include <array>
#include <string> #include <string>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -47,30 +48,39 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declaration of classes // Forward Declarations
class SHA1;
class Istream; class Istream;
class Ostream; class Ostream;
// Forward declaration of friend functions and operators
class SHA1;
class SHA1Digest;
Ostream& operator<<(Ostream&, const SHA1Digest&);
Istream& operator>>(Istream&, SHA1Digest&);
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class SHA1Digest Declaration Class SHA1Digest Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class SHA1Digest class SHA1Digest
{ {
// Private Data
//- The digest contents, which has 20 (uncoded) bytes
std::array<unsigned char, 20> dig_;
// Private Member Functions
//- Pointer to the underlying digest data
unsigned char* data()
{
return dig_.data();
}
// Permit SHA1 to calculate the digest
friend class SHA1;
public: public:
friend class SHA1;
// Static data members
//- The length of the (uncoded) digest contents // Static Data Members
static const unsigned length = 20;
//- A null digest (ie, all zero) //- A null digest (ie, all zero)
static const SHA1Digest null; static const SHA1Digest null;
@ -81,8 +91,8 @@ public:
//- Construct a zero digest //- Construct a zero digest
SHA1Digest(); SHA1Digest();
//- Construct read a digest //- Read construct a digest
SHA1Digest(Istream&); explicit SHA1Digest(Istream& is);
// Member Functions // Member Functions
@ -96,8 +106,14 @@ public:
//- Return (40-byte) text representation, optionally with '_' prefix //- Return (40-byte) text representation, optionally with '_' prefix
std::string str(const bool prefixed=false) const; std::string str(const bool prefixed=false) const;
//- Read (40-byte) text representation.
// Since leading and intermediate underscores are skipped, a '_' can
// be prefixed to the text representation to use an unquoted
// SHA1Digest without parsing ambiguities as a number.
Istream& read(Istream& is);
//- Write (40-byte) text representation, optionally with '_' prefix //- Write (40-byte) text representation, optionally with '_' prefix
Ostream& write(Ostream&, const bool prefixed=false) const; Ostream& write(Ostream& os, const bool prefixed=false) const;
// Member Operators // Member Operators
@ -126,33 +142,18 @@ public:
//- Inequality operator //- Inequality operator
bool operator!=(const char* hexdigits) const; bool operator!=(const char* hexdigits) const;
// IOstream Operators
//- Read (40-byte) text representation
// Since leading and intermediate underscores are skipped, a '_' can
// be prefixed to the text representation to use an unquoted
// SHA1Digest without parsing ambiguities as a number.
friend Istream& operator>>(Istream&, SHA1Digest&);
//- Write (40-byte) text representation, unquoted and without prefix
friend Ostream& operator<<(Ostream&, const SHA1Digest&);
private:
// Private data
//- The digest contents
unsigned char v_[length];
//- Read hexadecimal value, ignoring leading or intermediate '_'
static unsigned char readHexDigit(Istream&);
}; };
// IOstream Operators
//- Read (40-byte) text representation (ignoring leading '_' prefix)
Istream& operator>>(Istream&is , SHA1Digest& dig);
//- Write (40-byte) text representation, unquoted and without prefix
Ostream& operator<<(Ostream& os, const SHA1Digest& dig);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2009-2011 OpenCFD Ltd. \\ / A nd | Copyright (C) 2009-2011, 2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
| Copyright (C) 2011 OpenFOAM Foundation | Copyright (C) 2011 OpenFOAM Foundation
@ -36,14 +36,14 @@ inline Foam::SHA1::SHA1()
} }
inline Foam::SHA1::SHA1(const std::string& str) inline Foam::SHA1::SHA1(const char* str)
{ {
clear(); clear();
append(str); append(str);
} }
inline Foam::SHA1::SHA1(const char* str) inline Foam::SHA1::SHA1(const std::string& str)
{ {
clear(); clear();
append(str); append(str);
@ -59,16 +59,9 @@ inline Foam::SHA1& Foam::SHA1::append(const char* data, size_t len)
} }
inline Foam::SHA1& Foam::SHA1::append(const std::string& str)
{
processBytes(str.data(), str.size());
return *this;
}
inline Foam::SHA1& Foam::SHA1::append(const char* str) inline Foam::SHA1& Foam::SHA1::append(const char* str)
{ {
if (str) if (str && *str)
{ {
processBytes(str, strlen(str)); processBytes(str, strlen(str));
} }
@ -76,17 +69,85 @@ inline Foam::SHA1& Foam::SHA1::append(const char* str)
} }
inline Foam::SHA1& Foam::SHA1::append(const std::string& str)
{
processBytes(str.data(), str.size());
return *this;
}
inline Foam::SHA1& Foam::SHA1::append
(
const std::string& str,
size_t pos,
size_t len
)
{
if (std::string::npos != pos && pos < str.length())
{
if (std::string::npos == len || pos + len > str.length())
{
len = str.length() - pos;
}
processBytes(str.data() + pos, len);
}
return *this;
}
inline Foam::SHA1Digest Foam::SHA1::digest() const
{
SHA1Digest dig;
if (finalized_)
{
calcDigest(dig);
}
else
{
// Avoid disturbing current data - use a copy
SHA1 sha(*this);
if (sha.finalize())
{
sha.calcDigest(dig);
}
}
return dig;
}
inline std::string Foam::SHA1::str(const bool prefixed) const
{
return digest().str(prefixed);
}
inline Foam::Ostream& Foam::SHA1::write(Ostream& os, const bool prefixed) const
{
return digest().write(os, prefixed);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline Foam::SHA1::operator Foam::SHA1Digest() const
{
return digest();
}
inline bool Foam::SHA1::operator==(const SHA1& rhs) const inline bool Foam::SHA1::operator==(const SHA1& rhs) const
{ {
return this->digest() == rhs.digest(); return this->digest() == rhs.digest();
} }
inline bool Foam::SHA1::operator==(const SHA1Digest& rhs) const inline bool Foam::SHA1::operator==(const SHA1Digest& dig) const
{ {
return this->digest() == rhs; return this->digest() == dig;
} }
@ -126,17 +187,11 @@ inline bool Foam::SHA1::operator!=(const char* rhs) const
} }
inline Foam::SHA1::operator Foam::SHA1Digest() const
{
return digest();
}
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
inline Foam::Ostream& Foam::operator<<(Ostream& os, const SHA1& sha) inline Foam::Ostream& Foam::operator<<(Ostream& os, const SHA1& sha)
{ {
return (os << sha.digest()); return sha.write(os);
} }