Bazel client: platform-dependent GetHashedBaseDir

Move the hashed base directory computation logic
into blaze_util_<platform>.cc in order to clean up
the call site and move platform-dependent code out
the client's main file.

--
MOS_MIGRATED_REVID=139319487
diff --git a/src/main/cpp/BUILD b/src/main/cpp/BUILD
index d74a325..e88611b 100644
--- a/src/main/cpp/BUILD
+++ b/src/main/cpp/BUILD
@@ -105,7 +105,6 @@
         ":blaze_abrupt_exit",
         ":blaze_util",
         "//src/main/cpp/util",
-        "//src/main/cpp/util:md5",
         "//src/main/cpp/util:strings",
         "//src/main/protobuf:command_server_cc_proto",
         "//third_party/ijar:zip",
diff --git a/src/main/cpp/blaze.cc b/src/main/cpp/blaze.cc
index 019df86..dc0884e 100644
--- a/src/main/cpp/blaze.cc
+++ b/src/main/cpp/blaze.cc
@@ -75,7 +75,6 @@
 #include "src/main/cpp/util/exit_code.h"
 #include "src/main/cpp/util/file.h"
 #include "src/main/cpp/util/file_platform.h"
-#include "src/main/cpp/util/md5.h"
 #include "src/main/cpp/util/numbers.h"
 #include "src/main/cpp/util/port.h"
 #include "src/main/cpp/util/strings.h"
@@ -84,7 +83,6 @@
 
 #include "src/main/protobuf/command_server.grpc.pb.h"
 
-using blaze_util::Md5Digest;
 using blaze_util::die;
 using blaze_util::pdie;
 
@@ -280,48 +278,6 @@
   fflush(stderr);
 }
 
-#if !defined(__CYGWIN__)
-// Returns the canonical form of the base dir given a root and a hashable
-// string. The resulting dir is composed of the root + md5(hashable)
-static string GetHashedBaseDir(const string &root,
-                               const string &hashable) {
-  unsigned char buf[Md5Digest::kDigestLength];
-  Md5Digest digest;
-  digest.Update(hashable.data(), hashable.size());
-  digest.Finish(buf);
-  return root + "/" + digest.String();
-}
-
-#else
-// Builds a shorter output base dir name for Windows.
-// This MD5s together user name and workspace directory,
-// and only uses 1/3 of the bits to get 8-char alphanumeric
-// file name.
-static string GetHashedBaseDirForWindows(const string &root,
-                                         const string &product_name,
-                                         const string &user_name,
-                                         const string &workspace_directory) {
-  static const char* alphabet
-    // Exactly 64 characters.
-    = "abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ0123456789$-";
-
-  // The length of the resulting filename (8 characters).
-  static const int filename_length = Md5Digest::kDigestLength / 2;
-  unsigned char buf[Md5Digest::kDigestLength];
-  char coded_name[filename_length + 1];
-  Md5Digest digest;
-  digest.Update(user_name.data(), user_name.size());
-  digest.Update(workspace_directory.data(), workspace_directory.size());
-  digest.Finish(buf);
-  for (int i = 0; i < filename_length; i++) {
-    coded_name[i] = alphabet[buf[i] & 0x3F];
-  }
-  coded_name[filename_length] = '\0';
-  return root + "/" + product_name + "/" + string(coded_name);
-}
-#endif
-
-
 // A devtools_ijar::ZipExtractorProcessor to extract the InstallKeyFile
 class GetInstallKeyFileProcessor : public devtools_ijar::ZipExtractorProcessor {
  public:
@@ -1333,12 +1289,16 @@
 
   if (globals->options->output_base.empty()) {
 #if !defined(__CYGWIN__)
-    globals->options->output_base = GetHashedBaseDir(
+    globals->options->output_base = blaze::GetHashedBaseDir(
         globals->options->output_user_root, globals->workspace);
 #else
-    globals->options->output_base = GetHashedBaseDirForWindows(
-        blaze::GetOutputRoot(), globals->options->product_name,
-        blaze::GetUserName(), globals->workspace);
+    // This MD5s together user name and workspace directory.
+    //
+    // TODO(bazel-team) 2016-11-16: use the --output_user_root instead of
+    // blaze::GetOutputRoot (https://github.com/bazelbuild/bazel/issues/2096).
+    globals->options->output_base = blaze::GetHashedBaseDir(
+        blaze::GetOutputRoot() + "/" + globals->options->product_name,
+        blaze::GetUserName() + globals->workspace);
 #endif
   }
 
diff --git a/src/main/cpp/blaze_util_platform.h b/src/main/cpp/blaze_util_platform.h
index 5892b0c..40b000b 100644
--- a/src/main/cpp/blaze_util_platform.h
+++ b/src/main/cpp/blaze_util_platform.h
@@ -136,6 +136,11 @@
 // Mark path as being excluded from backups (if supported by operating system).
 void ExcludePathFromBackup(const std::string& path);
 
+// Returns the canonical form of the base dir given a root and a hashable
+// string. The resulting dir is composed of the root + md5(hashable)
+std::string GetHashedBaseDir(const std::string& root,
+                             const std::string& hashable);
+
 }  // namespace blaze
 
 #endif  // BAZEL_SRC_MAIN_CPP_BLAZE_UTIL_PLATFORM_H_
diff --git a/src/main/cpp/blaze_util_posix.cc b/src/main/cpp/blaze_util_posix.cc
index 282c41c..b0cb90d 100644
--- a/src/main/cpp/blaze_util_posix.cc
+++ b/src/main/cpp/blaze_util_posix.cc
@@ -27,6 +27,7 @@
 #include "src/main/cpp/util/exit_code.h"
 #include "src/main/cpp/util/file.h"
 #include "src/main/cpp/util/file_platform.h"
+#include "src/main/cpp/util/md5.h"
 
 namespace blaze {
 
@@ -217,4 +218,12 @@
   return a == b;
 }
 
+string GetHashedBaseDir(const string& root, const string& hashable) {
+  unsigned char buf[blaze_util::Md5Digest::kDigestLength];
+  blaze_util::Md5Digest digest;
+  digest.Update(hashable.data(), hashable.size());
+  digest.Finish(buf);
+  return root + "/" + digest.String();
+}
+
 }   // namespace blaze.
