Allow extension extensions to be case-insensitive.

BUG=none
TEST=try to load an extension with a capital letter or two in the extension's extension. It should load.

Review URL: http://codereview.chromium.org/147017

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19520 0039d316-1c4b-4281-b951-d872f2087c98


CrOS-Libchrome-Original-Commit: f1ce6e6c4d6bb08bd1534170b4647aabf8ff25ef
diff --git a/base/file_path.cc b/base/file_path.cc
index e3dfbbd..6712d70 100644
--- a/base/file_path.cc
+++ b/base/file_path.cc
@@ -284,6 +284,18 @@
   return FilePath(str);
 }
 
+bool FilePath::MatchesExtension(const StringType& extension) const {
+  FilePath::StringType current_extension = Extension();
+
+  if (current_extension.length() != extension.length())
+    return false;
+
+  return std::equal(extension.begin(),
+                    extension.end(),
+                    current_extension.begin(),
+                    CaseInsensitiveCompare<FilePath::CharType>());
+}
+
 FilePath FilePath::Append(const StringType& component) const {
   DCHECK(!IsPathAbsolute(component));
   if (path_.compare(kCurrentDirectory) == 0) {
diff --git a/base/file_path.h b/base/file_path.h
index ae4d36d..5fe8cda 100644
--- a/base/file_path.h
+++ b/base/file_path.h
@@ -197,6 +197,10 @@
   // Returns "" if BaseName() == "." or "..".
   FilePath ReplaceExtension(const StringType& extension) const;
 
+  // Returns true if the file path matches the specified extension. The test is
+  // case insensitive. Don't forget the leading period if appropriate.
+  bool MatchesExtension(const StringType& extension) const;
+
   // Returns a FilePath by appending a separator and the supplied path
   // component to this object's path.  Append takes care to avoid adding
   // excessive separators if this object's path already ends with a separator.
diff --git a/base/file_path_unittest.cc b/base/file_path_unittest.cc
index 0df6838..55efeac 100644
--- a/base/file_path_unittest.cc
+++ b/base/file_path_unittest.cc
@@ -435,35 +435,35 @@
 
 TEST_F(FilePathTest, IsParentTest) {
   const struct BinaryBooleanTestData cases[] = {
-    { { FPL("/"),             FPL("/foo/bar/baz") },        true},
-    { { FPL("/foo/bar"),      FPL("/foo/bar/baz") },        true},
-    { { FPL("/foo/bar/"),     FPL("/foo/bar/baz") },        true},
-    { { FPL("//foo/bar/"),    FPL("//foo/bar/baz") },       true},
-    { { FPL("/foo/bar"),      FPL("/foo2/bar/baz") },       false},
-    { { FPL("/foo/bar.txt"),  FPL("/foo/bar/baz") },        false},
-    { { FPL("/foo/bar"),      FPL("/foo/bar2/baz") },       false},
-    { { FPL("/foo/bar"),      FPL("/foo/bar") },            false},
-    { { FPL("/foo/bar/baz"),  FPL("/foo/bar") },            false},
-    { { FPL("foo/bar"),       FPL("foo/bar/baz") },         true},
-    { { FPL("foo/bar"),       FPL("foo2/bar/baz") },        false},
-    { { FPL("foo/bar"),       FPL("foo/bar2/baz") },        false},
-    { { FPL(""),              FPL("foo") },                 false},
+    { { FPL("/"),             FPL("/foo/bar/baz") },      true},
+    { { FPL("/foo/bar"),      FPL("/foo/bar/baz") },      true},
+    { { FPL("/foo/bar/"),     FPL("/foo/bar/baz") },      true},
+    { { FPL("//foo/bar/"),    FPL("//foo/bar/baz") },     true},
+    { { FPL("/foo/bar"),      FPL("/foo2/bar/baz") },     false},
+    { { FPL("/foo/bar.txt"),  FPL("/foo/bar/baz") },      false},
+    { { FPL("/foo/bar"),      FPL("/foo/bar2/baz") },     false},
+    { { FPL("/foo/bar"),      FPL("/foo/bar") },          false},
+    { { FPL("/foo/bar/baz"),  FPL("/foo/bar") },          false},
+    { { FPL("foo/bar"),       FPL("foo/bar/baz") },       true},
+    { { FPL("foo/bar"),       FPL("foo2/bar/baz") },      false},
+    { { FPL("foo/bar"),       FPL("foo/bar2/baz") },      false},
+    { { FPL(""),              FPL("foo") },               false},
 #if defined(FILE_PATH_USES_DRIVE_LETTERS)
-    { { FPL("c:/foo/bar"),    FPL("c:/foo/bar/baz") },      true},
-    { { FPL("c:/"),           FPL("c:/foo/bar/baz") },      true},
-    { { FPL("c:"),            FPL("c:/foo/bar/baz") },      true},
-    { { FPL("c:/foo/bar"),    FPL("d:/foo/bar/baz") },      false},
-    { { FPL("c:/foo/bar"),    FPL("c:/foo2/bar/baz") },     false},
-    { { FPL("c:/foo/bar"),    FPL("c:/foo/bar2/baz") },     false},
+    { { FPL("c:/foo/bar"),    FPL("c:/foo/bar/baz") },    true},
+    { { FPL("c:/"),           FPL("c:/foo/bar/baz") },    true},
+    { { FPL("c:"),            FPL("c:/foo/bar/baz") },    true},
+    { { FPL("c:/foo/bar"),    FPL("d:/foo/bar/baz") },    false},
+    { { FPL("c:/foo/bar"),    FPL("c:/foo2/bar/baz") },   false},
+    { { FPL("c:/foo/bar"),    FPL("c:/foo/bar2/baz") },   false},
 #endif  // FILE_PATH_USES_DRIVE_LETTERS
 #if defined(FILE_PATH_USES_WIN_SEPARATORS)
-    { { FPL("\\foo\\bar"),    FPL("\\foo\\bar\\baz") },     true},
-    { { FPL("\\foo/bar"),     FPL("\\foo\\bar\\baz") },     true},
-    { { FPL("\\foo/bar"),     FPL("\\foo/bar/baz") },       true},
-    { { FPL("\\"),            FPL("\\foo\\bar\\baz") },     true},
-    { { FPL(""),              FPL("\\foo\\bar\\baz") },     false},
-    { { FPL("\\foo\\bar"),    FPL("\\foo2\\bar\\baz") },    false},
-    { { FPL("\\foo\\bar"),    FPL("\\foo\\bar2\\baz") },    false},
+    { { FPL("\\foo\\bar"),    FPL("\\foo\\bar\\baz") },   true},
+    { { FPL("\\foo/bar"),     FPL("\\foo\\bar\\baz") },   true},
+    { { FPL("\\foo/bar"),     FPL("\\foo/bar/baz") },     true},
+    { { FPL("\\"),            FPL("\\foo\\bar\\baz") },   true},
+    { { FPL(""),              FPL("\\foo\\bar\\baz") },   false},
+    { { FPL("\\foo\\bar"),    FPL("\\foo2\\bar\\baz") },  false},
+    { { FPL("\\foo\\bar"),    FPL("\\foo\\bar2\\baz") },  false},
 #endif  // FILE_PATH_USES_DRIVE_LETTERS
   };
 
@@ -634,3 +634,34 @@
         ", path: " << path.value() << ", replace: " << cases[i].inputs[1];
   }
 }
+
+TEST_F(FilePathTest, MatchesExtension) {
+  const struct BinaryBooleanTestData cases[] = {
+    { { FPL("foo"),                   FPL("") },      true},
+    { { FPL("foo"),                   FPL(".") },     false},
+    { { FPL("foo."),                  FPL("") },      false},
+    { { FPL("foo."),                  FPL(".") },     true},
+    { { FPL("foo.txt"),               FPL(".dll") },  false},
+    { { FPL("foo.txt"),               FPL(".txt") },  true},
+    { { FPL("foo.txt.dll"),           FPL(".txt") },  false},
+    { { FPL("foo.txt.dll"),           FPL(".dll") },  true},
+#if defined(FILE_PATH_USES_DRIVE_LETTERS)
+    { { FPL("c:/foo.txt.dll"),        FPL(".txt") },  false},
+    { { FPL("c:/foo.txt"),            FPL(".txt") },  true},
+#endif  // FILE_PATH_USES_DRIVE_LETTERS
+#if defined(FILE_PATH_USES_WIN_SEPARATORS)
+    { { FPL("c:\\bar\\foo.txt.dll"),  FPL(".txt") },  false},
+    { { FPL("c:\\bar\\foo.txt"),      FPL(".txt") },  true},
+#endif  // FILE_PATH_USES_DRIVE_LETTERS
+    { { FPL("/bar/foo.txt.dll"),      FPL(".txt") },  false},
+    { { FPL("/bar/foo.txt"),          FPL(".txt") },  true},
+  };
+
+  for (size_t i = 0; i < arraysize(cases); ++i) {
+    FilePath path(cases[i].inputs[0]);
+    FilePath::StringType ext(cases[i].inputs[1]);
+
+    EXPECT_EQ(cases[i].expected, path.MatchesExtension(ext)) <<
+        "i: " << i << ", path: " << path.value() << ", ext: " << ext;
+  }
+}