1 /*
2  * SPDX-FileCopyrightText: 2017~2017 CSSlayer <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  */
7 #ifndef _LIBIME_JYUTPING_JYUTPINGENCODER_H_
8 #define _LIBIME_JYUTPING_JYUTPINGENCODER_H_
9 
10 #include "libimejyutping_export.h"
11 #include <libime/core/segmentgraph.h>
12 
13 namespace libime {
14 namespace jyutping {
15 
16 enum class JyutpingInitial : char {
17     Invalid = 0,
18     B = 'A',
19     P,
20     M,
21     F,
22     D,
23     T,
24     N,
25     L,
26     G,
27     K,
28     NG,
29     H,
30     GW,
31     KW,
32     W,
33     Z,
34     C,
35     S,
36     J,
37     Zero,
38 };
39 
40 enum class JyutpingFinal : char {
41     Invalid = 0,
42     AA = 'A',
43     AAI,
44     AAU,
45     AAM,
46     AAN,
47     AANG,
48     AAP,
49     AAT,
50     AAK,
51     AI,
52     AU,
53     AM,
54     AN,
55     ANG,
56     AP,
57     AT,
58     AK,
59     E,
60     EI,
61     ET,
62     EU,
63     EM,
64     EN,
65     ENG,
66     EP,
67     EK,
68     I,
69     IU,
70     IM,
71     IN,
72     ING,
73     IP,
74     IT,
75     IK,
76     O,
77     OI,
78     OU,
79     ON,
80     ONG,
81     OT,
82     OK,
83     OE,
84     OENG,
85     OEK,
86     OM,
87     EOI,
88     EON,
89     EOT,
90     U,
91     UI,
92     UN,
93     UNG,
94     UT,
95     UK,
96     YU,
97     YUN,
98     YUT,
99     M,
100     NG,
101     Zero,
102 };
103 
104 struct LIBIMEJYUTPING_EXPORT JyutpingSyllable {
105 public:
JyutpingSyllableJyutpingSyllable106     JyutpingSyllable(JyutpingInitial initial, JyutpingFinal final)
107         : initial_(initial), final_(final) {}
FCITX_INLINE_DEFINE_DEFAULT_DTOR_AND_COPYJyutpingSyllable108     FCITX_INLINE_DEFINE_DEFAULT_DTOR_AND_COPY(JyutpingSyllable)
109 
110     JyutpingInitial initial() const { return initial_; }
finalJyutpingSyllable111     JyutpingFinal final() const { return final_; }
112 
113     std::string toString() const;
114 
115     bool operator==(const JyutpingSyllable &other) const {
116         return initial_ == other.initial_ && final_ == other.final_;
117     }
118 
119     bool operator!=(const JyutpingSyllable &other) const {
120         return !(*this == other);
121     }
122     bool operator<(const JyutpingSyllable &other) const {
123         return std::make_pair(initial_, final_) <
124                std::make_pair(other.initial_, other.final_);
125     }
126     bool operator<=(const JyutpingSyllable &other) const {
127         return *this < other || *this == other;
128     }
129     bool operator>(const JyutpingSyllable &other) const {
130         return !(*this <= other);
131     }
132     bool operator>=(const JyutpingSyllable &other) const {
133         return !(*this < other);
134     }
135 
136 private:
137     JyutpingInitial initial_;
138     JyutpingFinal final_;
139 };
140 
141 using MatchedJyutpingSyllables = std::vector<
142     std::pair<JyutpingInitial, std::vector<std::pair<JyutpingFinal, bool>>>>;
143 
144 class LIBIMEJYUTPING_EXPORT JyutpingEncoder {
145 public:
146     static SegmentGraph parseUserJyutping(std::string jyutping,
147                                           bool inner = true);
148     static std::vector<char> encodeOneUserJyutping(std::string jyutping);
149     static bool isValidUserJyutping(const char *data, size_t size);
150 
151     static std::vector<char> encodeFullJyutping(std::string_view jyutping);
152 
153     static std::string decodeFullJyutping(const char *data, size_t size);
decodeFullJyutping(std::string_view data)154     static std::string decodeFullJyutping(std::string_view data) {
155         return decodeFullJyutping(data.data(), data.size());
156     }
157 
158     static MatchedJyutpingSyllables
159     stringToSyllables(std::string_view jyutping);
160 
161     static const std::string &initialToString(JyutpingInitial initial);
162     static JyutpingInitial stringToInitial(const std::string &str);
isValidInitial(char c)163     static bool isValidInitial(char c) {
164         return c >= firstInitial && c <= lastInitial;
165     }
166 
167     static const std::string &finalToString(JyutpingFinal final);
168     static JyutpingFinal stringToFinal(const std::string &str);
isValidFinal(char c)169     static bool isValidFinal(char c) {
170         return c >= firstFinal && c <= lastFinal;
171     }
172 
173     static bool isValidInitialFinal(JyutpingInitial initial,
174                                     JyutpingFinal final);
175 
176     static const char firstInitial = static_cast<char>(JyutpingInitial::B);
177     static const char lastInitial = static_cast<char>(JyutpingInitial::Zero);
178     static const char firstFinal = static_cast<char>(JyutpingFinal::AA);
179     static const char lastFinal = static_cast<char>(JyutpingFinal::Zero);
180 };
181 
182 } // namespace jyutping
183 } // namespace libime
184 
185 #endif // _LIBIME_JYUTPING_JYUTPINGENCODER_H_
186