"Fossies" - the Fresh Open Source Software Archive

Member "google-gadgets-for-linux-0.11.2/ggadget/memory_options.cc" (20 Mar 2009, 7967 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 <climits>
   18 #include <set>
   19 #include "memory_options.h"
   20 #include "logger.h"
   21 #include "scriptable_holder.h"
   22 #include "string_utils.h"
   23 #include "small_object.h"
   24 
   25 namespace ggadget {
   26 
   27 class OptionsItem {
   28  public:
   29   OptionsItem() {
   30   }
   31 
   32   explicit OptionsItem(const Variant &value) {
   33     SetValue(value);
   34   }
   35 
   36   void SetValue(const Variant &value) {
   37     value_ = value;
   38     if (value.type() == Variant::TYPE_SCRIPTABLE)
   39       holder_.Reset(VariantValue<ScriptableInterface *>()(value));
   40     else
   41       holder_.Reset(NULL);
   42   }
   43 
   44   Variant GetValue() const {
   45     return value_.type() == Variant::TYPE_SCRIPTABLE ?
   46            Variant(holder_.Get()) : value_;
   47   }
   48 
   49  private:
   50   Variant value_;
   51   ScriptableHolder<ScriptableInterface> holder_;
   52 };
   53 
   54 class MemoryOptions::Impl : public SmallObject<> {
   55  public:
   56   Impl(size_t size_limit)
   57       : size_limit_(size_limit), total_size_(0) {
   58   }
   59 
   60   void FireChangedEvent(const char *name, const Variant &value) {
   61     DLOG("option %s changed to %s", name, value.Print().c_str());
   62     onoptionchanged_signal_(name);
   63   }
   64 
   65   typedef LightMap<std::string, OptionsItem, GadgetStringComparator> OptionsMap;
   66   typedef LightSet<std::string, GadgetStringComparator> EncryptedSet;
   67   OptionsMap values_;
   68   OptionsMap defaults_;
   69   OptionsMap internal_values_;
   70   EncryptedSet encrypted_;
   71   Signal1<void, const char *> onoptionchanged_signal_;
   72   size_t size_limit_, total_size_;
   73 };
   74 
   75 MemoryOptions::MemoryOptions()
   76     // Though INT_MAX is much smaller than the maximum value of size_t on
   77     // some platforms, it is still big enough to be treated as "unlimited".
   78     : impl_(new Impl(INT_MAX)) {
   79 }
   80 
   81 MemoryOptions::MemoryOptions(size_t size_limit)
   82     : impl_(new Impl(size_limit)) {
   83 }
   84 
   85 MemoryOptions::~MemoryOptions() {
   86   delete impl_;
   87 }
   88 
   89 // Returns the approximate size of a variant.
   90 static size_t GetVariantSize(const Variant& v) {
   91   switch (v.type()) {
   92     case Variant::TYPE_VOID:
   93       // It's important to return 0 for TYPE_VOID because sometimes
   94       // non-existance values are treated as void.
   95       return 0;
   96     case Variant::TYPE_STRING:
   97       return VariantValue<std::string>()(v).size();
   98     case Variant::TYPE_JSON:
   99       return VariantValue<JSONString>()(v).value.size();
  100     case Variant::TYPE_UTF16STRING:
  101       return VariantValue<UTF16String>()(v).size() * 2;
  102     default:
  103       // Value of other types only counted approximately.
  104       return sizeof(Variant);
  105   }
  106 }
  107 
  108 Connection *MemoryOptions::ConnectOnOptionChanged(
  109     Slot1<void, const char *> *handler) {
  110   return impl_->onoptionchanged_signal_.Connect(handler);
  111 }
  112 
  113 size_t MemoryOptions::GetCount() {
  114   return impl_->values_.size();
  115 }
  116 
  117 void MemoryOptions::Add(const char *name, const Variant &value) {
  118   std::string name_str(name); // Avoid multiple std::string() construction.
  119   if (impl_->values_.find(name_str) == impl_->values_.end()) {
  120     size_t new_total_size = impl_->total_size_ + name_str.size() +
  121                             GetVariantSize(value);
  122     if (new_total_size > impl_->size_limit_) {
  123       LOG("Options exceeds size limit %zu.", impl_->size_limit_);
  124     } else {
  125       impl_->total_size_ = new_total_size;
  126       impl_->values_[name_str].SetValue(value);
  127       impl_->FireChangedEvent(name, value);
  128     }
  129   }
  130 }
  131 
  132 bool MemoryOptions::Exists(const char *name) {
  133   return impl_->values_.find(name) != impl_->values_.end();
  134 }
  135 
  136 Variant MemoryOptions::GetDefaultValue(const char *name) {
  137   Impl::OptionsMap::const_iterator it = impl_->defaults_.find(name);
  138   return it == impl_->defaults_.end() ? Variant() : it->second.GetValue();
  139 }
  140 
  141 void MemoryOptions::PutDefaultValue(const char *name, const Variant &value) {
  142   impl_->defaults_[name].SetValue(value);
  143 }
  144 
  145 Variant MemoryOptions::GetValue(const char *name) {
  146   Impl::OptionsMap::const_iterator it = impl_->values_.find(name);
  147   return it == impl_->values_.end() ?
  148          GetDefaultValue(name) : it->second.GetValue();
  149 }
  150 
  151 void MemoryOptions::PutValue(const char *name, const Variant &value) {
  152   std::string name_str(name); // Avoid multiple std::string construction.
  153   Impl::OptionsMap::iterator it = impl_->values_.find(name_str);
  154   if (it == impl_->values_.end()) {
  155     Add(name, value);
  156   } else {
  157     Variant last_value = it->second.GetValue();
  158     if (last_value != value) {
  159       ASSERT(impl_->total_size_ >= GetVariantSize(last_value));
  160       size_t new_total_size = impl_->total_size_ + GetVariantSize(value) -
  161                               GetVariantSize(last_value);
  162       if (new_total_size > impl_->size_limit_) {
  163         LOG("Options exceeds size limit %zu.", impl_->size_limit_);
  164       } else {
  165         impl_->total_size_ = new_total_size;
  166         it->second.SetValue(value);
  167         impl_->FireChangedEvent(name, value);
  168       }
  169     }
  170     // Putting a value automatically removes the encrypted state.
  171     impl_->encrypted_.erase(name_str);
  172   }
  173 }
  174 
  175 void MemoryOptions::Remove(const char *name) {
  176   std::string name_str(name); // Avoid multiple std::string construction.
  177   Impl::OptionsMap::iterator it = impl_->values_.find(name_str);
  178   if (it != impl_->values_.end()) {
  179     size_t last_value_size = GetVariantSize(it->second.GetValue());
  180     ASSERT(impl_->total_size_ >= name_str.size() + last_value_size);
  181     impl_->total_size_ -= name_str.size() + last_value_size;
  182     impl_->values_.erase(it);
  183     impl_->encrypted_.erase(name_str);
  184     impl_->FireChangedEvent(name, Variant());
  185   }
  186 }
  187 
  188 void MemoryOptions::RemoveAll() {
  189   while (!impl_->values_.empty()) {
  190     Impl::OptionsMap::iterator it = impl_->values_.begin();
  191     std::string name(it->first);
  192     impl_->values_.erase(it);
  193     impl_->encrypted_.erase(name);
  194     impl_->FireChangedEvent(name.c_str(), Variant());
  195   }
  196   impl_->total_size_ = 0;
  197 }
  198 
  199 void MemoryOptions::EncryptValue(const char *name) {
  200   impl_->encrypted_.insert(name);
  201 }
  202 
  203 bool MemoryOptions::IsEncrypted(const char *name) {
  204   return impl_->encrypted_.find(name) != impl_->encrypted_.end();
  205 }
  206 
  207 Variant MemoryOptions::GetInternalValue(const char *name) {
  208   Impl::OptionsMap::const_iterator it = impl_->internal_values_.find(name);
  209   return it == impl_->internal_values_.end() ?
  210          Variant() : it->second.GetValue();
  211 }
  212 
  213 void MemoryOptions::PutInternalValue(const char *name, const Variant &value) {
  214   // Internal values are not counted in total_size_.
  215   impl_->internal_values_[name].SetValue(value);
  216 }
  217 
  218 bool MemoryOptions::Flush() {
  219   return true;
  220 }
  221 
  222 void MemoryOptions::DeleteStorage() {
  223   impl_->values_.clear();
  224   impl_->internal_values_.clear();
  225   impl_->encrypted_.clear();
  226   impl_->total_size_ = 0;
  227 }
  228 
  229 bool MemoryOptions::EnumerateItems(
  230     Slot3<bool, const char *, const Variant &, bool> *callback) {
  231   ASSERT(callback);
  232   for (Impl::OptionsMap::const_iterator it = impl_->values_.begin();
  233        it != impl_->values_.end(); ++it) {
  234     const char *name = it->first.c_str();
  235     if (!(*callback)(name, it->second.GetValue(), IsEncrypted(name))) {
  236       delete callback;
  237       return false;
  238     }
  239   }
  240   delete callback;
  241   return true;
  242 }
  243 
  244 bool MemoryOptions::EnumerateInternalItems(
  245     Slot2<bool, const char *, const Variant &> *callback) {
  246   ASSERT(callback);
  247   for (Impl::OptionsMap::const_iterator it = impl_->internal_values_.begin();
  248        it != impl_->internal_values_.end(); ++it) {
  249     if (!(*callback)(it->first.c_str(), it->second.GetValue())) {
  250       delete callback;
  251       return false;
  252     }
  253   }
  254   delete callback;
  255   return true;
  256 }
  257 
  258 } // namespace ggadget