Home | History | Annotate | Download | only in internal
      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:
     32     DicNodeStateOutput()
     33             : mOutputtedCodePointCount(0), mCurrentWordStart(0), mPrevWordCount(0),
     34               mPrevWordsLength(0), mPrevWordStart(0), mSecondWordFirstInputIndex(NOT_AN_INDEX) {}
     35 
     36     ~DicNodeStateOutput() {}
     37 
     38     // Init for root
     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.
     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 
     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 
     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 
     93     int getCurrentWordCodePointAt(const int index) const {
     94         return mOutputCodePoints[mCurrentWordStart + index];
     95     }
     96 
     97     const int *getCodePointBuf() const {
     98         return mOutputCodePoints;
     99     }
    100 
    101     void setSecondWordFirstInputIndex(const int inputIndex) {
    102         mSecondWordFirstInputIndex = inputIndex;
    103     }
    104 
    105     int getSecondWordFirstInputIndex() const {
    106         return mSecondWordFirstInputIndex;
    107     }
    108 
    109     // TODO: remove
    110     int16_t getPrevWordsLength() const {
    111         return mPrevWordsLength;
    112     }
    113 
    114     int16_t getPrevWordCount() const {
    115         return mPrevWordCount;
    116     }
    117 
    118     int16_t getPrevWordStart() const {
    119         return mPrevWordStart;
    120     }
    121 
    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