LCOV - code coverage report
Current view: directory - ipc/chromium/src/base - path_service.cc (source / functions) Found Hit Coverage
Test: app.info Lines: 89 0 0.0 %
Date: 2012-06-02 Functions: 11 0 0.0 %

       1                 : // Copyright (c) 2006-2008 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                 : #include "base/path_service.h"
       6                 : 
       7                 : #ifdef OS_WIN
       8                 : #include <windows.h>
       9                 : #include <shellapi.h>
      10                 : #include <shlobj.h>
      11                 : #endif
      12                 : 
      13                 : #include "base/file_path.h"
      14                 : #include "base/file_util.h"
      15                 : #include "base/hash_tables.h"
      16                 : #include "base/lock.h"
      17                 : #include "base/logging.h"
      18                 : #include "base/singleton.h"
      19                 : #include "base/string_util.h"
      20                 : 
      21                 : namespace base {
      22                 :   bool PathProvider(int key, FilePath* result);
      23                 : #if defined(OS_WIN)
      24                 :   bool PathProviderWin(int key, FilePath* result);
      25                 : #elif defined(OS_MACOSX)
      26                 :   bool PathProviderMac(int key, FilePath* result);
      27                 : #elif defined(OS_LINUX)
      28                 :   bool PathProviderLinux(int key, FilePath* result);
      29                 : #endif
      30                 : }
      31                 : 
      32                 : namespace {
      33                 : 
      34                 : typedef base::hash_map<int, FilePath> PathMap;
      35                 : typedef base::hash_set<int> PathSet;
      36                 : 
      37                 : // We keep a linked list of providers.  In a debug build we ensure that no two
      38                 : // providers claim overlapping keys.
      39                 : struct Provider {
      40                 :   PathService::ProviderFunc func;
      41                 :   struct Provider* next;
      42                 : #ifndef NDEBUG
      43                 :   int key_start;
      44                 :   int key_end;
      45                 : #endif
      46                 :   bool is_static;
      47                 : };
      48                 : 
      49                 : static Provider base_provider = {
      50                 :   base::PathProvider,
      51                 :   NULL,
      52                 : #ifndef NDEBUG
      53                 :   base::PATH_START,
      54                 :   base::PATH_END,
      55                 : #endif
      56                 :   true
      57                 : };
      58                 : 
      59                 : #ifdef OS_WIN
      60                 : static Provider base_provider_win = {
      61                 :   base::PathProviderWin,
      62                 :   &base_provider,
      63                 : #ifndef NDEBUG
      64                 :   base::PATH_WIN_START,
      65                 :   base::PATH_WIN_END,
      66                 : #endif
      67                 :   true
      68                 : };
      69                 : #endif
      70                 : 
      71                 : #ifdef OS_MACOSX
      72                 : static Provider base_provider_mac = {
      73                 :   base::PathProviderMac,
      74                 :   &base_provider,
      75                 : #ifndef NDEBUG
      76                 :   base::PATH_MAC_START,
      77                 :   base::PATH_MAC_END,
      78                 : #endif
      79                 :   true
      80                 : };
      81                 : #endif
      82                 : 
      83                 : #if defined(OS_LINUX)
      84                 : static Provider base_provider_linux = {
      85                 :   base::PathProviderLinux,
      86                 :   &base_provider,
      87                 : #ifndef NDEBUG
      88                 :   base::PATH_LINUX_START,
      89                 :   base::PATH_LINUX_END,
      90                 : #endif
      91                 :   true
      92                 : };
      93                 : #endif
      94                 : 
      95                 : 
      96                 : struct PathData {
      97                 :   Lock      lock;
      98                 :   PathMap   cache;      // Track mappings from path key to path value.
      99                 :   PathSet   overrides;  // Track whether a path has been overridden.
     100                 :   Provider* providers;  // Linked list of path service providers.
     101                 : 
     102               0 :   PathData() {
     103                 : #if defined(OS_WIN)
     104                 :     providers = &base_provider_win;
     105                 : #elif defined(OS_MACOSX)
     106                 :     providers = &base_provider_mac;
     107                 : #elif defined(OS_LINUX)
     108               0 :     providers = &base_provider_linux;
     109                 : #endif
     110               0 :   }
     111                 : 
     112               0 :   ~PathData() {
     113               0 :     Provider* p = providers;
     114               0 :     while (p) {
     115               0 :       Provider* next = p->next;
     116               0 :       if (!p->is_static)
     117                 :         delete p;
     118               0 :       p = next;
     119                 :     }
     120               0 :   }
     121                 : };
     122                 : 
     123               0 : static PathData* GetPathData() {
     124               0 :   return Singleton<PathData>::get();
     125                 : }
     126                 : 
     127                 : }  // namespace
     128                 : 
     129                 : 
     130                 : // static
     131               0 : bool PathService::GetFromCache(int key, FilePath* result) {
     132               0 :   PathData* path_data = GetPathData();
     133               0 :   AutoLock scoped_lock(path_data->lock);
     134                 : 
     135                 :   // check for a cached version
     136               0 :   PathMap::const_iterator it = path_data->cache.find(key);
     137               0 :   if (it != path_data->cache.end()) {
     138               0 :     *result = it->second;
     139               0 :     return true;
     140                 :   }
     141               0 :   return false;
     142                 : }
     143                 : 
     144                 : // static
     145               0 : void PathService::AddToCache(int key, const FilePath& path) {
     146               0 :   PathData* path_data = GetPathData();
     147               0 :   AutoLock scoped_lock(path_data->lock);
     148                 :   // Save the computed path in our cache.
     149               0 :   path_data->cache[key] = path;
     150               0 : }
     151                 : 
     152                 : // TODO(brettw): this function does not handle long paths (filename > MAX_PATH)
     153                 : // characters). This isn't supported very well by Windows right now, so it is
     154                 : // moot, but we should keep this in mind for the future.
     155                 : // static
     156               0 : bool PathService::Get(int key, FilePath* result) {
     157               0 :   PathData* path_data = GetPathData();
     158               0 :   DCHECK(path_data);
     159               0 :   DCHECK(result);
     160               0 :   DCHECK(key >= base::DIR_CURRENT);
     161                 : 
     162                 :   // special case the current directory because it can never be cached
     163               0 :   if (key == base::DIR_CURRENT)
     164               0 :     return file_util::GetCurrentDirectory(result);
     165                 : 
     166               0 :   if (GetFromCache(key, result))
     167               0 :     return true;
     168                 : 
     169               0 :   FilePath path;
     170                 : 
     171                 :   // search providers for the requested path
     172                 :   // NOTE: it should be safe to iterate here without the lock
     173                 :   // since RegisterProvider always prepends.
     174               0 :   Provider* provider = path_data->providers;
     175               0 :   while (provider) {
     176               0 :     if (provider->func(key, &path))
     177               0 :       break;
     178               0 :     DCHECK(path.empty()) << "provider should not have modified path";
     179               0 :     provider = provider->next;
     180                 :   }
     181                 : 
     182               0 :   if (path.empty())
     183               0 :     return false;
     184                 : 
     185               0 :   AddToCache(key, path);
     186                 : 
     187               0 :   *result = path;
     188               0 :   return true;
     189                 : }
     190                 : 
     191                 : // static
     192               0 : bool PathService::Get(int key, std::wstring* result) {
     193                 :   // Deprecated compatibility function.
     194               0 :   FilePath path;
     195               0 :   if (!Get(key, &path))
     196               0 :     return false;
     197               0 :   *result = path.ToWStringHack();
     198               0 :   return true;
     199                 : }
     200                 : 
     201               0 : bool PathService::IsOverridden(int key) {
     202               0 :   PathData* path_data = GetPathData();
     203               0 :   DCHECK(path_data);
     204                 : 
     205               0 :   AutoLock scoped_lock(path_data->lock);
     206               0 :   return path_data->overrides.find(key) != path_data->overrides.end();
     207                 : }
     208                 : 
     209               0 : bool PathService::Override(int key, const std::wstring& path) {
     210               0 :   PathData* path_data = GetPathData();
     211               0 :   DCHECK(path_data);
     212               0 :   DCHECK(key > base::DIR_CURRENT) << "invalid path key";
     213                 : 
     214               0 :   std::wstring file_path = path;
     215                 : #if defined(OS_WIN)
     216                 :   // On Windows we switch the current working directory to load plugins (at
     217                 :   // least). That's not the case on POSIX.
     218                 :   // Also, on POSIX, AbsolutePath fails if called on a non-existant path.
     219                 :   if (!file_util::AbsolutePath(&file_path))
     220                 :     return false;
     221                 : #endif
     222                 : 
     223                 :   // make sure the directory exists:
     224               0 :   if (!file_util::CreateDirectory(file_path))
     225               0 :     return false;
     226                 : 
     227               0 :   file_util::TrimTrailingSeparator(&file_path);
     228                 : 
     229               0 :   AutoLock scoped_lock(path_data->lock);
     230               0 :   path_data->cache[key] = FilePath::FromWStringHack(file_path);
     231               0 :   path_data->overrides.insert(key);
     232               0 :   return true;
     233                 : }
     234                 : 
     235               0 : bool PathService::SetCurrentDirectory(const std::wstring& current_directory) {
     236               0 :   return file_util::SetCurrentDirectory(current_directory);
     237                 : }
     238                 : 
     239               0 : void PathService::RegisterProvider(ProviderFunc func, int key_start,
     240                 :                                    int key_end) {
     241               0 :   PathData* path_data = GetPathData();
     242               0 :   DCHECK(path_data);
     243               0 :   DCHECK(key_end > key_start);
     244                 : 
     245               0 :   AutoLock scoped_lock(path_data->lock);
     246                 : 
     247                 :   Provider* p;
     248                 : 
     249                 : #ifndef NDEBUG
     250               0 :   p = path_data->providers;
     251               0 :   while (p) {
     252               0 :     DCHECK(key_start >= p->key_end || key_end <= p->key_start) <<
     253               0 :       "path provider collision";
     254               0 :     p = p->next;
     255                 :   }
     256                 : #endif
     257                 : 
     258               0 :   p = new Provider;
     259               0 :   p->is_static = false;
     260               0 :   p->func = func;
     261               0 :   p->next = path_data->providers;
     262                 : #ifndef NDEBUG
     263               0 :   p->key_start = key_start;
     264               0 :   p->key_end = key_end;
     265                 : #endif
     266               0 :   path_data->providers = p;
     267               0 : }

Generated by: LCOV version 1.7