diff --git a/src/main/cpp/blaze_util_windows.cc b/src/main/cpp/blaze_util_windows.cc
index 2bf92f6..87fe5fa 100644
--- a/src/main/cpp/blaze_util_windows.cc
+++ b/src/main/cpp/blaze_util_windows.cc
@@ -34,6 +34,7 @@
 #include "src/main/cpp/util/errors.h"
 #include "src/main/cpp/util/exit_code.h"
 #include "src/main/cpp/util/file.h"
+#include "src/main/cpp/util/md5.h"
 #include "src/main/cpp/util/strings.h"
 
 namespace blaze {
@@ -827,6 +828,29 @@
 void ExcludePathFromBackup(const string &path) {
 }
 
+string GetHashedBaseDir(const string& root, const string& hashable) {
+  // Builds a shorter output base dir name for Windows.
+  // This algorithm only uses 1/3 of the bits to get 8-char alphanumeric
+  // file name.
+
+  static const char* alphabet
+      // Exactly 64 characters.
+      = "abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ0123456789$-";
+
+  // The length of the resulting filename (8 characters).
+  static const int filename_length = blaze_util::Md5Digest::kDigestLength / 2;
+  unsigned char buf[blaze_util::Md5Digest::kDigestLength];
+  char coded_name[filename_length + 1];
+  blaze_util::Md5Digest digest;
+  digest.Update(hashable.data(), hashable.size());
+  digest.Finish(buf);
+  for (int i = 0; i < filename_length; i++) {
+    coded_name[i] = alphabet[buf[i] & 0x3F];
+  }
+  coded_name[filename_length] = '\0';
+  return root + "/" + string(coded_name);
+}
+
 LARGE_INTEGER WindowsClock::GetFrequency() {
   LARGE_INTEGER result;
   if (!QueryPerformanceFrequency(&result)) {
diff --git a/src/main/cpp/util/BUILD b/src/main/cpp/util/BUILD
index bd1e80b..ae75b94 100644
--- a/src/main/cpp/util/BUILD
+++ b/src/main/cpp/util/BUILD
@@ -7,6 +7,7 @@
         "errors.h",
         "file.h",
         "file_platform.h",
+        "md5.h",
         "numbers.h",
         "port.h",
     ],
@@ -15,6 +16,7 @@
         ":blaze_exit_code",
         ":errors",
         ":file",
+        ":md5",
         ":numbers",
         ":port",
         ":strings",
@@ -70,7 +72,10 @@
     name = "md5",
     srcs = ["md5.cc"],
     hdrs = ["md5.h"],
-    visibility = ["//visibility:public"],
+    visibility = [
+        "//src/main/native:__pkg__",
+        "//src/test/cpp/util:__pkg__",
+    ],
 )
 
 cc_library(