Roll src/third_party/WebKit 3aea697:d9c6159 (svn 201973:201974)
[chromium-blink-merge.git] / tools / android / md5sum / md5sum.cc
blob31f65f39523806ccdc7ba0a0f44db0df0da9d42b
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Md5sum implementation for Android. This version handles files as well as
6 // directories. Its output is sorted by file path.
8 #include <fstream>
9 #include <iostream>
10 #include <set>
11 #include <string>
13 #include "base/files/file_enumerator.h"
14 #include "base/files/file_path.h"
15 #include "base/files/file_util.h"
16 #include "base/logging.h"
17 #include "base/md5.h"
19 namespace {
21 // Returns whether |path|'s MD5 was successfully written to |digest_string|.
22 bool MD5Sum(const char* path, std::string* digest_string) {
23 base::ScopedFILE file(fopen(path, "rb"));
24 if (!file) {
25 LOG(ERROR) << "Could not open file " << path;
26 return false;
28 base::MD5Context ctx;
29 base::MD5Init(&ctx);
30 const size_t kBufferSize = 1 << 16;
31 scoped_ptr<char[]> buf(new char[kBufferSize]);
32 size_t len;
33 while ((len = fread(buf.get(), 1, kBufferSize, file.get())) > 0)
34 base::MD5Update(&ctx, base::StringPiece(buf.get(), len));
35 if (ferror(file.get())) {
36 LOG(ERROR) << "Error reading file " << path;
37 return false;
39 base::MD5Digest digest;
40 base::MD5Final(&digest, &ctx);
41 *digest_string = base::MD5DigestToBase16(digest);
42 return true;
45 // Returns the set of all files contained in |files|. This handles directories
46 // by walking them recursively. Excludes, .svn directories and file under them.
47 std::set<std::string> MakeFileSet(const char** files) {
48 const std::string svn_dir_component = FILE_PATH_LITERAL("/.svn/");
49 std::set<std::string> file_set;
50 for (const char** file = files; *file; ++file) {
51 base::FilePath file_path(*file);
52 if (base::DirectoryExists(file_path)) {
53 base::FileEnumerator file_enumerator(
54 file_path, true /* recurse */, base::FileEnumerator::FILES);
55 for (base::FilePath child, empty;
56 (child = file_enumerator.Next()) != empty; ) {
57 // If the path contains /.svn/, ignore it.
58 if (child.value().find(svn_dir_component) == std::string::npos) {
59 file_set.insert(child.value());
62 } else {
63 file_set.insert(*file);
66 return file_set;
69 } // namespace
71 int main(int argc, const char* argv[]) {
72 if (argc < 2) {
73 LOG(ERROR) << "Usage: md5sum <path/to/file_or_dir>...";
74 return 1;
76 const std::set<std::string> files = MakeFileSet(argv + 1);
77 bool failed = false;
78 std::string digest;
79 for (std::set<std::string>::const_iterator it = files.begin();
80 it != files.end(); ++it) {
81 if (!MD5Sum(it->c_str(), &digest)) {
82 failed = true;
83 } else {
84 std::cout << digest << " " << *it << std::endl;
87 return failed;