LCOV - app.info - ipc/chromium/src/base/path_service.cc

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-04-21 | 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