"Fossies" - the Fresh Open Source Software Archive

Member "google-gadgets-for-linux-0.11.2/ggadget/file_manager_wrapper.cc" (20 Mar 2009, 11706 Bytes) of package /linux/misc/old/google-gadgets-for-linux-0.11.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2   Copyright 2008 Google Inc.
    3 
    4   Licensed under the Apache License, Version 2.0 (the "License");
    5   you may not use this file except in compliance with the License.
    6   You may obtain a copy of the License at
    7 
    8        http://www.apache.org/licenses/LICENSE-2.0
    9 
   10   Unless required by applicable law or agreed to in writing, software
   11   distributed under the License is distributed on an "AS IS" BASIS,
   12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   13   See the License for the specific language governing permissions and
   14   limitations under the License.
   15 */
   16 
   17 #include "file_manager_wrapper.h"
   18 
   19 #include <vector>
   20 #include "gadget_consts.h"
   21 #include "light_map.h"
   22 #include "logger.h"
   23 #include "slot.h"
   24 #include "string_utils.h"
   25 #include "system_utils.h"
   26 #include "small_object.h"
   27 
   28 namespace ggadget {
   29 
   30 class FileManagerWrapper::Impl : public SmallObject<> {
   31  public:
   32   Impl() : default_(NULL) {
   33   }
   34 
   35   ~Impl() {
   36     delete default_;
   37     default_ = NULL;
   38 
   39     for (size_t i = 0; i < file_managers_.size(); ++i)
   40       delete file_managers_[i].second;
   41 
   42     file_managers_.clear();
   43   }
   44 
   45   bool RegisterFileManager(const char *prefix, FileManagerInterface *fm) {
   46     // The default FileManager
   47     if (!prefix || !*prefix) {
   48       if (default_) {
   49         LOG("Default file manager must be unregistered before replaced.");
   50         return false;
   51       }
   52       default_ = fm;
   53       return true;
   54     }
   55 
   56     if (!fm || !fm->IsValid()) {
   57       LOG("An invalid FileManager instance is specified for prefix %s",
   58           prefix);
   59       return false;
   60     }
   61 
   62     file_managers_.push_back(std::make_pair(std::string(prefix), fm));
   63     return true;
   64   }
   65 
   66   bool UnregisterFileManager(const char *prefix,
   67                              FileManagerInterface *fm) {
   68     // The default FileManager
   69     if (!prefix || !*prefix) {
   70       if (fm == default_) {
   71         default_ = NULL;
   72         return true;
   73       }
   74       LOG("UnregisterFileManager: Default file manager mismatch.");
   75       return false;
   76     }
   77 
   78     for (FileManagerPrefixMap::iterator it = file_managers_.begin();
   79          it != file_managers_.end(); ++it) {
   80       if (it->first == prefix && it->second == fm) {
   81         file_managers_.erase(it);
   82         return true;
   83       }
   84     }
   85 
   86     LOG("UnregisterFileManager: File manager not found.");
   87     return false;
   88   }
   89 
   90   bool IsValid() {
   91     if (default_ && default_->IsValid())
   92       return true;
   93 
   94     for (FileManagerPrefixMap::iterator it = file_managers_.begin();
   95          it != file_managers_.end(); ++it) {
   96       if (it->second->IsValid())
   97         return true;
   98     }
   99 
  100     return false;
  101   }
  102 
  103   bool Init(const char *base_path, bool create) {
  104     if (default_)
  105       return default_->Init(base_path, create);
  106     return false;
  107   }
  108 
  109   bool ReadFile(const char *file, std::string *data) {
  110     size_t index = 0;
  111     FileManagerInterface *fm = NULL;
  112     std::string path;
  113     bool matched = false;
  114     while ((fm = GetNextMatching(file, &index, &path)) != NULL) {
  115       matched = true;
  116       if (fm->ReadFile(path.c_str(), data))
  117         return true;
  118     }
  119 
  120     if (default_ && !matched)
  121       return default_->ReadFile(file, data);
  122 
  123     return false;
  124   }
  125 
  126   bool WriteFile(const char *file, const std::string &data, bool overwrite) {
  127     size_t index = 0;
  128     FileManagerInterface *fm = NULL;
  129     std::string path;
  130     bool matched = false;
  131     while ((fm = GetNextMatching(file, &index, &path)) != NULL) {
  132       matched = true;
  133       // Only writes the file to the first matched FileManager,
  134       // unless it fails.
  135       if (fm->WriteFile(path.c_str(), data, overwrite))
  136         return true;
  137     }
  138 
  139     if (default_ && !matched)
  140       return default_->WriteFile(file, data, overwrite);
  141 
  142     return false;
  143   }
  144 
  145   bool RemoveFile(const char *file) {
  146     size_t index = 0;
  147     FileManagerInterface *fm = NULL;
  148     std::string path;
  149     bool result = false;
  150     bool matched = false;
  151     while ((fm = GetNextMatching(file, &index, &path)) != NULL) {
  152       matched = true;
  153       // Removes the file in all matched FileManager instance.
  154       if (fm->RemoveFile(path.c_str()))
  155         result = true;
  156     }
  157 
  158     if (default_ && !matched)
  159       result = default_->RemoveFile(file);
  160 
  161     return result;
  162   }
  163 
  164   bool ExtractFile(const char *file, std::string *into_file) {
  165     size_t index = 0;
  166     FileManagerInterface *fm = NULL;
  167     std::string path;
  168     bool matched = false;
  169     while ((fm = GetNextMatching(file, &index, &path)) != NULL) {
  170       matched = true;
  171       if (fm->ExtractFile(path.c_str(), into_file))
  172         return true;
  173     }
  174 
  175     if (default_ && !matched)
  176       return default_->ExtractFile(file, into_file);
  177 
  178     return false;
  179   }
  180 
  181   bool FileExists(const char *file, std::string *path) {
  182     size_t index = 0;
  183     FileManagerInterface *fm = NULL;
  184     std::string lookup_path;
  185     bool matched = false;
  186     while ((fm = GetNextMatching(file, &index, &lookup_path)) != NULL) {
  187       matched = true;
  188       if (fm->FileExists(lookup_path.c_str(), path))
  189         return true;
  190     }
  191 
  192     if (default_ && !matched)
  193       return default_->FileExists(file, path);
  194 
  195     return false;
  196   }
  197 
  198   bool IsDirectlyAccessible(const char *file, std::string *path) {
  199     size_t index = 0;
  200     FileManagerInterface *fm = NULL;
  201     std::string lookup_path;
  202     bool matched = false;
  203     while ((fm = GetNextMatching(file, &index, &lookup_path)) != NULL) {
  204       matched = true;
  205       if (fm->IsDirectlyAccessible(lookup_path.c_str(), path))
  206         return true;
  207     }
  208 
  209     if (default_ && !matched)
  210       return default_->IsDirectlyAccessible(file, path);
  211 
  212     return false;
  213   }
  214 
  215   std::string GetFullPath(const char *file) {
  216     size_t index = 0;
  217     FileManagerInterface *fm = NULL;
  218     std::string lookup_path;
  219     bool matched = false;
  220     while ((fm = GetNextMatching(file, &index, &lookup_path)) != NULL) {
  221       matched = true;
  222       std::string full_path = fm->GetFullPath(lookup_path.c_str());
  223       if (full_path.length())
  224         return full_path;
  225     }
  226 
  227     if (default_ && !matched)
  228       return default_->GetFullPath(file);
  229 
  230     return std::string("");
  231   }
  232 
  233   class EnumProxy {
  234    public:
  235     EnumProxy(LightSet<std::string> *history, const std::string &prefix,
  236               Slot1<bool, const char *> *callback)
  237         : history_(history), prefix_(prefix), callback_(callback) {
  238     }
  239     bool Callback(const char *name) {
  240       std::string path = BuildFilePath(prefix_.c_str(), name, NULL);
  241       if (history_->find(path) == history_->end()) {
  242         history_->insert(path);
  243         return (*callback_)(BuildFilePath(prefix_.c_str(), name, NULL).c_str());
  244       }
  245       return true;
  246     }
  247    private:
  248     LightSet<std::string> *history_;
  249     std::string prefix_;
  250     Slot1<bool, const char *> *callback_;
  251   };
  252 
  253   bool EnumerateFiles(const char *dir, Slot1<bool, const char *> *callback) {
  254     ASSERT(dir);
  255     std::string dir_name(dir);
  256     std::string dir_name_with_sep(dir_name);
  257     if (!dir_name.empty() && dir_name[dir_name.size() - 1] == kDirSeparator)
  258       dir_name.erase(dir_name.size() - 1);
  259     if (!dir_name_with_sep.empty() &&
  260         dir_name_with_sep[dir_name_with_sep.size() - 1] != kDirSeparator)
  261       dir_name += kDirSeparator;
  262 
  263     // Record enumrated files to prevent duplication in multiple managers.
  264     bool result = true;
  265     LightSet<std::string> history;
  266     for (size_t i = 0; result && i < file_managers_.size(); i++) {
  267       const std::string &prefix = file_managers_[i].first;
  268       FileManagerInterface *fm = file_managers_[i].second;
  269       if (GadgetStrNCmp(prefix.c_str(), dir_name.c_str(), prefix.size()) == 0) {
  270         // Dir is under this file manager.
  271         EnumProxy proxy(&history, "", callback);
  272         result = fm->EnumerateFiles(dir_name.c_str() + prefix.size(),
  273                                     NewSlot(&proxy, &EnumProxy::Callback));
  274       } else if (GadgetStrNCmp(prefix.c_str(), dir_name_with_sep.c_str(),
  275                                dir_name_with_sep.size()) == 0) {
  276         // This file manager is under dir.
  277         EnumProxy proxy(&history, prefix.substr(dir_name_with_sep.size()),
  278                         callback);
  279         result = fm->EnumerateFiles("", NewSlot(&proxy, &EnumProxy::Callback));
  280       }
  281     }
  282 
  283     if (result && default_) {
  284       EnumProxy proxy(&history, "", callback);
  285       result = default_->EnumerateFiles(dir_name.c_str(),
  286                                         NewSlot(&proxy, &EnumProxy::Callback));
  287     }
  288     delete callback;
  289     return result;
  290   }
  291 
  292   uint64_t GetLastModifiedTime(const char *file) {
  293     size_t index = 0;
  294     FileManagerInterface *fm = NULL;
  295     std::string lookup_path;
  296     bool matched = false;
  297     while ((fm = GetNextMatching(file, &index, &lookup_path)) != NULL) {
  298       matched = true;
  299       uint64_t result = fm->GetLastModifiedTime(lookup_path.c_str());
  300       if (result > 0)
  301         return result;
  302     }
  303 
  304     if (default_ && !matched)
  305       return default_->GetLastModifiedTime(file);
  306 
  307     return 0;
  308   }
  309 
  310   FileManagerInterface *GetNextMatching(const char *path,
  311                                         size_t *index,
  312                                         std::string *lookup_path) {
  313     if (*index >= file_managers_.size() || !path || !*path)
  314       return NULL;
  315 
  316     while (*index < file_managers_.size()) {
  317       const std::string &prefix = file_managers_[*index].first;
  318       FileManagerInterface *fm = file_managers_[*index].second;
  319       ++*index;
  320 
  321       if (GadgetStrNCmp(prefix.c_str(), path, prefix.size()) == 0) {
  322         *lookup_path = std::string(path + prefix.size());
  323         return fm;
  324       }
  325     }
  326 
  327     return NULL;
  328   }
  329 
  330   typedef std::vector<std::pair<std::string, FileManagerInterface *> >
  331       FileManagerPrefixMap;
  332 
  333   FileManagerPrefixMap file_managers_;
  334   FileManagerInterface *default_;
  335 };
  336 
  337 FileManagerWrapper::FileManagerWrapper()
  338     : impl_(new Impl()) {
  339 }
  340 
  341 FileManagerWrapper::~FileManagerWrapper() {
  342   delete impl_;
  343   impl_ = NULL;
  344 }
  345 
  346 bool FileManagerWrapper::RegisterFileManager(const char *prefix,
  347                                              FileManagerInterface *fm) {
  348   return impl_->RegisterFileManager(prefix, fm);
  349 }
  350 
  351 bool FileManagerWrapper::UnregisterFileManager(const char *prefix,
  352                                                FileManagerInterface *fm) {
  353   return impl_->UnregisterFileManager(prefix, fm);
  354 }
  355 
  356 bool FileManagerWrapper::IsValid() {
  357   return impl_->IsValid();
  358 }
  359 
  360 bool FileManagerWrapper::Init(const char *base_path, bool create) {
  361   return impl_->Init(base_path, create);
  362 }
  363 
  364 bool FileManagerWrapper::ReadFile(const char *file, std::string *data) {
  365   return impl_->ReadFile(file, data);
  366 }
  367 
  368 bool FileManagerWrapper::WriteFile(const char *file, const std::string &data,
  369                                    bool overwrite) {
  370   return impl_->WriteFile(file, data, overwrite);
  371 }
  372 
  373 bool FileManagerWrapper::RemoveFile(const char *file) {
  374   return impl_->RemoveFile(file);
  375 }
  376 
  377 bool FileManagerWrapper::ExtractFile(const char *file, std::string *into_file) {
  378   return impl_->ExtractFile(file, into_file);
  379 }
  380 
  381 bool FileManagerWrapper::FileExists(const char *file, std::string *path) {
  382   return impl_->FileExists(file, path);
  383 }
  384 
  385 bool FileManagerWrapper::IsDirectlyAccessible(const char *file,
  386                                           std::string *path) {
  387   return impl_->IsDirectlyAccessible(file, path);
  388 }
  389 
  390 std::string FileManagerWrapper::GetFullPath(const char *file) {
  391   return impl_->GetFullPath(file);
  392 }
  393 
  394 uint64_t FileManagerWrapper::GetLastModifiedTime(const char *file) {
  395   return impl_->GetLastModifiedTime(file);
  396 }
  397 
  398 bool FileManagerWrapper::EnumerateFiles(const char *dir,
  399                                         Slot1<bool, const char *> *callback) {
  400   return impl_->EnumerateFiles(dir, callback);
  401 }
  402 
  403 } // namespace ggadget