1 /* 2 * Copyright (C) 2012 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_DIC_NODE_STATE_OUTPUT_H 18 #define LATINIME_DIC_NODE_STATE_OUTPUT_H 19 20 #include <algorithm> 21 #include <cstdint> 22 #include <cstring> // for memmove() 23 24 #include "defines.h" 25 26 namespace latinime { 27 28 // Class to have information to be output. This can contain previous words when the suggestion 29 // is a multi-word suggestion. 30 class DicNodeStateOutput { 31 public: DicNodeStateOutput()32 DicNodeStateOutput() 33 : mOutputtedCodePointCount(0), mCurrentWordStart(0), mPrevWordCount(0), 34 mPrevWordsLength(0), mPrevWordStart(0), mSecondWordFirstInputIndex(NOT_AN_INDEX) {} 35 ~DicNodeStateOutput()36 ~DicNodeStateOutput() {} 37 38 // Init for root init()39 void init() { 40 mOutputtedCodePointCount = 0; 41 mCurrentWordStart = 0; 42 mOutputCodePoints[0] = 0; 43 mPrevWordCount = 0; 44 mPrevWordsLength = 0; 45 mPrevWordStart = 0; 46 mSecondWordFirstInputIndex = NOT_AN_INDEX; 47 } 48 49 // Init for next word. init(const DicNodeStateOutput * const stateOutput)50 void init(const DicNodeStateOutput *const stateOutput) { 51 mOutputtedCodePointCount = stateOutput->mOutputtedCodePointCount + 1; 52 memmove(mOutputCodePoints, stateOutput->mOutputCodePoints, 53 stateOutput->mOutputtedCodePointCount * sizeof(mOutputCodePoints[0])); 54 mOutputCodePoints[stateOutput->mOutputtedCodePointCount] = KEYCODE_SPACE; 55 mCurrentWordStart = stateOutput->mOutputtedCodePointCount + 1; 56 mPrevWordCount = std::min(static_cast<int16_t>(stateOutput->mPrevWordCount + 1), 57 static_cast<int16_t>(MAX_RESULTS)); 58 mPrevWordsLength = stateOutput->mOutputtedCodePointCount + 1; 59 mPrevWordStart = stateOutput->mCurrentWordStart; 60 mSecondWordFirstInputIndex = stateOutput->mSecondWordFirstInputIndex; 61 } 62 initByCopy(const DicNodeStateOutput * const stateOutput)63 void initByCopy(const DicNodeStateOutput *const stateOutput) { 64 memmove(mOutputCodePoints, stateOutput->mOutputCodePoints, 65 stateOutput->mOutputtedCodePointCount * sizeof(mOutputCodePoints[0])); 66 mOutputtedCodePointCount = stateOutput->mOutputtedCodePointCount; 67 if (mOutputtedCodePointCount < MAX_WORD_LENGTH) { 68 mOutputCodePoints[mOutputtedCodePointCount] = 0; 69 } 70 mCurrentWordStart = stateOutput->mCurrentWordStart; 71 mPrevWordCount = stateOutput->mPrevWordCount; 72 mPrevWordsLength = stateOutput->mPrevWordsLength; 73 mPrevWordStart = stateOutput->mPrevWordStart; 74 mSecondWordFirstInputIndex = stateOutput->mSecondWordFirstInputIndex; 75 } 76 addMergedNodeCodePoints(const uint16_t mergedNodeCodePointCount,const int * const mergedNodeCodePoints)77 void addMergedNodeCodePoints(const uint16_t mergedNodeCodePointCount, 78 const int *const mergedNodeCodePoints) { 79 if (mergedNodeCodePoints) { 80 const int additionalCodePointCount = std::min( 81 static_cast<int>(mergedNodeCodePointCount), 82 MAX_WORD_LENGTH - mOutputtedCodePointCount); 83 memmove(&mOutputCodePoints[mOutputtedCodePointCount], mergedNodeCodePoints, 84 additionalCodePointCount * sizeof(mOutputCodePoints[0])); 85 mOutputtedCodePointCount = static_cast<uint16_t>( 86 mOutputtedCodePointCount + additionalCodePointCount); 87 if (mOutputtedCodePointCount < MAX_WORD_LENGTH) { 88 mOutputCodePoints[mOutputtedCodePointCount] = 0; 89 } 90 } 91 } 92 getCurrentWordCodePointAt(const int index)93 int getCurrentWordCodePointAt(const int index) const { 94 return mOutputCodePoints[mCurrentWordStart + index]; 95 } 96 getCodePointBuf()97 const int *getCodePointBuf() const { 98 return mOutputCodePoints; 99 } 100 setSecondWordFirstInputIndex(const int inputIndex)101 void setSecondWordFirstInputIndex(const int inputIndex) { 102 mSecondWordFirstInputIndex = inputIndex; 103 } 104 getSecondWordFirstInputIndex()105 int getSecondWordFirstInputIndex() const { 106 return mSecondWordFirstInputIndex; 107 } 108 109 // TODO: remove getPrevWordsLength()110 int16_t getPrevWordsLength() const { 111 return mPrevWordsLength; 112 } 113 getPrevWordCount()114 int16_t getPrevWordCount() const { 115 return mPrevWordCount; 116 } 117 getPrevWordStart()118 int16_t getPrevWordStart() const { 119 return mPrevWordStart; 120 } 121 getOutputCodePointAt(const int id)122 int getOutputCodePointAt(const int id) const { 123 return mOutputCodePoints[id]; 124 } 125 126 private: 127 DISALLOW_COPY_AND_ASSIGN(DicNodeStateOutput); 128 129 // When the DicNode represents "this is a pen": 130 // mOutputtedCodePointCount is 13, which is total code point count of "this is a pen" including 131 // spaces. 132 // mCurrentWordStart indicates the head of "pen", thus it is 10. 133 // This contains 3 previous words, "this", "is" and "a"; thus, mPrevWordCount is 3. 134 // mPrevWordsLength is length of "this is a ", which is 10. 135 // mPrevWordStart is the start index of "a"; thus, it is 8. 136 // mSecondWordFirstInputIndex is the first input index of "is". 137 138 uint16_t mOutputtedCodePointCount; 139 int mOutputCodePoints[MAX_WORD_LENGTH]; 140 int16_t mCurrentWordStart; 141 // Previous word count in mOutputCodePoints. 142 int16_t mPrevWordCount; 143 // Total length of previous words in mOutputCodePoints. This is being used by the algorithm 144 // that may want to look at the previous word information. 145 int16_t mPrevWordsLength; 146 // Start index of the previous word in mOutputCodePoints. This is being used for auto commit. 147 int16_t mPrevWordStart; 148 int mSecondWordFirstInputIndex; 149 }; 150 } // namespace latinime 151 #endif // LATINIME_DIC_NODE_STATE_OUTPUT_H 152