duplicate_tree_detector.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
1// Copyright (c) 2011 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.
4//
5
6#include "chrome/installer/util/duplicate_tree_detector.h"
7
8#include "base/file_util.h"
9#include "base/logging.h"
10
11namespace installer {
12
13bool IsIdenticalFileHierarchy(const FilePath& src_path,
14                              const FilePath& dest_path) {
15  using file_util::FileEnumerator;
16  base::PlatformFileInfo src_info;
17  base::PlatformFileInfo dest_info;
18
19  bool is_identical = false;
20  if (file_util::GetFileInfo(src_path, &src_info) &&
21      file_util::GetFileInfo(dest_path, &dest_info)) {
22    // Both paths exist, check the types:
23    if (!src_info.is_directory && !dest_info.is_directory) {
24      // Two files are "identical" if the file sizes are equivalent.
25      is_identical = src_info.size == dest_info.size;
26#ifndef NDEBUG
27      // For Debug builds, also check last modification time (to make sure
28      // version dir DLLs are replaced on over-install even if the tested change
29      // doesn't happen to change a given DLL's size).
30      if (is_identical)
31        is_identical = (src_info.last_modified == dest_info.last_modified);
32#endif
33    } else if (src_info.is_directory && dest_info.is_directory) {
34      // Two directories are "identical" if dest_path contains entries that are
35      // "identical" to all the entries in src_path.
36      is_identical = true;
37
38      FileEnumerator path_enum(src_path, false /* not recursive */,
39          FileEnumerator::FILES | FileEnumerator::DIRECTORIES);
40      for (FilePath path = path_enum.Next(); is_identical && !path.empty();
41           path = path_enum.Next()) {
42        is_identical =
43            IsIdenticalFileHierarchy(path, dest_path.Append(path.BaseName()));
44      }
45    } else {
46      // The two paths are of different types, so they cannot be identical.
47      DCHECK(!is_identical);
48    }
49  }
50
51  return is_identical;
52}
53
54}  // namespace installer
55