| // Copyright 2010-2015, Google Inc. |
| // All rights reserved. |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are |
| // met: |
| // |
| // * Redistributions of source code must retain the above copyright |
| // notice, this list of conditions and the following disclaimer. |
| // * Redistributions in binary form must reproduce the above |
| // copyright notice, this list of conditions and the following disclaimer |
| // in the documentation and/or other materials provided with the |
| // distribution. |
| // * Neither the name of Google Inc. nor the names of its |
| // contributors may be used to endorse or promote products derived from |
| // this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| #include "session/generic_storage_manager.h" |
| |
| #include <cstring> |
| #include <string> |
| #include <vector> |
| |
| #include "base/config_file_stream.h" |
| #include "base/logging.h" |
| #include "base/mutex.h" |
| #include "base/port.h" |
| #include "base/scoped_ptr.h" |
| #include "base/singleton.h" |
| #include "storage/lru_storage.h" |
| |
| namespace { |
| |
| mozc::Mutex g_storage_ensure_mutex; |
| |
| mozc::GenericStorageManagerInterface *g_storage_manager = NULL; |
| |
| const char kSymbolStorageFileName[] = |
| "user://symbol_history.db"; |
| // 32 characters * 3 bytes(typical byte size per character) |
| const size_t kSymbolValueSize = 32 * 3; |
| const size_t kSymbolSize = 100; |
| const uint32 kSymbolSeed = 336843897; |
| |
| const char kEmoticonStorageFileName[] = |
| "user://emoticon_history.db"; |
| // 64 characters * 3 bytes(typical byte size per character) |
| const size_t kEmoticonValueSize = 64 * 3; |
| const size_t kEmoticonSize = 100; |
| const uint32 kEmoticonSeed = 236843897; |
| |
| const char kEmojiStorageFileName[] = |
| "user://emoji_history.db"; |
| // 32 characters * 3 bytes(typical byte size per character) |
| const size_t kEmojiValueSize = 32 * 3; |
| const size_t kEmojiSize = 100; |
| const uint32 kEmojiSeed = 136843897; |
| |
| } // namespace |
| |
| namespace mozc { |
| |
| using mozc::storage::LRUStorage; |
| |
| class GenericStorageManagerImpl |
| : public GenericStorageManagerInterface { |
| public: |
| GenericStorageManagerImpl() : |
| symbol_history_storage_(kSymbolStorageFileName, |
| kSymbolValueSize, |
| kSymbolSize, |
| kSymbolSeed), |
| emoticon_history_storage_(kEmoticonStorageFileName, |
| kEmoticonValueSize, |
| kEmoticonSize, |
| kEmoticonSeed), |
| emoji_history_storage_(kEmojiStorageFileName, |
| kEmojiValueSize, |
| kEmojiSize, |
| kEmojiSeed) {} |
| virtual ~GenericStorageManagerImpl() {} |
| virtual GenericStorageInterface *GetStorage( |
| commands::GenericStorageEntry::StorageType storage_type); |
| private: |
| GenericLruStorage symbol_history_storage_; |
| GenericLruStorage emoticon_history_storage_; |
| GenericLruStorage emoji_history_storage_; |
| }; |
| |
| GenericStorageInterface *GenericStorageManagerImpl::GetStorage( |
| commands::GenericStorageEntry::StorageType storage_type) { |
| switch (storage_type) { |
| case commands::GenericStorageEntry::SYMBOL_HISTORY: |
| return &symbol_history_storage_; |
| case commands::GenericStorageEntry::EMOTICON_HISTORY: |
| return &emoticon_history_storage_; |
| case commands::GenericStorageEntry::EMOJI_HISTORY: |
| return &emoji_history_storage_; |
| default: |
| LOG(WARNING) << "Invalid storage type"; |
| } |
| return NULL; |
| } |
| |
| // static |
| void GenericStorageManagerFactory::SetGenericStorageManager( |
| GenericStorageManagerInterface *manager) { |
| g_storage_manager = manager; |
| } |
| |
| // static |
| GenericStorageInterface *GenericStorageManagerFactory::GetStorage( |
| commands::GenericStorageEntry::StorageType storage_type) { |
| GenericStorageManagerInterface *manager = g_storage_manager ? |
| g_storage_manager : Singleton<GenericStorageManagerImpl>::get(); |
| return manager->GetStorage(storage_type); |
| } |
| |
| |
| GenericLruStorage::GenericLruStorage( |
| const char *file_name, size_t value_size, size_t size, uint32 seed) |
| : file_name_(file_name), value_size_(value_size), |
| size_(size), seed_(seed), value_buffer_(new char[value_size + 1]) { |
| } |
| |
| GenericLruStorage::~GenericLruStorage() { |
| } |
| |
| bool GenericLruStorage::EnsureStorage() { |
| scoped_lock lock(&g_storage_ensure_mutex); |
| if (lru_storage_.get()) { |
| // We already have prepared storage. |
| return true; |
| } |
| scoped_ptr<LRUStorage> new_storage; |
| new_storage.reset(new LRUStorage()); |
| const string &filename = |
| ConfigFileStream::GetFileName(file_name_); |
| if (!new_storage->OpenOrCreate(filename.data(), value_size_, size_, seed_)) { |
| return false; |
| } |
| lru_storage_.swap(new_storage); |
| return true; |
| } |
| |
| bool GenericLruStorage::Insert(const string &key, const char *value) { |
| if (!EnsureStorage()) { |
| return false; |
| } |
| const size_t value_size = strnlen(value, value_size_ + 1); |
| if (value_size > value_size_) { |
| LOG(DFATAL) << "Too long value: [" << value << "] size: " << value_size; |
| return false; |
| } |
| // LRUStorage only accepts fixed-length value, so we should allocate enough |
| // memory to avoid illegal access. |
| memcpy(value_buffer_.get(), value, value_size + 1); |
| return lru_storage_->Insert(key, value_buffer_.get()); |
| } |
| |
| const char *GenericLruStorage::Lookup(const string &key) { |
| if (!EnsureStorage()) { |
| return NULL; |
| } |
| return lru_storage_->Lookup(key); |
| } |
| |
| bool GenericLruStorage::GetAllValues(vector<string> *values) { |
| if (!EnsureStorage()) { |
| return false; |
| } |
| return lru_storage_->GetAllValues(values); |
| } |
| |
| bool GenericLruStorage::Clear() { |
| if (!EnsureStorage()) { |
| return false; |
| } |
| return lru_storage_->Clear(); |
| } |
| |
| } // namespace mozc |