Browse Source

cmCryptoHash: New ByteHash methods that return a byte vector

Sebastian Holtermann 9 years ago
parent
commit
3a5f609cbb
2 changed files with 55 additions and 26 deletions
  1. 40 26
      Source/cmCryptoHash.cxx
  2. 15 0
      Source/cmCryptoHash.h

+ 40 - 26
Source/cmCryptoHash.cxx

@@ -65,43 +65,57 @@ std::string cmCryptoHash::ByteHashToString(
   return res;
 }
 
-std::string cmCryptoHash::HashString(const std::string& input)
+std::vector<unsigned char> cmCryptoHash::ByteHashString(
+  const std::string& input)
 {
   this->Initialize();
   this->Append(reinterpret_cast<unsigned char const*>(input.c_str()),
                static_cast<int>(input.size()));
-  return ByteHashToString(this->Finalize());
+  return this->Finalize();
 }
 
-std::string cmCryptoHash::HashFile(const std::string& file)
+std::vector<unsigned char> cmCryptoHash::ByteHashFile(const std::string& file)
 {
   cmsys::ifstream fin(file.c_str(), std::ios::in | std::ios::binary);
-  if (!fin) {
-    return "";
+  if (fin) {
+    this->Initialize();
+    {
+      // Should be efficient enough on most system:
+      cm_sha2_uint64_t buffer[512];
+      char* buffer_c = reinterpret_cast<char*>(buffer);
+      unsigned char const* buffer_uc =
+        reinterpret_cast<unsigned char const*>(buffer);
+      // This copy loop is very sensitive on certain platforms with
+      // slightly broken stream libraries (like HPUX).  Normally, it is
+      // incorrect to not check the error condition on the fin.read()
+      // before using the data, but the fin.gcount() will be zero if an
+      // error occurred.  Therefore, the loop should be safe everywhere.
+      while (fin) {
+        fin.read(buffer_c, sizeof(buffer));
+        if (int gcount = static_cast<int>(fin.gcount())) {
+          this->Append(buffer_uc, gcount);
+        }
+      }
+    }
+    if (fin.eof()) {
+      // Success
+      return this->Finalize();
+    }
+    // Finalize anyway
+    this->Finalize();
   }
+  // Return without success
+  return std::vector<unsigned char>();
+}
 
-  this->Initialize();
+std::string cmCryptoHash::HashString(const std::string& input)
+{
+  return ByteHashToString(this->ByteHashString(input));
+}
 
-  // Should be efficient enough on most system:
-  cm_sha2_uint64_t buffer[512];
-  char* buffer_c = reinterpret_cast<char*>(buffer);
-  unsigned char const* buffer_uc =
-    reinterpret_cast<unsigned char const*>(buffer);
-  // This copy loop is very sensitive on certain platforms with
-  // slightly broken stream libraries (like HPUX).  Normally, it is
-  // incorrect to not check the error condition on the fin.read()
-  // before using the data, but the fin.gcount() will be zero if an
-  // error occurred.  Therefore, the loop should be safe everywhere.
-  while (fin) {
-    fin.read(buffer_c, sizeof(buffer));
-    if (int gcount = static_cast<int>(fin.gcount())) {
-      this->Append(buffer_uc, gcount);
-    }
-  }
-  if (fin.eof()) {
-    return ByteHashToString(this->Finalize());
-  }
-  return "";
+std::string cmCryptoHash::HashFile(const std::string& file)
+{
+  return ByteHashToString(this->ByteHashFile(file));
 }
 
 cmCryptoHashMD5::cmCryptoHashMD5()

+ 15 - 0
Source/cmCryptoHash.h

@@ -23,22 +23,37 @@ class cmCryptoHash
 {
 public:
   virtual ~cmCryptoHash() {}
+
   /// @brief Returns a new hash generator of the requested type
   /// @arg algo Hash type name. Supported hash types are
   ///      MD5, SHA1, SHA224, SHA256, SHA384, SHA512
   /// @return A valid auto pointer if algo is supported or
   ///         an invalid/NULL pointer otherwise
   static CM_AUTO_PTR<cmCryptoHash> New(const char* algo);
+
   /// @brief Converts a hex character to its binary value (4 bits)
   /// @arg input Hex character [0-9a-fA-F].
   /// @arg output Binary value of the input character (4 bits)
   /// @return True if input was a valid hex character
   static bool IntFromHexDigit(char input, char& output);
+
   /// @brief Converts a byte hash to a sequence of hex character pairs
   static std::string ByteHashToString(const std::vector<unsigned char>& hash);
+
+  /// @brief Calculates a binary hash from string input data
+  /// @return Binary hash vector
+  std::vector<unsigned char> ByteHashString(const std::string& input);
+
+  /// @brief Calculates a binary hash from file content
+  /// @see ByteHashString()
+  /// @return Non empty binary hash vector if the file was read successfully.
+  ///         An empty vector otherwise.
+  std::vector<unsigned char> ByteHashFile(const std::string& file);
+
   /// @brief Calculates a hash string from string input data
   /// @return Sequence of hex characters pairs for each byte of the binary hash
   std::string HashString(const std::string& input);
+
   /// @brief Calculates a hash string from file content
   /// @see HashString()
   /// @return Non empty hash string if the file was read successfully.