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_PREVWORD_H
1838c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka#define LATINIME_DIC_NODE_STATE_PREVWORD_H
1938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
2038c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka#include <cstring> // for memset()
2138c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka#include <stdint.h>
2238c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
2338c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka#include "defines.h"
2438c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka#include "dic_node_utils.h"
2538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
2638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataokanamespace latinime {
2738c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
2838c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataokaclass DicNodeStatePrevWord {
2938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka public:
3038c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    AK_FORCE_INLINE DicNodeStatePrevWord()
3138c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka            : mPrevWordCount(0), mPrevWordLength(0), mPrevWordStart(0), mPrevWordProbability(0),
3238c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka              mPrevWordNodePos(0) {
3338c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        memset(mPrevWord, 0, sizeof(mPrevWord));
3438c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        memset(mPrevSpacePositions, 0, sizeof(mPrevSpacePositions));
3538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    }
3638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
3738c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    virtual ~DicNodeStatePrevWord() {}
3838c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
3938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    void init() {
4038c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordLength = 0;
4138c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordCount = 0;
4238c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordStart = 0;
4338c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordProbability = -1;
4438c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordNodePos = NOT_VALID_WORD;
4538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        memset(mPrevSpacePositions, 0, sizeof(mPrevSpacePositions));
4638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    }
4738c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
4838c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    void init(const int prevWordNodePos) {
4938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordLength = 0;
5038c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordCount = 0;
5138c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordStart = 0;
5238c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordProbability = -1;
5338c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordNodePos = prevWordNodePos;
5438c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        memset(mPrevSpacePositions, 0, sizeof(mPrevSpacePositions));
5538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    }
5638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
5738c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    // Init by copy
5838c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    AK_FORCE_INLINE void init(const DicNodeStatePrevWord *const prevWord) {
5938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordLength = prevWord->mPrevWordLength;
6038c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordCount = prevWord->mPrevWordCount;
6138c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordStart = prevWord->mPrevWordStart;
6238c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordProbability = prevWord->mPrevWordProbability;
6338c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordNodePos = prevWord->mPrevWordNodePos;
6438c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        memcpy(mPrevWord, prevWord->mPrevWord, prevWord->mPrevWordLength * sizeof(mPrevWord[0]));
6538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        memcpy(mPrevSpacePositions, prevWord->mPrevSpacePositions, sizeof(mPrevSpacePositions));
6638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    }
6738c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
6838c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    void init(const int16_t prevWordCount, const int16_t prevWordProbability,
6938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka            const int prevWordNodePos, const int *const src0, const int16_t length0,
7038c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka            const int *const src1, const int16_t length1, const int *const prevSpacePositions,
7138c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka            const int lastInputIndex) {
7238c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordCount = prevWordCount;
7338c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordProbability = prevWordProbability;
7438c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordNodePos = prevWordNodePos;
7538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        const int twoWordsLen =
7638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka                DicNodeUtils::appendTwoWords(src0, length0, src1, length1, mPrevWord);
7738c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWord[twoWordsLen] = KEYCODE_SPACE;
7838c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordStart = length0;
7938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordLength = static_cast<int16_t>(twoWordsLen + 1);
8038c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        memcpy(mPrevSpacePositions, prevSpacePositions, sizeof(mPrevSpacePositions));
8138c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevSpacePositions[mPrevWordCount - 1] = lastInputIndex;
8238c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    }
8338c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
8438c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    void truncate(const int offset) {
8538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        // TODO: memmove
8638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        if (mPrevWordLength < offset) {
8738c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka            memset(mPrevWord, 0, sizeof(mPrevWord));
8838c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka            mPrevWordLength = 0;
8938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka            return;
9038c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        }
9138c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        const int newPrevWordLength = mPrevWordLength - offset;
9238c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        memmove(mPrevWord, &mPrevWord[offset], newPrevWordLength * sizeof(mPrevWord[0]));
9338c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        mPrevWordLength = newPrevWordLength;
9438c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    }
9538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
9638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    void outputSpacePositions(int *spaceIndices) const {
9738c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        // Convert uint16_t to int
9838c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        for (int i = 0; i < MAX_RESULTS; i++) {
9938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka            spaceIndices[i] = mPrevSpacePositions[i];
10038c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        }
10138c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    }
10238c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
10338c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    // TODO: remove
10438c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    int16_t getPrevWordLength() const {
10538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        return mPrevWordLength;
10638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    }
10738c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
10838c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    int16_t getPrevWordCount() const {
10938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        return mPrevWordCount;
11038c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    }
11138c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
11238c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    int16_t getPrevWordStart() const {
11338c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        return mPrevWordStart;
11438c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    }
11538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
11638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    int16_t getPrevWordProbability() const {
11738c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        return mPrevWordProbability;
11838c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    }
11938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
12038c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    int getPrevWordNodePos() const {
12138c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        return mPrevWordNodePos;
12238c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    }
12338c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
12438c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    int getPrevWordCodePointAt(const int id) const {
12538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        return mPrevWord[id];
12638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    }
12738c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
12838c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    bool startsWith(const DicNodeStatePrevWord *const prefix, const int prefixLen) const {
12938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        if (prefixLen > mPrevWordLength) {
13038c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka            return false;
13138c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        }
13238c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        for (int i = 0; i < prefixLen; ++i) {
13338c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka            if (mPrevWord[i] != prefix->mPrevWord[i]) {
13438c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka                return false;
13538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka            }
13638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        }
13738c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka        return true;
13838c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    }
13938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
14038c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    // TODO: Move to private
14138c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    int mPrevWord[MAX_WORD_LENGTH];
14238c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    // TODO: Move to private
14338c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    int mPrevSpacePositions[MAX_RESULTS];
14438c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka
14538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka private:
14638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    // Caution!!!
14738c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    // Use a default copy constructor and an assign operator because shallow copies are ok
14838c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    // for this class
14938c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    int16_t mPrevWordCount;
15038c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    int16_t mPrevWordLength;
15138c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    int16_t mPrevWordStart;
15238c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    int16_t mPrevWordProbability;
15338c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka    int mPrevWordNodePos;
15438c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka};
15538c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka} // namespace latinime
15638c26dd0bf8cd5c4511e4a02d5eeae4b3553f03aSatoshi Kataoka#endif // LATINIME_DIC_NODE_STATE_PREVWORD_H
157