1 /*
2  * Copyright (C) 2013 The Android Open Source Project
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 #ifndef LATINIME_VER4_SHORTCUT_LIST_POLICY_H
18 #define LATINIME_VER4_SHORTCUT_LIST_POLICY_H
19 
20 #include "defines.h"
21 #include "dictionary/interface/dictionary_shortcuts_structure_policy.h"
22 #include "dictionary/structure/pt_common/shortcut/shortcut_list_reading_utils.h"
23 #include "dictionary/structure/v4/content/shortcut_dict_content.h"
24 #include "dictionary/structure/v4/content/terminal_position_lookup_table.h"
25 
26 namespace latinime {
27 
28 class Ver4ShortcutListPolicy : public DictionaryShortcutsStructurePolicy {
29  public:
Ver4ShortcutListPolicy(ShortcutDictContent * const shortcutDictContent,const TerminalPositionLookupTable * const terminalPositionLookupTable)30     Ver4ShortcutListPolicy(ShortcutDictContent *const shortcutDictContent,
31             const TerminalPositionLookupTable *const terminalPositionLookupTable)
32             : mShortcutDictContent(shortcutDictContent) {}
33 
~Ver4ShortcutListPolicy()34     ~Ver4ShortcutListPolicy() {}
35 
getStartPos(const int pos)36     int getStartPos(const int pos) const {
37         // The first shortcut entry is located at the head position of the shortcut list.
38         return pos;
39     }
40 
getNextShortcut(const int maxCodePointCount,int * const outCodePoint,int * const outCodePointCount,bool * const outIsWhitelist,bool * const outHasNext,int * const pos)41     void getNextShortcut(const int maxCodePointCount, int *const outCodePoint,
42             int *const outCodePointCount, bool *const outIsWhitelist, bool *const outHasNext,
43             int *const pos) const {
44         int probability = 0;
45         mShortcutDictContent->getShortcutEntryAndAdvancePosition(maxCodePointCount,
46                 outCodePoint, outCodePointCount, &probability, outHasNext, pos);
47         if (outIsWhitelist) {
48             *outIsWhitelist = ShortcutListReadingUtils::isWhitelist(probability);
49         }
50     }
51 
skipAllShortcuts(int * const pos)52     void skipAllShortcuts(int *const pos) const {
53         // Do nothing because we don't need to skip shortcut lists in ver4 dictionaries.
54     }
55 
addNewShortcut(const int terminalId,const int * const codePoints,const int codePointCount,const int probability)56     bool addNewShortcut(const int terminalId, const int *const codePoints, const int codePointCount,
57             const int probability) {
58         const int shortcutListPos = mShortcutDictContent->getShortcutListHeadPos(terminalId);
59         if (shortcutListPos == NOT_A_DICT_POS) {
60             // Create shortcut list.
61             if (!mShortcutDictContent->createNewShortcutList(terminalId)) {
62                 AKLOGE("Cannot create new shortcut list. terminal id: %d", terminalId);
63                 return false;
64             }
65             const int writingPos =  mShortcutDictContent->getShortcutListHeadPos(terminalId);
66             return mShortcutDictContent->writeShortcutEntry(codePoints, codePointCount, probability,
67                     false /* hasNext */, writingPos);
68         }
69         const int entryPos = mShortcutDictContent->findShortcutEntryAndGetPos(shortcutListPos,
70                 codePoints, codePointCount);
71         if (entryPos == NOT_A_DICT_POS) {
72             // Add new entry to the shortcut list.
73             // Create new shortcut list.
74             if (!mShortcutDictContent->createNewShortcutList(terminalId)) {
75                 AKLOGE("Cannot create new shortcut list. terminal id: %d", terminalId);
76                 return false;
77             }
78             int writingPos =  mShortcutDictContent->getShortcutListHeadPos(terminalId);
79             if (!mShortcutDictContent->writeShortcutEntryAndAdvancePosition(codePoints,
80                     codePointCount, probability, true /* hasNext */, &writingPos)) {
81                 AKLOGE("Cannot write shortcut entry. terminal id: %d, pos: %d", terminalId,
82                         writingPos);
83                 return false;
84             }
85             return mShortcutDictContent->copyShortcutList(shortcutListPos, writingPos);
86         }
87         // Overwrite existing entry.
88         bool hasNext = false;
89         mShortcutDictContent->getShortcutEntry(MAX_WORD_LENGTH, 0 /* outCodePoint */,
90                 0 /* outCodePointCount */ , 0 /* probability */, &hasNext, entryPos);
91         if (!mShortcutDictContent->writeShortcutEntry(codePoints,
92                 codePointCount, probability, hasNext, entryPos)) {
93             AKLOGE("Cannot overwrite shortcut entry. terminal id: %d, pos: %d", terminalId,
94                     entryPos);
95             return false;
96         }
97         return true;
98     }
99 
100  private:
101     DISALLOW_IMPLICIT_CONSTRUCTORS(Ver4ShortcutListPolicy);
102 
103     ShortcutDictContent *const mShortcutDictContent;
104 };
105 } // namespace latinime
106 #endif // LATINIME_VER4_SHORTCUT_LIST_POLICY_H
107