| // 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 "dictionary/dictionary_mock.h" |
| |
| #include <climits> |
| #include <map> |
| #include <string> |
| |
| #include "base/logging.h" |
| #include "base/scoped_ptr.h" |
| #include "base/stl_util.h" |
| #include "base/string_piece.h" |
| #include "base/util.h" |
| #include "dictionary/dictionary_token.h" |
| |
| namespace mozc { |
| namespace { |
| |
| const int kDummyPosId = 1; |
| |
| bool HasKeyInternal(const map<string, vector<Token *>> &dic, StringPiece key) { |
| typedef vector<Token *> TokenPtrVector; |
| for (map<string, vector<Token *> >::const_iterator map_it = dic.begin(); |
| map_it != dic.end(); ++map_it) { |
| const TokenPtrVector &v = map_it->second; |
| for (TokenPtrVector::const_iterator it = v.begin(); it != v.end(); ++it) { |
| if ((*it)->key == key) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| bool HasValueInternal(const map<string, vector<Token *>> &dic, |
| StringPiece value) { |
| typedef vector<Token *> TokenPtrVector; |
| for (map<string, vector<Token *> >::const_iterator map_it = dic.begin(); |
| map_it != dic.end(); ++map_it) { |
| const TokenPtrVector &v = map_it->second; |
| for (TokenPtrVector::const_iterator it = v.begin(); it != v.end(); ++it) { |
| if ((*it)->value == value) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| Token *CreateToken(const string &str, const string &key, const string &value, |
| Token::AttributesBitfield attributes) { |
| scoped_ptr<Token> token(new Token()); |
| token->key = key; |
| token->value = value; |
| // TODO(noriyukit): Currently, we cannot set cost and POS IDs. |
| token->cost = 0; |
| token->lid = token->rid = kDummyPosId; |
| token->attributes = attributes; |
| return token.release(); |
| } |
| |
| void DeletePtrs(map<string, vector<Token *> > *m) { |
| for (map<string, vector<Token *> >::iterator iter = m->begin(); |
| iter != m->end(); ++iter) { |
| STLDeleteElements(&iter->second); |
| } |
| } |
| |
| } // namespace |
| |
| DictionaryMock::DictionaryMock() { |
| LOG(INFO) << "DictionaryMock is created"; |
| } |
| |
| DictionaryMock::~DictionaryMock() { |
| DeletePtrs(&prefix_dictionary_); |
| DeletePtrs(&exact_dictionary_); |
| DeletePtrs(&reverse_dictionary_); |
| DeletePtrs(&predictive_dictionary_); |
| } |
| |
| bool DictionaryMock::HasKey(StringPiece key) const { |
| return HasKeyInternal(predictive_dictionary_, key) || |
| HasKeyInternal(prefix_dictionary_, key) || |
| HasKeyInternal(reverse_dictionary_, key) || |
| HasKeyInternal(exact_dictionary_, key); |
| } |
| |
| bool DictionaryMock::HasValue(StringPiece value) const { |
| return HasValueInternal(predictive_dictionary_, value) || |
| HasValueInternal(prefix_dictionary_, value) || |
| HasValueInternal(reverse_dictionary_, value) || |
| HasValueInternal(exact_dictionary_, value); |
| } |
| |
| void DictionaryMock::LookupPredictive( |
| StringPiece key, |
| bool, // use_kana_modifier_insensitive_lookup |
| Callback *callback) const { |
| map<string, vector<Token *> >::const_iterator vector_iter = |
| predictive_dictionary_.find(key.as_string()); |
| if (vector_iter == predictive_dictionary_.end()) { |
| return; |
| } |
| if (callback->OnKey(key) != Callback::TRAVERSE_CONTINUE || |
| callback->OnActualKey(key, key, false) != Callback::TRAVERSE_CONTINUE) { |
| return; |
| } |
| for (vector<Token *>::const_iterator iter = vector_iter->second.begin(); |
| iter != vector_iter->second.end(); ++iter) { |
| if (callback->OnToken(key, key, **iter) != Callback::TRAVERSE_CONTINUE) { |
| return; |
| } |
| } |
| } |
| |
| void DictionaryMock::LookupPrefix( |
| StringPiece key, |
| bool, // use_kana_modifier_insensitive_lookup |
| Callback *callback) const { |
| CHECK(!key.empty()); |
| |
| string prefix; |
| for (size_t len = 1; len <= key.size(); ++len) { |
| key.substr(0, len).CopyToString(&prefix); |
| map<string, vector<Token *> >::const_iterator iter = |
| prefix_dictionary_.find(prefix); |
| if (iter == prefix_dictionary_.end()) { |
| continue; |
| } |
| switch (callback->OnKey(prefix)) { |
| case Callback::TRAVERSE_DONE: |
| case Callback::TRAVERSE_CULL: |
| return; |
| case Callback::TRAVERSE_NEXT_KEY: |
| continue; |
| default: |
| break; |
| } |
| switch (callback->OnActualKey(prefix, prefix, false)) { |
| case Callback::TRAVERSE_DONE: |
| case Callback::TRAVERSE_CULL: |
| return; |
| case Callback::TRAVERSE_NEXT_KEY: |
| continue; |
| default: |
| break; |
| } |
| for (vector<Token *>::const_iterator token_iter = iter->second.begin(); |
| token_iter != iter->second.end(); ++token_iter) { |
| Callback::ResultType ret = |
| callback->OnToken(prefix, prefix, **token_iter); |
| if (ret == Callback::TRAVERSE_DONE || ret == Callback::TRAVERSE_CULL) { |
| return; |
| } |
| if (ret == Callback::TRAVERSE_NEXT_KEY) { |
| break; |
| } |
| } |
| } |
| } |
| |
| void DictionaryMock::LookupExact(StringPiece key, Callback *callback) const { |
| map<string, vector<Token *> >::const_iterator iter = |
| exact_dictionary_.find(key.as_string()); |
| if (iter == exact_dictionary_.end()) { |
| return; |
| } |
| if (callback->OnKey(key) != Callback::TRAVERSE_CONTINUE) { |
| return; |
| } |
| for (vector<Token *>::const_iterator token_iter = iter->second.begin(); |
| token_iter != iter->second.end(); ++token_iter) { |
| if (callback->OnToken(key, key, **token_iter) != |
| Callback::TRAVERSE_CONTINUE) { |
| return; |
| } |
| } |
| } |
| |
| void DictionaryMock::LookupReverse(StringPiece str, |
| NodeAllocatorInterface *allocator, |
| Callback *callback) const { |
| CHECK(!str.empty()); |
| |
| for (int i = 1; i <= str.size(); ++i) { |
| StringPiece prefix = str.substr(0, i); |
| |
| map<string, vector<Token *> >::const_iterator iter = |
| reverse_dictionary_.find(prefix.as_string()); |
| if (iter == reverse_dictionary_.end()) { |
| continue; |
| } |
| |
| if (callback->OnKey(prefix) != Callback::TRAVERSE_CONTINUE) { |
| return; |
| } |
| for (vector<Token *>::const_iterator token_iter = iter->second.begin(); |
| token_iter != iter->second.end(); ++token_iter) { |
| if (callback->OnToken(prefix, prefix, **token_iter) != |
| Callback::TRAVERSE_CONTINUE) { |
| return; |
| } |
| } |
| } |
| } |
| |
| void DictionaryMock::AddLookupPredictive(const string &str, |
| const string &key, const string &value, |
| Token::AttributesBitfield attributes) { |
| predictive_dictionary_[str].push_back( |
| CreateToken(str, key, value, attributes)); |
| } |
| |
| void DictionaryMock::AddLookupPrefix(const string &str, |
| const string &key, const string &value, |
| Token::AttributesBitfield attributes) { |
| prefix_dictionary_[str].push_back( |
| CreateToken(str, key, value, attributes)); |
| } |
| |
| void DictionaryMock::AddLookupReverse(const string &str, |
| const string &key, const string &value, |
| Token::AttributesBitfield attributes) { |
| reverse_dictionary_[str].push_back( |
| CreateToken(str, key, value, attributes)); |
| } |
| |
| void DictionaryMock::AddLookupExact(const string &str, |
| const string &key, const string &value, |
| Token::AttributesBitfield attributes) { |
| exact_dictionary_[str].push_back( |
| CreateToken(str, key, value, attributes)); |
| } |
| |
| } // namespace mozc |