138c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka/*
238c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka * Copyright (C) 2012 The Android Open Source Project
338c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka *
438c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka * Licensed under the Apache License, Version 2.0 (the "License");
538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka * you may not use this file except in compliance with the License.
638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka * You may obtain a copy of the License at
738c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka *
838c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka *      http://www.apache.org/licenses/LICENSE-2.0
938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka *
1038c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka * Unless required by applicable law or agreed to in writing, software
1138c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka * distributed under the License is distributed on an "AS IS" BASIS,
1238c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1338c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka * See the License for the specific language governing permissions and
1438c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka * limitations under the License.
1538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka */
1638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
1738c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka#ifndef LATINIME_DIC_NODE_STATE_OUTPUT_H
1838c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka#define LATINIME_DIC_NODE_STATE_OUTPUT_H
1938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
20865e6cf49764f3a411ee32861d927b15653ee398Keisuke Kuroyanagi#include <algorithm>
21cafab169cdb21244c82b99c09983c98066113d87Ken Wakasa#include <cstdint>
223e0777e726ce40b4c4b65174a21db41c19f04602Keisuke Kuroyanagi#include <cstring> // for memmove()
2338c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
2438c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka#include "defines.h"
2538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
2638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataokanamespace latinime {
2738c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
28eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi// Class to have information to be output. This can contain previous words when the suggestion
29eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi// is a multi-word suggestion.
3038c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataokaclass DicNodeStateOutput {
3138c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka public:
32eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    DicNodeStateOutput()
33eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi            : mOutputtedCodePointCount(0), mCurrentWordStart(0), mPrevWordCount(0),
34eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi              mPrevWordsLength(0), mPrevWordStart(0), mSecondWordFirstInputIndex(NOT_AN_INDEX) {}
3538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
36632c9aca5bbae49be278cf3e88d12b364fbd6fc8Keisuke Kuroyanagi    ~DicNodeStateOutput() {}
3738c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
38eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    // Init for root
3938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    void init() {
406379a4de29fee7019b32b93bc424eda720e02dcfKeisuke Kuroynagi        mOutputtedCodePointCount = 0;
41eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        mCurrentWordStart = 0;
42eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        mOutputCodePoints[0] = 0;
43eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        mPrevWordCount = 0;
44eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        mPrevWordsLength = 0;
45eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        mPrevWordStart = 0;
46eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        mSecondWordFirstInputIndex = NOT_AN_INDEX;
4738c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    }
4838c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
49eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    // Init for next word.
5038c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    void init(const DicNodeStateOutput *const stateOutput) {
51eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        mOutputtedCodePointCount = stateOutput->mOutputtedCodePointCount + 1;
52eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        memmove(mOutputCodePoints, stateOutput->mOutputCodePoints,
53eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi                stateOutput->mOutputtedCodePointCount * sizeof(mOutputCodePoints[0]));
54eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        mOutputCodePoints[stateOutput->mOutputtedCodePointCount] = KEYCODE_SPACE;
55eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        mCurrentWordStart = stateOutput->mOutputtedCodePointCount + 1;
56eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        mPrevWordCount = std::min(static_cast<int16_t>(stateOutput->mPrevWordCount + 1),
57eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi                static_cast<int16_t>(MAX_RESULTS));
58eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        mPrevWordsLength = stateOutput->mOutputtedCodePointCount + 1;
59eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        mPrevWordStart = stateOutput->mCurrentWordStart;
60eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        mSecondWordFirstInputIndex = stateOutput->mSecondWordFirstInputIndex;
61eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    }
62eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi
63eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    void initByCopy(const DicNodeStateOutput *const stateOutput) {
64eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        memmove(mOutputCodePoints, stateOutput->mOutputCodePoints,
65eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi                stateOutput->mOutputtedCodePointCount * sizeof(mOutputCodePoints[0]));
666379a4de29fee7019b32b93bc424eda720e02dcfKeisuke Kuroynagi        mOutputtedCodePointCount = stateOutput->mOutputtedCodePointCount;
676379a4de29fee7019b32b93bc424eda720e02dcfKeisuke Kuroynagi        if (mOutputtedCodePointCount < MAX_WORD_LENGTH) {
68eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi            mOutputCodePoints[mOutputtedCodePointCount] = 0;
6938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        }
70eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        mCurrentWordStart = stateOutput->mCurrentWordStart;
71eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        mPrevWordCount = stateOutput->mPrevWordCount;
72eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        mPrevWordsLength = stateOutput->mPrevWordsLength;
73eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        mPrevWordStart = stateOutput->mPrevWordStart;
74eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        mSecondWordFirstInputIndex = stateOutput->mSecondWordFirstInputIndex;
7538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    }
7638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
776379a4de29fee7019b32b93bc424eda720e02dcfKeisuke Kuroynagi    void addMergedNodeCodePoints(const uint16_t mergedNodeCodePointCount,
786379a4de29fee7019b32b93bc424eda720e02dcfKeisuke Kuroynagi            const int *const mergedNodeCodePoints) {
796379a4de29fee7019b32b93bc424eda720e02dcfKeisuke Kuroynagi        if (mergedNodeCodePoints) {
80865e6cf49764f3a411ee32861d927b15653ee398Keisuke Kuroyanagi            const int additionalCodePointCount = std::min(
81865e6cf49764f3a411ee32861d927b15653ee398Keisuke Kuroyanagi                    static_cast<int>(mergedNodeCodePointCount),
824a65258bc7c284ecf61ba6e4399a7012e71d7952Keisuke Kuroyanagi                    MAX_WORD_LENGTH - mOutputtedCodePointCount);
83eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi            memmove(&mOutputCodePoints[mOutputtedCodePointCount], mergedNodeCodePoints,
84eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi                    additionalCodePointCount * sizeof(mOutputCodePoints[0]));
856379a4de29fee7019b32b93bc424eda720e02dcfKeisuke Kuroynagi            mOutputtedCodePointCount = static_cast<uint16_t>(
86eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi                    mOutputtedCodePointCount + additionalCodePointCount);
876379a4de29fee7019b32b93bc424eda720e02dcfKeisuke Kuroynagi            if (mOutputtedCodePointCount < MAX_WORD_LENGTH) {
88eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi                mOutputCodePoints[mOutputtedCodePointCount] = 0;
8938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka            }
9038c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        }
9138c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    }
9238c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
93eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    int getCurrentWordCodePointAt(const int index) const {
94eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        return mOutputCodePoints[mCurrentWordStart + index];
9538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    }
9638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
970a5efa31de50a204423efeab8b9e54bf81672300Keisuke Kuroyanagi    const int *getCodePointBuf() const {
98eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        return mOutputCodePoints;
99eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    }
100eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi
101eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    void setSecondWordFirstInputIndex(const int inputIndex) {
102eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        mSecondWordFirstInputIndex = inputIndex;
103eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    }
104eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi
105eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    int getSecondWordFirstInputIndex() const {
106eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        return mSecondWordFirstInputIndex;
107eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    }
108eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi
109eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    // TODO: remove
110eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    int16_t getPrevWordsLength() const {
111eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        return mPrevWordsLength;
112eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    }
113eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi
114eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    int16_t getPrevWordCount() const {
115eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        return mPrevWordCount;
116eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    }
117eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi
118eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    int16_t getPrevWordStart() const {
119eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        return mPrevWordStart;
120eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    }
121eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi
122eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    int getOutputCodePointAt(const int id) const {
123eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi        return mOutputCodePoints[id];
1240a5efa31de50a204423efeab8b9e54bf81672300Keisuke Kuroyanagi    }
12538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
12638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka private:
127632c9aca5bbae49be278cf3e88d12b364fbd6fc8Keisuke Kuroyanagi    DISALLOW_COPY_AND_ASSIGN(DicNodeStateOutput);
128632c9aca5bbae49be278cf3e88d12b364fbd6fc8Keisuke Kuroyanagi
129eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    // When the DicNode represents "this is a pen":
130eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    // mOutputtedCodePointCount is 13, which is total code point count of "this is a pen" including
131eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    // spaces.
132eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    // mCurrentWordStart indicates the head of "pen", thus it is 10.
133eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    // This contains 3 previous words, "this", "is" and "a"; thus, mPrevWordCount is 3.
134eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    // mPrevWordsLength is length of "this is a ", which is 10.
135eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    // mPrevWordStart is the start index of "a"; thus, it is 8.
136eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    // mSecondWordFirstInputIndex is the first input index of "is".
137eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi
1386379a4de29fee7019b32b93bc424eda720e02dcfKeisuke Kuroynagi    uint16_t mOutputtedCodePointCount;
139eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    int mOutputCodePoints[MAX_WORD_LENGTH];
140eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    int16_t mCurrentWordStart;
141eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    // Previous word count in mOutputCodePoints.
142eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    int16_t mPrevWordCount;
143eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    // Total length of previous words in mOutputCodePoints. This is being used by the algorithm
144eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    // that may want to look at the previous word information.
145eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    int16_t mPrevWordsLength;
146eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    // Start index of the previous word in mOutputCodePoints. This is being used for auto commit.
147eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    int16_t mPrevWordStart;
148eddbb7ac88c3174ffdc38a9dd799029302f55d03Keisuke Kuroyanagi    int mSecondWordFirstInputIndex;
14938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka};
15038c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka} // namespace latinime
15138c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka#endif // LATINIME_DIC_NODE_STATE_OUTPUT_H
152