summaryrefslogtreecommitdiffstats
path: root/Source/cmCryptoHash.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2011-11-16 00:37:38 (GMT)
committerBrad King <brad.king@kitware.com>2011-11-16 15:14:53 (GMT)
commited7cef563445644684af47720c2f7c6fb0a2e440 (patch)
treeb18e93e7293b6592ef0f98c57a493eb8c4ca30c0 /Source/cmCryptoHash.cxx
parenta9e686d68b5375c471c7204b818fdd2c0a547000 (diff)
downloadCMake-ed7cef563445644684af47720c2f7c6fb0a2e440.zip
CMake-ed7cef563445644684af47720c2f7c6fb0a2e440.tar.gz
CMake-ed7cef563445644684af47720c2f7c6fb0a2e440.tar.bz2
Factor Compute(File|String)MD5 into cmCryptoHash helper
Define an abstract API around the backend hash algorithm. Expose ifstream errors to HashFile callers. Always try opening the file. Succeed only if the end of file is reached without error.
Diffstat (limited to 'Source/cmCryptoHash.cxx')
-rw-r--r--Source/cmCryptoHash.cxx90
1 files changed, 90 insertions, 0 deletions
diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx
new file mode 100644
index 0000000..3a73398
--- /dev/null
+++ b/Source/cmCryptoHash.cxx
@@ -0,0 +1,90 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmCryptoHash.h"
+
+#include <cmsys/MD5.h>
+
+//----------------------------------------------------------------------------
+std::string cmCryptoHash::HashString(const char* input)
+{
+ this->Initialize();
+ this->Append(reinterpret_cast<unsigned char const*>(input),
+ static_cast<int>(strlen(input)));
+ return this->Finalize();
+}
+
+//----------------------------------------------------------------------------
+std::string cmCryptoHash::HashFile(const char* file)
+{
+ std::ifstream fin(file, std::ios::in | cmsys_ios_binary);
+ if(!fin)
+ {
+ return "";
+ }
+
+ this->Initialize();
+
+ // Should be efficient enough on most system:
+ const int bufferSize = 4096;
+ char buffer[bufferSize];
+ 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, bufferSize);
+ if(int gcount = static_cast<int>(fin.gcount()))
+ {
+ this->Append(buffer_uc, gcount);
+ }
+ }
+ if(fin.eof())
+ {
+ return this->Finalize();
+ }
+ return "";
+}
+
+//----------------------------------------------------------------------------
+cmCryptoHashMD5::cmCryptoHashMD5(): MD5(cmsysMD5_New())
+{
+}
+
+//----------------------------------------------------------------------------
+cmCryptoHashMD5::~cmCryptoHashMD5()
+{
+ cmsysMD5_Delete(this->MD5);
+}
+
+//----------------------------------------------------------------------------
+void cmCryptoHashMD5::Initialize()
+{
+ cmsysMD5_Initialize(this->MD5);
+}
+
+//----------------------------------------------------------------------------
+void cmCryptoHashMD5::Append(unsigned char const* buf, int sz)
+{
+ cmsysMD5_Append(this->MD5, buf, sz);
+}
+
+//----------------------------------------------------------------------------
+std::string cmCryptoHashMD5::Finalize()
+{
+ char md5out[32];
+ cmsysMD5_FinalizeHex(this->MD5, md5out);
+ return std::string(md5out, 32);
+}