Update from the upstream (BUILD 4190).
* Code refactoring.
* Removed code for NaCl, which was deprecated in 2019Q4.
+ https://developer.chrome.com/native-client/nacl-and-pnacl
Hiroyuki Komatsu
3 years ago
268 | 268 | deps = [":port"], |
269 | 269 | ) |
270 | 270 | |
271 | LOGGING_APP_BUILD_DEPS = [ | |
272 | ":const", | |
273 | ":clock", | |
274 | ":flags", | |
275 | ":mutex", | |
276 | ":singleton", | |
277 | ] | |
278 | ||
279 | 271 | cc_library_mozc( |
280 | 272 | name = "logging", |
281 | 273 | srcs = ["logging.cc"], |
285 | 277 | android = ["-llog"], |
286 | 278 | ), |
287 | 279 | deps = select_mozc( |
288 | client = LOGGING_APP_BUILD_DEPS, | |
280 | client = [ | |
281 | ":clock", | |
282 | ":const", | |
283 | ":flags", | |
284 | ":mutex", | |
285 | ":singleton", | |
286 | "@com_google_absl//absl/strings", | |
287 | ], | |
289 | 288 | default = [ |
290 | 289 | "//base", |
291 | 290 | "//base:logging_extensions", |
456 | 455 | cc_library_mozc( |
457 | 456 | name = "mozc_hash_map", |
458 | 457 | hdrs = ["mozc_hash_map.h"], |
459 | visibility = [ | |
460 | "//:__subpackages__", | |
461 | ], | |
462 | deps = select_mozc( | |
463 | default = ["@com_google_absl//absl/container:flat_hash_map"], | |
464 | linux = [], | |
465 | oss = [], | |
466 | ), | |
458 | visibility = ["//:__subpackages__"], | |
459 | deps = ["@com_google_absl//absl/container:flat_hash_map"], | |
467 | 460 | ) |
468 | 461 | |
469 | 462 | cc_library_mozc( |
470 | 463 | name = "mozc_hash_set", |
471 | 464 | hdrs = ["mozc_hash_set.h"], |
472 | 465 | visibility = ["//:__subpackages__"], |
473 | deps = select_mozc( | |
474 | default = ["@com_google_absl//absl/container:flat_hash_set"], | |
475 | linux = [], | |
476 | oss = [], | |
477 | ), | |
466 | deps = ["@com_google_absl//absl/container:flat_hash_set"], | |
478 | 467 | ) |
479 | 468 | |
480 | 469 | py_binary_mozc( |
541 | 530 | deps = [ |
542 | 531 | ":port", |
543 | 532 | ":singleton", |
533 | "@com_google_absl//absl/time", | |
544 | 534 | ], |
545 | 535 | ) |
546 | 536 | |
745 | 735 | deps = [ |
746 | 736 | ":port", |
747 | 737 | ":util", |
738 | "@com_google_absl//absl/time", | |
748 | 739 | ], |
749 | 740 | ) |
750 | 741 |
46 | 46 | '<(absl_srcdir)/base/internal/thread_identity.cc', |
47 | 47 | '<(absl_srcdir)/base/internal/throw_delegate.cc', |
48 | 48 | '<(absl_srcdir)/base/internal/unscaledcycleclock.cc', |
49 | '<(absl_srcdir)/container/internal/raw_hash_set.cc', | |
50 | '<(absl_srcdir)/hash/internal/city.cc', | |
51 | '<(absl_srcdir)/hash/internal/hash.cc', | |
49 | 52 | ], |
50 | 53 | 'msvs_disabled_warnings': [ |
51 | 54 | # 'type' : forcing value to bool 'true' or 'false' |
109 | 112 | 'absl_strings_internal', |
110 | 113 | ], |
111 | 114 | }, |
115 | { | |
116 | 'target_name': 'absl_time', | |
117 | 'type': 'static_library', | |
118 | 'toolsets': ['host', 'target'], | |
119 | 'sources': [ | |
120 | '<(absl_srcdir)/time/civil_time.cc', | |
121 | '<(absl_srcdir)/time/clock.cc', | |
122 | '<(absl_srcdir)/time/duration.cc', | |
123 | '<(absl_srcdir)/time/format.cc', | |
124 | '<(absl_srcdir)/time/time.cc', | |
125 | '<(absl_srcdir)/time/internal/cctz/src/civil_time_detail.cc', | |
126 | '<(absl_srcdir)/time/internal/cctz/src/time_zone_fixed.cc', | |
127 | '<(absl_srcdir)/time/internal/cctz/src/time_zone_format.cc', | |
128 | '<(absl_srcdir)/time/internal/cctz/src/time_zone_if.cc', | |
129 | '<(absl_srcdir)/time/internal/cctz/src/time_zone_impl.cc', | |
130 | '<(absl_srcdir)/time/internal/cctz/src/time_zone_info.cc', | |
131 | '<(absl_srcdir)/time/internal/cctz/src/time_zone_libc.cc', | |
132 | '<(absl_srcdir)/time/internal/cctz/src/time_zone_lookup.cc', | |
133 | '<(absl_srcdir)/time/internal/cctz/src/time_zone_posix.cc', | |
134 | '<(absl_srcdir)/time/internal/cctz/src/zone_info_source.cc', | |
135 | ], | |
136 | 'cflags': [ | |
137 | '-Wno-error', | |
138 | ], | |
139 | 'dependencies': [ | |
140 | 'absl_base', | |
141 | 'absl_numeric', | |
142 | 'absl_strings_internal', | |
143 | ], | |
144 | }, | |
112 | 145 | ], |
113 | 146 | } |
117 | 117 | 'mutex', |
118 | 118 | 'singleton', |
119 | 119 | 'absl.gyp:absl_strings', |
120 | 'absl.gyp:absl_time', | |
120 | 121 | ], |
121 | 122 | 'conditions': [ |
122 | 123 | ['OS=="win"', { |
201 | 202 | ], |
202 | 203 | 'dependencies': [ |
203 | 204 | 'singleton', |
205 | 'absl.gyp:absl_time', | |
204 | 206 | ], |
205 | 207 | }, |
206 | 208 | { |
146 | 146 | 'sources': [ |
147 | 147 | 'clock_mock.cc' |
148 | 148 | ], |
149 | 'dependencies': [ | |
150 | 'absl.gyp:absl_time', | |
151 | ], | |
149 | 152 | }, |
150 | 153 | { |
151 | 154 | 'target_name': 'clock_mock_test', |
41 | 41 | #endif // OS_WIN |
42 | 42 | |
43 | 43 | #include "base/singleton.h" |
44 | #include "absl/time/clock.h" | |
44 | 45 | |
45 | 46 | namespace mozc { |
46 | 47 | namespace { |
47 | 48 | |
48 | 49 | class ClockImpl : public ClockInterface { |
49 | 50 | public: |
50 | #ifndef OS_NACL | |
51 | ClockImpl() {} | |
52 | #else // OS_NACL | |
53 | ClockImpl() : timezone_offset_sec_(0) {} | |
54 | #endif // OS_NACL | |
55 | ||
51 | ClockImpl() : timezone_offset_sec_(0), timezone_(absl::LocalTimeZone()) {} | |
56 | 52 | ~ClockImpl() override {} |
57 | 53 | |
58 | 54 | void GetTimeOfDay(uint64 *sec, uint32 *usec) override { |
90 | 86 | #endif // OS_WIN |
91 | 87 | } |
92 | 88 | |
93 | bool GetTmWithOffsetSecond(time_t offset_sec, tm *output) override { | |
94 | const time_t current_sec = static_cast<time_t>(this->GetTime()); | |
95 | const time_t modified_sec = current_sec + offset_sec; | |
96 | ||
97 | #ifdef OS_WIN | |
98 | if (_localtime64_s(output, &modified_sec) != 0) { | |
99 | return false; | |
100 | } | |
101 | #elif defined(OS_NACL) | |
102 | const time_t localtime_sec = modified_sec + timezone_offset_sec_; | |
103 | if (gmtime_r(&localtime_sec, output) == nullptr) { | |
104 | return false; | |
105 | } | |
106 | #else // !OS_WIN && !OS_NACL | |
107 | if (localtime_r(&modified_sec, output) == nullptr) { | |
108 | return false; | |
109 | } | |
110 | #endif // OS_WIN | |
111 | return true; | |
89 | absl::Time GetAbslTime() override { | |
90 | return absl::Now(); | |
112 | 91 | } |
113 | 92 | |
114 | 93 | uint64 GetFrequency() override { |
152 | 131 | #endif // platforms (OS_WIN, __APPLE__, OS_LINUX, ...) |
153 | 132 | } |
154 | 133 | |
155 | #ifdef OS_NACL | |
156 | virtual void SetTimezoneOffset(int32 timezone_offset_sec) { | |
134 | const absl::TimeZone& GetTimeZone() override { | |
135 | return timezone_; | |
136 | } | |
137 | ||
138 | void SetTimeZoneOffset(int32 timezone_offset_sec) override { | |
157 | 139 | timezone_offset_sec_ = timezone_offset_sec; |
140 | timezone_ = absl::FixedTimeZone(timezone_offset_sec); | |
158 | 141 | } |
159 | 142 | |
160 | 143 | private: |
161 | 144 | int32 timezone_offset_sec_; |
162 | #endif // OS_NACL | |
145 | absl::TimeZone timezone_; | |
163 | 146 | }; |
164 | 147 | |
165 | 148 | ClockInterface *g_clock = nullptr; |
176 | 159 | |
177 | 160 | uint64 Clock::GetTime() { return GetClock()->GetTime(); } |
178 | 161 | |
179 | bool Clock::GetTmWithOffsetSecond(tm *time_with_offset, int offset_sec) { | |
180 | return GetClock()->GetTmWithOffsetSecond(offset_sec, time_with_offset); | |
181 | } | |
162 | absl::Time Clock::GetAbslTime() { return GetClock()->GetAbslTime(); } | |
182 | 163 | |
183 | 164 | uint64 Clock::GetFrequency() { return GetClock()->GetFrequency(); } |
184 | 165 | |
185 | 166 | uint64 Clock::GetTicks() { return GetClock()->GetTicks(); } |
186 | 167 | |
187 | #ifdef OS_NACL | |
188 | void Clock::SetTimezoneOffset(int32 timezone_offset_sec) { | |
189 | return GetClock()->SetTimezoneOffset(timezone_offset_sec); | |
168 | const absl::TimeZone& Clock::GetTimeZone() { | |
169 | return GetClock()->GetTimeZone(); | |
190 | 170 | } |
191 | #endif // OS_NACL | |
171 | ||
172 | void Clock::SetTimeZoneOffset(int32 timezone_offset_sec) { | |
173 | return GetClock()->SetTimeZoneOffset(timezone_offset_sec); | |
174 | } | |
192 | 175 | |
193 | 176 | void Clock::SetClockForUnitTest(ClockInterface *clock) { g_clock = clock; } |
194 | 177 | |
178 | ||
195 | 179 | } // namespace mozc |
32 | 32 | #include <ctime> |
33 | 33 | |
34 | 34 | #include "base/port.h" |
35 | #include "absl/time/time.h" | |
35 | 36 | |
36 | 37 | namespace mozc { |
37 | 38 | |
41 | 42 | |
42 | 43 | virtual void GetTimeOfDay(uint64 *sec, uint32 *usec) = 0; |
43 | 44 | virtual uint64 GetTime() = 0; |
44 | virtual bool GetTmWithOffsetSecond(time_t offset_sec, tm *output) = 0; | |
45 | virtual absl::Time GetAbslTime() = 0; | |
45 | 46 | |
46 | 47 | // High accuracy clock. |
47 | 48 | virtual uint64 GetFrequency() = 0; |
48 | 49 | virtual uint64 GetTicks() = 0; |
49 | 50 | |
50 | #ifdef OS_NACL | |
51 | virtual void SetTimezoneOffset(int32 timezone_offset_sec) = 0; | |
52 | #endif // OS_NACL | |
51 | virtual const absl::TimeZone& GetTimeZone() = 0; | |
52 | virtual void SetTimeZoneOffset(int32 timezone_offset_sec) = 0; | |
53 | 53 | |
54 | 54 | protected: |
55 | 55 | ClockInterface() {} |
67 | 67 | // For Linux/Mac, time() is used. |
68 | 68 | static uint64 GetTime(); |
69 | 69 | |
70 | // Gets local time, which is offset_sec seconds after now. Returns true if | |
71 | // succeeded. | |
72 | static bool GetTmWithOffsetSecond(tm *time_with_offset, int offset_sec); | |
73 | ||
74 | // Gets the current local time to current_time. Returns true if succeeded. | |
75 | static bool GetCurrentTm(tm *current_time) { | |
76 | return GetTmWithOffsetSecond(current_time, 0); | |
77 | } | |
70 | // Returns the current time in absl::Time. | |
71 | static absl::Time GetAbslTime(); | |
78 | 72 | |
79 | 73 | // Gets the system frequency to calculate the time from ticks. |
80 | 74 | static uint64 GetFrequency(); |
84 | 78 | // GetFrequency(). |
85 | 79 | static uint64 GetTicks(); |
86 | 80 | |
87 | #ifdef OS_NACL | |
81 | // Returns the timezone. LocalTimeZone is usually returned. | |
82 | static const absl::TimeZone& GetTimeZone(); | |
83 | ||
88 | 84 | // Sets the time difference between local time and UTC time in seconds. |
89 | 85 | // We use this function in NaCl Mozc because we can't know the local timezone |
90 | 86 | // in NaCl environment. |
91 | static void SetTimezoneOffset(int32 timezone_offset_sec); | |
92 | #endif // OS_NACL | |
87 | static void SetTimeZoneOffset(int32 timezone_offset_sec); | |
93 | 88 | |
94 | 89 | // TESTONLY: The behavior of global system clock can be overridden by using |
95 | 90 | // this method. Set to nullptr to restore the default clock. This method |
37 | 37 | micro_seconds_(usec), |
38 | 38 | frequency_(1000000000), |
39 | 39 | ticks_(0), |
40 | #ifdef OS_NACL | |
40 | timezone_(absl::UTCTimeZone()), | |
41 | 41 | timezone_offset_sec_(0), |
42 | #endif // OS_NACL | |
43 | 42 | delta_seconds_(0), |
44 | 43 | delta_micro_seconds_(0) { |
45 | 44 | } |
58 | 57 | return ret_sec; |
59 | 58 | } |
60 | 59 | |
61 | bool ClockMock::GetTmWithOffsetSecond(time_t offset_sec, tm *output) { | |
62 | const time_t current_sec = static_cast<time_t>(seconds_); | |
63 | const time_t modified_sec = current_sec + offset_sec; | |
64 | ||
65 | #ifdef OS_WIN | |
66 | if (_gmtime64_s(output, &modified_sec) != 0) { | |
67 | return false; | |
68 | } | |
69 | #elif defined(OS_NACL) | |
70 | const time_t localtime_sec = modified_sec + timezone_offset_sec_; | |
71 | if (gmtime_r(&localtime_sec, output) == nullptr) { | |
72 | return false; | |
73 | } | |
74 | #else // !OS_WIN && !OS_NACL | |
75 | if (gmtime_r(&modified_sec, output) == nullptr) { | |
76 | return false; | |
77 | } | |
78 | #endif | |
60 | absl::Time ClockMock::GetAbslTime() { | |
61 | absl::Time at = absl::FromUnixSeconds(seconds_); | |
79 | 62 | PutClockForward(delta_seconds_, delta_micro_seconds_); |
80 | ||
81 | return true; | |
63 | return at; | |
82 | 64 | } |
83 | 65 | |
84 | 66 | uint64 ClockMock::GetFrequency() { return frequency_; } |
85 | 67 | |
86 | 68 | uint64 ClockMock::GetTicks() { return ticks_; } |
87 | 69 | |
88 | #ifdef OS_NACL | |
89 | void ClockMock::SetTimezoneOffset(int32 timezone_offset_sec) { | |
70 | const absl::TimeZone& ClockMock::GetTimeZone() { | |
71 | return timezone_; | |
72 | } | |
73 | ||
74 | void ClockMock::SetTimeZoneOffset(int32 timezone_offset_sec) { | |
90 | 75 | timezone_offset_sec_ = timezone_offset_sec; |
76 | timezone_ = absl::FixedTimeZone(timezone_offset_sec); | |
91 | 77 | } |
92 | #endif // OS_NACL | |
93 | 78 | |
94 | 79 | void ClockMock::PutClockForward(uint64 delta_sec, uint32 delta_usec) { |
95 | 80 | const uint32 one_second = 1000000u; |
47 | 47 | |
48 | 48 | void GetTimeOfDay(uint64 *sec, uint32 *usec) override; |
49 | 49 | uint64 GetTime() override; |
50 | bool GetTmWithOffsetSecond(time_t offset_sec, tm *output) override; | |
50 | absl::Time GetAbslTime() override; | |
51 | 51 | uint64 GetFrequency() override; |
52 | 52 | uint64 GetTicks() override; |
53 | #ifdef OS_NACL | |
54 | void SetTimezoneOffset(int32 timezone_offset_sec) override; | |
55 | #endif // OS_NACL | |
53 | ||
54 | const absl::TimeZone& GetTimeZone() override; | |
55 | void SetTimeZoneOffset(int32 timezone_offset_sec) override; | |
56 | 56 | |
57 | 57 | // Puts this clock forward. |
58 | 58 | // It has no impact on ticks. |
75 | 75 | uint32 micro_seconds_; |
76 | 76 | uint64 frequency_; |
77 | 77 | uint64 ticks_; |
78 | #ifdef OS_NACL | |
78 | absl::TimeZone timezone_; | |
79 | 79 | int32 timezone_offset_sec_; |
80 | #endif // OS_NACL | |
81 | 80 | // Everytime user requests time clock, following time is added to the |
82 | 81 | // internal clock. |
83 | 82 | uint64 delta_seconds_; |
63 | 63 | // 2020-12-23 13:24:00 (Wed) |
64 | 64 | ClockMock mock(kTestSeconds, kTestMicroSeconds); |
65 | 65 | const int offset = -35; |
66 | tm current_tm; | |
67 | ||
68 | EXPECT_TRUE(mock.GetTmWithOffsetSecond(offset, ¤t_tm)); | |
69 | EXPECT_EQ(120, current_tm.tm_year); | |
70 | EXPECT_EQ(11, current_tm.tm_mon); | |
71 | EXPECT_EQ(23, current_tm.tm_mday); | |
72 | EXPECT_EQ(13, current_tm.tm_hour); | |
73 | EXPECT_EQ(24, current_tm.tm_min); | |
74 | EXPECT_EQ(0, current_tm.tm_sec); | |
75 | EXPECT_EQ(3, current_tm.tm_wday); | |
76 | } | |
77 | ||
78 | #ifdef OS_NACL | |
79 | TEST(ClockMockTest, GetCurrentTmWithOffsetWithTimezoneOffsetTest) { | |
66 | ||
67 | const absl::Time at = mock.GetAbslTime(); | |
68 | const absl::TimeZone &tz = mock.GetTimeZone(); | |
69 | const absl::CivilSecond cs = absl::ToCivilSecond(at, tz) + offset; | |
70 | ||
71 | EXPECT_EQ(2020, cs.year()); | |
72 | EXPECT_EQ(12, cs.month()); | |
73 | EXPECT_EQ(23, cs.day()); | |
74 | EXPECT_EQ(13, cs.hour()); | |
75 | EXPECT_EQ(24, cs.minute()); | |
76 | EXPECT_EQ(0, cs.second()); | |
77 | EXPECT_EQ(absl::Weekday::wednesday, absl::GetWeekday(cs)); | |
78 | } | |
79 | ||
80 | TEST(ClockMockTest, GetCurrentTmWithOffsetWithTimeZoneOffsetTest) { | |
80 | 81 | // 2020-12-23 13:24:00 (Wed) |
81 | 82 | ClockMock mock(kTestSeconds, kTestMicroSeconds); |
82 | mock.SetTimezoneOffset(3600); | |
83 | mock.SetTimeZoneOffset(3600); | |
83 | 84 | const int offset = -35; |
84 | tm current_tm; | |
85 | ||
86 | EXPECT_TRUE(mock.GetTmWithOffsetSecond(offset, ¤t_tm)); | |
87 | EXPECT_EQ(120, current_tm.tm_year); | |
88 | EXPECT_EQ(11, current_tm.tm_mon); | |
89 | EXPECT_EQ(23, current_tm.tm_mday); | |
90 | EXPECT_EQ(14, current_tm.tm_hour); | |
91 | EXPECT_EQ(24, current_tm.tm_min); | |
92 | EXPECT_EQ(0, current_tm.tm_sec); | |
93 | EXPECT_EQ(3, current_tm.tm_wday); | |
94 | } | |
95 | #endif // OS_NACL | |
85 | ||
86 | const absl::Time at = mock.GetAbslTime(); | |
87 | const absl::TimeZone &tz = mock.GetTimeZone(); | |
88 | const absl::CivilSecond cs = absl::ToCivilSecond(at, tz) + offset; | |
89 | ||
90 | EXPECT_EQ(2020, cs.year()); | |
91 | EXPECT_EQ(12, cs.month()); | |
92 | EXPECT_EQ(23, cs.day()); | |
93 | EXPECT_EQ(14, cs.hour()); | |
94 | EXPECT_EQ(24, cs.minute()); | |
95 | EXPECT_EQ(0, cs.second()); | |
96 | EXPECT_EQ(absl::Weekday::wednesday, absl::GetWeekday(cs)); | |
97 | } | |
96 | 98 | |
97 | 99 | TEST(ClockMockTest, GetFrequencyAndTicks) { |
98 | 100 | ClockMock mock(0, 0); |
189 | 191 | ClockMock mock(kTestSeconds, kTestMicroSeconds); |
190 | 192 | mock.SetAutoPutClockForward(kDeltaSeconds, kDeltaMicroSeconds); |
191 | 193 | const int offset = -35; |
192 | tm current_tm; | |
193 | ||
194 | EXPECT_TRUE(mock.GetTmWithOffsetSecond(offset, ¤t_tm)); | |
195 | EXPECT_EQ(120, current_tm.tm_year); | |
196 | EXPECT_EQ(11, current_tm.tm_mon); | |
197 | EXPECT_EQ(23, current_tm.tm_mday); | |
198 | EXPECT_EQ(13, current_tm.tm_hour); | |
199 | EXPECT_EQ(24, current_tm.tm_min); | |
200 | EXPECT_EQ(0, current_tm.tm_sec); | |
201 | EXPECT_EQ(3, current_tm.tm_wday); | |
202 | ||
203 | EXPECT_TRUE(mock.GetTmWithOffsetSecond(offset, ¤t_tm)); | |
204 | EXPECT_EQ(120, current_tm.tm_year); | |
205 | EXPECT_EQ(11, current_tm.tm_mon); | |
206 | EXPECT_EQ(23, current_tm.tm_mday); | |
207 | EXPECT_EQ(13, current_tm.tm_hour); | |
208 | EXPECT_EQ(24, current_tm.tm_min); | |
209 | EXPECT_EQ(kDeltaSeconds, current_tm.tm_sec); | |
210 | EXPECT_EQ(3, current_tm.tm_wday); | |
194 | ||
195 | const absl::Time at = mock.GetAbslTime(); | |
196 | const absl::TimeZone &tz = mock.GetTimeZone(); | |
197 | absl::CivilSecond cs = absl::ToCivilSecond(at, tz) + offset; | |
198 | ||
199 | EXPECT_EQ(2020, cs.year()); | |
200 | EXPECT_EQ(12, cs.month()); | |
201 | EXPECT_EQ(23, cs.day()); | |
202 | EXPECT_EQ(13, cs.hour()); | |
203 | EXPECT_EQ(24, cs.minute()); | |
204 | EXPECT_EQ(0, cs.second()); | |
205 | EXPECT_EQ(absl::Weekday::wednesday, absl::GetWeekday(cs)); | |
206 | ||
207 | const absl::Time at2 = mock.GetAbslTime(); | |
208 | cs = absl::ToCivilSecond(at2, tz) + offset; | |
209 | EXPECT_EQ(2020, cs.year()); | |
210 | EXPECT_EQ(12, cs.month()); | |
211 | EXPECT_EQ(23, cs.day()); | |
212 | EXPECT_EQ(13, cs.hour()); | |
213 | EXPECT_EQ(24, cs.minute()); | |
214 | EXPECT_EQ(kDeltaSeconds, cs.second()); | |
215 | EXPECT_EQ(absl::Weekday::wednesday, absl::GetWeekday(cs)); | |
211 | 216 | } |
212 | 217 | } |
213 | 218 |
55 | 55 | EXPECT_EQ(kTestMicroSeconds, current_usec); |
56 | 56 | } |
57 | 57 | |
58 | // GetCurrentTm | |
58 | // GetAbslTime | |
59 | 59 | // 2020-12-23 13:24:35 (Wed) |
60 | 60 | { |
61 | tm current_tm; | |
62 | Clock::GetCurrentTm(¤t_tm); | |
63 | EXPECT_EQ(120, current_tm.tm_year); | |
64 | EXPECT_EQ(11, current_tm.tm_mon); | |
65 | EXPECT_EQ(23, current_tm.tm_mday); | |
66 | EXPECT_EQ(13, current_tm.tm_hour); | |
67 | EXPECT_EQ(24, current_tm.tm_min); | |
68 | EXPECT_EQ(35, current_tm.tm_sec); | |
69 | EXPECT_EQ(3, current_tm.tm_wday); | |
61 | const absl::Time at = Clock::GetAbslTime(); | |
62 | const absl::TimeZone &tz = Clock::GetTimeZone(); | |
63 | const absl::CivilSecond cs = absl::ToCivilSecond(at, tz); | |
64 | ||
65 | EXPECT_EQ(2020, cs.year()); | |
66 | EXPECT_EQ(12, cs.month()); | |
67 | EXPECT_EQ(23, cs.day()); | |
68 | EXPECT_EQ(13, cs.hour()); | |
69 | EXPECT_EQ(24, cs.minute()); | |
70 | EXPECT_EQ(35, cs.second()); | |
71 | EXPECT_EQ(absl::Weekday::wednesday, absl::GetWeekday(cs)); | |
70 | 72 | } |
71 | 73 | |
72 | // GetTmWithoutOffsetSecond | |
74 | // GetAbslTime + offset | |
73 | 75 | // 2024/02/23 23:11:15 (Fri) |
74 | 76 | { |
75 | 77 | const int offset_seconds = 100000000; |
76 | tm offset_tm; | |
77 | Clock::GetTmWithOffsetSecond(&offset_tm, offset_seconds); | |
78 | EXPECT_EQ(124, offset_tm.tm_year); | |
79 | EXPECT_EQ(1, offset_tm.tm_mon); | |
80 | EXPECT_EQ(23, offset_tm.tm_mday); | |
81 | EXPECT_EQ(23, offset_tm.tm_hour); | |
82 | EXPECT_EQ(11, offset_tm.tm_min); | |
83 | EXPECT_EQ(15, offset_tm.tm_sec); | |
84 | EXPECT_EQ(5, offset_tm.tm_wday); | |
78 | const absl::Time at = Clock::GetAbslTime(); | |
79 | const absl::TimeZone &tz = Clock::GetTimeZone(); | |
80 | const absl::CivilSecond cs = absl::ToCivilSecond(at, tz) + offset_seconds; | |
81 | EXPECT_EQ(2024, cs.year()); | |
82 | EXPECT_EQ(2, cs.month()); | |
83 | EXPECT_EQ(23, cs.day()); | |
84 | EXPECT_EQ(23, cs.hour()); | |
85 | EXPECT_EQ(11, cs.minute()); | |
86 | EXPECT_EQ(15, cs.second()); | |
87 | EXPECT_EQ(absl::Weekday::friday, absl::GetWeekday(cs)); | |
85 | 88 | } |
86 | 89 | |
87 | 90 | // GetFrequency / GetTicks |
41 | 41 | // base/embedded_file.h is embedded as kEmbeddedFileTestData. |
42 | 42 | #include "base/embedded_file_test_data.inc" |
43 | 43 | |
44 | #ifndef OS_NACL | |
45 | // NaCl test doesn't support real file system, so currently disabled. | |
46 | 44 | TEST(EmbeddedFileTest, Basic) { |
47 | 45 | const std::string expected = |
48 | 46 | InputFileStream( |
51 | 49 | .Read(); |
52 | 50 | EXPECT_EQ(expected, LoadEmbeddedFile(kEmbeddedFileTestData)); |
53 | 51 | } |
54 | #endif // OS_NACL | |
55 | 52 | |
56 | 53 | } // namespace |
57 | 54 | } // namespace mozc |
83 | 83 | static bool FileExists(const std::string &filename); |
84 | 84 | |
85 | 85 | // Returns true if the directory exists. |
86 | static bool DirectoryExists(const std::string &filename); | |
86 | static bool DirectoryExists(const std::string &dirname); | |
87 | 87 | |
88 | 88 | #ifdef OS_WIN |
89 | 89 | // Adds file attributes to the file to hide it. |
59 | 59 | #include "base/flags.h" |
60 | 60 | #include "base/mutex.h" |
61 | 61 | #include "base/singleton.h" |
62 | #include "absl/strings/str_cat.h" | |
62 | 63 | |
63 | 64 | DEFINE_bool(colored_log, true, "Enables colored log messages on tty devices"); |
64 | 65 | DEFINE_bool(logtostderr, false, |
91 | 92 | |
92 | 93 | // Use the same implementation both for Opt and Debug. |
93 | 94 | string Logging::GetLogMessageHeader() { |
94 | #ifndef OS_ANDROID | |
95 | tm tm_time; | |
96 | Clock::GetCurrentTm(&tm_time); | |
97 | ||
98 | char buf[512]; | |
99 | snprintf(buf, sizeof(buf), | |
100 | "%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d %u " | |
101 | #if defined(OS_NACL) | |
102 | "%p", | |
103 | #elif defined(OS_LINUX) | |
104 | "%lu", | |
105 | #elif defined(__APPLE__) && defined(__LP64__) | |
106 | "%llu", | |
107 | #else // OS_WIN or __APPLE__(32bit) | |
108 | "%u", | |
109 | #endif | |
110 | 1900 + tm_time.tm_year, 1 + tm_time.tm_mon, tm_time.tm_mday, | |
111 | tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec, | |
112 | #if defined(OS_WIN) | |
113 | ::GetCurrentProcessId(), ::GetCurrentThreadId() | |
114 | #elif defined(__APPLE__) | |
115 | ::getpid(), | |
116 | #ifdef __LP64__ | |
117 | reinterpret_cast<uint64>(pthread_self()) | |
118 | #else // __LP64__ | |
119 | reinterpret_cast<uint32>(pthread_self()) | |
120 | #endif // __LP64__ | |
121 | #elif defined(OS_WASM) | |
122 | ::getpid(), static_cast<unsigned int>(pthread_self()) | |
123 | #elif defined(OS_NACL) | |
124 | ::getpid(), | |
125 | // pthread_self() returns __nc_basic_thread_data*. | |
126 | static_cast<void *>(pthread_self()) | |
127 | #else // = OS_LINUX | |
128 | ::getpid(), | |
129 | // It returns unsigned long. | |
130 | pthread_self() | |
131 | #endif | |
132 | ); | |
133 | return buf; | |
134 | #else // OS_ANDROID | |
95 | #ifdef OS_ANDROID | |
135 | 96 | // On Android, other records are not needed because they are added by |
136 | 97 | // Android's logging framework. |
137 | char buf[32]; | |
138 | snprintf(buf, sizeof(buf), "%lu ", | |
139 | pthread_self()); // returns unsigned long. | |
140 | return buf; | |
98 | return absl::StrCat(pthread_self(), " "); // returns unsigned long. | |
99 | ||
100 | #else // OS_ANDROID | |
101 | ||
102 | const absl::Time at = Clock::GetAbslTime(); | |
103 | const absl::TimeZone tz = Clock::GetTimeZone(); | |
104 | const std::string timestamp = absl::FormatTime("%Y-%m-%d %H:%M:%S ", at, tz); | |
105 | ||
106 | # if defined(OS_NACL) | |
107 | return absl::StrCat(timestamp, ::getpid(), " ", | |
108 | // pthread_self() returns __nc_basic_thread_data*. | |
109 | static_cast<void *>(pthread_self()); | |
110 | # elif defined(OS_WASM) | |
111 | return absl::StrCat(timestamp, ::getpid(), " ", | |
112 | static_cast<unsigned int>(pthread_self()); | |
113 | # elif defined(OS_LINUX) | |
114 | return absl::StrCat(timestamp, ::getpid(), " ", | |
115 | // It returns unsigned long. | |
116 | pthread_self()); | |
117 | # elif defined(__APPLE__) | |
118 | # ifdef __LP64__ | |
119 | return absl::StrCat(timestamp, ::getpid(), " ", | |
120 | reinterpret_cast<uint64>(pthread_self())); | |
121 | # else // __LP64__ | |
122 | return absl::StrCat(timestamp, ::getpid(), " ", | |
123 | ::getpid(), | |
124 | reinterpret_cast<uint32>(pthread_self())); | |
125 | # endif // __LP64__ | |
126 | # elif defined(OS_WIN) | |
127 | return absl::StrCat(timestamp, ::GetCurrentProcessId(), " ", | |
128 | ::GetCurrentThreadId()); | |
129 | # endif // OS_WIN | |
141 | 130 | #endif // OS_ANDROID |
142 | 131 | } |
143 | 132 | |
280 | 269 | delete real_log_stream_; |
281 | 270 | real_log_stream_ = nullptr; |
282 | 271 | config_verbose_level_ = 0; |
283 | #if defined(OS_NACL) | |
284 | // In NaCl, we only use stderr to output logs. | |
285 | use_cerr_ = true; | |
286 | support_color_ = false; | |
287 | #elif defined(OS_ANDROID) | |
272 | #if defined(OS_ANDROID) | |
288 | 273 | // Android uses Android's log library. |
289 | 274 | use_cerr_ = false; |
290 | 275 | support_color_ = false; |
294 | 279 | // TODO(team): Considers to use SetConsoleTextAttribute on Windows. |
295 | 280 | use_cerr_ = FLAGS_logtostderr; |
296 | 281 | support_color_ = false; |
297 | #else // OS_NACL, OS_ANDROID, OS_WIN | |
282 | #else // OS_ANDROID, OS_WIN | |
298 | 283 | use_cerr_ = FLAGS_logtostderr; |
299 | 284 | support_color_ = use_cerr_ && FLAGS_colored_log && ::isatty(::fileno(stderr)); |
300 | #endif // OS_NACL, OS_ANDROID, OS_WIN | |
285 | #endif // OS_ANDROID, OS_WIN | |
301 | 286 | } |
302 | 287 | |
303 | 288 | LogStreamImpl::~LogStreamImpl() { Reset(); } |
46 | 46 | #include "base/port.h" |
47 | 47 | #include "base/util.h" |
48 | 48 | |
49 | #ifdef OS_NACL | |
50 | #include <set> | |
51 | ||
52 | #include "base/file_stream.h" | |
53 | #include "base/mutex.h" | |
54 | #elif defined(OS_WIN) // !OS_NACL | |
49 | #if defined(OS_WIN) | |
55 | 50 | #include "base/scoped_handle.h" |
56 | #endif // !OS_NACL | |
51 | #endif // OS_WIN | |
57 | 52 | |
58 | 53 | namespace mozc { |
59 | 54 | |
60 | #ifdef OS_NACL | |
61 | namespace { | |
62 | Mutex mmap_set_lock; // NOLINT | |
63 | std::set<Mmap *> mmap_set; | |
64 | } // namespace | |
65 | ||
66 | Mmap::Mmap() : write_mode_(false), size_(0) {} | |
67 | ||
68 | bool Mmap::Open(const char *filename, const char *mode) { | |
69 | Close(); | |
70 | ||
71 | if (strcmp(mode, "r") == 0) { | |
72 | write_mode_ = false; | |
73 | } else if (strcmp(mode, "r+") == 0) { | |
74 | write_mode_ = true; | |
75 | } else { | |
76 | LOG(WARNING) << "unknown open mode: " << filename; | |
77 | return false; | |
78 | } | |
79 | InputFileStream ifs(filename); | |
80 | if (!ifs) { | |
81 | LOG(WARNING) << "open failed: " << filename; | |
82 | } | |
83 | // get length of file: | |
84 | ifs.seekg(0, ifs.end); | |
85 | int64 length = ifs.tellg(); | |
86 | ifs.seekg(0, ifs.beg); | |
87 | if (length <= 0) { | |
88 | LOG(WARNING) << "file size = 0: " << filename; | |
89 | return false; | |
90 | } | |
91 | buffer_.reset(new char[length]); | |
92 | ifs.read(buffer_.get(), length); | |
93 | if (!ifs) { | |
94 | LOG(WARNING) << "read failed: " << filename; | |
95 | return false; | |
96 | } | |
97 | ifs.close(); | |
98 | filename_ = filename; | |
99 | size_ = length; | |
100 | if (write_mode_) { | |
101 | scoped_lock lock(&mmap_set_lock); | |
102 | mmap_set.insert(this); | |
103 | } | |
104 | return true; | |
105 | } | |
106 | ||
107 | void Mmap::Close() { | |
108 | if (write_mode_) { | |
109 | { | |
110 | scoped_lock lock(&mmap_set_lock); | |
111 | mmap_set.erase(this); | |
112 | } | |
113 | OutputFileStream ofs; | |
114 | ofs.open(filename_.c_str()); | |
115 | ofs.write(buffer_.get(), size_); | |
116 | ||
117 | if (!ofs) { | |
118 | LOG(WARNING) << "write failed: " << filename_; | |
119 | } | |
120 | } | |
121 | buffer_.reset(); | |
122 | size_ = 0; | |
123 | } | |
124 | ||
125 | bool Mmap::SyncToFile() { | |
126 | if (!write_mode_) { | |
127 | LOG(ERROR) << "Mmap::SyncToFile error. This file is opened in read mode: " | |
128 | << filename_; | |
129 | return false; | |
130 | } | |
131 | OutputFileStream ofs; | |
132 | ofs.open(filename_.c_str()); | |
133 | ofs.write(buffer_.get(), size_); | |
134 | return !!ofs; | |
135 | } | |
136 | ||
137 | bool Mmap::SyncMmapToFile() { | |
138 | scoped_lock lock(&mmap_set_lock); | |
139 | for (Mmap* m : mmap_set) { | |
140 | m->SyncToFile(); | |
141 | } | |
142 | return true; | |
143 | } | |
144 | ||
145 | #elif defined(OS_WIN) // !OS_NACL | |
55 | #if defined(OS_WIN) | |
146 | 56 | |
147 | 57 | Mmap::Mmap() : text_(nullptr), size_(0) {} |
148 | 58 | |
203 | 113 | size_ = 0; |
204 | 114 | } |
205 | 115 | |
206 | #else // !OS_NACL || !OS_WIN | |
116 | #else // !OS_WIN | |
207 | 117 | |
208 | 118 | Mmap::Mmap() : text_(nullptr), size_(0) {} |
209 | 119 | |
276 | 186 | text_ = nullptr; |
277 | 187 | size_ = 0; |
278 | 188 | } |
279 | #endif // !OS_NACL || !OS_WIN | |
189 | #endif // !OS_WIN | |
280 | 190 | |
281 | 191 | // Define a macro (MOZC_HAVE_MLOCK) to indicate mlock support. |
282 | 192 |
34 | 34 | #include "base/mmap_sync_interface.h" |
35 | 35 | #include "base/port.h" |
36 | 36 | |
37 | #ifdef OS_NACL | |
38 | #include <memory> | |
39 | #endif // OS_NACL | |
40 | 37 | |
41 | 38 | namespace mozc { |
42 | 39 | |
43 | 40 | class Mmap : public MmapSyncInterface { |
44 | 41 | public: |
45 | #ifdef OS_NACL | |
46 | // Save the all the mmap data in memory to the file. | |
47 | static bool SyncMmapToFile(); | |
48 | #endif // OS_NACL | |
49 | ||
50 | 42 | Mmap(); |
51 | 43 | ~Mmap() override { Close(); } |
52 | 44 | |
68 | 60 | static int MaybeMLock(const void *addr, size_t len); |
69 | 61 | static int MaybeMUnlock(const void *addr, size_t len); |
70 | 62 | |
71 | #ifdef OS_NACL | |
72 | char &operator[](size_t n) { return *(buffer_.get() + n); } | |
73 | char operator[](size_t n) const { return *(buffer_.get() + n); } | |
74 | char *begin() { return buffer_.get(); } | |
75 | const char *begin() const { return buffer_.get(); } | |
76 | char *end() { return buffer_.get() + size_; } | |
77 | const char *end() const { return buffer_.get() + size_; } | |
78 | #else // !OS_NACL | |
79 | 63 | char &operator[](size_t n) { return *(text_ + n); } |
80 | 64 | char operator[](size_t n) const { return *(text_ + n); } |
81 | 65 | char *begin() { return text_; } |
82 | 66 | const char *begin() const { return text_; } |
83 | 67 | char *end() { return text_ + size_; } |
84 | 68 | const char *end() const { return text_ + size_; } |
85 | #endif // !OS_NACL | |
86 | 69 | |
87 | 70 | size_t size() const { return size_; } |
88 | 71 | |
89 | 72 | private: |
90 | #ifdef OS_NACL | |
91 | bool SyncToFile(); | |
92 | string filename_; | |
93 | std::unique_ptr<char[]> buffer_; | |
94 | bool write_mode_; | |
95 | #else // OS_NACL | |
96 | 73 | char *text_; |
97 | #endif // OS_NACL | |
98 | 74 | size_t size_; |
99 | 75 | |
100 | 76 | DISALLOW_COPY_AND_ASSIGN(Mmap); |
29 | 29 | #ifndef MOZC_BASE_MOZC_HASH_MAP_H_ |
30 | 30 | #define MOZC_BASE_MOZC_HASH_MAP_H_ |
31 | 31 | |
32 | #include <unordered_map> | |
32 | #include "absl/container/flat_hash_map.h" | |
33 | 33 | |
34 | 34 | namespace mozc { |
35 | 35 | |
36 | 36 | template <typename K, typename V, typename Hash = std::hash<K>, |
37 | 37 | typename Eq = std::equal_to<K>, |
38 | 38 | typename Allocator = std::allocator<std::pair<const K, V>>> |
39 | using mozc_hash_map = std::unordered_map<K, V, Hash, Eq, Allocator>; | |
39 | using mozc_hash_map = absl::flat_hash_map<K, V, Hash, Eq, Allocator>; | |
40 | 40 | |
41 | 41 | } // namespace mozc |
42 | 42 |
29 | 29 | #ifndef MOZC_BASE_MOZC_HASH_SET_H_ |
30 | 30 | #define MOZC_BASE_MOZC_HASH_SET_H_ |
31 | 31 | |
32 | #include <unordered_set> | |
32 | #include "absl/container/flat_hash_set.h" | |
33 | 33 | |
34 | 34 | namespace mozc { |
35 | 35 | |
36 | template <typename T, typename Hash = std::hash<T>, | |
37 | typename Eq = std::equal_to<T>, | |
36 | template <typename T, | |
37 | typename Hash = typename absl::flat_hash_set<T>::hasher, | |
38 | typename Eq = typename absl::flat_hash_set<T, Hash>::key_equal, | |
38 | 39 | typename Allocator = std::allocator<T>> |
39 | using mozc_hash_set = std::unordered_set<T, Hash, Eq, Allocator>; | |
40 | using mozc_hash_set = absl::flat_hash_set<T, Hash, Eq, Allocator>; | |
40 | 41 | |
41 | 42 | } // namespace mozc |
42 | 43 |
49 | 49 | #endif // OS_ANDROID |
50 | 50 | |
51 | 51 | #ifdef OS_NACL |
52 | #define MOZC_OS_DEFINED | |
52 | #error "We no longer support NaCl. Still need? Report to b/158959918 ASAP." | |
53 | 53 | #endif // OS_NACL |
54 | 54 | |
55 | 55 | #ifdef OS_LINUX |
202 | 202 | #endif // OS_WIN |
203 | 203 | |
204 | 204 | UserProfileDirectoryImpl::UserProfileDirectoryImpl() { |
205 | #if defined(OS_NACL) || defined(OS_CHROMEOS) | |
205 | #if defined(OS_CHROMEOS) | |
206 | 206 | // TODO(toka): Must use passed in user profile dir which passed in. If mojo |
207 | 207 | // platform the user profile is determined on runtime. |
208 | 208 | // It's hack, the user profile dir should be passed in. Although the value in |
209 | 209 | // NaCL platform is correct. |
210 | 210 | dir_ = "/mutable"; |
211 | 211 | return; |
212 | #endif // OS_NACL || OS_CHROMEOS | |
212 | #endif // OS_CHROMEOS | |
213 | 213 | |
214 | 214 | #if defined(OS_WASM) |
215 | 215 | // Do nothing for WebAssembly. |
445 | 445 | } |
446 | 446 | |
447 | 447 | std::string SystemUtil::GetUserNameAsString() { |
448 | #ifdef OS_NACL | |
449 | LOG(ERROR) << "SystemUtil::GetUserNameAsString() is not implemented in NaCl."; | |
450 | return "username"; | |
451 | #endif // OS_NACL | |
452 | ||
453 | 448 | #if defined(OS_WIN) |
454 | 449 | wchar_t wusername[UNLEN + 1]; |
455 | 450 | DWORD name_size = UNLEN + 1; |
60 | 60 | SystemUtil::IS_WINDOWS_X64_DEFAULT_MODE); |
61 | 61 | } |
62 | 62 | |
63 | #ifndef OS_NACL | |
64 | 63 | TEST_F(SystemUtilTest, GetTotalPhysicalMemoryTest) { |
65 | 64 | EXPECT_GT(SystemUtil::GetTotalPhysicalMemory(), 0); |
66 | 65 | } |
67 | #endif // OS_NACL | |
68 | 66 | |
69 | 67 | #ifdef OS_ANDROID |
70 | 68 | TEST_F(SystemUtilTest, GetOSVersionStringTestForAndroid) { |
140 | 140 | state_->is_running = false; |
141 | 141 | state_->handle.reset(); |
142 | 142 | } else { |
143 | #if defined(OS_NACL) | |
144 | // NaCl doesn't support setname. | |
145 | #elif defined(OS_WASM) | |
146 | // WASM also doesn't support setname? | |
147 | #elif defined(__APPLE__) | |
143 | #if defined(OS_WASM) | |
144 | // WASM doesn't support setname? | |
145 | #elif defined(__APPLE__) // !OS_WASM | |
148 | 146 | pthread_setname_np(thread_name.c_str()); |
149 | #else // !(OS_NACL | __APPLE__) | |
147 | #else // !(OS_WASM | __APPLE__) | |
150 | 148 | pthread_setname_np(*state_->handle, thread_name.c_str()); |
151 | #endif // !(OS_NACL | __APPLE__) | |
149 | #endif // !(OS_WASM | __APPLE__) | |
152 | 150 | } |
153 | 151 | } |
154 | 152 |
49 | 49 | // Does AES256 CBC transformation. |
50 | 50 | // CAVEATS: See the above comment. |
51 | 51 | static void TransformCBC(const uint8 (&key)[kKeyBytes], |
52 | const uint8 (&iv)[kBlockBytes], uint8 *buffer, | |
52 | const uint8 (&iv)[kBlockBytes], uint8 *block, | |
53 | 53 | size_t block_count); |
54 | 54 | |
55 | 55 | // Does AES256 CBC inverse transformation. |
56 | 56 | // CAVEATS: See the above comment. |
57 | 57 | static void InverseTransformCBC(const uint8 (&key)[kKeyBytes], |
58 | const uint8 (&iv)[kBlockBytes], uint8 *buffer, | |
58 | const uint8 (&iv)[kBlockBytes], uint8 *block, | |
59 | 59 | size_t block_count); |
60 | 60 | |
61 | 61 | protected: |
62 | 62 | // Does AES256 ECB transformation. |
63 | 63 | // CAVEATS: See the above comment. |
64 | 64 | static void TransformECB(const uint8 (&w)[kKeyScheduleBytes], |
65 | uint8 buffer[kBlockBytes]); | |
65 | uint8 block[kBlockBytes]); | |
66 | 66 | |
67 | 67 | // Does AES256 ECB inverse transformation. |
68 | 68 | // CAVEATS: See the above comment. |
69 | 69 | static void InverseTransformECB(const uint8 (&w)[kKeyScheduleBytes], |
70 | uint8 buffer[kBlockBytes]); | |
70 | uint8 block[kBlockBytes]); | |
71 | 71 | |
72 | 72 | // Declared as protected for unit test. |
73 | 73 | static void MakeKeySchedule(const uint8 (&key)[kKeyBytes], |
74 | 74 | uint8 w[kKeyScheduleBytes]); |
75 | static void SubBytes(uint8 buf[kBlockBytes]); | |
76 | static void InvSubBytes(uint8 buf[kBlockBytes]); | |
77 | static void MixColumns(uint8 buf[kBlockBytes]); | |
78 | static void InvMixColumns(uint8 buf[kBlockBytes]); | |
79 | static void ShiftRows(uint8 buf[kBlockBytes]); | |
80 | static void InvShiftRows(uint8 buf[kBlockBytes]); | |
75 | static void SubBytes(uint8 block[kBlockBytes]); | |
76 | static void InvSubBytes(uint8 block[kBlockBytes]); | |
77 | static void MixColumns(uint8 block[kBlockBytes]); | |
78 | static void InvMixColumns(uint8 block[kBlockBytes]); | |
79 | static void ShiftRows(uint8 block[kBlockBytes]); | |
80 | static void InvShiftRows(uint8 block[kBlockBytes]); | |
81 | 81 | |
82 | 82 | private: |
83 | 83 | DISALLOW_IMPLICIT_CONSTRUCTORS(UnverifiedAES256); |
42 | 42 | #include <mach/mach_time.h> |
43 | 43 | #endif // __APPLE__ |
44 | 44 | |
45 | #if defined(OS_NACL) | |
46 | #include <irt.h> | |
47 | #endif // OS_NACL | |
48 | ||
49 | 45 | #ifndef OS_WIN |
50 | 46 | #include <sys/mman.h> |
51 | 47 | #include <sys/time.h> |
472 | 468 | return kUTF8LenTbl[*reinterpret_cast<const uint8 *>(src)]; |
473 | 469 | } |
474 | 470 | |
475 | size_t Util::CharsLen(const char *src, size_t length) { | |
471 | size_t Util::CharsLen(const char *src, size_t size) { | |
476 | 472 | const char *begin = src; |
477 | const char *end = src + length; | |
478 | int result = 0; | |
473 | const char *end = src + size; | |
474 | int length = 0; | |
479 | 475 | while (begin < end) { |
480 | ++result; | |
476 | ++length; | |
481 | 477 | begin += OneCharLen(begin); |
482 | 478 | } |
483 | return result; | |
479 | return length; | |
484 | 480 | } |
485 | 481 | |
486 | 482 | char32 Util::UTF8ToUCS4(const char *begin, const char *end, size_t *mblen) { |
841 | 837 | return true; |
842 | 838 | #endif // OS_WIN |
843 | 839 | |
844 | #if defined(OS_NACL) | |
845 | struct nacl_irt_random interface; | |
846 | ||
847 | if (nacl_interface_query(NACL_IRT_RANDOM_v0_1, &interface, | |
848 | sizeof(interface)) != sizeof(interface)) { | |
849 | DLOG(ERROR) << "Cannot get NACL_IRT_RANDOM_v0_1 interface"; | |
850 | return false; | |
851 | } | |
852 | ||
853 | size_t nread; | |
854 | const int error = interface.get_random_bytes(buf, buf_size, &nread); | |
855 | if (error != 0) { | |
856 | LOG(ERROR) << "interface.get_random_bytes error: " << error; | |
857 | return false; | |
858 | } else if (nread != buf_size) { | |
859 | LOG(ERROR) << "interface.get_random_bytes error. nread: " << nread | |
860 | << " buf_size: " << buf_size; | |
861 | return false; | |
862 | } | |
863 | return true; | |
864 | #endif | |
865 | ||
866 | 840 | #if defined(OS_CHROMEOS) |
867 | 841 | // TODO(googleo): b/171939770 Accessing "/dev/urandom" is not allowed in |
868 | 842 | // "ime" sandbox. Returns false to use the self-implemented random number |
1257 | 1231 | } |
1258 | 1232 | } |
1259 | 1233 | |
1260 | void Util::DecodeURI(const std::string &src, std::string *output) { | |
1234 | void Util::DecodeURI(const std::string &input, std::string *output) { | |
1261 | 1235 | output->clear(); |
1262 | const char *p = src.data(); | |
1263 | const char *end = src.data() + src.size(); | |
1236 | const char *p = input.data(); | |
1237 | const char *end = input.data() + input.size(); | |
1264 | 1238 | while (p < end) { |
1265 | 1239 | if (*p == '%' && p + 2 < end) { |
1266 | 1240 | const char h = toupper(p[1]); |
119 | 119 | static void SplitStringToUtf8Chars(absl::string_view str, |
120 | 120 | std::vector<std::string> *output); |
121 | 121 | |
122 | static void SplitCSV(const std::string &str, | |
122 | static void SplitCSV(const std::string &input, | |
123 | 123 | std::vector<std::string> *output); |
124 | 124 | |
125 | 125 | template <typename Range> |
152 | 152 | absl::string_view newsub, bool replace_all, |
153 | 153 | std::string *res); |
154 | 154 | |
155 | static void LowerString(std::string *output); | |
156 | static void UpperString(std::string *output); | |
155 | static void LowerString(std::string *str); | |
156 | static void UpperString(std::string *str); | |
157 | 157 | |
158 | 158 | // Transforms the first character to the upper case and tailing characters to |
159 | 159 | // the lower cases. ex. "abCd" => "Abcd". |
160 | static void CapitalizeString(std::string *output); | |
160 | static void CapitalizeString(std::string *str); | |
161 | 161 | |
162 | 162 | // Returns true if the characters in [first, last) are all in lower case |
163 | 163 | // ASCII. |
182 | 182 | // Strips the leading/trailing white spaces from the input and stores it to |
183 | 183 | // the output. If the input does not have such white spaces, this method just |
184 | 184 | // copies the input into the output. It clears the output always. |
185 | static void StripWhiteSpaces(const std::string &str, std::string *output); | |
185 | static void StripWhiteSpaces(const std::string &input, std::string *output); | |
186 | 186 | |
187 | 187 | static size_t OneCharLen(const char *src); |
188 | 188 | |
189 | // Returns the lengths of [src, src+size] encoded in UTF8. | |
189 | 190 | static size_t CharsLen(const char *src, size_t size); |
190 | 191 | |
191 | 192 | static size_t CharsLen(absl::string_view str) { |
341 | 342 | static bool IsKanaSymbolContained(const std::string &input); |
342 | 343 | |
343 | 344 | // Returns true if |input| looks like a pure English word. |
344 | static bool IsEnglishTransliteration(const std::string &input); | |
345 | static bool IsEnglishTransliteration(const std::string &value); | |
345 | 346 | |
346 | 347 | static void NormalizeVoicedSoundMark(absl::string_view input, |
347 | 348 | std::string *output); |
47 | 47 | namespace mozc { |
48 | 48 | namespace { |
49 | 49 | |
50 | #ifndef OS_NACL | |
51 | // Disabled on NaCl since it uses a mock file system. | |
52 | 50 | void FillTestCharacterSetMap(std::map<char32, Util::CharacterSet> *test_map) { |
53 | 51 | CHECK(test_map); |
54 | 52 | const std::string &path = testing::GetSourceFileOrDie( |
85 | 83 | test_map->insert(std::make_pair(ucs4, itr->second)); |
86 | 84 | } |
87 | 85 | } |
88 | #endif // !OS_NACL | |
89 | 86 | |
90 | 87 | Util::CharacterSet GetExpectedCharacterSet( |
91 | 88 | const std::map<char32, Util::CharacterSet> &test_map, char32 ucs4) { |
1473 | 1470 | EXPECT_EQ(Util::HALF_WIDTH, Util::GetFormType("@!#")); |
1474 | 1471 | } |
1475 | 1472 | |
1476 | #ifndef OS_NACL | |
1477 | 1473 | // We have a snapshot of the result of |Util::GetCharacterSet(ucs4)| in |
1478 | 1474 | // data/test/character_set/character_set.tsv. |
1479 | 1475 | // Compare the result for each character just in case. |
1480 | // | |
1481 | // Disabled on NaCl since it uses a mock file system. | |
1482 | 1476 | TEST(UtilTest, CharacterSetFullTest) { |
1483 | 1477 | std::map<char32, Util::CharacterSet> test_set; |
1484 | 1478 | FillTestCharacterSetMap(&test_set); |
1491 | 1485 | << "Character set changed at " << ucs4; |
1492 | 1486 | } |
1493 | 1487 | } |
1494 | #endif // OS_NACL | |
1495 | 1488 | |
1496 | 1489 | TEST(UtilTest, CharacterSet_gen_character_set) { |
1497 | 1490 | // [0x00, 0x7f] are ASCII |
26 | 26 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 | 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | 28 | |
29 | #ifdef OS_NACL | |
30 | ||
31 | #include "chrome/nacl/dictionary_downloader.h" | |
32 | ||
33 | #include <ppapi/cpp/instance.h> | |
34 | #include <ppapi/utility/completion_callback_factory.h> | |
35 | ||
36 | #include "base/logging.h" | |
37 | #include "base/mutex.h" | |
38 | #include "base/port.h" | |
39 | #include "base/util.h" | |
40 | #include "chrome/nacl/url_loader_util.h" | |
41 | ||
42 | namespace mozc { | |
43 | namespace chrome { | |
44 | namespace nacl { | |
45 | ||
46 | class DictionaryDownloader::Impl { | |
47 | public: | |
48 | Impl(const string &url, const string &file_name, pp::Instance *instance); | |
49 | ~Impl(); | |
50 | void SetOption(uint32 start_delay, uint32 random_delay, uint32 retry_interval, | |
51 | uint32 retry_backoff_count, uint32 max_retry); | |
52 | void StartDownload(); | |
53 | DownloadStatus GetStatus(); | |
54 | ||
55 | private: | |
56 | void SetStatus(DownloadStatus status); | |
57 | void StartDownloadCallback(int32 result); | |
58 | void OnDownloaded(int32 result); | |
59 | const string url_; | |
60 | const string file_name_; | |
61 | pp::Instance *instance_; | |
62 | DownloadStatus status_; | |
63 | uint32 retry_count_; | |
64 | uint32 start_delay_; | |
65 | uint32 random_delay_; | |
66 | uint32 retry_interval_; | |
67 | uint32 retry_backoff_count_; | |
68 | uint32 max_retry_; | |
69 | pp::CompletionCallbackFactory<Impl> callback_factory_; | |
70 | Mutex mutex_; | |
71 | DISALLOW_COPY_AND_ASSIGN(Impl); | |
72 | }; | |
73 | ||
74 | DictionaryDownloader::Impl::Impl(const string &url, const string &file_name, | |
75 | pp::Instance *instance) | |
76 | : url_(url), | |
77 | file_name_(file_name), | |
78 | instance_(instance), | |
79 | status_(DOWNLOAD_INITIALIZED), | |
80 | retry_count_(0), | |
81 | start_delay_(0), | |
82 | random_delay_(0), | |
83 | retry_interval_(0), | |
84 | retry_backoff_count_(0), | |
85 | max_retry_(0) { | |
86 | callback_factory_.Initialize(this); | |
87 | } | |
88 | ||
89 | DictionaryDownloader::Impl::~Impl() {} | |
90 | ||
91 | void DictionaryDownloader::Impl::SetOption(uint32 start_delay, | |
92 | uint32 random_delay, | |
93 | uint32 retry_interval, | |
94 | uint32 retry_backoff_count, | |
95 | uint32 max_retry) { | |
96 | start_delay_ = start_delay; | |
97 | random_delay_ = random_delay; | |
98 | retry_interval_ = retry_interval; | |
99 | retry_backoff_count_ = retry_backoff_count; | |
100 | max_retry_ = max_retry; | |
101 | } | |
102 | ||
103 | void DictionaryDownloader::Impl::StartDownload() { | |
104 | SetStatus(DOWNLOAD_PENDING); | |
105 | const int32 delay = start_delay_ + Util::Random(random_delay_); | |
106 | pp::Module::Get()->core()->CallOnMainThread( | |
107 | delay, callback_factory_.NewCallback( | |
108 | &DictionaryDownloader::Impl::StartDownloadCallback)); | |
109 | } | |
110 | ||
111 | void DictionaryDownloader::Impl::StartDownloadCallback(int32 result) { | |
112 | if (GetStatus() == DOWNLOAD_STARTED) { | |
113 | VLOG(2) << "Currently downloading"; | |
114 | } | |
115 | VLOG(2) << " url_:" << url_; | |
116 | VLOG(2) << " file_name_:" << file_name_; | |
117 | SetStatus(DOWNLOAD_STARTED); | |
118 | URLLoaderUtil::StartDownloadToFile( | |
119 | instance_, url_, file_name_, | |
120 | callback_factory_.NewCallback(&DictionaryDownloader::Impl::OnDownloaded)); | |
121 | } | |
122 | ||
123 | DictionaryDownloader::DownloadStatus DictionaryDownloader::Impl::GetStatus() { | |
124 | scoped_lock l(&mutex_); | |
125 | return status_; | |
126 | } | |
127 | ||
128 | void DictionaryDownloader::Impl::SetStatus( | |
129 | DictionaryDownloader::DownloadStatus status) { | |
130 | scoped_lock l(&mutex_); | |
131 | status_ = status; | |
132 | } | |
133 | ||
134 | void DictionaryDownloader::Impl::OnDownloaded(int32 result) { | |
135 | if (result == PP_OK) { | |
136 | SetStatus(DOWNLOAD_FINISHED); | |
137 | return; | |
138 | } | |
139 | if (retry_count_ >= max_retry_) { | |
140 | SetStatus(DOWNLOAD_ERROR); | |
141 | return; | |
142 | } | |
143 | ++retry_count_; | |
144 | int32 back_off = retry_count_ - 1; | |
145 | if (back_off > retry_backoff_count_) { | |
146 | back_off = retry_backoff_count_; | |
147 | } | |
148 | int32 next_delay = retry_interval_ << back_off; | |
149 | if (random_delay_ != 0) { | |
150 | next_delay += Util::Random(random_delay_); | |
151 | } | |
152 | SetStatus(DOWNLOAD_WAITING_FOR_RETRY); | |
153 | VLOG(2) << " next_delay:" << next_delay; | |
154 | pp::Module::Get()->core()->CallOnMainThread( | |
155 | next_delay, callback_factory_.NewCallback( | |
156 | &DictionaryDownloader::Impl::StartDownloadCallback)); | |
157 | } | |
158 | ||
159 | DictionaryDownloader::DictionaryDownloader(const string &url, | |
160 | const string &file_name, | |
161 | pp::Instance *instance) | |
162 | : impl_(new Impl(url, file_name, instance)) {} | |
163 | ||
164 | DictionaryDownloader::~DictionaryDownloader() {} | |
165 | ||
166 | void DictionaryDownloader::SetOption(uint32 start_delay, uint32 random_delay, | |
167 | uint32 retry_interval, | |
168 | uint32 retry_backoff_count, | |
169 | uint32 max_retry) { | |
170 | impl_->SetOption(start_delay, random_delay, retry_interval, | |
171 | retry_backoff_count, max_retry); | |
172 | } | |
173 | ||
174 | void DictionaryDownloader::StartDownload() { impl_->StartDownload(); } | |
175 | ||
176 | DictionaryDownloader::DownloadStatus DictionaryDownloader::GetStatus() { | |
177 | return impl_->GetStatus(); | |
178 | } | |
179 | ||
180 | } // namespace nacl | |
181 | } // namespace chrome | |
182 | } // namespace mozc | |
183 | ||
184 | #endif // OS_NACL |
29 | 29 | #ifndef MOZC_CHROME_NACL_DICTIONARY_DOWNLOADER_H_ |
30 | 30 | #define MOZC_CHROME_NACL_DICTIONARY_DOWNLOADER_H_ |
31 | 31 | |
32 | #ifdef OS_NACL | |
33 | ||
34 | #include <ppapi/cpp/instance.h> | |
35 | ||
36 | #include <memory> | |
37 | #include <string> | |
38 | ||
39 | #include "base/port.h" | |
40 | ||
41 | namespace mozc { | |
42 | namespace chrome { | |
43 | namespace nacl { | |
44 | ||
45 | class DictionaryDownloader { | |
46 | public: | |
47 | enum DownloadStatus { | |
48 | DOWNLOAD_INITIALIZED, | |
49 | DOWNLOAD_PENDING, | |
50 | DOWNLOAD_STARTED, | |
51 | DOWNLOAD_FINISHED, | |
52 | DOWNLOAD_WAITING_FOR_RETRY, | |
53 | DOWNLOAD_ERROR | |
54 | }; | |
55 | DictionaryDownloader(const string &url, const string &file_name, | |
56 | pp::Instance *instance); | |
57 | ~DictionaryDownloader(); | |
58 | // Sets the options. | |
59 | void SetOption(uint32 start_delay, uint32 random_delay, uint32 retry_interval, | |
60 | uint32 retry_backoff_count, uint32 max_retry); | |
61 | // Downloading will be started after start_delay + [0 - random_delay] msec. | |
62 | // If failed, 1st retry is started after retry_interval + [0 - random_delay]. | |
63 | // While the retry count is less than retry_backoff_count, retry_interval will | |
64 | // be doubled. | |
65 | void StartDownload(); | |
66 | DownloadStatus GetStatus(); | |
67 | ||
68 | private: | |
69 | class Impl; | |
70 | std::unique_ptr<Impl> impl_; | |
71 | DISALLOW_COPY_AND_ASSIGN(DictionaryDownloader); | |
72 | }; | |
73 | ||
74 | } // namespace nacl | |
75 | } // namespace chrome | |
76 | } // namespace mozc | |
77 | ||
78 | #endif // OS_NACL | |
79 | ||
80 | 32 | #endif // MOZC_CHROME_NACL_DICTIONARY_DOWNLOADER_H_ |
28 | 28 | |
29 | 29 | // TODO(horo): write tests. |
30 | 30 | |
31 | #ifdef OS_NACL | |
32 | ||
33 | #include <ppapi/cpp/instance.h> | |
34 | #include <ppapi/cpp/module.h> | |
35 | #include <ppapi/cpp/var.h> | |
36 | #include <ppapi/utility/completion_callback_factory.h> | |
37 | ||
38 | #include <cstring> | |
39 | #include <memory> | |
40 | #include <queue> | |
41 | #include <string> | |
42 | ||
43 | #include "base/clock.h" | |
44 | #include "base/flags.h" | |
45 | #include "base/init_mozc.h" | |
46 | #include "base/logging.h" | |
47 | #include "base/port.h" | |
48 | #include "base/scheduler.h" | |
49 | #include "base/thread.h" | |
50 | #include "base/util.h" | |
51 | #include "base/version.h" | |
52 | #include "chrome/nacl/dictionary_downloader.h" | |
53 | #include "config/config_handler.h" | |
54 | #include "data_manager/data_manager.h" | |
55 | #include "dictionary/user_dictionary_util.h" | |
56 | #include "dictionary/user_pos.h" | |
57 | #include "engine/engine.h" | |
58 | #include "net/http_client.h" | |
59 | #include "net/json_util.h" | |
60 | #include "net/jsoncpp.h" | |
61 | #include "protocol/commands.pb.h" | |
62 | #include "protocol/config.pb.h" | |
63 | #include "session/session_handler.h" | |
64 | #include "session/session_usage_observer.h" | |
65 | #include "usage_stats/usage_stats.h" | |
66 | #include "usage_stats/usage_stats_uploader.h" | |
67 | #include "i18n/input/engine/nacl/impl/blocking_queue.h" | |
68 | #include "i18n/input/engine/nacl/storage_util.h" | |
69 | #include "absl/strings/string_view.h" | |
70 | ||
71 | using mozc::net::JsonUtil; | |
72 | ||
73 | namespace mozc { | |
74 | namespace { | |
75 | ||
76 | using i18n_input::engine::StorageUtil; | |
77 | ||
78 | // TODO(horo): Need to confirm that this 1024 is OK. | |
79 | const uint32 kFileIoFileSystemExpectedSize = 1024; | |
80 | ||
81 | string GetBundleData(absl::string_view file_name) { | |
82 | return file::JoinPath(StorageUtil::kBundledDataDir, file_name); | |
83 | } | |
84 | ||
85 | string GetMutableData(absl::string_view file_name) { | |
86 | return file::JoinPath(StorageUtil::kMutableDataDir, file_name); | |
87 | } | |
88 | } // namespace | |
89 | ||
90 | namespace session { | |
91 | ||
92 | class MozcSessionHandlerThread : public Thread { | |
93 | public: | |
94 | MozcSessionHandlerThread(pp::Instance *instance, | |
95 | BlockingQueue<Json::Value *> *queue) | |
96 | : instance_(instance), message_queue_(queue), factory_(this) {} | |
97 | ||
98 | ~MozcSessionHandlerThread() override = default; | |
99 | ||
100 | void Run() override { | |
101 | Util::SetRandomSeed(static_cast<uint32>(Clock::GetTime())); | |
102 | std::unique_ptr<DataManager> data_manager; | |
103 | #ifdef GOOGLE_JAPANESE_INPUT_BUILD | |
104 | data_manager_status_ = DataManager::Status::UNKNOWN; | |
105 | const bool filesystem_available = | |
106 | StorageUtil::Initialize(instance_, kFileIoFileSystemExpectedSize); | |
107 | if (!filesystem_available) { | |
108 | // Mutable file system is not available, so ignore the big dictionary and | |
109 | // use the small dictionary. | |
110 | data_manager = LoadDictionary(&data_manager_model_data_buffer_); | |
111 | } else { | |
112 | data_manager = LoadBigDictionary(&data_manager_status_); | |
113 | if (data_manager_status_ != DataManager::Status::OK) { | |
114 | LOG_IF(ERROR, data_manager_status_ != DataManager::Status::MMAP_FAILURE) | |
115 | << "Failed to load big dictionary: " | |
116 | << DataManager::StatusCodeToString(data_manager_status_); | |
117 | LOG(INFO) << "Big dictionary is to be downloaded"; | |
118 | StartDownloadDictionary(); | |
119 | data_manager = LoadDictionary(&data_manager_model_data_buffer_); | |
120 | } | |
121 | } | |
122 | #else // GOOGLE_JAPANESE_INPUT_BUILD | |
123 | data_manager = LoadDictionary(&data_manager_model_data_buffer_); | |
124 | #endif // GOOGLE_JAPANESE_INPUT_BUILD | |
125 | CHECK(data_manager) | |
126 | << "Unexpected failure: Data manager shoulnd't be nullptr"; | |
127 | ||
128 | user_pos_.reset(dictionary::UserPOS::CreateFromDataManager(*data_manager)); | |
129 | handler_.reset(new SessionHandler( | |
130 | mozc::Engine::CreateDesktopEngine(std::move(data_manager)).value())); | |
131 | ||
132 | #ifdef GOOGLE_JAPANESE_INPUT_BUILD | |
133 | usage_observer_.reset(new SessionUsageObserver()); | |
134 | handler_->AddObserver(usage_observer_.get()); | |
135 | #endif // GOOGLE_JAPANESE_INPUT_BUILD | |
136 | ||
137 | // Gets the current config. | |
138 | config::Config config; | |
139 | config::ConfigHandler::GetStoredConfig(&config); | |
140 | // Sends "InitializeDone" message to JavaScript side code. | |
141 | Json::Value message(Json::objectValue); | |
142 | message["event"] = Json::objectValue; | |
143 | message["event"]["type"] = "InitializeDone"; | |
144 | JsonUtil::ProtobufMessageToJsonValue(config, &message["event"]["config"]); | |
145 | message["event"]["version"] = Version::GetMozcVersion(); | |
146 | message["event"]["data_version"] = | |
147 | string(handler_->engine().GetDataVersion()); | |
148 | ||
149 | pp::Module::Get()->core()->CallOnMainThread( | |
150 | 0, factory_.NewCallback(&MozcSessionHandlerThread::PostMessage, | |
151 | Json::FastWriter().write(message))); | |
152 | while (true) { | |
153 | std::unique_ptr<Json::Value> message; | |
154 | message.reset(message_queue_->take()); | |
155 | if (!message->isMember("id") || | |
156 | (!message->isMember("cmd") && !message->isMember("event"))) { | |
157 | LOG(ERROR) << "request error"; | |
158 | continue; | |
159 | } | |
160 | Json::Value response(Json::objectValue); | |
161 | response["id"] = (*message)["id"]; | |
162 | if (message->isMember("cmd")) { | |
163 | commands::Command command; | |
164 | JsonUtil::JsonValueToProtobufMessage((*message)["cmd"], &command); | |
165 | handler_->EvalCommand(&command); | |
166 | JsonUtil::ProtobufMessageToJsonValue(command, &response["cmd"]); | |
167 | } | |
168 | if (message->isMember("event") && (*message)["event"].isMember("type")) { | |
169 | response["event"] = Json::objectValue; | |
170 | const string event_type = (*message)["event"]["type"].asString(); | |
171 | response["event"]["type"] = event_type; | |
172 | if (event_type == "SyncToFile") { | |
173 | response["event"]["result"] = true; | |
174 | } else if (event_type == "GetVersionInfo") { | |
175 | response["event"]["version"] = Version::GetMozcVersion(); | |
176 | response["event"]["data_version"] = | |
177 | string(handler_->engine().GetDataVersion()); | |
178 | #ifdef GOOGLE_JAPANESE_INPUT_BUILD | |
179 | response["event"]["big_dictionary_state"] = GetBigDictionaryState(); | |
180 | #endif // GOOGLE_JAPANESE_INPUT_BUILD | |
181 | } else if (event_type == "GetPosList") { | |
182 | GetPosList(&response); | |
183 | } else if (event_type == "IsValidReading") { | |
184 | IsValidReading((*message)["event"], &response); | |
185 | } else { | |
186 | response["event"]["error"] = "Unsupported event"; | |
187 | } | |
188 | } | |
189 | ||
190 | pp::Module::Get()->core()->CallOnMainThread( | |
191 | 0, factory_.NewCallback(&MozcSessionHandlerThread::PostMessage, | |
192 | Json::FastWriter().write(response))); | |
193 | } | |
194 | } | |
195 | ||
196 | void PostMessage(int32_t result, const string &message) { | |
197 | instance_->PostMessage(message); | |
198 | } | |
199 | ||
200 | private: | |
201 | #ifdef GOOGLE_JAPANESE_INPUT_BUILD | |
202 | // Loads the big dictionary | |
203 | // Returns true and sets the dictionary version if successful. | |
204 | static std::unique_ptr<DataManager> LoadBigDictionary( | |
205 | DataManager::Status *status) { | |
206 | std::unique_ptr<DataManager> data_manager(new DataManager()); | |
207 | // The big dictionary data is in the user's HTML5 file system. | |
208 | *status = data_manager->InitFromFile(GetMutableData("mozc.data")); | |
209 | return data_manager; | |
210 | } | |
211 | ||
212 | // Starts downloading the big dictionary. | |
213 | void StartDownloadDictionary() { | |
214 | downloader_.reset(new chrome::nacl::DictionaryDownloader( | |
215 | Version::GetMozcNaclDictionaryUrl(), GetMutableData("mozc.data"), | |
216 | instance_)); | |
217 | downloader_->SetOption(10 * 60 * 1000, // 10 minutes start delay | |
218 | 20 * 60 * 1000, // + [0-20] minutes random delay | |
219 | 30 * 60 * 1000, // retry_interval 30 min | |
220 | 4, // retry interval [30, 60, 120, 240, 240, 240...] | |
221 | 10); // 10 retries | |
222 | downloader_->StartDownload(); | |
223 | } | |
224 | #endif // GOOGLE_JAPANESE_INPUT_BUILD | |
225 | ||
226 | // Loads the dictionary. | |
227 | static std::unique_ptr<DataManager> LoadDictionary( | |
228 | std::unique_ptr<uint64[]> *data_buffer) { | |
229 | HTTPClient::Option option; | |
230 | option.timeout = 200000; | |
231 | option.max_data_size = 100 * 1024 * 1024; // 100MB | |
232 | // System dictionary data is in the user's Extensions directory. | |
233 | const string data_file_name = GetBundleData("zipped_data_chromeos"); | |
234 | string file_content; | |
235 | CHECK(i18n_input::engine::StorageUtil::LoadContent(data_file_name, | |
236 | &file_content)) | |
237 | << "Failed to read the content of " << data_file_name; | |
238 | ||
239 | // Align the data image at 64 bit boundary. | |
240 | const size_t u64_buf_size = (file_content.size() + 7) / 8; | |
241 | data_buffer->reset(new uint64[u64_buf_size]); | |
242 | memcpy(data_buffer->get(), file_content.data(), file_content.size()); | |
243 | const absl::string_view data( | |
244 | reinterpret_cast<const char *>(data_buffer->get()), | |
245 | file_content.size()); | |
246 | std::unique_ptr<DataManager> data_manager(new mozc::DataManager()); | |
247 | const DataManager::Status status = data_manager->InitFromArray(data); | |
248 | CHECK_EQ(status, DataManager::Status::OK) | |
249 | << "Failed to load " << data_file_name << ": " | |
250 | << DataManager::StatusCodeToString(status); | |
251 | return data_manager; | |
252 | } | |
253 | ||
254 | #ifdef GOOGLE_JAPANESE_INPUT_BUILD | |
255 | // Returns BigDictionaryState | |
256 | // 0x00: Correct version of BigDictionary is found. | |
257 | // 0x1-: BigDictionary is not found. | |
258 | // 0x2-: BigDictionary version mismatch. | |
259 | // 0x3-: BigDictionary misses some data. | |
260 | // 0x4-: BigDictionary is broken. | |
261 | // 0x5-: Unknown error. | |
262 | // 0x-*: Status of the downloader. | |
263 | int GetBigDictionaryState() { | |
264 | int status = 0x00; | |
265 | switch (data_manager_status_) { | |
266 | case DataManager::Status::OK: | |
267 | return 0x00; | |
268 | case DataManager::Status::MMAP_FAILURE: | |
269 | status = 0x10; | |
270 | break; | |
271 | case DataManager::Status::ENGINE_VERSION_MISMATCH: | |
272 | status = 0x20; | |
273 | break; | |
274 | case DataManager::Status::DATA_MISSING: | |
275 | status = 0x30; | |
276 | break; | |
277 | case DataManager::Status::DATA_BROKEN: | |
278 | status = 0x40; | |
279 | break; | |
280 | default: | |
281 | status = 0x50; | |
282 | break; | |
283 | } | |
284 | if (downloader_.get()) { | |
285 | status += downloader_->GetStatus(); | |
286 | } | |
287 | return status; | |
288 | } | |
289 | ||
290 | static bool SendUsageStats(void *data) { | |
291 | MozcSessionHandlerThread *self = | |
292 | static_cast<MozcSessionHandlerThread *>(data); | |
293 | usage_stats::UsageStats::SetInteger("BigDictionaryState", | |
294 | self->GetBigDictionaryState()); | |
295 | return usage_stats::UsageStatsUploader::Send(nullptr); | |
296 | } | |
297 | #endif // GOOGLE_JAPANESE_INPUT_BUILD | |
298 | ||
299 | void GetPosList(Json::Value *response) { | |
300 | (*response)["event"]["posList"] = Json::Value(Json::arrayValue); | |
301 | Json::Value *pos_list = &(*response)["event"]["posList"]; | |
302 | std::vector<string> tmp_pos_vec; | |
303 | user_pos_->GetPOSList(&tmp_pos_vec); | |
304 | for (int i = 0; i < tmp_pos_vec.size(); ++i) { | |
305 | (*pos_list)[i] = Json::Value(Json::objectValue); | |
306 | const user_dictionary::UserDictionary::PosType pos_type = | |
307 | UserDictionaryUtil::ToPosType(tmp_pos_vec[i].c_str()); | |
308 | (*pos_list)[i]["type"] = | |
309 | Json::Value(user_dictionary::UserDictionary::PosType_Name(pos_type)); | |
310 | (*pos_list)[i]["name"] = Json::Value(tmp_pos_vec[i]); | |
311 | } | |
312 | } | |
313 | ||
314 | void IsValidReading(const Json::Value &event, Json::Value *response) { | |
315 | if (!event.isMember("data")) { | |
316 | (*response)["event"]["result"] = false; | |
317 | return; | |
318 | } | |
319 | (*response)["event"]["data"] = event["data"].asString(); | |
320 | (*response)["event"]["result"] = | |
321 | UserDictionaryUtil::IsValidReading(event["data"].asString()); | |
322 | } | |
323 | ||
324 | pp::Instance *instance_; | |
325 | BlockingQueue<Json::Value *> *message_queue_; | |
326 | pp::CompletionCallbackFactory<MozcSessionHandlerThread> factory_; | |
327 | std::unique_ptr<SessionHandler> handler_; | |
328 | std::unique_ptr<const UserPOSInterface> user_pos_; | |
329 | std::unique_ptr<uint64[]> data_manager_model_data_buffer_; | |
330 | #ifdef GOOGLE_JAPANESE_INPUT_BUILD | |
331 | std::unique_ptr<SessionUsageObserver> usage_observer_; | |
332 | std::unique_ptr<chrome::nacl::DictionaryDownloader> downloader_; | |
333 | DataManager::Status data_manager_status_; | |
334 | #endif // GOOGLE_JAPANESE_INPUT_BUILD | |
335 | DISALLOW_COPY_AND_ASSIGN(MozcSessionHandlerThread); | |
336 | }; | |
337 | ||
338 | class NaclSessionHandlerInstance : public pp::Instance { | |
339 | public: | |
340 | explicit NaclSessionHandlerInstance(PP_Instance instance); | |
341 | virtual ~NaclSessionHandlerInstance() {} | |
342 | virtual void HandleMessage(const pp::Var &var_message); | |
343 | ||
344 | private: | |
345 | void CheckStatusAndStartMozcSessionHandlerThread(); | |
346 | ||
347 | std::unique_ptr<MozcSessionHandlerThread> mozc_thread_; | |
348 | BlockingQueue<Json::Value *> message_queue_; | |
349 | ||
350 | DISALLOW_COPY_AND_ASSIGN(NaclSessionHandlerInstance); | |
351 | }; | |
352 | ||
353 | NaclSessionHandlerInstance::NaclSessionHandlerInstance(PP_Instance instance) | |
354 | : pp::Instance(instance) { | |
355 | mozc_thread_.reset(new MozcSessionHandlerThread(this, &message_queue_)); | |
356 | mozc_thread_->Start("NaclSessionHandler"); | |
357 | } | |
358 | ||
359 | void NaclSessionHandlerInstance::HandleMessage(const pp::Var &var_message) { | |
360 | if (!var_message.is_string()) { | |
361 | return; | |
362 | } | |
363 | ||
364 | std::unique_ptr<Json::Value> message(new Json::Value); | |
365 | if (Json::Reader().parse(var_message.AsString(), *message.get())) { | |
366 | message_queue_.put(message.release()); | |
367 | } | |
368 | } | |
369 | ||
370 | class NaclSessionHandlerModule : public pp::Module { | |
371 | public: | |
372 | NaclSessionHandlerModule() : pp::Module() {} | |
373 | virtual ~NaclSessionHandlerModule() {} | |
374 | ||
375 | protected: | |
376 | virtual pp::Instance *CreateInstance(PP_Instance instance) { | |
377 | return new NaclSessionHandlerInstance(instance); | |
378 | } | |
379 | ||
380 | private: | |
381 | DISALLOW_COPY_AND_ASSIGN(NaclSessionHandlerModule); | |
382 | }; | |
383 | ||
384 | } // namespace session | |
385 | } // namespace mozc | |
386 | ||
387 | namespace pp { | |
388 | ||
389 | Module *CreateModule() { | |
390 | // We use dummy argc and argv to call mozc::InitMozc(). | |
391 | int argc = 1; | |
392 | char argv0[] = "NaclModule"; | |
393 | char *argv_body[] = {argv0, nullptr}; | |
394 | char **argv = argv_body; | |
395 | mozc::InitMozc(argv[0], &argc, &argv); | |
396 | ||
397 | return new mozc::session::NaclSessionHandlerModule(); | |
398 | } | |
399 | ||
400 | } // namespace pp | |
401 | ||
402 | #endif // OS_NACL |
26 | 26 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 | 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | 28 | |
29 | #ifdef OS_NACL | |
30 | ||
31 | #include "chrome/nacl/url_loader_util.h" | |
32 | ||
33 | #include <algorithm> | |
34 | #include <memory> | |
35 | ||
36 | #include <ppapi/c/pp_file_info.h> | |
37 | #include <ppapi/c/ppb_file_io.h> | |
38 | #include <ppapi/cpp/file_io.h> | |
39 | #include <ppapi/cpp/file_ref.h> | |
40 | #include <ppapi/cpp/file_system.h> | |
41 | #include <ppapi/cpp/instance.h> | |
42 | #include <ppapi/cpp/url_loader.h> | |
43 | #include <ppapi/cpp/url_request_info.h> | |
44 | #include <ppapi/cpp/url_response_info.h> | |
45 | #include <ppapi/utility/completion_callback_factory.h> | |
46 | ||
47 | #include "base/logging.h" | |
48 | #include "base/port.h" | |
49 | ||
50 | using std::unique_ptr; | |
51 | ||
52 | namespace mozc { | |
53 | namespace chrome { | |
54 | namespace nacl { | |
55 | ||
56 | namespace { | |
57 | const int32_t kReadBufferSize = 32768; | |
58 | ||
59 | class URLLoaderStreamToFileHandler { | |
60 | public: | |
61 | URLLoaderStreamToFileHandler(pp::Instance *instance, const string &url, | |
62 | const string &file_name, | |
63 | pp::CompletionCallback callback); | |
64 | void Start(); | |
65 | ||
66 | private: | |
67 | // "delete this" is called in URLLoaderStreamToFileHandler::Complete(). | |
68 | ~URLLoaderStreamToFileHandler(); | |
69 | void StartImpl(int32_t result); | |
70 | void OnOpen(int32 result); | |
71 | void OnStreamComplete(int32 result); | |
72 | void OnInputFileOpen(int32_t result); | |
73 | void OnInputFileQuery(int32_t result); | |
74 | void OnFileSystemOpen(int32_t result); | |
75 | void OnDeleteOutputFile(int32_t result); | |
76 | void OnOutputFileOpen(int32_t result); | |
77 | void OnInputFileRead(int32_t bytes_read); | |
78 | void OnOutputFileWrite(int32_t bytes_written); | |
79 | void OnOutputFileFlush(int32_t result); | |
80 | void Complete(bool result); | |
81 | ||
82 | pp::Instance *instance_; | |
83 | const string url_; | |
84 | const string file_name_; | |
85 | pp::CompletionCallback callback_; | |
86 | unique_ptr<pp::URLRequestInfo> url_request_; | |
87 | unique_ptr<pp::URLLoader> url_loader_; | |
88 | pp::URLResponseInfo url_response_; | |
89 | pp::FileRef body_file_ref_; | |
90 | pp::CompletionCallbackFactory<URLLoaderStreamToFileHandler> callback_factory_; | |
91 | unique_ptr<pp::FileSystem> file_system_; | |
92 | unique_ptr<pp::FileRef> output_file_ref_; | |
93 | unique_ptr<pp::FileIO> output_file_io_; | |
94 | unique_ptr<pp::FileIO> input_file_io_; | |
95 | PP_FileInfo input_file_info_; | |
96 | int64_t total_read_bytes_; | |
97 | int64_t total_written_bytes_; | |
98 | int64_t buffer_written_bytes_; | |
99 | unique_ptr<char[]> tmp_buffer_; | |
100 | ||
101 | DISALLOW_COPY_AND_ASSIGN(URLLoaderStreamToFileHandler); | |
102 | }; | |
103 | ||
104 | URLLoaderStreamToFileHandler::URLLoaderStreamToFileHandler( | |
105 | pp::Instance *instance, const string &url, const string &file_name, | |
106 | pp::CompletionCallback callback) | |
107 | : instance_(instance), | |
108 | url_(url), | |
109 | file_name_(file_name), | |
110 | callback_(callback), | |
111 | total_read_bytes_(0), | |
112 | total_written_bytes_(0), | |
113 | buffer_written_bytes_(0) {} | |
114 | ||
115 | URLLoaderStreamToFileHandler::~URLLoaderStreamToFileHandler() {} | |
116 | ||
117 | void URLLoaderStreamToFileHandler::Start() { | |
118 | callback_factory_.Initialize(this); | |
119 | if (pp::Module::Get()->core()->IsMainThread()) { | |
120 | StartImpl(0); | |
121 | return; | |
122 | } | |
123 | pp::Module::Get()->core()->CallOnMainThread( | |
124 | 0, | |
125 | callback_factory_.NewCallback(&URLLoaderStreamToFileHandler::StartImpl)); | |
126 | } | |
127 | ||
128 | void URLLoaderStreamToFileHandler::StartImpl(int32_t result) { | |
129 | CHECK(pp::Module::Get()->core()->IsMainThread()); | |
130 | CHECK(!url_request_.get()); | |
131 | CHECK(!url_loader_.get()); | |
132 | url_request_.reset(new pp::URLRequestInfo(instance_)); | |
133 | url_loader_.reset(new pp::URLLoader(instance_)); | |
134 | url_request_->SetAllowCrossOriginRequests(true); | |
135 | url_request_->SetURL(url_); | |
136 | url_request_->SetMethod("GET"); | |
137 | url_request_->SetStreamToFile(true); | |
138 | url_loader_->Open(*url_request_, callback_factory_.NewCallback( | |
139 | &URLLoaderStreamToFileHandler::OnOpen)); | |
140 | } | |
141 | ||
142 | void URLLoaderStreamToFileHandler::OnOpen(int32 result) { | |
143 | if (result != PP_OK) { | |
144 | DLOG(ERROR) << "URLLoaderStreamToFileHandler::OnOpen error"; | |
145 | Complete(false); | |
146 | return; | |
147 | } | |
148 | const pp::URLResponseInfo response = url_loader_->GetResponseInfo(); | |
149 | if (response.GetStatusCode() != 200) { | |
150 | DLOG(ERROR) << "pp::URLLoader::Open() failed: " << url_ | |
151 | << " Status code: " << response.GetStatusCode(); | |
152 | Complete(false); | |
153 | return; | |
154 | } | |
155 | url_loader_->FinishStreamingToFile(callback_factory_.NewCallback( | |
156 | &URLLoaderStreamToFileHandler::OnStreamComplete)); | |
157 | url_response_ = url_loader_->GetResponseInfo(); | |
158 | body_file_ref_ = url_response_.GetBodyAsFileRef(); | |
159 | } | |
160 | ||
161 | void URLLoaderStreamToFileHandler::OnStreamComplete(int32 result) { | |
162 | if (result != PP_OK) { | |
163 | DLOG(ERROR) << "URLLoaderStreamToFileHandler::OnStreamComplete error"; | |
164 | Complete(false); | |
165 | return; | |
166 | } | |
167 | input_file_io_.reset(new pp::FileIO(instance_)); | |
168 | const int32_t ret = | |
169 | input_file_io_->Open(body_file_ref_, PP_FILEOPENFLAG_READ, | |
170 | callback_factory_.NewCallback( | |
171 | &URLLoaderStreamToFileHandler::OnInputFileOpen)); | |
172 | if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) { | |
173 | DLOG(ERROR) << "input_file_io_->Open error"; | |
174 | Complete(false); | |
175 | return; | |
176 | } | |
177 | } | |
178 | ||
179 | void URLLoaderStreamToFileHandler::OnInputFileOpen(int32_t result) { | |
180 | if (result != PP_OK) { | |
181 | DLOG(ERROR) << "URLLoaderStreamToFileHandler::OnInputFileOpen error"; | |
182 | Complete(false); | |
183 | return; | |
184 | } | |
185 | const int32_t ret = input_file_io_->Query( | |
186 | &input_file_info_, callback_factory_.NewCallback( | |
187 | &URLLoaderStreamToFileHandler::OnInputFileQuery)); | |
188 | if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) { | |
189 | DLOG(ERROR) << "input_file_io_->Query error"; | |
190 | Complete(false); | |
191 | return; | |
192 | } | |
193 | } | |
194 | void URLLoaderStreamToFileHandler::OnInputFileQuery(int32_t result) { | |
195 | if (result != PP_OK) { | |
196 | DLOG(ERROR) << "URLLoaderStreamToFileHandler::OnInputFileQuery error"; | |
197 | Complete(false); | |
198 | return; | |
199 | } | |
200 | file_system_.reset( | |
201 | new pp::FileSystem(instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT)); | |
202 | const int32_t ret = | |
203 | file_system_->Open(input_file_info_.size, | |
204 | callback_factory_.NewCallback( | |
205 | &URLLoaderStreamToFileHandler::OnFileSystemOpen)); | |
206 | if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) { | |
207 | DLOG(ERROR) << "file_system_->Open error"; | |
208 | Complete(false); | |
209 | return; | |
210 | } | |
211 | } | |
212 | ||
213 | void URLLoaderStreamToFileHandler::OnFileSystemOpen(int32_t result) { | |
214 | if (result != PP_OK) { | |
215 | DLOG(ERROR) << "URLLoaderStreamToFileHandler::OnFileSystemOpen error"; | |
216 | Complete(false); | |
217 | return; | |
218 | } | |
219 | output_file_ref_.reset(new pp::FileRef(*file_system_, file_name_.c_str())); | |
220 | const int32_t ret = output_file_ref_->Delete(callback_factory_.NewCallback( | |
221 | &URLLoaderStreamToFileHandler::OnDeleteOutputFile)); | |
222 | if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) { | |
223 | DLOG(ERROR) << "output_file_ref_->Delete error"; | |
224 | Complete(false); | |
225 | return; | |
226 | } | |
227 | } | |
228 | ||
229 | void URLLoaderStreamToFileHandler::OnDeleteOutputFile(int32_t result) { | |
230 | output_file_io_.reset(new pp::FileIO(instance_)); | |
231 | const int32_t ret = output_file_io_->Open( | |
232 | *output_file_ref_, PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE, | |
233 | callback_factory_.NewCallback( | |
234 | &URLLoaderStreamToFileHandler::OnOutputFileOpen)); | |
235 | if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) { | |
236 | DLOG(ERROR) << "output_file_io_->Open error"; | |
237 | Complete(false); | |
238 | return; | |
239 | } | |
240 | } | |
241 | ||
242 | void URLLoaderStreamToFileHandler::OnOutputFileOpen(int32_t result) { | |
243 | if (result != PP_OK) { | |
244 | DLOG(ERROR) << "URLLoaderStreamToFileHandler::OnOutputFileOpen error"; | |
245 | Complete(false); | |
246 | return; | |
247 | } | |
248 | tmp_buffer_.reset(new char[kReadBufferSize]); | |
249 | OnInputFileRead(0); | |
250 | } | |
251 | ||
252 | void URLLoaderStreamToFileHandler::OnInputFileRead(int32_t bytes_read) { | |
253 | if (bytes_read < 0) { | |
254 | DLOG(ERROR) << "URLLoaderStreamToFileHandler::OnInputFileRead error"; | |
255 | Complete(false); | |
256 | return; | |
257 | } | |
258 | total_read_bytes_ += bytes_read; | |
259 | if (bytes_read == 0) { | |
260 | const int32_t ret = input_file_io_->Read( | |
261 | total_read_bytes_, tmp_buffer_.get(), | |
262 | std::min(kReadBufferSize, static_cast<int32_t>(input_file_info_.size - | |
263 | total_read_bytes_)), | |
264 | callback_factory_.NewCallback( | |
265 | &URLLoaderStreamToFileHandler::OnInputFileRead)); | |
266 | if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) { | |
267 | DLOG(ERROR) << "input_file_io_->Read error"; | |
268 | Complete(false); | |
269 | return; | |
270 | } | |
271 | } else { | |
272 | buffer_written_bytes_ = 0; | |
273 | const int32_t ret = output_file_io_->Write( | |
274 | total_written_bytes_, tmp_buffer_.get(), bytes_read, | |
275 | callback_factory_.NewCallback( | |
276 | &URLLoaderStreamToFileHandler::OnOutputFileWrite)); | |
277 | if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) { | |
278 | DLOG(ERROR) << "output_file_io_->Write error"; | |
279 | Complete(false); | |
280 | return; | |
281 | } | |
282 | } | |
283 | } | |
284 | ||
285 | void URLLoaderStreamToFileHandler::OnOutputFileWrite(int32_t bytes_written) { | |
286 | if (bytes_written < 0) { | |
287 | DLOG(ERROR) << "URLLoaderStreamToFileHandler::OnOutputFileWrite error"; | |
288 | Complete(false); | |
289 | return; | |
290 | } | |
291 | total_written_bytes_ += bytes_written; | |
292 | buffer_written_bytes_ += bytes_written; | |
293 | if (total_read_bytes_ == total_written_bytes_) { | |
294 | if (total_read_bytes_ == input_file_info_.size) { | |
295 | // Finish writing | |
296 | const int32_t ret = output_file_io_->Flush(callback_factory_.NewCallback( | |
297 | &URLLoaderStreamToFileHandler::OnOutputFileFlush)); | |
298 | if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) { | |
299 | DLOG(ERROR) << "output_file_io_->Flush error"; | |
300 | Complete(false); | |
301 | return; | |
302 | } | |
303 | } else { | |
304 | // Read more | |
305 | const int32_t ret = input_file_io_->Read( | |
306 | total_read_bytes_, tmp_buffer_.get(), | |
307 | std::min(kReadBufferSize, static_cast<int32_t>(input_file_info_.size - | |
308 | total_read_bytes_)), | |
309 | callback_factory_.NewCallback( | |
310 | &URLLoaderStreamToFileHandler::OnInputFileRead)); | |
311 | if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) { | |
312 | DLOG(ERROR) << "input_file_io_->Read error"; | |
313 | Complete(false); | |
314 | return; | |
315 | } | |
316 | } | |
317 | } else { | |
318 | // Writes more | |
319 | const int32_t ret = output_file_io_->Write( | |
320 | total_written_bytes_, &tmp_buffer_[buffer_written_bytes_], | |
321 | total_read_bytes_ - total_written_bytes_, | |
322 | callback_factory_.NewCallback( | |
323 | &URLLoaderStreamToFileHandler::OnOutputFileWrite)); | |
324 | if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) { | |
325 | DLOG(ERROR) << "output_file_io_->Write error"; | |
326 | Complete(false); | |
327 | return; | |
328 | } | |
329 | } | |
330 | } | |
331 | ||
332 | void URLLoaderStreamToFileHandler::OnOutputFileFlush(int32_t result) { | |
333 | if (result != PP_OK) { | |
334 | DLOG(ERROR) << "URLLoaderStreamToFileHandler::OnOutputFileFlush error"; | |
335 | Complete(false); | |
336 | return; | |
337 | } | |
338 | Complete(true); | |
339 | } | |
340 | ||
341 | void URLLoaderStreamToFileHandler::Complete(bool result) { | |
342 | callback_.Run(result ? PP_OK : PP_ERROR_FAILED); | |
343 | delete this; | |
344 | } | |
345 | ||
346 | } // namespace | |
347 | ||
348 | void URLLoaderUtil::StartDownloadToFile(pp::Instance *instance, | |
349 | const string &url, | |
350 | const string &file_name, | |
351 | pp::CompletionCallback callback) { | |
352 | URLLoaderStreamToFileHandler *handler = | |
353 | new URLLoaderStreamToFileHandler(instance, url, file_name, callback); | |
354 | DCHECK(handler); | |
355 | handler->Start(); | |
356 | } | |
357 | ||
358 | } // namespace nacl | |
359 | } // namespace chrome | |
360 | } // namespace mozc | |
361 | ||
362 | #endif // OS_NACL |
29 | 29 | #ifndef MOZC_CHROME_NACL_URL_LOADER_UTIL_H_ |
30 | 30 | #define MOZC_CHROME_NACL_URL_LOADER_UTIL_H_ |
31 | 31 | |
32 | #ifdef OS_NACL | |
33 | ||
34 | #include <ppapi/cpp/completion_callback.h> | |
35 | ||
36 | #include <string> | |
37 | ||
38 | #include "base/port.h" | |
39 | ||
40 | namespace pp { | |
41 | class Instance; | |
42 | } // namespace pp | |
43 | ||
44 | namespace mozc { | |
45 | namespace chrome { | |
46 | namespace nacl { | |
47 | ||
48 | // Utility class to handle pp::URLLoader. | |
49 | class URLLoaderUtil { | |
50 | public: | |
51 | // Downloads the file from url to file_name on HTML5 filesystem. | |
52 | static void StartDownloadToFile(pp::Instance *instance, const string &url, | |
53 | const string &file_name, | |
54 | pp::CompletionCallback callback); | |
55 | ||
56 | private: | |
57 | DISALLOW_IMPLICIT_CONSTRUCTORS(URLLoaderUtil); | |
58 | }; | |
59 | ||
60 | } // namespace nacl | |
61 | } // namespace chrome | |
62 | } // namespace mozc | |
63 | ||
64 | #endif // OS_NACL | |
65 | ||
66 | 32 | #endif // MOZC_CHROME_NACL_URL_LOADER_UTIL_H_ |
123 | 123 | "//base:init_mozc", |
124 | 124 | "//base:logging", |
125 | 125 | "//base:process", |
126 | "@com_google_absl//absl/flags:flag", | |
126 | 127 | ], |
127 | 128 | ) |
128 | 129 | |
141 | 142 | "//protocol:renderer_proto", |
142 | 143 | "//renderer:renderer_client", |
143 | 144 | "//session:random_keyevents_generator", |
145 | "@com_google_absl//absl/flags:flag", | |
144 | 146 | ], |
145 | 147 | ) |
146 | 148 | |
162 | 164 | "//protocol:commands_proto", |
163 | 165 | "//protocol:renderer_proto", |
164 | 166 | "//renderer:renderer_client", |
167 | "@com_google_absl//absl/flags:flag", | |
165 | 168 | "@com_google_absl//absl/strings", |
166 | 169 | ], |
167 | 170 | ) |
184 | 187 | "//config:config_handler", |
185 | 188 | "//protocol:commands_proto", |
186 | 189 | "//session:random_keyevents_generator", |
190 | "@com_google_absl//absl/flags:flag", | |
187 | 191 | ], |
188 | 192 | ) |
189 | 193 | |
232 | 236 | "//base:util", |
233 | 237 | "//evaluation:scorer", |
234 | 238 | "//protocol:commands_proto", |
239 | "@com_google_absl//absl/flags:flag", | |
235 | 240 | "@com_google_absl//absl/strings", |
236 | 241 | ], |
237 | 242 | ) |
45 | 45 | #include "config/config_handler.h" |
46 | 46 | #include "protocol/commands.pb.h" |
47 | 47 | #include "session/random_keyevents_generator.h" |
48 | #include "absl/flags/flag.h" | |
48 | 49 | |
49 | 50 | DEFINE_string(server_path, "", "specify server path"); |
50 | 51 | DEFINE_string(log_path, "", "specify log output file path"); |
98 | 99 | virtual void Run(Result *result) = 0; |
99 | 100 | |
100 | 101 | TestScenarioInterface() { |
101 | if (!FLAGS_server_path.empty()) { | |
102 | if (!mozc::GetFlag(FLAGS_server_path).empty()) { | |
102 | 103 | client_.set_server_program(FLAGS_server_path); |
103 | 104 | } |
104 | 105 | CHECK(client_.IsValidRunLevel()) << "IsValidRunLevel failed"; |
376 | 377 | CHECK_EQ(results.size(), tests.size()); |
377 | 378 | |
378 | 379 | std::ostream *ofs = &std::cout; |
379 | if (!FLAGS_log_path.empty()) { | |
380 | if (!mozc::GetFlag(FLAGS_log_path).empty()) { | |
380 | 381 | ofs = new mozc::OutputFileStream(FLAGS_log_path.c_str()); |
381 | 382 | } |
382 | 383 |
46 | 46 | // Test data automatically generated by gen_client_quality_test_data.py |
47 | 47 | // TestCase test_cases[] is defined. |
48 | 48 | #include "client/client_quality_test_data.inc" |
49 | #include "absl/flags/flag.h" | |
49 | 50 | |
50 | 51 | DEFINE_string(server_path, "", "specify server path"); |
51 | 52 | DEFINE_string(log_path, "", "specify log output file path"); |
201 | 202 | mozc::InitMozc(argv[0], &argc, &argv); |
202 | 203 | |
203 | 204 | mozc::client::Client client; |
204 | if (!FLAGS_server_path.empty()) { | |
205 | if (!mozc::GetFlag(FLAGS_server_path).empty()) { | |
205 | 206 | client.set_server_program(FLAGS_server_path); |
206 | 207 | } |
207 | 208 | |
220 | 221 | if (scores.find(source) == scores.end()) { |
221 | 222 | scores[source] = std::vector<double>(); |
222 | 223 | } |
223 | if (scores[source].size() >= FLAGS_max_case_for_source) { | |
224 | if (scores[source].size() >= mozc::GetFlag(FLAGS_max_case_for_source)) { | |
224 | 225 | continue; |
225 | 226 | } |
226 | 227 | |
246 | 247 | } |
247 | 248 | |
248 | 249 | std::ostream* ofs = &std::cout; |
249 | if (!FLAGS_log_path.empty()) { | |
250 | if (!mozc::GetFlag(FLAGS_log_path).empty()) { | |
250 | 251 | ofs = new mozc::OutputFileStream(FLAGS_log_path.c_str()); |
251 | 252 | } |
252 | 253 |
49 | 49 | #include "protocol/commands.pb.h" |
50 | 50 | #include "protocol/renderer_command.pb.h" |
51 | 51 | #include "renderer/renderer_client.h" |
52 | #include "absl/flags/flag.h" | |
52 | 53 | #include "absl/strings/match.h" |
53 | 54 | |
54 | 55 | DEFINE_string(input, "", "Input file"); |
94 | 95 | |
95 | 96 | int Loop(std::istream *input) { |
96 | 97 | mozc::client::Client client; |
97 | if (!FLAGS_server_path.empty()) { | |
98 | if (!mozc::GetFlag(FLAGS_server_path).empty()) { | |
98 | 99 | client.set_server_program(FLAGS_server_path); |
99 | 100 | } |
100 | 101 | |
105 | 106 | std::unique_ptr<mozc::renderer::RendererClient> renderer_client; |
106 | 107 | mozc::commands::RendererCommand renderer_command; |
107 | 108 | |
108 | if (FLAGS_test_renderer) { | |
109 | if (mozc::GetFlag(FLAGS_test_renderer)) { | |
109 | 110 | #if defined(OS_WIN) || defined(__APPLE__) |
110 | 111 | #ifdef OS_WIN |
111 | 112 | renderer_command.mutable_application_info()->set_process_id( |
136 | 137 | while (ReadKeys(input, &keys, &answer)) { |
137 | 138 | CHECK(client.NoOperation()) << "Server is not responding"; |
138 | 139 | for (size_t i = 0; i < keys.size(); ++i) { |
139 | Util::Sleep(FLAGS_key_duration); | |
140 | Util::Sleep(mozc::GetFlag(FLAGS_key_duration)); | |
140 | 141 | |
141 | if (FLAGS_test_testsendkey) { | |
142 | if (mozc::GetFlag(FLAGS_test_testsendkey)) { | |
142 | 143 | VLOG(2) << "Sending to Server: " << keys[i].DebugString(); |
143 | 144 | client.TestSendKey(keys[i], &output); |
144 | 145 | VLOG(2) << "Output of TestSendKey: " << output.DebugString(); |
172 | 173 | int main(int argc, char **argv) { |
173 | 174 | mozc::InitMozc(argv[0], &argc, &argv); |
174 | 175 | |
175 | if (!FLAGS_profile_dir.empty()) { | |
176 | if (!mozc::GetFlag(FLAGS_profile_dir).empty()) { | |
176 | 177 | mozc::FileUtil::CreateDirectory(FLAGS_profile_dir); |
177 | 178 | mozc::SystemUtil::SetUserProfileDirectory(FLAGS_profile_dir); |
178 | 179 | } |
180 | 181 | std::unique_ptr<mozc::InputFileStream> input_file; |
181 | 182 | std::istream *input = nullptr; |
182 | 183 | |
183 | if (!FLAGS_input.empty()) { | |
184 | if (!mozc::GetFlag(FLAGS_input).empty()) { | |
184 | 185 | // Batch mode loading the input file. |
185 | 186 | input_file.reset(new mozc::InputFileStream(FLAGS_input.c_str())); |
186 | 187 | if (input_file->fail()) { |
29 | 29 | #include <iostream> |
30 | 30 | |
31 | 31 | #include "client/client.h" |
32 | #include "absl/flags/flag.h" | |
32 | 33 | |
33 | 34 | #ifdef OS_WIN |
34 | 35 | #include <windows.h> |
66 | 67 | mozc::SetFlag(&FLAGS_logtostderr, true); |
67 | 68 | |
68 | 69 | mozc::client::Client client; |
69 | if (!FLAGS_server_path.empty()) { | |
70 | if (!mozc::GetFlag(FLAGS_server_path).empty()) { | |
70 | 71 | client.set_server_program(FLAGS_server_path); |
71 | 72 | } |
72 | 73 | |
77 | 78 | std::unique_ptr<mozc::renderer::RendererClient> renderer_client; |
78 | 79 | mozc::commands::RendererCommand renderer_command; |
79 | 80 | |
80 | if (FLAGS_test_renderer) { | |
81 | if (mozc::GetFlag(FLAGS_test_renderer)) { | |
81 | 82 | #if defined(OS_WIN) || defined(__APPLE__) |
82 | 83 | #ifdef OS_WIN |
83 | 84 | renderer_command.mutable_application_info()->set_process_id( |
109 | 110 | mozc::session::RandomKeyEventsGenerator::GenerateSequence(&keys); |
110 | 111 | CHECK(client.NoOperation()) << "Server is not responding"; |
111 | 112 | for (size_t i = 0; i < keys.size(); ++i) { |
112 | mozc::Util::Sleep(FLAGS_key_duration); | |
113 | mozc::Util::Sleep(mozc::GetFlag(FLAGS_key_duration)); | |
113 | 114 | keyevents_size++; |
114 | 115 | if (keyevents_size % 100 == 0) { |
115 | 116 | std::cout << keyevents_size << " key events finished" << std::endl; |
116 | 117 | } |
117 | if (FLAGS_max_keyevents < keyevents_size) { | |
118 | std::cout << "key events reached to " << FLAGS_max_keyevents | |
119 | << std::endl; | |
118 | if (mozc::GetFlag(FLAGS_max_keyevents) < keyevents_size) { | |
119 | std::cout << "key events reached to " | |
120 | << mozc::GetFlag(FLAGS_max_keyevents) << std::endl; | |
120 | 121 | return 0; |
121 | 122 | } |
122 | if (FLAGS_test_testsendkey) { | |
123 | if (mozc::GetFlag(FLAGS_test_testsendkey)) { | |
123 | 124 | VLOG(2) << "Sending to Server: " << keys[i].DebugString(); |
124 | 125 | client.TestSendKey(keys[i], &output); |
125 | 126 | VLOG(2) << "Output of TestSendKey: " << output.DebugString(); |
32 | 32 | #include "base/init_mozc.h" |
33 | 33 | #include "base/logging.h" |
34 | 34 | #include "client/client.h" |
35 | #include "absl/flags/flag.h" | |
35 | 36 | |
36 | 37 | DEFINE_bool(shutdown, false, "shutdown server if mozc_server is running"); |
37 | 38 | |
40 | 41 | mozc::InitMozc(argv[0], &argc, &argv); |
41 | 42 | mozc::client::Client client; |
42 | 43 | |
43 | if (FLAGS_shutdown) { | |
44 | if (mozc::GetFlag(FLAGS_shutdown)) { | |
44 | 45 | client.Shutdown(); |
45 | 46 | } |
46 | 47 |
243 | 243 | }; |
244 | 244 | #endif // OS_ANDROID |
245 | 245 | |
246 | #ifdef OS_NACL | |
247 | class NaclStatsConfigUtilImpl : public StatsConfigUtilInterface { | |
248 | public: | |
249 | NaclStatsConfigUtilImpl() {} | |
250 | virtual ~NaclStatsConfigUtilImpl() {} | |
251 | virtual bool IsEnabled() { | |
252 | Config config; | |
253 | ConfigHandler::GetConfig(&config); | |
254 | return config.general_config().upload_usage_stats(); | |
255 | } | |
256 | virtual bool SetEnabled(bool val) { return false; } | |
257 | ||
258 | private: | |
259 | DISALLOW_COPY_AND_ASSIGN(NaclStatsConfigUtilImpl); | |
260 | }; | |
261 | #endif // OS_NACL | |
262 | ||
263 | 246 | #endif // GOOGLE_JAPANESE_INPUT_BUILD |
264 | 247 | |
265 | 248 | class NullStatsConfigUtilImpl : public StatsConfigUtilInterface { |
206 | 206 | if (!status.ok()) { |
207 | 207 | return status; |
208 | 208 | } |
209 | #ifdef OS_NACL | |
210 | // TODO(noriyukit): This wrapping std::move() is normally unnecessary but NaCl | |
211 | // compiler doesn't work without it. Remove this workaround when possible. | |
212 | return std::move(connector); | |
213 | #else // OS_NACL | |
214 | 209 | return connector; |
215 | #endif // OS_NACL | |
216 | 210 | } |
217 | 211 | |
218 | 212 | Connector::Connector() = default; |
50 | 50 | int cost; |
51 | 51 | }; |
52 | 52 | |
53 | #ifndef OS_NACL | |
54 | // Disabled on NaCl since it uses a mock file system. | |
55 | 53 | TEST(ConnectorTest, CompareWithRawData) { |
56 | 54 | const std::string path = testing::GetSourceFileOrDie( |
57 | 55 | {"data_manager", "testing", "connection.data"}); |
139 | 137 | EXPECT_FALSE(status.ok()); |
140 | 138 | } |
141 | 139 | } |
142 | #endif // !OS_NACL | |
143 | 140 | |
144 | 141 | } // namespace |
145 | 142 | } // namespace mozc |
25 | 25 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
26 | 26 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 | 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | ||
29 | #ifndef OS_NACL | |
30 | // Disabled on NaCl since it uses a mock file system. | |
31 | 28 | |
32 | 29 | #include "converter/pos_id_printer.h" |
33 | 30 | |
74 | 71 | |
75 | 72 | } // namespace internal |
76 | 73 | } // namespace mozc |
77 | ||
78 | #endif // !OS_NACL |
469 | 469 | // Let converter know the maximum size of |
470 | 470 | // candidates converter can generate. |
471 | 471 | // NOTE: This field is used as an "optional" field. |
472 | // Rewriter might insert more than |size| candiates. | |
472 | // Rewriter might insert more than |size| candidates. | |
473 | 473 | // Default setting is 200. |
474 | 474 | void set_max_conversion_candidates_size(size_t size); |
475 | 475 | size_t max_conversion_candidates_size() const; |
32 | 32 | MINOR = 25 |
33 | 33 | |
34 | 34 | # Number to be increased. This value may be replaced by other tools. |
35 | BUILD = 4180 | |
35 | BUILD = 4190 | |
36 | 36 | |
37 | 37 | # Represent the platform and release channel. |
38 | 38 | REVISION = 100 |
82 | 82 | 'gen_system_dictionary_data_main.cc', |
83 | 83 | ], |
84 | 84 | 'dependencies': [ |
85 | '../base/absl.gyp:absl_base', | |
85 | 86 | '../base/absl.gyp:absl_strings', |
86 | 87 | '../base/base.gyp:base', |
87 | 88 | '../data_manager/data_manager_base.gyp:data_manager', |
176 | 176 | "//dictionary/file:codec_interface", |
177 | 177 | "//storage/louds:bit_vector_based_array_builder", |
178 | 178 | "//storage/louds:louds_trie_builder", |
179 | "@com_google_absl//absl/flags:flag", | |
179 | 180 | ], |
180 | 181 | ) |
181 | 182 | |
198 | 199 | ":system_dictionary", |
199 | 200 | ":system_dictionary_builder", |
200 | 201 | "//base:file_util", |
202 | "//base:flags", | |
201 | 203 | "//base:logging", |
202 | 204 | "//base:port", |
203 | 205 | "//base:stl_util", |
214 | 216 | "//request:conversion_request", |
215 | 217 | "//testing:gunit_main", |
216 | 218 | "//testing:mozctest", |
219 | "@com_google_absl//absl/flags:flag", | |
217 | 220 | "@com_google_absl//absl/strings", |
218 | 221 | ], |
219 | 222 | ) |
474 | 474 | return mozc::UnknownError("Failed to create system dictionary"); |
475 | 475 | } |
476 | 476 | |
477 | #ifdef OS_NACL | |
478 | // TODO(noriyukit): This wrapping std::move() is normally unnecessary but NaCl | |
479 | // compiler doesn't work without it. Remove this workaround when possible. | |
480 | return std::move(instance); | |
481 | #else // OS_NACL | |
482 | 477 | return instance; |
483 | #endif // OS_NACL | |
484 | 478 | } |
485 | 479 | |
486 | 480 | SystemDictionary::SystemDictionary( |
48 | 48 | #include "dictionary/text_dictionary_loader.h" |
49 | 49 | #include "storage/louds/bit_vector_based_array_builder.h" |
50 | 50 | #include "storage/louds/louds_trie_builder.h" |
51 | #include "absl/flags/flag.h" | |
51 | 52 | |
52 | 53 | DEFINE_bool(preserve_intermediate_dictionary, false, |
53 | 54 | "preserve inetemediate dictionary file."); |
161 | 162 | file_codec_->GetSectionName(codec_->GetSectionNameForPos())); |
162 | 163 | sections.push_back(frequent_pos_section); |
163 | 164 | |
164 | if (FLAGS_preserve_intermediate_dictionary && | |
165 | if (mozc::GetFlag(FLAGS_preserve_intermediate_dictionary) && | |
165 | 166 | !intermediate_output_file_base_path.empty()) { |
166 | 167 | // Write out intermediate results to files. |
167 | 168 | const std::string &basepath = intermediate_output_file_base_path; |
363 | 364 | for (size_t i = 0; i < key_info->tokens.size(); ++i) { |
364 | 365 | TokenInfo *token_info = &key_info->tokens[i]; |
365 | 366 | const int key_len = Util::CharsLen(token_info->token->key); |
366 | if (key_len >= FLAGS_min_key_length_to_use_small_cost_encoding) { | |
367 | if (key_len >= | |
368 | mozc::GetFlag(FLAGS_min_key_length_to_use_small_cost_encoding)) { | |
367 | 369 | token_info->cost_type = TokenInfo::CAN_USE_SMALL_ENCODING; |
368 | 370 | } |
369 | 371 | } |
36 | 36 | #include <utility> |
37 | 37 | #include <vector> |
38 | 38 | |
39 | #include "base/flags.h" | |
39 | 40 | #include "base/file_util.h" |
40 | 41 | #include "base/logging.h" |
41 | 42 | #include "base/port.h" |
74 | 75 | dic_fn_(FileUtil::JoinPath(FLAGS_test_tmpdir, "mozc.dic")) { |
75 | 76 | const std::string dic_path = mozc::testing::GetSourceFileOrDie( |
76 | 77 | {"data", "dictionary_oss", "dictionary00.txt"}); |
77 | text_dict_->LoadWithLineLimit(dic_path, "", FLAGS_dictionary_test_size); | |
78 | text_dict_->LoadWithLineLimit(dic_path, "", | |
79 | mozc::GetFlag(FLAGS_dictionary_test_size)); | |
78 | 80 | |
79 | 81 | convreq_.set_request(&request_); |
80 | 82 | convreq_.set_config(&config_); |
83 | 85 | void SetUp() override { |
84 | 86 | // Don't use small cost encoding by default. |
85 | 87 | original_flags_min_key_length_to_use_small_cost_encoding_ = |
86 | FLAGS_min_key_length_to_use_small_cost_encoding; | |
87 | FLAGS_min_key_length_to_use_small_cost_encoding = | |
88 | std::numeric_limits<int32>::max(); | |
88 | mozc::GetFlag(FLAGS_min_key_length_to_use_small_cost_encoding); | |
89 | mozc::SetFlag(&FLAGS_min_key_length_to_use_small_cost_encoding, | |
90 | std::numeric_limits<int32>::max()); | |
89 | 91 | |
90 | 92 | request_.Clear(); |
91 | 93 | config::ConfigHandler::GetDefaultConfig(&config_); |
92 | 94 | } |
93 | 95 | |
94 | 96 | void TearDown() override { |
95 | FLAGS_min_key_length_to_use_small_cost_encoding = | |
96 | original_flags_min_key_length_to_use_small_cost_encoding_; | |
97 | mozc::SetFlag(&FLAGS_min_key_length_to_use_small_cost_encoding, | |
98 | original_flags_min_key_length_to_use_small_cost_encoding_); | |
97 | 99 | |
98 | 100 | // This config initialization will be removed once ConversionRequest can |
99 | 101 | // take config as an injected argument. |
259 | 261 | t0->lid = 50; |
260 | 262 | t0->rid = 70; |
261 | 263 | source_tokens.push_back(t0.get()); |
262 | BuildSystemDictionary(source_tokens, FLAGS_dictionary_test_size); | |
264 | BuildSystemDictionary(source_tokens, | |
265 | mozc::GetFlag(FLAGS_dictionary_test_size)); | |
263 | 266 | |
264 | 267 | std::unique_ptr<SystemDictionary> system_dic = |
265 | 268 | SystemDictionary::Builder(dic_fn_).Build().value(); |
315 | 318 | for (size_t i = 0; i < tokens.size(); ++i) { |
316 | 319 | source_tokens.push_back(&tokens[i]); |
317 | 320 | } |
318 | BuildSystemDictionary(source_tokens, FLAGS_dictionary_test_size); | |
321 | BuildSystemDictionary(source_tokens, | |
322 | mozc::GetFlag(FLAGS_dictionary_test_size)); | |
319 | 323 | |
320 | 324 | std::unique_ptr<SystemDictionary> system_dic = |
321 | 325 | SystemDictionary::Builder(dic_fn_).Build().value(); |
329 | 333 | |
330 | 334 | TEST_F(SystemDictionaryTest, LookupAllWords) { |
331 | 335 | const std::vector<Token *> &source_tokens = text_dict_->tokens(); |
332 | BuildSystemDictionary(source_tokens, FLAGS_dictionary_test_size); | |
336 | BuildSystemDictionary(source_tokens, | |
337 | mozc::GetFlag(FLAGS_dictionary_test_size)); | |
333 | 338 | |
334 | 339 | std::unique_ptr<SystemDictionary> system_dic = |
335 | 340 | SystemDictionary::Builder(dic_fn_).Build().value(); |
699 | 704 | SystemDictionary::Builder(dic_fn_).Build().value(); |
700 | 705 | ASSERT_TRUE(system_dic) << "Failed to open dictionary source:" << dic_fn_; |
701 | 706 | const size_t test_size = |
702 | std::min(static_cast<size_t>(FLAGS_dictionary_reverse_lookup_test_size), | |
707 | std::min(static_cast<size_t>( | |
708 | mozc::GetFlag(FLAGS_dictionary_reverse_lookup_test_size)), | |
703 | 709 | source_tokens.size()); |
704 | 710 | for (size_t source_index = 0; source_index < test_size; ++source_index) { |
705 | 711 | const Token &source_token = *source_tokens[source_index]; |
757 | 763 | |
758 | 764 | TEST_F(SystemDictionaryTest, LookupReverseIndex) { |
759 | 765 | const std::vector<Token *> &source_tokens = text_dict_->tokens(); |
760 | BuildSystemDictionary(source_tokens, FLAGS_dictionary_test_size); | |
766 | BuildSystemDictionary(source_tokens, | |
767 | mozc::GetFlag(FLAGS_dictionary_test_size)); | |
761 | 768 | |
762 | 769 | std::unique_ptr<SystemDictionary> system_dic_without_index = |
763 | 770 | SystemDictionary::Builder(dic_fn_) |
775 | 782 | << "Failed to open dictionary source:" << dic_fn_; |
776 | 783 | |
777 | 784 | std::vector<Token *>::const_iterator it; |
778 | int size = FLAGS_dictionary_reverse_lookup_test_size; | |
785 | int size = mozc::GetFlag(FLAGS_dictionary_reverse_lookup_test_size); | |
779 | 786 | for (it = source_tokens.begin(); size > 0 && it != source_tokens.end(); |
780 | 787 | ++it, --size) { |
781 | 788 | const Token &t = **it; |
140 | 140 | |
141 | 141 | void UserDictionarySessionHandler::ClearStorage( |
142 | 142 | const UserDictionaryCommand &command, UserDictionaryCommandStatus *status) { |
143 | #ifdef OS_NACL | |
144 | // File operation is not supported on NaCl. | |
145 | status->set_status(UserDictionaryCommandStatus::UNKNOWN_ERROR); | |
146 | #else // OS_NACL | |
147 | 143 | // Note: session_ might not be created when ClearStorage is called. So create |
148 | 144 | // a local session to clear the storage. |
149 | 145 | UserDictionarySession session(dictionary_path_); |
150 | 146 | session.ClearDictionariesAndUndoHistory(); |
151 | 147 | status->set_status(session.Save()); |
152 | #endif // OS_NACL | |
153 | 148 | } |
154 | 149 | |
155 | 150 | void UserDictionarySessionHandler::CreateSession( |
222 | 222 | } |
223 | 223 | |
224 | 224 | TEST_F(UserDictionarySessionHandlerTest, ClearStorage) { |
225 | #ifdef OS_NACL | |
226 | Clear(); | |
227 | command_->set_type(UserDictionaryCommand::CLEAR_STORAGE); | |
228 | EXPECT_TRUE(handler_->Evaluate(*command_, status_.get())); | |
229 | EXPECT_EQ(UserDictionaryCommandStatus::UNKNOWN_ERROR, status_->status()); | |
230 | #else // OS_NACL | |
231 | 225 | // Set up a user dictionary. |
232 | 226 | { |
233 | 227 | Clear(); |
261 | 255 | ">\n", |
262 | 256 | *status_); |
263 | 257 | } |
264 | #endif // OS_NACL | |
265 | 258 | } |
266 | 259 | |
267 | 260 | TEST_F(UserDictionarySessionHandlerTest, CreateDeleteSession) { |
338 | 338 | while (id == kInvalidDictionaryId) { |
339 | 339 | Util::GetRandomSequence(reinterpret_cast<char *>(&id), sizeof(id)); |
340 | 340 | |
341 | #ifdef OS_NACL | |
342 | // Because JavaScript does not support uint64, we downsize the dictionary id | |
343 | // range from uint64 to uint32 in NaCl. | |
344 | id = static_cast<uint32>(id); | |
345 | #endif // OS_NACL | |
346 | ||
347 | 341 | // Duplication check. |
348 | 342 | for (int i = 0; i < storage.dictionaries_size(); ++i) { |
349 | 343 | if (storage.dictionaries(i).id() == id) { |
143 | 143 | if (!status.ok()) { |
144 | 144 | return status; |
145 | 145 | } |
146 | #ifdef OS_NACL | |
147 | // TODO(noriyukit): This wrapping std::move() is normally unnecessary but NaCl | |
148 | // compiler doesn't work without it. Remove this workaround when possible. | |
149 | return std::move(engine); | |
150 | #else // OS_NACL | |
151 | 146 | return engine; |
152 | #endif // OS_NACL | |
153 | 147 | } |
154 | 148 | |
155 | 149 | mozc::StatusOr<std::unique_ptr<Engine>> Engine::CreateMobileEngine( |
160 | 154 | if (!status.ok()) { |
161 | 155 | return status; |
162 | 156 | } |
163 | #ifdef OS_NACL | |
164 | // TODO(noriyukit): Remove std::move() if possible; see the above comment. | |
165 | return std::move(engine); | |
166 | #else // OS_NACL | |
167 | 157 | return engine; |
168 | #endif // OS_NACL | |
169 | 158 | } |
170 | 159 | |
171 | 160 | Engine::Engine() = default; |
62 | 62 | const testing::ScopedTmpUserProfileDirectory scoped_profile_dir_; |
63 | 63 | }; |
64 | 64 | |
65 | // Most of tests are disabled on NaCl as it uses mock file system for tests. | |
66 | #ifndef OS_NACL | |
67 | ||
68 | 65 | TEST_F(EngineBuilderTest, PrepareAsync) { |
69 | 66 | { |
70 | 67 | // Test request without install. |
211 | 208 | ASSERT_EQ(EngineReloadResponse::DATA_BROKEN, response_.status()); |
212 | 209 | } |
213 | 210 | |
214 | #endif // !OS_NACL | |
215 | ||
216 | 211 | TEST_F(EngineBuilderTest, FailureCase_FileDoesNotExist) { |
217 | 212 | // Test the case where input file doesn't exist. |
218 | 213 | request_.set_engine_type(EngineReloadRequest::MOBILE); |
57 | 57 | #include "gui/base/util.h" |
58 | 58 | #include "gui/config_dialog/keymap_editor.h" |
59 | 59 | #include "gui/config_dialog/roman_table_editor.h" |
60 | #include "protocol/commands.pb.h" | |
61 | 60 | #include "protocol/config.pb.h" |
62 | 61 | #include "session/internal/keymap.h" |
63 | 62 |
30 | 30 | |
31 | 31 | #include "net/http_client_null.h" |
32 | 32 | |
33 | #ifdef OS_NACL | |
34 | #include <ppapi/cpp/instance.h> | |
35 | #endif // OS_NACL | |
36 | ||
37 | 33 | #include "base/logging.h" |
38 | 34 | |
39 | 35 | namespace mozc { |
53 | 49 | return false; |
54 | 50 | } |
55 | 51 | |
56 | #ifdef OS_NACL | |
57 | void RegisterPepperInstanceForHTTPClient(pp::Instance *instance) { Error(); } | |
58 | ||
59 | pp::Instance *GetPepperInstanceForHTTPClient() { | |
60 | Error(); | |
61 | return nullptr; | |
62 | } | |
63 | #endif // OS_NACL | |
64 | ||
65 | 52 | } // namespace mozc |
66 | 53 | |
67 | 54 | #endif // !GOOGLE_JAPANESE_INPUT_BUILD |
36 | 36 | #include "net/http_client.h" |
37 | 37 | #include "net/http_client_common.h" |
38 | 38 | |
39 | #ifdef OS_NACL | |
40 | namespace pp { | |
41 | class Instance; | |
42 | } // namespace pp | |
43 | #endif // OS_NACL | |
44 | ||
45 | 39 | namespace mozc { |
46 | 40 | class NullHTTPRequestHandler { |
47 | 41 | public: |
53 | 47 | DISALLOW_IMPLICIT_CONSTRUCTORS(NullHTTPRequestHandler); |
54 | 48 | }; |
55 | 49 | |
56 | #ifdef OS_NACL | |
57 | void RegisterPepperInstanceForHTTPClient(pp::Instance *instance); | |
58 | pp::Instance *GetPepperInstanceForHTTPClient(); | |
59 | #endif // OS_NACL | |
60 | ||
61 | 50 | } // namespace mozc |
62 | 51 | |
63 | 52 | #endif // !GOOGLE_JAPANESE_INPUT_BUILD |
181 | 181 | '(_toolset=="host" and (compiler_host=="clang" or compiler_host=="gcc"))', { |
182 | 182 | 'cflags': [ |
183 | 183 | '-Wno-tautological-constant-out-of-range-compare', |
184 | '-Wno-unused-const-variable', | |
184 | 185 | '-Wno-unused-function', |
185 | 186 | ], |
186 | 187 | }], |
924 | 924 | required CommandType type = 1; |
925 | 925 | |
926 | 926 | // Session ID created by CREATE_SESSION. |
927 | optional uint64 id = 2; | |
927 | optional uint64 id = 2 [jstype = JS_STRING]; | |
928 | 928 | |
929 | 929 | // Key combinations used for SEND_KEY or TEST_SEND_KEY. |
930 | 930 | optional KeyEvent key = 3; |
1099 | 1099 | } |
1100 | 1100 | |
1101 | 1101 | message Output { |
1102 | optional uint64 id = 1; | |
1102 | optional uint64 id = 1 [jstype = JS_STRING]; | |
1103 | 1103 | |
1104 | 1104 | // This variable is going to be obsolete. |
1105 | 1105 | optional CompositionMode mode = 2; |
47 | 47 | optional string last_modified_product_version = 2 [default = "0.0.0.0"]; |
48 | 48 | |
49 | 49 | // last modified time in UTC second |
50 | optional uint64 last_modified_time = 3 [default = 0]; | |
50 | optional uint64 last_modified_time = 3 [default = 0, jstype = JS_STRING]; | |
51 | 51 | |
52 | 52 | // These fields are not used now |
53 | 53 | // platform of machine that wrote this config |
31 | 31 | package mozc.converter; |
32 | 32 | |
33 | 33 | message SegmenterDataSizeInfo { |
34 | optional uint64 compressed_lsize = 1; | |
35 | optional uint64 compressed_rsize = 2; | |
34 | optional uint64 compressed_lsize = 1 [jstype = JS_STRING]; | |
35 | optional uint64 compressed_rsize = 2 [jstype = JS_STRING]; | |
36 | 36 | } |
36 | 36 | |
37 | 37 | message SessionState { |
38 | 38 | // session id |
39 | required uint64 id = 1; | |
39 | required uint64 id = 1 [jstype = JS_STRING]; | |
40 | 40 | // session created time |
41 | optional uint64 created_time = 2; | |
41 | optional uint64 created_time = 2 [jstype = JS_STRING]; | |
42 | 42 | |
43 | 43 | // whether session is just after commitment |
44 | 44 | optional bool committed = 3 [default = false]; |
47 | 47 | |
48 | 48 | reserved 5; // Deprecated mode |
49 | 49 | |
50 | optional uint64 start_preedit_time = 10; | |
51 | optional uint64 start_conversion_window_time = 11; | |
52 | optional uint64 start_prediction_window_time = 12; | |
53 | optional uint64 start_suggestion_window_time = 13; | |
54 | optional uint64 start_infolist_window_time = 14; | |
50 | optional uint64 start_preedit_time = 10 [jstype = JS_STRING]; | |
51 | optional uint64 start_conversion_window_time = 11 [jstype = JS_STRING]; | |
52 | optional uint64 start_prediction_window_time = 12 [jstype = JS_STRING]; | |
53 | optional uint64 start_suggestion_window_time = 13 [jstype = JS_STRING]; | |
54 | optional uint64 start_infolist_window_time = 14 [jstype = JS_STRING]; | |
55 | 55 | |
56 | 56 | // last preedit state |
57 | 57 | optional mozc.commands.Preedit preedit = 20; |
87 | 87 | } |
88 | 88 | |
89 | 89 | // ID of this dictionary |
90 | optional uint64 id = 1 [default = 0]; | |
90 | optional uint64 id = 1 [default = 0, jstype = JS_STRING]; | |
91 | 91 | |
92 | 92 | // set false if this dictionary is not used. |
93 | 93 | // Even if |enabled| is false, the dictionary |
253 | 253 | } |
254 | 254 | |
255 | 255 | required CommandType type = 1; |
256 | optional uint64 session_id = 2; | |
257 | optional uint64 dictionary_id = 3; | |
256 | optional uint64 session_id = 2 [jstype = JS_STRING]; | |
257 | optional uint64 dictionary_id = 3 [jstype = JS_STRING]; | |
258 | 258 | optional string dictionary_name = 4; |
259 | 259 | repeated int32 entry_index = 5; |
260 | 260 | optional UserDictionary.Entry entry = 6; |
316 | 316 | } |
317 | 317 | |
318 | 318 | required Status status = 1; |
319 | optional uint64 session_id = 2; | |
319 | optional uint64 session_id = 2 [jstype = JS_STRING]; | |
320 | 320 | optional UserDictionaryStorage storage = 3; |
321 | 321 | // Use entries field instead. |
322 | 322 | reserved 4; // Deprecated entry |
323 | optional uint64 dictionary_id = 5; | |
323 | optional uint64 dictionary_id = 5 [jstype = JS_STRING]; | |
324 | 324 | optional uint32 entry_size = 6; |
325 | 325 | repeated UserDictionary.Entry entries = 7; |
326 | 326 | } |
243 | 243 | "//request:conversion_request", |
244 | 244 | "//testing:gunit_prod", |
245 | 245 | "@com_google_absl//absl/strings", |
246 | "@com_google_absl//absl/time", | |
246 | 247 | ], |
247 | 248 | alwayslink = 1, |
248 | 249 | ) |
238 | 238 | return true; |
239 | 239 | } |
240 | 240 | |
241 | CalculatorInterface *g_calculator = NULL; | |
241 | CalculatorInterface *g_calculator = nullptr; | |
242 | 242 | } // namespace |
243 | 243 | |
244 | 244 | CalculatorInterface *CalculatorFactory::GetCalculator() { |
245 | if (g_calculator == NULL) { | |
245 | if (g_calculator == nullptr) { | |
246 | 246 | return Singleton<CalculatorImpl>::get(); |
247 | 247 | } else { |
248 | 248 | return g_calculator; |
323 | 323 | |
324 | 324 | #ifndef NDEBUG |
325 | 325 | #include <stdio.h> |
326 | static FILE *yyTraceFILE = 0; | |
327 | static char *yyTracePrompt = 0; | |
326 | static FILE *yyTraceFILE = nullptr; | |
327 | static char *yyTracePrompt = nullptr; | |
328 | 328 | #endif /* NDEBUG */ |
329 | 329 | |
330 | 330 | #ifndef NDEBUG |
507 | 507 | void (*freeProc)(void*) /* Function used to reclaim memory */ |
508 | 508 | ){ |
509 | 509 | yyParser *pParser = (yyParser*)p; |
510 | if( pParser==0 ) return; | |
510 | if (pParser == nullptr) return; | |
511 | 511 | while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); |
512 | 512 | #if YYSTACKDEPTH<=0 |
513 | 513 | free(pParser->yystack); |
142 | 142 | for (int n = 0; n < 2; ++n) { |
143 | 143 | int current_offset = offset + n; |
144 | 144 | Segment::Candidate *candidate = segment->insert_candidate(current_offset); |
145 | if (candidate == NULL) { | |
145 | if (candidate == nullptr) { | |
146 | 146 | LOG(ERROR) << "cannot insert candidate at " << current_offset; |
147 | 147 | return false; |
148 | 148 | } |
124 | 124 | |
125 | 125 | virtual void TearDown() { |
126 | 126 | // Clear the mock test calculator |
127 | CalculatorFactory::SetCalculator(NULL); | |
127 | CalculatorFactory::SetCalculator(nullptr); | |
128 | 128 | } |
129 | 129 | |
130 | 130 | ConversionRequest convreq_; |
151 | 151 | {kPat7, arraysize(kPat7) - 1}, |
152 | 152 | {kPat8, arraysize(kPat8) - 1}, |
153 | 153 | {kPat9, arraysize(kPat9) - 1}, |
154 | {NULL, 0}}; | |
155 | ||
156 | for (size_t i = 0; kParticles[i].pat != NULL; ++i) { | |
154 | {nullptr, 0}}; | |
155 | ||
156 | for (size_t i = 0; kParticles[i].pat != nullptr; ++i) { | |
157 | 157 | const absl::string_view particle(kParticles[i].pat, kParticles[i].len); |
158 | 158 | absl::string_view first_content, second; |
159 | 159 | if (!ParseCompound(top_value, particle, &first_content, &second)) { |
550 | 550 | : pos_matcher_(data_manager->GetPOSMatcherData()), |
551 | 551 | first_name_id_(pos_matcher_.GetFirstNameId()), |
552 | 552 | last_name_id_(pos_matcher_.GetLastNameId()) { |
553 | const char *data = NULL; | |
553 | const char *data = nullptr; | |
554 | 554 | size_t size = 0; |
555 | 555 | |
556 | 556 | data_manager->GetCollocationData(&data, &size); |
175 | 175 | |
176 | 176 | bool CommandRewriter::Rewrite(const ConversionRequest &request, |
177 | 177 | Segments *segments) const { |
178 | if (segments == NULL || segments->conversion_segments_size() != 1) { | |
178 | if (segments == nullptr || segments->conversion_segments_size() != 1) { | |
179 | 179 | return false; |
180 | 180 | } |
181 | 181 |
38 | 38 | |
39 | 39 | #include <algorithm> |
40 | 40 | #include <cstdio> |
41 | #include <ctime> | |
42 | 41 | #include <string> |
43 | 42 | #include <vector> |
44 | 43 | |
55 | 54 | #include "request/conversion_request.h" |
56 | 55 | #include "absl/strings/str_cat.h" |
57 | 56 | #include "absl/strings/string_view.h" |
57 | #include "absl/time/time.h" | |
58 | 58 | |
59 | 59 | namespace mozc { |
60 | 60 | namespace { |
61 | ||
62 | struct DateData { | |
63 | const char *key; | |
64 | const char *value; | |
65 | const char *description; | |
66 | int diff; // diff from the current time in day or month or year | |
61 | enum { | |
62 | YEAR, | |
63 | MONTH, | |
64 | DATE, | |
65 | WEEKDAY, | |
66 | CURRENT_TIME, | |
67 | DATE_AND_CURRENT_TIME, | |
67 | 68 | }; |
68 | 69 | |
69 | const struct DateData kDateData[] = { | |
70 | {// きょう will show today's date | |
71 | "きょう", "今日", "今日の日付", 0}, | |
72 | {// あした will show tomorrow's date | |
73 | "あした", "明日", "明日の日付", 1}, | |
74 | {// あす will show tomorrow's date | |
75 | "あす", "明日", "明日の日付", 1}, | |
76 | {// さくじつ will show yesterday's date | |
77 | "さくじつ", "昨日", "昨日の日付", -1}, | |
78 | {// きのう will show yesterday's date | |
79 | "きのう", "昨日", "昨日の日付", -1}, | |
80 | {// おととい will show the date of 2 days ago | |
81 | "おととい", "一昨日", "2日前の日付", -2}, | |
82 | {// おとつい will show the date of 2 days ago | |
83 | "おとつい", "一昨日", "2日前の日付", -2}, | |
84 | {// いっさくじつ will show the date of 2 days ago | |
85 | "いっさくじつ", "一昨日", "2日前の日付", -2}, | |
86 | {// さきおととい will show the date of 3 days ago | |
87 | "さきおととい", "一昨昨日", "3日前の日付", -3}, | |
88 | { | |
89 | // あさって will show the date of 2 days from now | |
90 | "あさって", | |
91 | "明後日", | |
92 | "明後日の日付", | |
93 | 2, | |
94 | }, | |
95 | {// みょうごにち will show the date of 2 days from now | |
96 | "みょうごにち", "明後日", "明後日の日付", 2}, | |
97 | {// しあさって will show the date of 3 days from now | |
98 | "しあさって", "明明後日", | |
99 | "明明後日の" | |
100 | "日付", | |
101 | 3}}; | |
102 | ||
103 | const struct DateData kWeekDayData[] = { | |
104 | {"にちようび", "日曜日", "次の日曜日", 0}, | |
105 | {"げつようび", "月曜日", "次の月曜日", 1}, | |
106 | {"かようび", "火曜日", "次の火曜日", 2}, | |
107 | {"すいようび", "水曜日", "次の水曜日", 3}, | |
108 | {"もくようび", "木曜日", "次の木曜日", 4}, | |
109 | {"きんようび", "金曜日", "次の金曜日", 5}, | |
110 | {"どようび", "土曜日", "次の土曜日", 6}, | |
111 | {"にちよう", "日曜", "次の日曜日", 0}, | |
112 | {"げつよう", "月曜", "次の月曜日", 1}, | |
113 | {"かよう", "火曜", "次の火曜日", 2}, | |
114 | {"すいよう", "水曜", "次の水曜日", 3}, | |
115 | {"もくよう", "木曜", "次の木曜日", 4}, | |
116 | {"きんよう", "金曜", "次の金曜日", 5}, | |
117 | {"どよう", "土曜", "次の土曜日", 6}}; | |
118 | ||
119 | const struct DateData kYearData[] = {{"ことし", "今年", "今年", 0}, | |
120 | {"らいねん", "来年", "来年", 1}, | |
121 | {"さくねん", "昨年", "昨年", -1}, | |
122 | {"きょねん", "去年", "去年", -1}, | |
123 | {"おととし", "一昨年", "一昨年", -2}, | |
124 | {"さらいねん", "再来年", "再来年", 2}}; | |
125 | ||
126 | const struct DateData kMonthData[] = {{"こんげつ", "今月", "今月", 0}, | |
127 | {"らいげつ", "来月", "来月", 1}, | |
128 | {"せんげつ", "先月", "先月", -1}, | |
129 | {"せんせんげつ", "先々月", "先々月", -2}, | |
130 | {"さらいげつ", "再来月", "再来月", 2}}; | |
131 | ||
132 | const struct DateData kCurrentTimeData[] = { | |
133 | {"いま", "今", "現在の時刻", 0}, {"じこく", "時刻", "現在の時刻", 0}}; | |
134 | ||
135 | const struct DateData kDateAndCurrentTimeData[] = { | |
136 | {"にちじ", "日時", "現在の日時", 0}, | |
137 | }; | |
70 | const struct DateRewriter::DateData kDateData[] = { | |
71 | // Date rewrites. | |
72 | {"きょう", "今日", "今日の日付", 0, DATE}, | |
73 | {"あした", "明日", "明日の日付", 1, DATE}, | |
74 | {"あす", "明日", "明日の日付", 1, DATE}, | |
75 | {"さくじつ", "昨日", "昨日の日付", -1, DATE}, | |
76 | {"きのう", "昨日", "昨日の日付", -1, DATE}, | |
77 | {"おととい", "一昨日", "2日前の日付", -2, DATE}, | |
78 | {"おとつい", "一昨日", "2日前の日付", -2, DATE}, | |
79 | {"いっさくじつ", "一昨日", "2日前の日付", -2, DATE}, | |
80 | {"さきおととい", "一昨昨日", "3日前の日付", -3, DATE}, | |
81 | {"あさって", "明後日", "明後日の日付", 2, DATE}, | |
82 | {"みょうごにち", "明後日", "明後日の日付", 2, DATE}, | |
83 | {"しあさって", "明明後日", "明明後日の日付", 3, DATE}, | |
84 | ||
85 | // Weekday rewrites | |
86 | // Absl::Weekday starts from Monday, while std::tm.tm_wday starts from | |
87 | // Sunday. | |
88 | {"げつようび", "月曜日", "次の月曜日", 0, WEEKDAY}, | |
89 | {"かようび", "火曜日", "次の火曜日", 1, WEEKDAY}, | |
90 | {"すいようび", "水曜日", "次の水曜日", 2, WEEKDAY}, | |
91 | {"もくようび", "木曜日", "次の木曜日", 3, WEEKDAY}, | |
92 | {"きんようび", "金曜日", "次の金曜日", 4, WEEKDAY}, | |
93 | {"どようび", "土曜日", "次の土曜日", 5, WEEKDAY}, | |
94 | {"にちようび", "日曜日", "次の日曜日", 6, WEEKDAY}, | |
95 | {"げつよう", "月曜", "次の月曜日", 0, WEEKDAY}, | |
96 | {"かよう", "火曜", "次の火曜日", 1, WEEKDAY}, | |
97 | {"すいよう", "水曜", "次の水曜日", 2, WEEKDAY}, | |
98 | {"もくよう", "木曜", "次の木曜日", 3, WEEKDAY}, | |
99 | {"きんよう", "金曜", "次の金曜日", 4, WEEKDAY}, | |
100 | {"どよう", "土曜", "次の土曜日", 5, WEEKDAY}, | |
101 | {"にちよう", "日曜", "次の日曜日", 6, WEEKDAY}, | |
102 | ||
103 | // Year rewrites | |
104 | {"ことし", "今年", "今年", 0, YEAR}, | |
105 | {"らいねん", "来年", "来年", 1, YEAR}, | |
106 | {"さくねん", "昨年", "昨年", -1, YEAR}, | |
107 | {"きょねん", "去年", "去年", -1, YEAR}, | |
108 | {"おととし", "一昨年", "一昨年", -2, YEAR}, | |
109 | {"さらいねん", "再来年", "再来年", 2, YEAR}, | |
110 | ||
111 | // Month rewrites | |
112 | {"こんげつ", "今月", "今月", 0, MONTH}, | |
113 | {"らいげつ", "来月", "来月", 1, MONTH}, | |
114 | {"せんげつ", "先月", "先月", -1, MONTH}, | |
115 | {"せんせんげつ", "先々月", "先々月", -2, MONTH}, | |
116 | {"さらいげつ", "再来月", "再来月", 2, MONTH}, | |
117 | ||
118 | // Time rewrites. | |
119 | {"いま", "今", "現在の時刻", 0, CURRENT_TIME}, | |
120 | {"じこく", "時刻", "現在の時刻", 0, CURRENT_TIME}, | |
121 | ||
122 | // Date and time rewrites. | |
123 | {"にちじ", "日時", "現在の日時", 0, DATE_AND_CURRENT_TIME}}; | |
124 | ||
125 | // Absl::Weekday starts from Monday, while std::tm.tm_wday starts from Sunday. | |
126 | const char *kWeekDayString[] = {"月", "火", "水", "木", "金", "土", "日"}; | |
127 | ||
128 | const char kDateDescription[] = "日付"; | |
129 | const char kTimeDescription[] = "時刻"; | |
138 | 130 | |
139 | 131 | struct YearData { |
140 | 132 | int ad; // AD year |
144 | 136 | |
145 | 137 | const YearData kEraData[] = { |
146 | 138 | // "元徳", "建武" and "明徳" are used for both south and north courts. |
147 | { | |
148 | 645, | |
149 | "大化", | |
150 | "たいか", | |
151 | }, | |
152 | { | |
153 | 650, | |
154 | "白雉", | |
155 | "はくち", | |
156 | }, | |
157 | { | |
158 | 686, | |
159 | "朱鳥", | |
160 | "しゅちょう", | |
161 | }, | |
162 | { | |
163 | 701, | |
164 | "大宝", | |
165 | "たいほう", | |
166 | }, | |
167 | { | |
168 | 704, | |
169 | "慶雲", | |
170 | "けいうん", | |
171 | }, | |
172 | { | |
173 | 708, | |
174 | "和銅", | |
175 | "わどう", | |
176 | }, | |
177 | { | |
178 | 715, | |
179 | "霊亀", | |
180 | "れいき", | |
181 | }, | |
182 | { | |
183 | 717, | |
184 | "養老", | |
185 | "ようろう", | |
186 | }, | |
187 | { | |
188 | 724, | |
189 | "神亀", | |
190 | "じんき", | |
191 | }, | |
192 | { | |
193 | 729, | |
194 | "天平", | |
195 | "てんぴょう", | |
196 | }, | |
197 | { | |
198 | 749, | |
199 | "天平感宝", | |
200 | "てんぴょう" | |
201 | "かんぽう", | |
202 | }, | |
203 | { | |
204 | 749, | |
205 | "天平勝宝", | |
206 | "てんぴょう" | |
207 | "しょうほう", | |
208 | }, | |
209 | { | |
210 | 757, | |
211 | "天平宝字", | |
212 | "てんぴょう" | |
213 | "ほうじ", | |
214 | }, | |
215 | { | |
216 | 765, | |
217 | "天平神護", | |
218 | "てんぴょう" | |
219 | "じんご", | |
220 | }, | |
221 | { | |
222 | 767, | |
223 | "神護景雲", | |
224 | "じんご" | |
225 | "けいうん", | |
226 | }, | |
227 | { | |
228 | 770, | |
229 | "宝亀", | |
230 | "ほうき", | |
231 | }, | |
232 | { | |
233 | 781, | |
234 | "天応", | |
235 | "てんおう", | |
236 | }, | |
237 | { | |
238 | 782, | |
239 | "延暦", | |
240 | "えんりゃく", | |
241 | }, | |
242 | { | |
243 | 806, | |
244 | "大同", | |
245 | "たいどう", | |
246 | }, | |
247 | { | |
248 | 810, | |
249 | "弘仁", | |
250 | "こうにん", | |
251 | }, | |
252 | { | |
253 | 824, | |
254 | "天長", | |
255 | "てんちょう", | |
256 | }, | |
257 | { | |
258 | 834, | |
259 | "承和", | |
260 | "じょうわ", | |
261 | }, | |
262 | { | |
263 | 848, | |
264 | "嘉祥", | |
265 | "かしょう", | |
266 | }, | |
267 | { | |
268 | 851, | |
269 | "仁寿", | |
270 | "にんじゅ", | |
271 | }, | |
272 | { | |
273 | 854, | |
274 | "斉衡", | |
275 | "さいこう", | |
276 | }, | |
277 | { | |
278 | 857, | |
279 | "天安", | |
280 | "てんなん", | |
281 | }, | |
282 | { | |
283 | 859, | |
284 | "貞観", | |
285 | "じょうかん", | |
286 | }, | |
287 | { | |
288 | 877, | |
289 | "元慶", | |
290 | "がんぎょう", | |
291 | }, | |
292 | { | |
293 | 885, | |
294 | "仁和", | |
295 | "にんな", | |
296 | }, | |
297 | { | |
298 | 889, | |
299 | "寛平", | |
300 | "かんぴょう", | |
301 | }, | |
302 | { | |
303 | 898, | |
304 | "昌泰", | |
305 | "しょうたい", | |
306 | }, | |
307 | { | |
308 | 901, | |
309 | "延喜", | |
310 | "えんぎ", | |
311 | }, | |
312 | { | |
313 | 923, | |
314 | "延長", | |
315 | "えんちょう", | |
316 | }, | |
317 | { | |
318 | 931, | |
319 | "承平", | |
320 | "じょうへい", | |
321 | }, | |
322 | { | |
323 | 938, | |
324 | "天慶", | |
325 | "てんぎょう", | |
326 | }, | |
327 | { | |
328 | 947, | |
329 | "天暦", | |
330 | "てんりゃく", | |
331 | }, | |
332 | { | |
333 | 957, | |
334 | "天徳", | |
335 | "てんとく", | |
336 | }, | |
337 | { | |
338 | 961, | |
339 | "応和", | |
340 | "おうわ", | |
341 | }, | |
342 | { | |
343 | 964, | |
344 | "康保", | |
345 | "こうほう", | |
346 | }, | |
347 | { | |
348 | 968, | |
349 | "安和", | |
350 | "あんな", | |
351 | }, | |
352 | { | |
353 | 970, | |
354 | "天禄", | |
355 | "てんろく", | |
356 | }, | |
357 | { | |
358 | 973, | |
359 | "天延", | |
360 | "てんえん", | |
361 | }, | |
362 | { | |
363 | 976, | |
364 | "貞元", | |
365 | "じょうげん", | |
366 | }, | |
367 | { | |
368 | 978, | |
369 | "天元", | |
370 | "てんげん", | |
371 | }, | |
372 | { | |
373 | 983, | |
374 | "永観", | |
375 | "えいかん", | |
376 | }, | |
377 | { | |
378 | 985, | |
379 | "寛和", | |
380 | "かんな", | |
381 | }, | |
382 | { | |
383 | 987, | |
384 | "永延", | |
385 | "えいえん", | |
386 | }, | |
387 | { | |
388 | 989, | |
389 | "永祚", | |
390 | "えいそ", | |
391 | }, | |
392 | { | |
393 | 990, | |
394 | "正暦", | |
395 | "しょうりゃく", | |
396 | }, | |
397 | { | |
398 | 995, | |
399 | "長徳", | |
400 | "ちょうとく", | |
401 | }, | |
402 | { | |
403 | 999, | |
404 | "長保", | |
405 | "ちょうほう", | |
406 | }, | |
407 | { | |
408 | 1004, | |
409 | "寛弘", | |
410 | "かんこう", | |
411 | }, | |
412 | { | |
413 | 1012, | |
414 | "長和", | |
415 | "ちょうわ", | |
416 | }, | |
417 | { | |
418 | 1017, | |
419 | "寛仁", | |
420 | "かんにん", | |
421 | }, | |
422 | { | |
423 | 1021, | |
424 | "治安", | |
425 | "じあん", | |
426 | }, | |
427 | { | |
428 | 1024, | |
429 | "万寿", | |
430 | "まんじゅ", | |
431 | }, | |
432 | { | |
433 | 1028, | |
434 | "長元", | |
435 | "ちょうげん", | |
436 | }, | |
437 | { | |
438 | 1037, | |
439 | "長暦", | |
440 | "ちょうりゃく", | |
441 | }, | |
442 | { | |
443 | 1040, | |
444 | "長久", | |
445 | "ちょうきゅう", | |
446 | }, | |
447 | { | |
448 | 1044, | |
449 | "寛徳", | |
450 | "かんとく", | |
451 | }, | |
452 | { | |
453 | 1046, | |
454 | "永承", | |
455 | "えいしょう", | |
456 | }, | |
457 | { | |
458 | 1053, | |
459 | "天喜", | |
460 | "てんき", | |
461 | }, | |
462 | { | |
463 | 1058, | |
464 | "康平", | |
465 | "こうへい", | |
466 | }, | |
467 | { | |
468 | 1065, | |
469 | "治暦", | |
470 | "じりゃく", | |
471 | }, | |
472 | { | |
473 | 1069, | |
474 | "延久", | |
475 | "えんきゅう", | |
476 | }, | |
477 | { | |
478 | 1074, | |
479 | "承保", | |
480 | "じょうほう", | |
481 | }, | |
482 | { | |
483 | 1077, | |
484 | "承暦", | |
485 | "じょうりゃく", | |
486 | }, | |
487 | { | |
488 | 1081, | |
489 | "永保", | |
490 | "えいほ", | |
491 | }, | |
492 | { | |
493 | 1084, | |
494 | "応徳", | |
495 | "おうとく", | |
496 | }, | |
497 | { | |
498 | 1087, | |
499 | "寛治", | |
500 | "かんじ", | |
501 | }, | |
502 | { | |
503 | 1094, | |
504 | "嘉保", | |
505 | "かほう", | |
506 | }, | |
507 | { | |
508 | 1096, | |
509 | "永長", | |
510 | "えいちょう", | |
511 | }, | |
512 | { | |
513 | 1097, | |
514 | "承徳", | |
515 | "じょうとく", | |
516 | }, | |
517 | { | |
518 | 1099, | |
519 | "康和", | |
520 | "こうわ", | |
521 | }, | |
522 | { | |
523 | 1104, | |
524 | "長治", | |
525 | "ちょうじ", | |
526 | }, | |
527 | { | |
528 | 1106, | |
529 | "嘉承", | |
530 | "かしょう", | |
531 | }, | |
532 | { | |
533 | 1108, | |
534 | "天仁", | |
535 | "てんにん", | |
536 | }, | |
537 | { | |
538 | 1110, | |
539 | "天永", | |
540 | "てんえい", | |
541 | }, | |
542 | { | |
543 | 1113, | |
544 | "永久", | |
545 | "えいきゅう", | |
546 | }, | |
547 | { | |
548 | 1118, | |
549 | "元永", | |
550 | "げんえい", | |
551 | }, | |
552 | { | |
553 | 1120, | |
554 | "保安", | |
555 | "ほうあん", | |
556 | }, | |
557 | { | |
558 | 1124, | |
559 | "天治", | |
560 | "てんじ", | |
561 | }, | |
562 | { | |
563 | 1126, | |
564 | "大治", | |
565 | "だいじ", | |
566 | }, | |
567 | { | |
568 | 1131, | |
569 | "天承", | |
570 | "てんじょう", | |
571 | }, | |
572 | { | |
573 | 1132, | |
574 | "長承", | |
575 | "ちょうじょう", | |
576 | }, | |
577 | { | |
578 | 1135, | |
579 | "保延", | |
580 | "ほうえん", | |
581 | }, | |
582 | { | |
583 | 1141, | |
584 | "永治", | |
585 | "えいじ", | |
586 | }, | |
587 | { | |
588 | 1142, | |
589 | "康治", | |
590 | "こうじ", | |
591 | }, | |
592 | { | |
593 | 1144, | |
594 | "天養", | |
595 | "てんよう", | |
596 | }, | |
597 | { | |
598 | 1145, | |
599 | "久安", | |
600 | "きゅうあん", | |
601 | }, | |
602 | { | |
603 | 1151, | |
604 | "仁平", | |
605 | "にんぺい", | |
606 | }, | |
607 | { | |
608 | 1154, | |
609 | "久寿", | |
610 | "きゅうじゅ", | |
611 | }, | |
612 | { | |
613 | 1156, | |
614 | "保元", | |
615 | "ほうげん", | |
616 | }, | |
617 | { | |
618 | 1159, | |
619 | "平治", | |
620 | "へいじ", | |
621 | }, | |
622 | { | |
623 | 1160, | |
624 | "永暦", | |
625 | "えいりゃく", | |
626 | }, | |
627 | { | |
628 | 1161, | |
629 | "応保", | |
630 | "おうほ", | |
631 | }, | |
632 | { | |
633 | 1163, | |
634 | "長寛", | |
635 | "ちょうかん", | |
636 | }, | |
637 | { | |
638 | 1165, | |
639 | "永万", | |
640 | "えいまん", | |
641 | }, | |
642 | { | |
643 | 1166, | |
644 | "仁安", | |
645 | "にんあん", | |
646 | }, | |
647 | { | |
648 | 1169, | |
649 | "嘉応", | |
650 | "かおう", | |
651 | }, | |
652 | { | |
653 | 1171, | |
654 | "承安", | |
655 | "しょうあん", | |
656 | }, | |
657 | { | |
658 | 1175, | |
659 | "安元", | |
660 | "あんげん", | |
661 | }, | |
662 | { | |
663 | 1177, | |
664 | "治承", | |
665 | "じしょう", | |
666 | }, | |
667 | { | |
668 | 1181, | |
669 | "養和", | |
670 | "ようわ", | |
671 | }, | |
672 | { | |
673 | 1182, | |
674 | "寿永", | |
675 | "じゅえい", | |
676 | }, | |
677 | { | |
678 | 1184, | |
679 | "元暦", | |
680 | "げんりゃく", | |
681 | }, | |
682 | { | |
683 | 1185, | |
684 | "文治", | |
685 | "ぶんじ", | |
686 | }, | |
687 | { | |
688 | 1190, | |
689 | "建久", | |
690 | "けんきゅう", | |
691 | }, | |
692 | { | |
693 | 1199, | |
694 | "正治", | |
695 | "しょうじ", | |
696 | }, | |
697 | { | |
698 | 1201, | |
699 | "建仁", | |
700 | "けんにん", | |
701 | }, | |
702 | { | |
703 | 1204, | |
704 | "元久", | |
705 | "げんきゅう", | |
706 | }, | |
707 | { | |
708 | 1206, | |
709 | "建永", | |
710 | "けんえい", | |
711 | }, | |
712 | { | |
713 | 1207, | |
714 | "承元", | |
715 | "じょうげん", | |
716 | }, | |
717 | { | |
718 | 1211, | |
719 | "建暦", | |
720 | "けんりゃく", | |
721 | }, | |
722 | { | |
723 | 1213, | |
724 | "建保", | |
725 | "けんぽう", | |
726 | }, | |
727 | { | |
728 | 1219, | |
729 | "承久", | |
730 | "しょうきゅう", | |
731 | }, | |
732 | { | |
733 | 1222, | |
734 | "貞応", | |
735 | "じょうおう", | |
736 | }, | |
737 | { | |
738 | 1224, | |
739 | "元仁", | |
740 | "げんにん", | |
741 | }, | |
742 | { | |
743 | 1225, | |
744 | "嘉禄", | |
745 | "かろく", | |
746 | }, | |
747 | { | |
748 | 1227, | |
749 | "安貞", | |
750 | "あんてい", | |
751 | }, | |
752 | { | |
753 | 1229, | |
754 | "寛喜", | |
755 | "かんき", | |
756 | }, | |
757 | { | |
758 | 1232, | |
759 | "貞永", | |
760 | "じょうえい", | |
761 | }, | |
762 | { | |
763 | 1233, | |
764 | "天福", | |
765 | "てんぷく", | |
766 | }, | |
767 | { | |
768 | 1234, | |
769 | "文暦", | |
770 | "ぶんりゃく", | |
771 | }, | |
772 | { | |
773 | 1235, | |
774 | "嘉禎", | |
775 | "かてい", | |
776 | }, | |
777 | { | |
778 | 1238, | |
779 | "暦仁", | |
780 | "りゃくにん", | |
781 | }, | |
782 | { | |
783 | 1239, | |
784 | "延応", | |
785 | "えんおう", | |
786 | }, | |
787 | { | |
788 | 1240, | |
789 | "仁治", | |
790 | "にんじゅ", | |
791 | }, | |
792 | { | |
793 | 1243, | |
794 | "寛元", | |
795 | "かんげん", | |
796 | }, | |
797 | { | |
798 | 1247, | |
799 | "宝治", | |
800 | "ほうじ", | |
801 | }, | |
802 | { | |
803 | 1249, | |
804 | "建長", | |
805 | "けんちょう", | |
806 | }, | |
807 | { | |
808 | 1256, | |
809 | "康元", | |
810 | "こうげん", | |
811 | }, | |
812 | { | |
813 | 1257, | |
814 | "正嘉", | |
815 | "しょうか", | |
816 | }, | |
817 | { | |
818 | 1259, | |
819 | "正元", | |
820 | "しょうげん", | |
821 | }, | |
822 | { | |
823 | 1260, | |
824 | "文応", | |
825 | "ぶんおう", | |
826 | }, | |
827 | { | |
828 | 1261, | |
829 | "弘長", | |
830 | "こうちょう", | |
831 | }, | |
832 | { | |
833 | 1264, | |
834 | "文永", | |
835 | "ぶんえい", | |
836 | }, | |
837 | { | |
838 | 1275, | |
839 | "建治", | |
840 | "けんじ", | |
841 | }, | |
842 | { | |
843 | 1278, | |
844 | "弘安", | |
845 | "こうあん", | |
846 | }, | |
847 | { | |
848 | 1288, | |
849 | "正応", | |
850 | "しょうおう", | |
851 | }, | |
852 | { | |
853 | 1293, | |
854 | "永仁", | |
855 | "えいにん", | |
856 | }, | |
857 | { | |
858 | 1299, | |
859 | "正安", | |
860 | "しょうあん", | |
861 | }, | |
862 | { | |
863 | 1302, | |
864 | "乾元", | |
865 | "けんげん", | |
866 | }, | |
867 | { | |
868 | 1303, | |
869 | "嘉元", | |
870 | "かげん", | |
871 | }, | |
872 | { | |
873 | 1306, | |
874 | "徳治", | |
875 | "とくじ", | |
876 | }, | |
877 | { | |
878 | 1308, | |
879 | "延慶", | |
880 | "えんぎょう", | |
881 | }, | |
882 | { | |
883 | 1311, | |
884 | "応長", | |
885 | "おうちょう", | |
886 | }, | |
887 | { | |
888 | 1312, | |
889 | "正和", | |
890 | "しょうわ", | |
891 | }, | |
892 | { | |
893 | 1317, | |
894 | "文保", | |
895 | "ぶんぽう", | |
896 | }, | |
897 | { | |
898 | 1319, | |
899 | "元応", | |
900 | "げんおう", | |
901 | }, | |
902 | { | |
903 | 1321, | |
904 | "元亨", | |
905 | "げんこう", | |
906 | }, | |
907 | { | |
908 | 1324, | |
909 | "正中", | |
910 | "しょうちゅう", | |
911 | }, | |
912 | { | |
913 | 1326, | |
914 | "嘉暦", | |
915 | "かりゃく", | |
916 | }, | |
917 | { | |
918 | 1329, | |
919 | "元徳", | |
920 | "げんとく", | |
921 | }, | |
922 | { | |
923 | 1331, | |
924 | "元弘", | |
925 | "げんこう", | |
926 | }, | |
927 | { | |
928 | 1334, | |
929 | "建武", | |
930 | "けんむ", | |
931 | }, | |
932 | { | |
933 | 1336, | |
934 | "延元", | |
935 | "えんげん", | |
936 | }, | |
937 | { | |
938 | 1340, | |
939 | "興国", | |
940 | "こうこく", | |
941 | }, | |
942 | { | |
943 | 1346, | |
944 | "正平", | |
945 | "しょうへい", | |
946 | }, | |
947 | { | |
948 | 1370, | |
949 | "建徳", | |
950 | "けんとく", | |
951 | }, | |
952 | { | |
953 | 1372, | |
954 | "文中", | |
955 | "ぶんちゅう", | |
956 | }, | |
957 | { | |
958 | 1375, | |
959 | "天授", | |
960 | "てんじゅ", | |
961 | }, | |
962 | { | |
963 | 1381, | |
964 | "弘和", | |
965 | "こうわ", | |
966 | }, | |
967 | { | |
968 | 1384, | |
969 | "元中", | |
970 | "げんちゅう", | |
971 | }, | |
972 | { | |
973 | 1390, | |
974 | "明徳", | |
975 | "めいとく", | |
976 | }, | |
977 | { | |
978 | 1394, | |
979 | "応永", | |
980 | "おうえい", | |
981 | }, | |
982 | { | |
983 | 1428, | |
984 | "正長", | |
985 | "しょうちょう", | |
986 | }, | |
987 | { | |
988 | 1429, | |
989 | "永享", | |
990 | "えいきょう", | |
991 | }, | |
992 | { | |
993 | 1441, | |
994 | "嘉吉", | |
995 | "かきつ", | |
996 | }, | |
997 | { | |
998 | 1444, | |
999 | "文安", | |
1000 | "ぶんあん", | |
1001 | }, | |
1002 | { | |
1003 | 1449, | |
1004 | "宝徳", | |
1005 | "ほうとく", | |
1006 | }, | |
1007 | { | |
1008 | 1452, | |
1009 | "享徳", | |
1010 | "きょうとく", | |
1011 | }, | |
1012 | { | |
1013 | 1455, | |
1014 | "康正", | |
1015 | "こうしょう", | |
1016 | }, | |
1017 | { | |
1018 | 1457, | |
1019 | "長禄", | |
1020 | "ちょうろく", | |
1021 | }, | |
1022 | { | |
1023 | 1460, | |
1024 | "寛正", | |
1025 | "かんしょう", | |
1026 | }, | |
1027 | { | |
1028 | 1466, | |
1029 | "文正", | |
1030 | "ぶんしょう", | |
1031 | }, | |
1032 | { | |
1033 | 1467, | |
1034 | "応仁", | |
1035 | "おうにん", | |
1036 | }, | |
1037 | { | |
1038 | 1469, | |
1039 | "文明", | |
1040 | "ぶんめい", | |
1041 | }, | |
1042 | { | |
1043 | 1487, | |
1044 | "長享", | |
1045 | "ちょうきょう", | |
1046 | }, | |
1047 | { | |
1048 | 1489, | |
1049 | "延徳", | |
1050 | "えんとく", | |
1051 | }, | |
1052 | { | |
1053 | 1492, | |
1054 | "明応", | |
1055 | "めいおう", | |
1056 | }, | |
1057 | { | |
1058 | 1501, | |
1059 | "文亀", | |
1060 | "ぶんき", | |
1061 | }, | |
1062 | { | |
1063 | 1504, | |
1064 | "永正", | |
1065 | "えいしょう", | |
1066 | }, | |
1067 | { | |
1068 | 1521, | |
1069 | "大永", | |
1070 | "だいえい", | |
1071 | }, | |
1072 | { | |
1073 | 1528, | |
1074 | "享禄", | |
1075 | "きょうろく", | |
1076 | }, | |
1077 | { | |
1078 | 1532, | |
1079 | "天文", | |
1080 | "てんぶん", | |
1081 | }, | |
1082 | { | |
1083 | 1555, | |
1084 | "弘治", | |
1085 | "こうじ", | |
1086 | }, | |
1087 | { | |
1088 | 1558, | |
1089 | "永禄", | |
1090 | "えいろく", | |
1091 | }, | |
1092 | { | |
1093 | 1570, | |
1094 | "元亀", | |
1095 | "げんき", | |
1096 | }, | |
1097 | { | |
1098 | 1573, | |
1099 | "天正", | |
1100 | "てんしょう", | |
1101 | }, | |
1102 | { | |
1103 | 1592, | |
1104 | "文禄", | |
1105 | "ぶんろく", | |
1106 | }, | |
1107 | { | |
1108 | 1596, | |
1109 | "慶長", | |
1110 | "けいちょう", | |
1111 | }, | |
1112 | { | |
1113 | 1615, | |
1114 | "元和", | |
1115 | "げんな", | |
1116 | }, | |
1117 | { | |
1118 | 1624, | |
1119 | "寛永", | |
1120 | "かんえい", | |
1121 | }, | |
1122 | { | |
1123 | 1644, | |
1124 | "正保", | |
1125 | "しょうほう", | |
1126 | }, | |
1127 | { | |
1128 | 1648, | |
1129 | "慶安", | |
1130 | "けいあん", | |
1131 | }, | |
1132 | { | |
1133 | 1652, | |
1134 | "承応", | |
1135 | "じょうおう", | |
1136 | }, | |
1137 | { | |
1138 | 1655, | |
1139 | "明暦", | |
1140 | "めいれき", | |
1141 | }, | |
1142 | { | |
1143 | 1658, | |
1144 | "万治", | |
1145 | "まんじ", | |
1146 | }, | |
1147 | { | |
1148 | 1661, | |
1149 | "寛文", | |
1150 | "かんぶん", | |
1151 | }, | |
1152 | { | |
1153 | 1673, | |
1154 | "延宝", | |
1155 | "えんぽう", | |
1156 | }, | |
1157 | { | |
1158 | 1681, | |
1159 | "天和", | |
1160 | "てんな", | |
1161 | }, | |
1162 | { | |
1163 | 1684, | |
1164 | "貞享", | |
1165 | "じょうきょう", | |
1166 | }, | |
1167 | { | |
1168 | 1688, | |
1169 | "元禄", | |
1170 | "げんろく", | |
1171 | }, | |
1172 | { | |
1173 | 1704, | |
1174 | "宝永", | |
1175 | "ほうえい", | |
1176 | }, | |
1177 | { | |
1178 | 1711, | |
1179 | "正徳", | |
1180 | "しょうとく", | |
1181 | }, | |
1182 | { | |
1183 | 1716, | |
1184 | "享保", | |
1185 | "きょうほ", | |
1186 | }, | |
1187 | { | |
1188 | 1736, | |
1189 | "元文", | |
1190 | "げんぶん", | |
1191 | }, | |
1192 | { | |
1193 | 1741, | |
1194 | "寛保", | |
1195 | "かんぽ", | |
1196 | }, | |
1197 | { | |
1198 | 1744, | |
1199 | "延享", | |
1200 | "えんきょう", | |
1201 | }, | |
1202 | { | |
1203 | 1748, | |
1204 | "寛延", | |
1205 | "かんえん", | |
1206 | }, | |
1207 | { | |
1208 | 1751, | |
1209 | "宝暦", | |
1210 | "ほうれき", | |
1211 | }, | |
1212 | { | |
1213 | 1764, | |
1214 | "明和", | |
1215 | "めいわ", | |
1216 | }, | |
1217 | { | |
1218 | 1772, | |
1219 | "安永", | |
1220 | "あんえい", | |
1221 | }, | |
1222 | { | |
1223 | 1781, | |
1224 | "天明", | |
1225 | "てんめい", | |
1226 | }, | |
1227 | { | |
1228 | 1789, | |
1229 | "寛政", | |
1230 | "かんせい", | |
1231 | }, | |
1232 | { | |
1233 | 1801, | |
1234 | "享和", | |
1235 | "きょうわ", | |
1236 | }, | |
1237 | { | |
1238 | 1804, | |
1239 | "文化", | |
1240 | "ぶんか", | |
1241 | }, | |
1242 | { | |
1243 | 1818, | |
1244 | "文政", | |
1245 | "ぶんせい", | |
1246 | }, | |
1247 | { | |
1248 | 1830, | |
1249 | "天保", | |
1250 | "てんぽう", | |
1251 | }, | |
1252 | { | |
1253 | 1844, | |
1254 | "弘化", | |
1255 | "こうか", | |
1256 | }, | |
1257 | { | |
1258 | 1848, | |
1259 | "嘉永", | |
1260 | "かえい", | |
1261 | }, | |
1262 | { | |
1263 | 1854, | |
1264 | "安政", | |
1265 | "あんせい", | |
1266 | }, | |
1267 | { | |
1268 | 1860, | |
1269 | "万延", | |
1270 | "まんえん", | |
1271 | }, | |
1272 | { | |
1273 | 1861, | |
1274 | "文久", | |
1275 | "ぶんきゅう", | |
1276 | }, | |
1277 | { | |
1278 | 1864, | |
1279 | "元治", | |
1280 | "げんじ", | |
1281 | }, | |
1282 | { | |
1283 | 1865, | |
1284 | "慶応", | |
1285 | "けいおう", | |
1286 | }, | |
1287 | { | |
1288 | 1868, | |
1289 | "明治", | |
1290 | "めいじ", | |
1291 | }, | |
1292 | { | |
1293 | 1912, | |
1294 | "大正", | |
1295 | "たいしょう", | |
1296 | }, | |
1297 | { | |
1298 | 1926, | |
1299 | "昭和", | |
1300 | "しょうわ", | |
1301 | }, | |
1302 | { | |
1303 | 1989, | |
1304 | "平成", | |
1305 | "へいせい", | |
1306 | }, | |
1307 | { | |
1308 | 2019, | |
1309 | "令和", | |
1310 | "れいわ", | |
1311 | }}; | |
139 | {645, "大化", "たいか"}, | |
140 | {650, "白雉", "はくち"}, | |
141 | {686, "朱鳥", "しゅちょう"}, | |
142 | {701, "大宝", "たいほう"}, | |
143 | {704, "慶雲", "けいうん"}, | |
144 | {708, "和銅", "わどう"}, | |
145 | {715, "霊亀", "れいき"}, | |
146 | {717, "養老", "ようろう"}, | |
147 | {724, "神亀", "じんき"}, | |
148 | {729, "天平", "てんぴょう"}, | |
149 | {749, "天平感宝", "てんぴょうかんぽう"}, | |
150 | {749, "天平勝宝", "てんぴょうしょうほう"}, | |
151 | {757, "天平宝字", "てんぴょうほうじ"}, | |
152 | {765, "天平神護", "てんぴょうじんご"}, | |
153 | {767, "神護景雲", "じんごけいうん"}, | |
154 | {770, "宝亀", "ほうき"}, | |
155 | {781, "天応", "てんおう"}, | |
156 | {782, "延暦", "えんりゃく"}, | |
157 | {806, "大同", "たいどう"}, | |
158 | {810, "弘仁", "こうにん"}, | |
159 | {824, "天長", "てんちょう"}, | |
160 | {834, "承和", "じょうわ"}, | |
161 | {848, "嘉祥", "かしょう"}, | |
162 | {851, "仁寿", "にんじゅ"}, | |
163 | {854, "斉衡", "さいこう"}, | |
164 | {857, "天安", "てんなん"}, | |
165 | {859, "貞観", "じょうかん"}, | |
166 | {877, "元慶", "がんぎょう"}, | |
167 | {885, "仁和", "にんな"}, | |
168 | {889, "寛平", "かんぴょう"}, | |
169 | {898, "昌泰", "しょうたい"}, | |
170 | {901, "延喜", "えんぎ"}, | |
171 | {923, "延長", "えんちょう"}, | |
172 | {931, "承平", "じょうへい"}, | |
173 | {938, "天慶", "てんぎょう"}, | |
174 | {947, "天暦", "てんりゃく"}, | |
175 | {957, "天徳", "てんとく"}, | |
176 | {961, "応和", "おうわ"}, | |
177 | {964, "康保", "こうほう"}, | |
178 | {968, "安和", "あんな"}, | |
179 | {970, "天禄", "てんろく"}, | |
180 | {973, "天延", "てんえん"}, | |
181 | {976, "貞元", "じょうげん"}, | |
182 | {978, "天元", "てんげん"}, | |
183 | {983, "永観", "えいかん"}, | |
184 | {985, "寛和", "かんな"}, | |
185 | {987, "永延", "えいえん"}, | |
186 | {989, "永祚", "えいそ"}, | |
187 | {990, "正暦", "しょうりゃく"}, | |
188 | {995, "長徳", "ちょうとく"}, | |
189 | {999, "長保", "ちょうほう"}, | |
190 | {1004, "寛弘", "かんこう"}, | |
191 | {1012, "長和", "ちょうわ"}, | |
192 | {1017, "寛仁", "かんにん"}, | |
193 | {1021, "治安", "じあん"}, | |
194 | {1024, "万寿", "まんじゅ"}, | |
195 | {1028, "長元", "ちょうげん"}, | |
196 | {1037, "長暦", "ちょうりゃく"}, | |
197 | {1040, "長久", "ちょうきゅう"}, | |
198 | {1044, "寛徳", "かんとく"}, | |
199 | {1046, "永承", "えいしょう"}, | |
200 | {1053, "天喜", "てんき"}, | |
201 | {1058, "康平", "こうへい"}, | |
202 | {1065, "治暦", "じりゃく"}, | |
203 | {1069, "延久", "えんきゅう"}, | |
204 | {1074, "承保", "じょうほう"}, | |
205 | {1077, "承暦", "じょうりゃく"}, | |
206 | {1081, "永保", "えいほ"}, | |
207 | {1084, "応徳", "おうとく"}, | |
208 | {1087, "寛治", "かんじ"}, | |
209 | {1094, "嘉保", "かほう"}, | |
210 | {1096, "永長", "えいちょう"}, | |
211 | {1097, "承徳", "じょうとく"}, | |
212 | {1099, "康和", "こうわ"}, | |
213 | {1104, "長治", "ちょうじ"}, | |
214 | {1106, "嘉承", "かしょう"}, | |
215 | {1108, "天仁", "てんにん"}, | |
216 | {1110, "天永", "てんえい"}, | |
217 | {1113, "永久", "えいきゅう"}, | |
218 | {1118, "元永", "げんえい"}, | |
219 | {1120, "保安", "ほうあん"}, | |
220 | {1124, "天治", "てんじ"}, | |
221 | {1126, "大治", "だいじ"}, | |
222 | {1131, "天承", "てんじょう"}, | |
223 | {1132, "長承", "ちょうじょう"}, | |
224 | {1135, "保延", "ほうえん"}, | |
225 | {1141, "永治", "えいじ"}, | |
226 | {1142, "康治", "こうじ"}, | |
227 | {1144, "天養", "てんよう"}, | |
228 | {1145, "久安", "きゅうあん"}, | |
229 | {1151, "仁平", "にんぺい"}, | |
230 | {1154, "久寿", "きゅうじゅ"}, | |
231 | {1156, "保元", "ほうげん"}, | |
232 | {1159, "平治", "へいじ"}, | |
233 | {1160, "永暦", "えいりゃく"}, | |
234 | {1161, "応保", "おうほ"}, | |
235 | {1163, "長寛", "ちょうかん"}, | |
236 | {1165, "永万", "えいまん"}, | |
237 | {1166, "仁安", "にんあん"}, | |
238 | {1169, "嘉応", "かおう"}, | |
239 | {1171, "承安", "しょうあん"}, | |
240 | {1175, "安元", "あんげん"}, | |
241 | {1177, "治承", "じしょう"}, | |
242 | {1181, "養和", "ようわ"}, | |
243 | {1182, "寿永", "じゅえい"}, | |
244 | {1184, "元暦", "げんりゃく"}, | |
245 | {1185, "文治", "ぶんじ"}, | |
246 | {1190, "建久", "けんきゅう"}, | |
247 | {1199, "正治", "しょうじ"}, | |
248 | {1201, "建仁", "けんにん"}, | |
249 | {1204, "元久", "げんきゅう"}, | |
250 | {1206, "建永", "けんえい"}, | |
251 | {1207, "承元", "じょうげん"}, | |
252 | {1211, "建暦", "けんりゃく"}, | |
253 | {1213, "建保", "けんぽう"}, | |
254 | {1219, "承久", "しょうきゅう"}, | |
255 | {1222, "貞応", "じょうおう"}, | |
256 | {1224, "元仁", "げんにん"}, | |
257 | {1225, "嘉禄", "かろく"}, | |
258 | {1227, "安貞", "あんてい"}, | |
259 | {1229, "寛喜", "かんき"}, | |
260 | {1232, "貞永", "じょうえい"}, | |
261 | {1233, "天福", "てんぷく"}, | |
262 | {1234, "文暦", "ぶんりゃく"}, | |
263 | {1235, "嘉禎", "かてい"}, | |
264 | {1238, "暦仁", "りゃくにん"}, | |
265 | {1239, "延応", "えんおう"}, | |
266 | {1240, "仁治", "にんじゅ"}, | |
267 | {1243, "寛元", "かんげん"}, | |
268 | {1247, "宝治", "ほうじ"}, | |
269 | {1249, "建長", "けんちょう"}, | |
270 | {1256, "康元", "こうげん"}, | |
271 | {1257, "正嘉", "しょうか"}, | |
272 | {1259, "正元", "しょうげん"}, | |
273 | {1260, "文応", "ぶんおう"}, | |
274 | {1261, "弘長", "こうちょう"}, | |
275 | {1264, "文永", "ぶんえい"}, | |
276 | {1275, "建治", "けんじ"}, | |
277 | {1278, "弘安", "こうあん"}, | |
278 | {1288, "正応", "しょうおう"}, | |
279 | {1293, "永仁", "えいにん"}, | |
280 | {1299, "正安", "しょうあん"}, | |
281 | {1302, "乾元", "けんげん"}, | |
282 | {1303, "嘉元", "かげん"}, | |
283 | {1306, "徳治", "とくじ"}, | |
284 | {1308, "延慶", "えんぎょう"}, | |
285 | {1311, "応長", "おうちょう"}, | |
286 | {1312, "正和", "しょうわ"}, | |
287 | {1317, "文保", "ぶんぽう"}, | |
288 | {1319, "元応", "げんおう"}, | |
289 | {1321, "元亨", "げんこう"}, | |
290 | {1324, "正中", "しょうちゅう"}, | |
291 | {1326, "嘉暦", "かりゃく"}, | |
292 | {1329, "元徳", "げんとく"}, | |
293 | {1331, "元弘", "げんこう"}, | |
294 | {1334, "建武", "けんむ"}, | |
295 | {1336, "延元", "えんげん"}, | |
296 | {1340, "興国", "こうこく"}, | |
297 | {1346, "正平", "しょうへい"}, | |
298 | {1370, "建徳", "けんとく"}, | |
299 | {1372, "文中", "ぶんちゅう"}, | |
300 | {1375, "天授", "てんじゅ"}, | |
301 | {1381, "弘和", "こうわ"}, | |
302 | {1384, "元中", "げんちゅう"}, | |
303 | {1390, "明徳", "めいとく"}, | |
304 | {1394, "応永", "おうえい"}, | |
305 | {1428, "正長", "しょうちょう"}, | |
306 | {1429, "永享", "えいきょう"}, | |
307 | {1441, "嘉吉", "かきつ"}, | |
308 | {1444, "文安", "ぶんあん"}, | |
309 | {1449, "宝徳", "ほうとく"}, | |
310 | {1452, "享徳", "きょうとく"}, | |
311 | {1455, "康正", "こうしょう"}, | |
312 | {1457, "長禄", "ちょうろく"}, | |
313 | {1460, "寛正", "かんしょう"}, | |
314 | {1466, "文正", "ぶんしょう"}, | |
315 | {1467, "応仁", "おうにん"}, | |
316 | {1469, "文明", "ぶんめい"}, | |
317 | {1487, "長享", "ちょうきょう"}, | |
318 | {1489, "延徳", "えんとく"}, | |
319 | {1492, "明応", "めいおう"}, | |
320 | {1501, "文亀", "ぶんき"}, | |
321 | {1504, "永正", "えいしょう"}, | |
322 | {1521, "大永", "だいえい"}, | |
323 | {1528, "享禄", "きょうろく"}, | |
324 | {1532, "天文", "てんぶん"}, | |
325 | {1555, "弘治", "こうじ"}, | |
326 | {1558, "永禄", "えいろく"}, | |
327 | {1570, "元亀", "げんき"}, | |
328 | {1573, "天正", "てんしょう"}, | |
329 | {1592, "文禄", "ぶんろく"}, | |
330 | {1596, "慶長", "けいちょう"}, | |
331 | {1615, "元和", "げんな"}, | |
332 | {1624, "寛永", "かんえい"}, | |
333 | {1644, "正保", "しょうほう"}, | |
334 | {1648, "慶安", "けいあん"}, | |
335 | {1652, "承応", "じょうおう"}, | |
336 | {1655, "明暦", "めいれき"}, | |
337 | {1658, "万治", "まんじ"}, | |
338 | {1661, "寛文", "かんぶん"}, | |
339 | {1673, "延宝", "えんぽう"}, | |
340 | {1681, "天和", "てんな"}, | |
341 | {1684, "貞享", "じょうきょう"}, | |
342 | {1688, "元禄", "げんろく"}, | |
343 | {1704, "宝永", "ほうえい"}, | |
344 | {1711, "正徳", "しょうとく"}, | |
345 | {1716, "享保", "きょうほ"}, | |
346 | {1736, "元文", "げんぶん"}, | |
347 | {1741, "寛保", "かんぽ"}, | |
348 | {1744, "延享", "えんきょう"}, | |
349 | {1748, "寛延", "かんえん"}, | |
350 | {1751, "宝暦", "ほうれき"}, | |
351 | {1764, "明和", "めいわ"}, | |
352 | {1772, "安永", "あんえい"}, | |
353 | {1781, "天明", "てんめい"}, | |
354 | {1789, "寛政", "かんせい"}, | |
355 | {1801, "享和", "きょうわ"}, | |
356 | {1804, "文化", "ぶんか"}, | |
357 | {1818, "文政", "ぶんせい"}, | |
358 | {1830, "天保", "てんぽう"}, | |
359 | {1844, "弘化", "こうか"}, | |
360 | {1848, "嘉永", "かえい"}, | |
361 | {1854, "安政", "あんせい"}, | |
362 | {1860, "万延", "まんえん"}, | |
363 | {1861, "文久", "ぶんきゅう"}, | |
364 | {1864, "元治", "げんじ"}, | |
365 | {1865, "慶応", "けいおう"}, | |
366 | {1868, "明治", "めいじ"}, | |
367 | {1912, "大正", "たいしょう"}, | |
368 | {1926, "昭和", "しょうわ"}, | |
369 | {1989, "平成", "へいせい"}, | |
370 | {2019, "令和", "れいわ"}}; | |
1312 | 371 | |
1313 | 372 | const YearData kNorthEraData[] = { |
1314 | 373 | // "元徳", "建武" and "明徳" are used for both south and north courts. |
1315 | { | |
1316 | 1329, | |
1317 | "元徳", | |
1318 | "げんとく", | |
1319 | }, | |
1320 | { | |
1321 | 1332, | |
1322 | "正慶", | |
1323 | "しょうけい", | |
1324 | }, | |
1325 | { | |
1326 | 1334, | |
1327 | "建武", | |
1328 | "けんむ", | |
1329 | }, | |
1330 | { | |
1331 | 1338, | |
1332 | "暦応", | |
1333 | "りゃくおう", | |
1334 | }, | |
1335 | { | |
1336 | 1342, | |
1337 | "康永", | |
1338 | "こうえい", | |
1339 | }, | |
1340 | { | |
1341 | 1345, | |
1342 | "貞和", | |
1343 | "じょうわ", | |
1344 | }, | |
1345 | { | |
1346 | 1350, | |
1347 | "観応", | |
1348 | "かんおう", | |
1349 | }, | |
1350 | { | |
1351 | 1352, | |
1352 | "文和", | |
1353 | "ぶんわ", | |
1354 | }, | |
1355 | { | |
1356 | 1356, | |
1357 | "延文", | |
1358 | "えんぶん", | |
1359 | }, | |
1360 | { | |
1361 | 1361, | |
1362 | "康安", | |
1363 | "こうあん", | |
1364 | }, | |
1365 | { | |
1366 | 1362, | |
1367 | "貞治", | |
1368 | "じょうじ", | |
1369 | }, | |
1370 | { | |
1371 | 1368, | |
1372 | "応安", | |
1373 | "おうあん", | |
1374 | }, | |
1375 | { | |
1376 | 1375, | |
1377 | "永和", | |
1378 | "えいわ", | |
1379 | }, | |
1380 | { | |
1381 | 1379, | |
1382 | "康暦", | |
1383 | "こうりゃく", | |
1384 | }, | |
1385 | { | |
1386 | 1381, | |
1387 | "永徳", | |
1388 | "えいとく", | |
1389 | }, | |
1390 | { | |
1391 | 1384, | |
1392 | "至徳", | |
1393 | "しとく", | |
1394 | }, | |
1395 | { | |
1396 | 1387, | |
1397 | "嘉慶", | |
1398 | "かけい", | |
1399 | }, | |
1400 | { | |
1401 | 1389, | |
1402 | "康応", | |
1403 | "こうおう", | |
1404 | }, | |
1405 | { | |
1406 | 1390, | |
1407 | "明徳", | |
1408 | "めいとく", | |
1409 | }}; | |
1410 | ||
1411 | const char *kWeekDayString[] = { | |
1412 | "日", "月", "火", "水", "木", "金", "土", | |
1413 | }; | |
1414 | ||
1415 | const char kDateDescription[] = "日付"; | |
1416 | const char kTimeDescription[] = "時刻"; | |
374 | {1329, "元徳", "げんとく"}, | |
375 | {1332, "正慶", "しょうけい"}, | |
376 | {1334, "建武", "けんむ"}, | |
377 | {1338, "暦応", "りゃくおう"}, | |
378 | {1342, "康永", "こうえい"}, | |
379 | {1345, "貞和", "じょうわ"}, | |
380 | {1350, "観応", "かんおう"}, | |
381 | {1352, "文和", "ぶんわ"}, | |
382 | {1356, "延文", "えんぶん"}, | |
383 | {1361, "康安", "こうあん"}, | |
384 | {1362, "貞治", "じょうじ"}, | |
385 | {1368, "応安", "おうあん"}, | |
386 | {1375, "永和", "えいわ"}, | |
387 | {1379, "康暦", "こうりゃく"}, | |
388 | {1381, "永徳", "えいとく"}, | |
389 | {1384, "至徳", "しとく"}, | |
390 | {1387, "嘉慶", "かけい"}, | |
391 | {1389, "康応", "こうおう"}, | |
392 | {1390, "明徳", "めいとく"}}; | |
1417 | 393 | |
1418 | 394 | bool PrintUint32(const char *format, uint32 num, char *buf, size_t buf_size) { |
1419 | 395 | const int ret = std::snprintf(buf, buf_size, format, num); |
1524 | 500 | c->description = description; |
1525 | 501 | } |
1526 | 502 | } |
1527 | ||
1528 | enum { | |
1529 | REWRITE_YEAR, | |
1530 | REWRITE_DATE, | |
1531 | REWRITE_MONTH, | |
1532 | REWRITE_CURRENT_TIME, | |
1533 | REWRITE_DATE_AND_CURRENT_TIME | |
1534 | }; | |
1535 | 503 | |
1536 | 504 | bool AdToEraForCourt(const YearData *data, int size, int year, |
1537 | 505 | std::vector<std::string> *results) { |
1770 | 738 | // The order is south to north. |
1771 | 739 | std::vector<std::string> eras; |
1772 | 740 | bool r = false; |
1773 | r = AdToEraForCourt(kEraData, arraysize(kEraData), year, &eras); | |
741 | r = AdToEraForCourt(kEraData, std::size(kEraData), year, &eras); | |
1774 | 742 | if (year > 1331 && year < 1393) { |
1775 | r |= AdToEraForCourt(kNorthEraData, arraysize(kNorthEraData), year, &eras); | |
743 | r |= AdToEraForCourt(kNorthEraData, std::size(kNorthEraData), year, &eras); | |
1776 | 744 | } |
1777 | 745 | // 1334 requires dedupe |
1778 | 746 | for (int i = 0; i < eras.size(); ++i) { |
1794 | 762 | std::vector<std::string> *descriptions) { |
1795 | 763 | bool ret = false; |
1796 | 764 | // The order is south to north, older to newer |
1797 | ret |= EraToAdForCourt(kEraData, arraysize(kEraData), key, results, | |
765 | ret |= EraToAdForCourt(kEraData, std::size(kEraData), key, results, | |
1798 | 766 | descriptions); |
1799 | ret |= EraToAdForCourt(kNorthEraData, arraysize(kNorthEraData), key, results, | |
767 | ret |= EraToAdForCourt(kNorthEraData, std::size(kNorthEraData), key, results, | |
1800 | 768 | descriptions); |
1801 | 769 | return ret; |
1802 | 770 | } |
1841 | 809 | return true; |
1842 | 810 | } |
1843 | 811 | |
1844 | bool DateRewriter::RewriteTime(Segment *segment, const char *key, | |
1845 | const char *value, const char *description, | |
1846 | int type, int diff) { | |
1847 | if (segment->key() != key) { // only exact match | |
1848 | return false; | |
1849 | } | |
1850 | ||
1851 | const size_t kMinSize = 10; | |
1852 | const size_t size = std::min(kMinSize, segment->candidates_size()); | |
1853 | ||
1854 | for (size_t cand_idx = 0; cand_idx < size; ++cand_idx) { | |
1855 | const Segment::Candidate &cand = segment->candidate(cand_idx); | |
1856 | if (cand.value != value) { | |
1857 | continue; | |
1858 | } | |
1859 | // Date candidates are too many, therefore highest candidate show at most | |
1860 | // 3rd. | |
1861 | // TODO(nona): learn date candidate even if the date is changed. | |
1862 | const size_t kMinimumDateCandidateIdx = 3; | |
1863 | const size_t insert_idx = | |
1864 | (size < kMinimumDateCandidateIdx) | |
1865 | ? size | |
1866 | : std::max(cand_idx + 1, kMinimumDateCandidateIdx); | |
1867 | ||
1868 | struct tm t_st; | |
1869 | std::vector<std::string> era; | |
1870 | switch (type) { | |
1871 | case REWRITE_DATE: { | |
1872 | if (!Clock::GetTmWithOffsetSecond(&t_st, diff * 86400)) { | |
1873 | LOG(ERROR) << "GetTmWithOffsetSecond() failed"; | |
1874 | return false; | |
812 | namespace { | |
813 | absl::CivilMinute GetCivilMinuteWithDiff(int type, int diff) { | |
814 | const absl::Time at = Clock::GetAbslTime(); | |
815 | const absl::TimeZone &tz = Clock::GetTimeZone(); | |
816 | ||
817 | if (type == DATE) { | |
818 | const absl::CivilDay c_day = absl::ToCivilDay(at, tz) + diff; | |
819 | return absl::CivilMinute(c_day); | |
820 | } | |
821 | if (type == MONTH) { | |
822 | const absl::CivilMonth c_mon = absl::ToCivilMonth(at, tz) + diff; | |
823 | return absl::CivilMinute(c_mon); | |
824 | } | |
825 | if (type == YEAR) { | |
826 | const absl::CivilYear c_year = absl::ToCivilYear(at, tz) + diff; | |
827 | return absl::CivilMinute(c_year); | |
828 | } | |
829 | if (type == WEEKDAY) { | |
830 | const absl::CivilDay c_day = absl::ToCivilDay(at, tz); | |
831 | const int weekday = static_cast<int>(absl::GetWeekday(c_day)); | |
832 | const int weekday_diff = (diff + 7 - weekday) % 7; | |
833 | return c_day + weekday_diff; | |
834 | } | |
835 | ||
836 | return absl::ToCivilMinute(at, tz); | |
837 | } | |
838 | ||
839 | std::vector<std::string> GetConversions(const DateRewriter::DateData &data) { | |
840 | std::vector<std::string> results; | |
841 | const absl::CivilMinute cm = GetCivilMinuteWithDiff(data.type, data.diff); | |
842 | ||
843 | switch (data.type) { | |
844 | case DATE: | |
845 | case WEEKDAY: { | |
846 | DateRewriter::ConvertDateWithYear(cm.year(), cm.month(), cm.day(), | |
847 | &results); | |
848 | std::vector<std::string> era; | |
849 | if (DateRewriter::AdToEra(cm.year(), cm.month(), &era) && !era.empty()) { | |
850 | results.push_back( | |
851 | Util::StringPrintf("%s年%d月%d日", era[0], cm.month(), cm.day())); | |
852 | } | |
853 | const int weekday = static_cast<int>(absl::GetWeekday(cm)); | |
854 | results.push_back(Util::StringPrintf("%s曜日", kWeekDayString[weekday])); | |
855 | break; | |
856 | } | |
857 | ||
858 | case MONTH: { | |
859 | results.push_back(Util::StringPrintf("%d", cm.month())); | |
860 | results.push_back(Util::StringPrintf("%d月", cm.month())); | |
861 | break; | |
862 | } | |
863 | ||
864 | case YEAR: { | |
865 | results.push_back(Util::StringPrintf("%d", cm.year())); | |
866 | results.push_back(Util::StringPrintf("%d年", cm.year())); | |
867 | ||
868 | std::vector<std::string> era; | |
869 | if (DateRewriter::AdToEra(cm.year(), 0, /* unknown mounth */ &era) && | |
870 | !era.empty()) { | |
871 | for (auto rit = era.crbegin(); rit != era.crend(); ++rit) { | |
872 | results.push_back(Util::StringPrintf("%s年", *rit)); | |
1875 | 873 | } |
1876 | std::vector<std::string> results; | |
1877 | ConvertDateWithYear(t_st.tm_year + 1900, t_st.tm_mon + 1, t_st.tm_mday, | |
1878 | &results); | |
1879 | if (AdToEra(t_st.tm_year + 1900, t_st.tm_mon + 1, &era) && | |
1880 | !era.empty()) { | |
1881 | results.push_back(Util::StringPrintf("%s年%d月%d日", era[0].c_str(), | |
1882 | t_st.tm_mon + 1, t_st.tm_mday)); | |
1883 | } | |
1884 | results.push_back( | |
1885 | Util::StringPrintf("%s曜日", kWeekDayString[t_st.tm_wday])); | |
1886 | ||
1887 | for (std::vector<std::string>::reverse_iterator rit = results.rbegin(); | |
1888 | rit != results.rend(); ++rit) { | |
1889 | Insert(cand, insert_idx, *rit, description, segment); | |
1890 | } | |
1891 | return true; | |
1892 | 874 | } |
1893 | ||
1894 | case REWRITE_MONTH: { | |
1895 | if (!Clock::GetCurrentTm(&t_st)) { | |
1896 | LOG(ERROR) << "GetCurrentTm failed"; | |
1897 | return false; | |
1898 | } | |
1899 | const int month = (t_st.tm_mon + diff + 12) % 12 + 1; | |
1900 | Insert(cand, insert_idx, Util::StringPrintf("%d月", month), description, | |
1901 | segment); | |
1902 | Insert(cand, insert_idx, Util::StringPrintf("%d", month), description, | |
1903 | segment); | |
1904 | return true; | |
1905 | } | |
1906 | ||
1907 | case REWRITE_YEAR: { | |
1908 | if (!Clock::GetCurrentTm(&t_st)) { | |
1909 | LOG(ERROR) << "GetCurrentTm failed"; | |
1910 | return false; | |
1911 | } | |
1912 | const int year = (t_st.tm_year + diff + 1900); | |
1913 | if (AdToEra(year, 0, /* unknown mounth */ &era) && !era.empty()) { | |
1914 | for (const auto &e : era) { | |
1915 | Insert(cand, insert_idx, Util::StringPrintf("%s年", e.c_str()), | |
1916 | description, segment); | |
1917 | } | |
1918 | } | |
1919 | Insert(cand, insert_idx, Util::StringPrintf("%d年", year), description, | |
1920 | segment); | |
1921 | Insert(cand, insert_idx, Util::StringPrintf("%d", year), description, | |
1922 | segment); | |
1923 | return true; | |
1924 | } | |
1925 | ||
1926 | case REWRITE_CURRENT_TIME: { | |
1927 | if (!Clock::GetCurrentTm(&t_st)) { | |
1928 | LOG(ERROR) << "GetCurrentTm failed"; | |
1929 | return false; | |
1930 | } | |
1931 | std::vector<std::string> times; | |
1932 | ConvertTime(t_st.tm_hour, t_st.tm_min, ×); | |
1933 | for (std::vector<std::string>::reverse_iterator rit = times.rbegin(); | |
1934 | rit != times.rend(); ++rit) { | |
1935 | Insert(cand, insert_idx, *rit, description, segment); | |
1936 | } | |
1937 | return true; | |
1938 | } | |
1939 | ||
1940 | case REWRITE_DATE_AND_CURRENT_TIME: { | |
1941 | if (!Clock::GetCurrentTm(&t_st)) { | |
1942 | LOG(ERROR) << "GetCurrentTm failed"; | |
1943 | return false; | |
1944 | } | |
1945 | // Y/MM/DD H:MM | |
1946 | const std::string ymmddhmm = Util::StringPrintf( | |
1947 | "%d/%2.2d/%2.2d %2d:%2.2d", t_st.tm_year + 1900, t_st.tm_mon + 1, | |
1948 | t_st.tm_mday, t_st.tm_hour, t_st.tm_min); | |
1949 | Insert(cand, insert_idx, ymmddhmm, description, segment); | |
1950 | return true; | |
1951 | } | |
1952 | } | |
1953 | } | |
1954 | ||
1955 | return false; | |
1956 | } | |
875 | break; | |
876 | } | |
877 | ||
878 | case CURRENT_TIME: { | |
879 | DateRewriter::ConvertTime(cm.hour(), cm.minute(), &results); | |
880 | break; | |
881 | } | |
882 | ||
883 | case DATE_AND_CURRENT_TIME: { | |
884 | // Y/MM/DD H:MM | |
885 | const std::string ymmddhmm = | |
886 | Util::StringPrintf("%d/%2.2d/%2.2d %2d:%2.2d", cm.year(), cm.month(), | |
887 | cm.day(), cm.hour(), cm.minute()); | |
888 | results.push_back(ymmddhmm); | |
889 | break; | |
890 | } | |
891 | ||
892 | default: { | |
893 | // Unknown type | |
894 | } | |
895 | } | |
896 | return results; | |
897 | } | |
898 | } // namespace | |
1957 | 899 | |
1958 | 900 | bool DateRewriter::RewriteDate(Segment *segment) { |
1959 | for (size_t i = 0; i < arraysize(kDateData); ++i) { | |
1960 | if (RewriteTime(segment, kDateData[i].key, kDateData[i].value, | |
1961 | kDateData[i].description, REWRITE_DATE, | |
1962 | kDateData[i].diff)) { | |
1963 | VLOG(1) << "RewriteDate: " << kDateData[i].key << " " | |
1964 | << kDateData[i].value; | |
1965 | return true; | |
1966 | } | |
1967 | } | |
1968 | return false; | |
1969 | } | |
1970 | ||
1971 | bool DateRewriter::RewriteMonth(Segment *segment) { | |
1972 | for (size_t i = 0; i < arraysize(kMonthData); ++i) { | |
1973 | if (RewriteTime(segment, kMonthData[i].key, kMonthData[i].value, | |
1974 | kMonthData[i].description, REWRITE_MONTH, | |
1975 | kMonthData[i].diff)) { | |
1976 | VLOG(1) << "RewriteMonth: " << kMonthData[i].key << " " | |
1977 | << kMonthData[i].value; | |
1978 | return true; | |
1979 | } | |
1980 | } | |
1981 | return false; | |
1982 | } | |
1983 | ||
1984 | bool DateRewriter::RewriteYear(Segment *segment) { | |
1985 | for (size_t i = 0; i < arraysize(kYearData); ++i) { | |
1986 | if (RewriteTime(segment, kYearData[i].key, kYearData[i].value, | |
1987 | kYearData[i].description, REWRITE_YEAR, | |
1988 | kYearData[i].diff)) { | |
1989 | VLOG(1) << "RewriteYear: " << kYearData[i].key << " " | |
1990 | << kYearData[i].value; | |
1991 | return true; | |
1992 | } | |
1993 | } | |
1994 | return false; | |
1995 | } | |
1996 | ||
1997 | bool DateRewriter::RewriteWeekday(Segment *segment) { | |
1998 | struct tm t_st; | |
1999 | if (!Clock::GetCurrentTm(&t_st)) { | |
2000 | LOG(ERROR) << "GetCurrentTm failed"; | |
2001 | return false; | |
2002 | } | |
2003 | ||
2004 | for (size_t i = 0; i < arraysize(kWeekDayData); ++i) { | |
2005 | const int weekday = kWeekDayData[i].diff % 7; | |
2006 | const int additional_dates = (weekday + 7 - t_st.tm_wday) % 7; | |
2007 | if (RewriteTime(segment, kWeekDayData[i].key, kWeekDayData[i].value, | |
2008 | kWeekDayData[i].description, REWRITE_DATE, | |
2009 | additional_dates)) { | |
2010 | VLOG(1) << "RewriteWeekday: " << kWeekDayData[i].key << " " | |
2011 | << kWeekDayData[i].value; | |
2012 | return true; | |
2013 | } | |
2014 | } | |
2015 | ||
2016 | return false; | |
2017 | } | |
2018 | ||
2019 | bool DateRewriter::RewriteCurrentTime(Segment *segment) { | |
2020 | for (size_t i = 0; i < arraysize(kCurrentTimeData); ++i) { | |
2021 | if (RewriteTime(segment, kCurrentTimeData[i].key, kCurrentTimeData[i].value, | |
2022 | kCurrentTimeData[i].description, REWRITE_CURRENT_TIME, 0)) { | |
2023 | VLOG(1) << "RewriteCurrentTime: " << kCurrentTimeData[i].key << " " | |
2024 | << kCurrentTimeData[i].value; | |
2025 | return true; | |
2026 | } | |
2027 | } | |
2028 | return false; | |
2029 | } | |
2030 | ||
2031 | bool DateRewriter::RewriteDateAndCurrentTime(Segment *segment) { | |
2032 | for (size_t i = 0; i < arraysize(kDateAndCurrentTimeData); ++i) { | |
2033 | if (RewriteTime(segment, kDateAndCurrentTimeData[i].key, | |
2034 | kDateAndCurrentTimeData[i].value, | |
2035 | kDateAndCurrentTimeData[i].description, | |
2036 | REWRITE_DATE_AND_CURRENT_TIME, 0)) { | |
2037 | VLOG(1) << "RewriteDateAndCurrentTime: " << kDateAndCurrentTimeData[i].key | |
2038 | << " " << kDateAndCurrentTimeData[i].value; | |
2039 | return true; | |
2040 | } | |
2041 | } | |
2042 | return false; | |
901 | const std::string &key = segment->key(); | |
902 | auto rit = std::find_if(std::begin(kDateData), std::end(kDateData), | |
903 | [&key](auto data) { return key == data.key; }); | |
904 | if (rit == std::end(kDateData)) { | |
905 | return false; | |
906 | } | |
907 | const DateData &data = *rit; | |
908 | const std::vector<std::string> &conversions = GetConversions(data); | |
909 | ||
910 | if (conversions.empty()) { | |
911 | return false; | |
912 | } | |
913 | ||
914 | // Calculate insert_idx | |
915 | // Candidates will be inserted less than 10th candidate. | |
916 | const size_t kMaxIdx = 10; | |
917 | const size_t end_idx = std::min(kMaxIdx, segment->candidates_size()); | |
918 | size_t cand_idx = 0; | |
919 | for (cand_idx = 0; cand_idx < end_idx; ++cand_idx) { | |
920 | if (segment->candidate(cand_idx).value == data.value) { | |
921 | break; | |
922 | } | |
923 | } | |
924 | if (cand_idx == end_idx) { | |
925 | return false; | |
926 | } | |
927 | ||
928 | // Date candidates are too many, therefore highest candidate show at most 3rd. | |
929 | // TODO(nona): learn date candidate even if the date is changed. | |
930 | const size_t kMinIdx = 3; | |
931 | size_t insert_idx = std::min(std::max(kMinIdx, cand_idx + 1), end_idx); | |
932 | ||
933 | // Insert words. | |
934 | const Segment::Candidate &base_cand = segment->candidate(cand_idx); | |
935 | for (const string &conversion : conversions) { | |
936 | Insert(base_cand, insert_idx++, conversion, data.description, segment); | |
937 | } | |
938 | return true; | |
2043 | 939 | } |
2044 | 940 | |
2045 | 941 | bool DateRewriter::RewriteEra(Segment *current_segment, |
2085 | 981 | kInsertPosition, static_cast<int>(current_segment->candidates_size())); |
2086 | 982 | |
2087 | 983 | const char kDescription[] = "和暦"; |
2088 | for (int i = static_cast<int>(results.size()) - 1; i >= 0; --i) { | |
2089 | Insert(current_segment->candidate(0), position, results[i], kDescription, | |
984 | for (auto rit = results.crbegin(); rit != results.crend(); ++rit) { | |
985 | Insert(current_segment->candidate(0), position, *rit, kDescription, | |
2090 | 986 | current_segment); |
2091 | 987 | current_segment->mutable_candidate(position)->attributes &= |
2092 | 988 | ~Segment::Candidate::NO_VARIANTS_EXPANSION; |
2403 | 1299 | return false; |
2404 | 1300 | } |
2405 | 1301 | |
2406 | if (RewriteDate(seg) || RewriteWeekday(seg) || RewriteMonth(seg) || | |
2407 | RewriteYear(seg) || RewriteCurrentTime(seg) || | |
2408 | RewriteDateAndCurrentTime(seg)) { | |
1302 | if (RewriteDate(seg)) { | |
2409 | 1303 | modified = true; |
2410 | 1304 | } else if (i + 1 < segments->segments_size() && |
2411 | 1305 | RewriteEra(seg, segments->segment(i + 1))) { |
62 | 62 | bool Rewrite(const ConversionRequest &request, |
63 | 63 | Segments *segments) const override; |
64 | 64 | |
65 | private: | |
66 | FRIEND_TEST(DateRewriterTest, ADToERA); | |
67 | FRIEND_TEST(DateRewriterTest, ERAToAD); | |
68 | FRIEND_TEST(DateRewriterTest, ADToERAWithNewName); | |
69 | FRIEND_TEST(DateRewriterTest, NewEraNameTest); | |
70 | FRIEND_TEST(DateRewriterTest, ConvertTime); | |
71 | FRIEND_TEST(DateRewriterTest, ConvertDateTest); | |
72 | ||
73 | static bool RewriteTime(Segment *segment, const char *key, const char *value, | |
74 | const char *description, int type, int diff); | |
75 | static bool RewriteDate(Segment *segment); | |
76 | static bool RewriteMonth(Segment *segment); | |
77 | static bool RewriteYear(Segment *segment); | |
78 | static bool RewriteCurrentTime(Segment *segment); | |
79 | static bool RewriteDateAndCurrentTime(Segment *segment); | |
80 | static bool RewriteEra(Segment *current_segment, const Segment &next_segment); | |
81 | static bool RewriteAd(Segment *segment); | |
82 | static bool RewriteWeekday(Segment *segment); | |
83 | ||
84 | // When only one conversion segment has consecutive number characters, | |
85 | // this function adds date and time candidates. | |
86 | // e.g.) | |
87 | // key -> candidates will be added | |
88 | // ------------------------------------------------ | |
89 | // 0101 -> "1月1日、01/01、1時1分,午前1時1分、1:01" | |
90 | // 2020 -> "20時20分、午後8時20分、20:20" | |
91 | // 2930 -> "29時30分、29時半、午前5時30分、午前5時半" | |
92 | // 123 -> "1月23日、01/23、1:23" | |
93 | static bool RewriteConsecutiveDigits(const composer::Composer &composer, | |
94 | int insert_position, Segments *segments); | |
95 | ||
96 | // Helper functions for RewriteConsecutiveDigits(). | |
97 | static bool RewriteConsecutiveTwoDigits( | |
98 | absl::string_view str, | |
99 | std::vector<std::pair<std::string, const char *>> *results); | |
100 | static bool RewriteConsecutiveThreeDigits( | |
101 | absl::string_view str, | |
102 | std::vector<std::pair<std::string, const char *>> *results); | |
103 | static bool RewriteConsecutiveFourDigits( | |
104 | absl::string_view str, | |
105 | std::vector<std::pair<std::string, const char *>> *results); | |
65 | struct DateData { | |
66 | const char *key; | |
67 | const char *value; | |
68 | const char *description; | |
69 | int diff; // diff from the current time in day or month or year | |
70 | int type; // type of diff (e.g. year, month, date, etc). | |
71 | }; | |
106 | 72 | |
107 | 73 | // In general, Japanese era can be identified without the month. |
108 | 74 | // However, during the era migration time, we have to check the month., i.e., |
161 | 127 | // 2000: 2 : 29 -> "平成12年2月29日,2000年2月29日,2000-02-29,2000/02/29" |
162 | 128 | static bool ConvertDateWithYear(uint32 year, uint32 month, uint32 day, |
163 | 129 | std::vector<std::string> *results); |
130 | ||
131 | private: | |
132 | static bool RewriteDate(Segment *segment); | |
133 | static bool RewriteEra(Segment *current_segment, const Segment &next_segment); | |
134 | static bool RewriteAd(Segment *segment); | |
135 | ||
136 | // When only one conversion segment has consecutive number characters, | |
137 | // this function adds date and time candidates. | |
138 | // e.g.) | |
139 | // key -> candidates will be added | |
140 | // ------------------------------------------------ | |
141 | // 0101 -> "1月1日、01/01、1時1分,午前1時1分、1:01" | |
142 | // 2020 -> "20時20分、午後8時20分、20:20" | |
143 | // 2930 -> "29時30分、29時半、午前5時30分、午前5時半" | |
144 | // 123 -> "1月23日、01/23、1:23" | |
145 | static bool RewriteConsecutiveDigits(const composer::Composer &composer, | |
146 | int insert_position, Segments *segments); | |
147 | ||
148 | // Helper functions for RewriteConsecutiveDigits(). | |
149 | static bool RewriteConsecutiveTwoDigits( | |
150 | absl::string_view str, | |
151 | std::vector<std::pair<std::string, const char *>> *results); | |
152 | static bool RewriteConsecutiveThreeDigits( | |
153 | absl::string_view str, | |
154 | std::vector<std::pair<std::string, const char *>> *results); | |
155 | static bool RewriteConsecutiveFourDigits( | |
156 | absl::string_view str, | |
157 | std::vector<std::pair<std::string, const char *>> *results); | |
164 | 158 | }; |
165 | 159 | |
166 | 160 | } // namespace mozc |
59 | 59 | size_t offset = std::min(insert_pos, segment->candidates_size()); |
60 | 60 | |
61 | 61 | Segment::Candidate *c = segment->insert_candidate(offset); |
62 | if (c == NULL) { | |
62 | if (c == nullptr) { | |
63 | 63 | LOG(ERROR) << "cannot insert candidate at " << offset; |
64 | 64 | return false; |
65 | 65 | } |
89 | 89 | DictionaryGenerator::~DictionaryGenerator() {} |
90 | 90 | |
91 | 91 | void DictionaryGenerator::AddToken(const Token &token) { |
92 | Token *new_token = NULL; | |
92 | Token *new_token = nullptr; | |
93 | 93 | std::map<uint64, Token *>::const_iterator it = |
94 | 94 | token_map_->find(token.GetID()); |
95 | 95 | if (it != token_map_->end()) { |
69 | 69 | absl::string_view description, int cost, Segment *segment, |
70 | 70 | size_t *insert_position) { |
71 | 71 | Segment::Candidate *candidate = segment->insert_candidate(*insert_position); |
72 | if (candidate == NULL) { | |
72 | if (candidate == nullptr) { | |
73 | 73 | LOG(ERROR) << "cannot insert candidate at " << insert_position |
74 | 74 | << "th position nor tail of candidates."; |
75 | 75 | return false; |
198 | 198 | return false; |
199 | 199 | } |
200 | 200 | |
201 | CHECK(segments != NULL); | |
201 | CHECK(segments != nullptr); | |
202 | 202 | return RewriteCandidates(segments); |
203 | 203 | } |
204 | 204 |
140 | 140 | |
141 | 141 | bool FocusCandidateRewriter::Focus(Segments *segments, size_t segment_index, |
142 | 142 | int candidate_index) const { |
143 | if (segments == NULL) { | |
143 | if (segments == nullptr) { | |
144 | 144 | LOG(ERROR) << "Segments is NULL"; |
145 | 145 | return false; |
146 | 146 | } |
177 | 177 | int num_nest = 1; |
178 | 178 | for (size_t i = segment_index + 1; i < segments->segments_size(); ++i) { |
179 | 179 | Segment *target_right_seg = segments->mutable_segment(i); |
180 | if (target_right_seg == NULL || | |
180 | if (target_right_seg == nullptr || | |
181 | 181 | target_right_seg->candidates_size() <= 0) { |
182 | 182 | LOG(WARNING) << "target right seg is not valid"; |
183 | 183 | return false; |
213 | 213 | int num_nest = 1; |
214 | 214 | for (int i = segment_index - 1; i >= 0; --i) { |
215 | 215 | Segment *target_left_seg = segments->mutable_segment(i); |
216 | if (target_left_seg == NULL || | |
216 | if (target_left_seg == nullptr || | |
217 | 217 | target_left_seg->candidates_size() <= 0) { |
218 | 218 | LOG(WARNING) << "target left seg is not valid"; |
219 | 219 | return false; |
244 | 244 | int distance = 0; |
245 | 245 | for (size_t i = segment_index + 1; i < segments->segments_size(); ++i) { |
246 | 246 | Segment *target_right_seg = segments->mutable_segment(i); |
247 | if (target_right_seg == NULL || | |
247 | if (target_right_seg == nullptr || | |
248 | 248 | target_right_seg->candidates_size() <= 0) { |
249 | 249 | LOG(WARNING) << "target right seg is not valid"; |
250 | 250 | return false; |
65 | 65 | |
66 | 66 | class FortuneData { |
67 | 67 | public: |
68 | FortuneData() | |
69 | : fortune_type_(FORTUNE_TYPE_EXCELLENT_LUCK), | |
70 | last_update_yday_(-1), | |
71 | last_update_year_(-1) { | |
68 | FortuneData() : fortune_type_(FORTUNE_TYPE_EXCELLENT_LUCK) { | |
72 | 69 | ChangeFortune(); |
73 | 70 | } |
74 | 71 | |
75 | 72 | void ChangeFortune() { |
76 | 73 | const int *levels = kNormalLevels; |
77 | tm today; | |
78 | if (Clock::GetCurrentTm(&today)) { | |
79 | // Modify once per one day | |
80 | if (today.tm_yday == last_update_yday_ && | |
81 | today.tm_year == last_update_year_) { | |
82 | return; | |
83 | } | |
84 | last_update_yday_ = today.tm_yday; | |
85 | last_update_year_ = today.tm_year; | |
86 | // More happy at New Year's Day | |
87 | if (today.tm_yday == 0) { | |
88 | levels = kNewYearLevels; | |
89 | } else if (today.tm_mon == 2 && today.tm_mday == 3) { | |
90 | // It's my birthday :) | |
91 | levels = kMyBirthdayLevels; | |
92 | } else if (today.tm_mday == 13 && today.tm_wday == 5) { | |
93 | // Friday the 13th | |
94 | levels = kFriday13Levels; | |
95 | } | |
74 | ||
75 | const absl::Time at = Clock::GetAbslTime(); | |
76 | const absl::TimeZone &tz = Clock::GetTimeZone(); | |
77 | const absl::CivilDay today = absl::ToCivilDay(at, tz); | |
78 | ||
79 | // Modify once per one day | |
80 | if (today == last_updated_day_) { | |
81 | return; | |
82 | } | |
83 | last_updated_day_ = today; | |
84 | ||
85 | // More happy at New Year's Day | |
86 | if (today.month() == 1 && today.day() == 1) { | |
87 | levels = kNewYearLevels; | |
88 | } else if (today.month() == 3 && today.day() == 3) { | |
89 | // It's my birthday :) | |
90 | levels = kMyBirthdayLevels; | |
91 | } else if (today.day() == 13 && | |
92 | absl::GetWeekday(today) == absl::Weekday::friday) { | |
93 | // Friday the 13th | |
94 | levels = kFriday13Levels; | |
96 | 95 | } |
97 | 96 | uint32 random = 0; |
98 | 97 | Util::GetRandomSequence(reinterpret_cast<char *>(&random), sizeof(random)); |
99 | 98 | const int level = random % kMaxLevel; |
100 | for (int i = 0; i < arraysize(kNormalLevels); ++i) { | |
99 | for (int i = 0; i < std::size(kNormalLevels); ++i) { | |
101 | 100 | if (level <= levels[i]) { |
102 | 101 | fortune_type_ = static_cast<FortuneType>(i); |
103 | 102 | break; |
110 | 109 | |
111 | 110 | private: |
112 | 111 | FortuneType fortune_type_; |
113 | int last_update_yday_; | |
114 | int last_update_year_; | |
112 | absl::CivilDay last_updated_day_; | |
115 | 113 | }; |
116 | 114 | |
117 | 115 | // Insert Fortune message into the |segment| |
128 | 126 | size_t offset = std::min(insert_pos, segment->candidates_size()); |
129 | 127 | |
130 | 128 | Segment::Candidate *c = segment->insert_candidate(offset); |
131 | if (c == NULL) { | |
129 | if (c == nullptr) { | |
132 | 130 | LOG(ERROR) << "cannot insert candidate at " << offset; |
133 | 131 | return false; |
134 | 132 | } |
69 | 69 | void OutputExistenceHeader(const std::vector<std::string> &entries, |
70 | 70 | const std::string &data_namespace, std::ostream *ofs, |
71 | 71 | double error_rate) { |
72 | char *existence_data = NULL; | |
72 | char *existence_data = nullptr; | |
73 | 73 | size_t existence_data_size = 0; |
74 | 74 | GenExistenceData(entries, error_rate, &existence_data, &existence_data_size); |
75 | 75 | |
88 | 88 | |
89 | 89 | void OutputExistenceBinary(const std::vector<std::string> &entries, |
90 | 90 | std::ostream *ofs, double error_rate) { |
91 | char *existence_data = NULL; | |
91 | char *existence_data = nullptr; | |
92 | 92 | size_t existence_data_size = 0; |
93 | 93 | GenExistenceData(entries, error_rate, &existence_data, &existence_data_size); |
94 | 94 | ofs->write(existence_data, existence_data_size); |
88 | 88 | std::vector<std::string> fields; |
89 | 89 | Util::SplitStringUsing(line, "\t ", &fields); |
90 | 90 | CHECK_GE(fields.size(), 2); |
91 | const char32 ucs4 = strtol(fields[1].c_str(), NULL, 16); | |
91 | const char32 ucs4 = strtol(fields[1].c_str(), nullptr, 16); | |
92 | 92 | std::string utf8; |
93 | 93 | Util::UCS4ToUTF8(ucs4, &utf8); |
94 | 94 | if (sorting_map->find(utf8) != sorting_map->end()) { |
49 | 49 | // return true if rewriter can be called with the segments. |
50 | 50 | bool CheckCapablity(const ConversionRequest &request, Segments *segments, |
51 | 51 | RewriterInterface *rewriter) const { |
52 | if (segments == NULL) { | |
52 | if (segments == nullptr) { | |
53 | 53 | return false; |
54 | 54 | } |
55 | 55 | switch (segments->request_type()) { |
263 | 263 | merger.AddRewriter(new TestRewriter(&call_result, "a", false)); |
264 | 264 | merger.AddRewriter(new TestRewriter(&call_result, "b", false)); |
265 | 265 | merger.AddRewriter(new TestRewriter(&call_result, "c", false)); |
266 | EXPECT_FALSE(merger.Focus(NULL, 0, 0)); | |
266 | EXPECT_FALSE(merger.Focus(nullptr, 0, 0)); | |
267 | 267 | EXPECT_EQ( |
268 | 268 | "a.Focus();" |
269 | 269 | "b.Focus();" |
271 | 271 | call_result); |
272 | 272 | merger.AddRewriter(new TestRewriter(&call_result, "d", true)); |
273 | 273 | call_result.clear(); |
274 | EXPECT_TRUE(merger.Focus(NULL, 0, 0)); | |
274 | EXPECT_TRUE(merger.Focus(nullptr, 0, 0)); | |
275 | 275 | EXPECT_EQ( |
276 | 276 | "a.Focus();" |
277 | 277 | "b.Focus();" |
287 | 287 | merger.AddRewriter(new TestRewriter(&call_result, "a", false)); |
288 | 288 | merger.AddRewriter(new TestRewriter(&call_result, "b", false)); |
289 | 289 | merger.AddRewriter(new TestRewriter(&call_result, "c", false)); |
290 | merger.Finish(request, NULL); | |
290 | merger.Finish(request, nullptr); | |
291 | 291 | EXPECT_EQ( |
292 | 292 | "a.Finish();" |
293 | 293 | "b.Finish();" |
76 | 76 | ], |
77 | 77 | 'dependencies': [ |
78 | 78 | '../base/absl.gyp:absl_strings', |
79 | '../base/absl.gyp:absl_time', | |
79 | 80 | '../base/base.gyp:base', |
80 | 81 | '../base/base.gyp:config_file_stream', |
81 | 82 | '../base/base.gyp:serialized_string_array', |
117 | 117 | void ModifyT13nsForGodan(const std::string &key, |
118 | 118 | std::vector<std::string> *t13ns) { |
119 | 119 | static const char *const kKeycodeToT13nMap[] = { |
120 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
121 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
122 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
123 | 0, "", "ya", "axtu", "ixtu", "uxtu", "", 0, 0, 0, "xi", | |
124 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
125 | 0, 0, 0, 0, "", "ann", "extu", "inn", 0, "oxtu", 0, | |
126 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
127 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
128 | 0, 0, 0, 0, "nn", 0, "yu", "xe", "", 0, 0, | |
129 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
130 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
131 | 0, 0, "unn", "yo", "enn", "onn", 0, | |
120 | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, | |
121 | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, | |
122 | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, | |
123 | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, | |
124 | nullptr, nullptr, "", "ya", "axtu", "ixtu", "uxtu", "", | |
125 | nullptr, nullptr, nullptr, "xi", nullptr, nullptr, nullptr, nullptr, | |
126 | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, | |
127 | nullptr, nullptr, nullptr, "", "ann", "extu", "inn", nullptr, | |
128 | "oxtu", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, | |
129 | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, | |
130 | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, | |
131 | nullptr, nullptr, nullptr, nullptr, "nn", nullptr, "yu", "xe", | |
132 | "", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, | |
133 | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, | |
134 | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, | |
135 | nullptr, nullptr, nullptr, "unn", "yo", "enn", "onn", nullptr, | |
132 | 136 | }; |
133 | 137 | |
134 | 138 | const std::string &src = (*t13ns)[transliteration::HALF_ASCII]; |
137 | 141 | using IsNonnegativeAndLessThanType = IsNonnegativeAndLessThan< |
138 | 142 | std::is_unsigned<std::string::value_type>::type>; |
139 | 143 | if (IsNonnegativeAndLessThanType()(*c, arraysize(kKeycodeToT13nMap)) && |
140 | kKeycodeToT13nMap[*c] != NULL) { | |
144 | kKeycodeToT13nMap[*c] != nullptr) { | |
141 | 145 | dst.append(kKeycodeToT13nMap[*c]); |
142 | 146 | } else { |
143 | 147 | dst.append(1, *c); |
232 | 232 | TEST_F(UnicodeRewriterTest, RewriteToUnicodeCharFormat) { |
233 | 233 | UnicodeRewriter rewriter(engine_->GetConverter()); |
234 | 234 | { // Typical case |
235 | composer::Composer composer(NULL, &default_request(), &default_config()); | |
235 | composer::Composer composer(nullptr, &default_request(), &default_config()); | |
236 | 236 | composer.set_source_text("A"); |
237 | 237 | ConversionRequest request(&composer, &default_request(), &default_config()); |
238 | 238 | |
244 | 244 | } |
245 | 245 | |
246 | 246 | { // If source_text is not set, this rewrite is not triggered. |
247 | composer::Composer composer(NULL, &default_request(), &default_config()); | |
247 | composer::Composer composer(nullptr, &default_request(), &default_config()); | |
248 | 248 | ConversionRequest request(&composer, &default_request(), &default_config()); |
249 | 249 | |
250 | 250 | Segments segments; |
256 | 256 | |
257 | 257 | { // If source_text is not a single character, this rewrite is not |
258 | 258 | // triggered. |
259 | composer::Composer composer(NULL, &default_request(), &default_config()); | |
259 | composer::Composer composer(nullptr, &default_request(), &default_config()); | |
260 | 260 | composer.set_source_text("AB"); |
261 | 261 | ConversionRequest request(&composer, &default_request(), &default_config()); |
262 | 262 | |
267 | 267 | } |
268 | 268 | |
269 | 269 | { // Multibyte character is also supported. |
270 | composer::Composer composer(NULL, &default_request(), &default_config()); | |
270 | composer::Composer composer(nullptr, &default_request(), &default_config()); | |
271 | 271 | composer.set_source_text("愛"); |
272 | 272 | ConversionRequest request(&composer, &default_request(), &default_config()); |
273 | 273 |
207 | 207 | ++usage_id_for_user_comment; |
208 | 208 | |
209 | 209 | // First, search the user dictionary for comment. |
210 | if (dictionary_ != NULL) { | |
210 | if (dictionary_ != nullptr) { | |
211 | 211 | if (dictionary_->LookupComment(segment->candidate(j).content_key, |
212 | 212 | segment->candidate(j).content_value, |
213 | 213 | request, &comment)) { |
134 | 134 | return; |
135 | 135 | } |
136 | 136 | |
137 | if (storage_.get() == NULL) { | |
137 | if (storage_.get() == nullptr) { | |
138 | 138 | VLOG(2) << "storage is NULL"; |
139 | 139 | return; |
140 | 140 | } |
174 | 174 | return false; |
175 | 175 | } |
176 | 176 | |
177 | if (storage_.get() == NULL) { | |
177 | if (storage_.get() == nullptr) { | |
178 | 178 | VLOG(2) << "storage is NULL"; |
179 | 179 | return false; |
180 | 180 | } |
272 | 272 | if (type == RESIZE) { |
273 | 273 | const LengthArray *value = |
274 | 274 | reinterpret_cast<const LengthArray *>(storage_->Lookup(key)); |
275 | if (value != NULL) { | |
275 | if (value != nullptr) { | |
276 | 276 | LengthArray orig_value; |
277 | 277 | orig_value.CopyFromUCharArray(length_array); |
278 | 278 | if (!value->Equal(orig_value)) { |
324 | 324 | } |
325 | 325 | |
326 | 326 | void UserBoundaryHistoryRewriter::Clear() { |
327 | if (storage_.get() != NULL) { | |
327 | if (storage_.get() != nullptr) { | |
328 | 328 | VLOG(1) << "Clearing user segment data"; |
329 | 329 | storage_->Clear(); |
330 | 330 | } |
46 | 46 | void AddCandidate(const std::string &value, bool is_user_dictionary, |
47 | 47 | Segments *segments) { |
48 | 48 | segments->set_request_type(Segments::CONVERSION); |
49 | Segment *seg = NULL; | |
49 | Segment *seg = nullptr; | |
50 | 50 | if (segments->segments_size() == 0) { |
51 | 51 | seg = segments->push_back_segment(); |
52 | 52 | seg->set_key("test"); |
461 | 461 | NormalizeCandidate(segment, old_position, &normalized_value); |
462 | 462 | |
463 | 463 | if (normalized_value != candidate->value) { |
464 | const Segment::Candidate *normalized_cand = NULL; | |
464 | const Segment::Candidate *normalized_cand = nullptr; | |
465 | 465 | for (size_t l = 0; l < segment->candidates_size(); ++l) { |
466 | 466 | if (segment->candidate(l).value == normalized_value) { |
467 | 467 | normalized_cand = &segment->candidate(l); |
469 | 469 | } |
470 | 470 | } |
471 | 471 | |
472 | if (normalized_cand != NULL) { | |
472 | if (normalized_cand != nullptr) { | |
473 | 473 | if (seen.find(normalized_value) == seen.end()) { |
474 | 474 | const int pos = segment->indexOf(normalized_cand); |
475 | 475 | DCHECK(pos != segment->candidates_size()); |
758 | 758 | return false; |
759 | 759 | } |
760 | 760 | |
761 | if (storage_.get() == NULL) { | |
761 | if (storage_.get() == nullptr) { | |
762 | 762 | VLOG(2) << "storage is NULL"; |
763 | 763 | return false; |
764 | 764 | } |
849 | 849 | const KeyTriggerValue *v1 = reinterpret_cast<const KeyTriggerValue *>( |
850 | 850 | storage_->Lookup(segment.key())); |
851 | 851 | |
852 | const KeyTriggerValue *v2 = NULL; | |
852 | const KeyTriggerValue *v2 = nullptr; | |
853 | 853 | if (segment.key() != segment.candidate(0).content_key) { |
854 | 854 | v2 = reinterpret_cast<const KeyTriggerValue *>( |
855 | 855 | storage_->Lookup(segment.candidate(0).content_key)); |
856 | 856 | } |
857 | 857 | |
858 | 858 | const size_t v1_size = |
859 | (v1 == NULL || !v1->IsValid()) ? 0 : v1->candidates_size(); | |
859 | (v1 == nullptr || !v1->IsValid()) ? 0 : v1->candidates_size(); | |
860 | 860 | const size_t v2_size = |
861 | (v2 == NULL || !v2->IsValid()) ? 0 : v2->candidates_size(); | |
861 | (v2 == nullptr || !v2->IsValid()) ? 0 : v2->candidates_size(); | |
862 | 862 | |
863 | 863 | *max_candidates_size = std::max(v1_size, v2_size); |
864 | 864 | |
908 | 908 | GetFeatureN(segment->candidate(j).style, &feature_key); |
909 | 909 | const FeatureValue *v = reinterpret_cast<const FeatureValue *>( |
910 | 910 | storage_->Lookup(feature_key, &last_access_time)); |
911 | if (v != NULL && v->IsValid()) { | |
911 | if (v != nullptr && v->IsValid()) { | |
912 | 912 | score = 10; |
913 | 913 | // Workaround for separated arabic. |
914 | 914 | // Because separated arabic and normal number is learned at the |
1016 | 1016 | } |
1017 | 1017 | |
1018 | 1018 | void UserSegmentHistoryRewriter::Clear() { |
1019 | if (storage_.get() != NULL) { | |
1019 | if (storage_.get() != nullptr) { | |
1020 | 1020 | VLOG(1) << "Clearing user segment data"; |
1021 | 1021 | storage_->Clear(); |
1022 | 1022 | } |
123 | 123 | } |
124 | 124 | CharacterFormManager::GetCharacterFormManager()->ReloadConfig(config_); |
125 | 125 | |
126 | Clock::SetClockForUnitTest(NULL); | |
126 | Clock::SetClockForUnitTest(nullptr); | |
127 | 127 | |
128 | 128 | pos_matcher_.Set(mock_data_manager_.GetPOSMatcherData()); |
129 | 129 | pos_group_.reset(new PosGroup(mock_data_manager_.GetPosGroupData())); |
130 | ASSERT_TRUE(pos_group_.get() != NULL); | |
130 | ASSERT_TRUE(pos_group_.get() != nullptr); | |
131 | 131 | } |
132 | 132 | |
133 | 133 | void TearDown() override { |
134 | Clock::SetClockForUnitTest(NULL); | |
134 | Clock::SetClockForUnitTest(nullptr); | |
135 | 135 | |
136 | 136 | std::unique_ptr<UserSegmentHistoryRewriter> rewriter( |
137 | 137 | CreateUserSegmentHistoryRewriter()); |
77 | 77 | |
78 | 78 | const size_t offset = std::min(insert_pos, segment->candidates_size()); |
79 | 79 | Segment::Candidate *candidate = segment->insert_candidate(offset); |
80 | if (candidate == NULL) { | |
80 | if (candidate == nullptr) { | |
81 | 81 | LOG(ERROR) << "cannot insert candidate at " << offset; |
82 | 82 | return false; |
83 | 83 | } |
59 | 59 | "//config:stats_config_util", |
60 | 60 | "//session", |
61 | 61 | "//session:session_server", |
62 | "@com_google_absl//absl/flags:flag", | |
62 | 63 | ], |
63 | 64 | ) |
64 | 65 | |
77 | 78 | "//session:random_keyevents_generator", |
78 | 79 | "//session:session_handler", |
79 | 80 | "//session:session_usage_observer", |
81 | "@com_google_absl//absl/flags:flag", | |
80 | 82 | ], |
81 | 83 | ) |
26 | 26 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 | 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | 28 | |
29 | #include "absl/flags/flag.h" | |
29 | 30 | #ifdef OS_WIN |
30 | 31 | #include <windows.h> |
31 | 32 | #include <ws2tcpip.h> |
142 | 143 | #endif |
143 | 144 | |
144 | 145 | ::memset(&sin, 0, sizeof(sin)); |
145 | sin.sin_port = htons(FLAGS_port); | |
146 | sin.sin_port = htons(mozc::GetFlag(FLAGS_port)); | |
146 | 147 | sin.sin_family = AF_INET; |
147 | 148 | sin.sin_addr.s_addr = htonl(INADDR_ANY); |
148 | 149 | |
180 | 181 | uint32 request_size = 0; |
181 | 182 | // Receive the size of data. |
182 | 183 | if (!Recv(client_socket, reinterpret_cast<char *>(&request_size), |
183 | sizeof(request_size), FLAGS_rpc_timeout)) { | |
184 | sizeof(request_size), mozc::GetFlag(FLAGS_rpc_timeout))) { | |
184 | 185 | LOG(ERROR) << "Cannot receive request_size header."; |
185 | 186 | CloseSocket(client_socket); |
186 | 187 | continue; |
192 | 193 | // Receive the body of serialized protobuf. |
193 | 194 | std::unique_ptr<char[]> request_str(new char[request_size]); |
194 | 195 | if (!Recv(client_socket, request_str.get(), request_size, |
195 | FLAGS_rpc_timeout)) { | |
196 | mozc::GetFlag(FLAGS_rpc_timeout))) { | |
196 | 197 | LOG(ERROR) << "cannot receive body of request."; |
197 | 198 | CloseSocket(client_socket); |
198 | 199 | continue; |
218 | 219 | output_size = htonl(output_size); |
219 | 220 | |
220 | 221 | if (!Send(client_socket, reinterpret_cast<char *>(&output_size), |
221 | sizeof(output_size), FLAGS_rpc_timeout) || | |
222 | sizeof(output_size), mozc::GetFlag(FLAGS_rpc_timeout)) || | |
222 | 223 | !Send(client_socket, output_str.data(), output_str.size(), |
223 | FLAGS_rpc_timeout)) { | |
224 | mozc::GetFlag(FLAGS_rpc_timeout))) { | |
224 | 225 | LOG(ERROR) << "Cannot send reply."; |
225 | 226 | } |
226 | 227 | |
282 | 283 | hints.ai_socktype = SOCK_STREAM; |
283 | 284 | hints.ai_family = AF_INET; |
284 | 285 | |
285 | const std::string port_str = std::to_string(FLAGS_port); | |
286 | CHECK_EQ(::getaddrinfo(FLAGS_host.c_str(), port_str.c_str(), &hints, &res), | |
286 | const std::string port_str = std::to_string(mozc::GetFlag(FLAGS_port)); | |
287 | CHECK_EQ(::getaddrinfo(mozc::GetFlag(FLAGS_host).c_str(), port_str.c_str(), | |
288 | &hints, &res), | |
287 | 289 | 0) |
288 | 290 | << "getaddrinfo failed"; |
289 | 291 | |
301 | 303 | request_size = htonl(request_size); |
302 | 304 | |
303 | 305 | CHECK(Send(client_socket, reinterpret_cast<char *>(&request_size), |
304 | sizeof(request_size), FLAGS_rpc_timeout)); | |
306 | sizeof(request_size), mozc::GetFlag(FLAGS_rpc_timeout))); | |
305 | 307 | CHECK(Send(client_socket, request_str.data(), request_str.size(), |
306 | FLAGS_rpc_timeout)); | |
308 | mozc::GetFlag(FLAGS_rpc_timeout))); | |
307 | 309 | |
308 | 310 | uint32 output_size = 0; |
309 | 311 | CHECK(Recv(client_socket, reinterpret_cast<char *>(&output_size), |
310 | sizeof(output_size), FLAGS_rpc_timeout)); | |
312 | sizeof(output_size), mozc::GetFlag(FLAGS_rpc_timeout))); | |
311 | 313 | output_size = ntohl(output_size); |
312 | 314 | CHECK_GT(output_size, 0); |
313 | 315 | CHECK_LT(output_size, kMaxOutputSize); |
314 | 316 | |
315 | 317 | std::unique_ptr<char[]> output_str(new char[output_size]); |
316 | CHECK( | |
317 | Recv(client_socket, output_str.get(), output_size, FLAGS_rpc_timeout)); | |
318 | CHECK(Recv(client_socket, output_str.get(), output_size, | |
319 | mozc::GetFlag(FLAGS_rpc_timeout))); | |
318 | 320 | |
319 | 321 | CHECK(output->ParseFromArray(output_str.get(), output_size)); |
320 | 322 | |
352 | 354 | |
353 | 355 | mozc::ScopedWSAData wsadata; |
354 | 356 | |
355 | if (!FLAGS_user_profile_directory.empty()) { | |
357 | if (!mozc::GetFlag(FLAGS_user_profile_directory).empty()) { | |
356 | 358 | LOG(INFO) << "Setting user profile directory to " |
357 | 359 | << FLAGS_user_profile_directory; |
358 | 360 | mozc::SystemUtil::SetUserProfileDirectory(FLAGS_user_profile_directory); |
359 | 361 | } |
360 | 362 | |
361 | if (FLAGS_client) { | |
363 | if (mozc::GetFlag(FLAGS_client)) { | |
362 | 364 | mozc::RPCClient client; |
363 | 365 | CHECK(client.CreateSession()); |
364 | for (int n = 0; n < FLAGS_client_test_size; ++n) { | |
366 | for (int n = 0; n < mozc::GetFlag(FLAGS_client_test_size); ++n) { | |
365 | 367 | std::vector<mozc::commands::KeyEvent> keys; |
366 | 368 | mozc::session::RandomKeyEventsGenerator::GenerateSequence(&keys); |
367 | 369 | for (size_t i = 0; i < keys.size(); ++i) { |
373 | 375 | } |
374 | 376 | CHECK(client.DeleteSession()); |
375 | 377 | return 0; |
376 | } else if (FLAGS_server) { | |
378 | } else if (mozc::GetFlag(FLAGS_server)) { | |
377 | 379 | mozc::RPCServer server; |
378 | 380 | server.Loop(); |
379 | 381 | } else { |
27 | 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | 28 | |
29 | 29 | #include "server/mozc_server.h" |
30 | ||
31 | #include "absl/flags/flag.h" | |
30 | 32 | |
31 | 33 | #ifdef OS_WIN |
32 | 34 | #include <windows.h> |
89 | 91 | |
90 | 92 | if (run_level == mozc::RunLevel::RESTRICTED) { |
91 | 93 | VLOG(1) << "Mozc server starts with timeout mode"; |
92 | FLAGS_restricted = true; | |
94 | mozc::SetFlag(&FLAGS_restricted, true); | |
93 | 95 | } |
94 | 96 | } |
95 | 97 |
44 | 44 | |
45 | 45 | mozc::Mutex g_storage_ensure_mutex; |
46 | 46 | |
47 | mozc::GenericStorageManagerInterface *g_storage_manager = NULL; | |
47 | mozc::GenericStorageManagerInterface *g_storage_manager = nullptr; | |
48 | 48 | |
49 | 49 | const char kSymbolStorageFileName[] = "user://symbol_history.db"; |
50 | 50 | // 32 characters * 3 bytes(typical byte size per character) |
105 | 105 | default: |
106 | 106 | LOG(WARNING) << "Invalid storage type"; |
107 | 107 | } |
108 | return NULL; | |
108 | return nullptr; | |
109 | 109 | } |
110 | 110 | |
111 | 111 | bool GenericStorageManagerImpl::SyncAll() { |
180 | 180 | |
181 | 181 | const char *GenericLruStorage::Lookup(const std::string &key) { |
182 | 182 | if (!EnsureStorage()) { |
183 | return NULL; | |
183 | return nullptr; | |
184 | 184 | } |
185 | 185 | return lru_storage_->Lookup(key); |
186 | 186 | } |
76 | 76 | } |
77 | 77 | |
78 | 78 | // First inserted entry is already pushed out. |
79 | EXPECT_EQ(NULL, storage.Lookup("0")); | |
79 | EXPECT_EQ(nullptr, storage.Lookup("0")); | |
80 | 80 | for (size_t i = 1; i < kSize + 1; ++i) { |
81 | 81 | const std::string value = Util::StringPrintf(kPrintFormat, i); |
82 | 82 | const std::string key = std::string("key") + value; |
46 | 46 | Candidate::Candidate() |
47 | 47 | : id_(0), |
48 | 48 | attributes_(NO_ATTRIBUTES), |
49 | subcandidate_list_(NULL), | |
49 | subcandidate_list_(nullptr), | |
50 | 50 | subcandidate_list_owner_(false) {} |
51 | 51 | |
52 | 52 | Candidate::~Candidate() {} |
54 | 54 | void Candidate::Clear() { |
55 | 55 | id_ = 0; |
56 | 56 | attributes_ = NO_ATTRIBUTES; |
57 | if (subcandidate_list_owner_ && subcandidate_list_ != NULL) { | |
57 | if (subcandidate_list_owner_ && subcandidate_list_ != nullptr) { | |
58 | 58 | delete subcandidate_list_; |
59 | 59 | } |
60 | subcandidate_list_ = NULL; | |
60 | subcandidate_list_ = nullptr; | |
61 | 61 | subcandidate_list_owner_ = false; |
62 | 62 | } |
63 | 63 | |
80 | 80 | } |
81 | 81 | |
82 | 82 | bool Candidate::IsSubcandidateList() const { |
83 | return (subcandidate_list_ != NULL); | |
83 | return (subcandidate_list_ != nullptr); | |
84 | 84 | } |
85 | 85 | |
86 | 86 | const CandidateList &Candidate::subcandidate_list() const { |
59 | 59 | // Don't access composer(). |
60 | 60 | // Before using composer, set_composer() must be called with non-null-value. |
61 | 61 | |
62 | EXPECT_TRUE(NULL == context.mutable_converter()); | |
62 | EXPECT_TRUE(nullptr == context.mutable_converter()); | |
63 | 63 | |
64 | 64 | EXPECT_EQ(ImeContext::NONE, context.state()); |
65 | 65 | |
80 | 80 | |
81 | 81 | // The ownership of composer is moved to context. |
82 | 82 | composer::Composer *composer = |
83 | new composer::Composer(NULL, &request, &config); | |
83 | new composer::Composer(nullptr, &request, &config); | |
84 | 84 | context.set_composer(composer); |
85 | 85 | EXPECT_EQ(composer, &context.composer()); |
86 | 86 | EXPECT_EQ(composer, context.mutable_composer()); |
227 | 227 | // Set composer |
228 | 228 | const commands::Request request; |
229 | 229 | composer::Composer *composer = |
230 | new composer::Composer(NULL, &request, &config); | |
230 | new composer::Composer(nullptr, &request, &config); | |
231 | 231 | context.set_composer(composer); |
232 | 232 | |
233 | 233 | // Set converter |
96 | 96 | } |
97 | 97 | |
98 | 98 | bool KeyEventTransformer::TransformKeyEvent(KeyEvent *key_event) const { |
99 | if (key_event == NULL) { | |
99 | if (key_event == nullptr) { | |
100 | 100 | LOG(ERROR) << "key_event is NULL"; |
101 | 101 | return false; |
102 | 102 | } |
87 | 87 | Reset(); |
88 | 88 | |
89 | 89 | const char *keymap_file = GetKeyMapFileName(keymap); |
90 | if (keymap != config::Config::CUSTOM && keymap_file != NULL && | |
90 | if (keymap != config::Config::CUSTOM && keymap_file != nullptr && | |
91 | 91 | LoadFile(keymap_file)) { |
92 | 92 | return true; |
93 | 93 | } |
166 | 166 | |
167 | 167 | bool KeyMapManager::LoadFile(const char *filename) { |
168 | 168 | std::unique_ptr<std::istream> ifs(ConfigFileStream::LegacyOpen(filename)); |
169 | if (ifs.get() == NULL) { | |
169 | if (ifs.get() == nullptr) { | |
170 | 170 | LOG(WARNING) << "cannot load keymap table: " << filename; |
171 | 171 | return false; |
172 | 172 | } |
92 | 92 | std::vector<KeyInformation> ExtractSortedDirectModeKeysFromFile( |
93 | 93 | const std::string &filename) { |
94 | 94 | std::unique_ptr<std::istream> ifs(ConfigFileStream::LegacyOpen(filename)); |
95 | if (ifs.get() == NULL) { | |
95 | if (ifs.get() == nullptr) { | |
96 | 96 | DLOG(FATAL) << "could not open file: " << filename; |
97 | 97 | return std::vector<KeyInformation>(); |
98 | 98 | } |
37 | 37 | bool OutputUtil::GetCandidateIndexById(const commands::Output &output, |
38 | 38 | int32 mozc_candidate_id, |
39 | 39 | int32 *candidate_index) { |
40 | if (candidate_index == NULL) { | |
40 | if (candidate_index == nullptr) { | |
41 | 41 | return false; |
42 | 42 | } |
43 | 43 | if (!output.has_all_candidate_words()) { |
51 | 51 | continue; |
52 | 52 | } |
53 | 53 | if (word.id() == mozc_candidate_id) { |
54 | DCHECK(NULL != candidate_index); | |
54 | DCHECK(nullptr != candidate_index); | |
55 | 55 | *candidate_index = word.index(); |
56 | 56 | return true; |
57 | 57 | } |
62 | 62 | bool OutputUtil::GetCandidateIdByIndex(const commands::Output &output, |
63 | 63 | int32 candidate_index, |
64 | 64 | int32 *mozc_candidate_id) { |
65 | if (mozc_candidate_id == NULL) { | |
65 | if (mozc_candidate_id == nullptr) { | |
66 | 66 | return false; |
67 | 67 | } |
68 | 68 | if (!output.has_all_candidate_words()) { |
76 | 76 | continue; |
77 | 77 | } |
78 | 78 | if (word.index() == candidate_index) { |
79 | DCHECK(NULL != mozc_candidate_id); | |
79 | DCHECK(nullptr != mozc_candidate_id); | |
80 | 80 | *mozc_candidate_id = word.id(); |
81 | 81 | return true; |
82 | 82 | } |
86 | 86 | |
87 | 87 | bool OutputUtil::GetFocusedCandidateId(const commands::Output &output, |
88 | 88 | int32 *mozc_candidate_id) { |
89 | if (mozc_candidate_id == NULL) { | |
89 | if (mozc_candidate_id == nullptr) { | |
90 | 90 | return false; |
91 | 91 | } |
92 | 92 | if (!output.has_all_candidate_words()) { |
104 | 104 | continue; |
105 | 105 | } |
106 | 106 | if (word.index() == focused_index) { |
107 | DCHECK(NULL != mozc_candidate_id); | |
107 | DCHECK(nullptr != mozc_candidate_id); | |
108 | 108 | *mozc_candidate_id = word.id(); |
109 | 109 | return true; |
110 | 110 | } |
211 | 211 | void Session::InitContext(ImeContext *context) const { |
212 | 212 | context->set_create_time(Clock::GetTime()); |
213 | 213 | context->set_last_command_time(0); |
214 | context->set_composer(new composer::Composer(NULL, &context->GetRequest(), | |
214 | context->set_composer(new composer::Composer(nullptr, &context->GetRequest(), | |
215 | 215 | &context->GetConfig())); |
216 | 216 | context->set_converter(new SessionConverter( |
217 | 217 | engine_->GetConverter(), &context->GetRequest(), &context->GetConfig())); |
1505 | 1505 | std::unique_ptr<composer::Composer> temporary_composer; |
1506 | 1506 | if (input.has_key() && input.key().has_mode()) { |
1507 | 1507 | // Allocate an object only when it is necessary. |
1508 | temporary_composer.reset(new composer::Composer(NULL, NULL, NULL)); | |
1508 | temporary_composer.reset(new composer::Composer(nullptr, nullptr, nullptr)); | |
1509 | 1509 | // Copy the current composer state just in case. |
1510 | 1510 | temporary_composer->CopyFrom(context_->composer()); |
1511 | 1511 | ApplyInputMode(input.key().mode(), temporary_composer.get()); |
1868 | 1868 | context_->mutable_converter()->Reset(); |
1869 | 1869 | |
1870 | 1870 | commands::Result *result = command->mutable_output()->mutable_result(); |
1871 | DCHECK(result != NULL); | |
1871 | DCHECK(result != nullptr); | |
1872 | 1872 | result->set_type(commands::Result::STRING); |
1873 | 1873 | result->mutable_key()->append(key); |
1874 | 1874 | result->mutable_value()->append(preedit); |
89 | 89 | mozc::InitMozc(argv[0], &argc, &argv); |
90 | 90 | std::unique_ptr<mozc::InputFileStream> input_file; |
91 | 91 | std::unique_ptr<mozc::OutputFileStream> output_file; |
92 | std::istream *input = NULL; | |
93 | std::ostream *output = NULL; | |
92 | std::istream *input = nullptr; | |
93 | std::ostream *output = nullptr; | |
94 | 94 | |
95 | 95 | if (!FLAGS_profile_dir.empty()) { |
96 | 96 | // TODO(komatsu): Make a tmp dir and use it. |
2571 | 2571 | { // validation |
2572 | 2572 | // Copy and validate |
2573 | 2573 | std::unique_ptr<SessionConverter> dest(src.Clone()); |
2574 | ASSERT_TRUE(dest.get() != NULL); | |
2574 | ASSERT_TRUE(dest.get() != nullptr); | |
2575 | 2575 | ExpectSameSessionConverter(src, *dest); |
2576 | 2576 | |
2577 | 2577 | // Convert source |
2584 | 2584 | |
2585 | 2585 | // Copy converted and validate |
2586 | 2586 | dest.reset(src.Clone()); |
2587 | ASSERT_TRUE(dest.get() != NULL); | |
2587 | ASSERT_TRUE(dest.get() != nullptr); | |
2588 | 2588 | ExpectSameSessionConverter(src, *dest); |
2589 | 2589 | } |
2590 | 2590 | } |
588 | 588 | bool SessionHandler::SendKey(commands::Command *command) { |
589 | 589 | const SessionID id = command->input().id(); |
590 | 590 | session::SessionInterface **session = session_map_->MutableLookup(id); |
591 | if (session == NULL || *session == NULL) { | |
591 | if (session == nullptr || *session == nullptr) { | |
592 | 592 | LOG(WARNING) << "SessionID " << id << " is not available"; |
593 | 593 | return false; |
594 | 594 | } |
600 | 600 | bool SessionHandler::TestSendKey(commands::Command *command) { |
601 | 601 | const SessionID id = command->input().id(); |
602 | 602 | session::SessionInterface **session = session_map_->MutableLookup(id); |
603 | if (session == NULL || *session == NULL) { | |
603 | if (session == nullptr || *session == nullptr) { | |
604 | 604 | LOG(WARNING) << "SessionID " << id << " is not available"; |
605 | 605 | return false; |
606 | 606 | } |
612 | 612 | const SessionID id = command->input().id(); |
613 | 613 | session::SessionInterface **session = |
614 | 614 | const_cast<session::SessionInterface **>(session_map_->Lookup(id)); |
615 | if (session == NULL || *session == NULL) { | |
615 | if (session == nullptr || *session == nullptr) { | |
616 | 616 | LOG(WARNING) << "SessionID " << id << " is not available"; |
617 | 617 | return false; |
618 | 618 | } |
637 | 637 | last_create_session_time_ = current_time; |
638 | 638 | |
639 | 639 | // if session map is FULL, remove the oldest item from the LRU |
640 | SessionElement *oldest_element = NULL; | |
640 | SessionElement *oldest_element = nullptr; | |
641 | 641 | if (session_map_->Size() >= max_session_size_) { |
642 | 642 | oldest_element = const_cast<SessionElement *>(session_map_->Tail()); |
643 | if (oldest_element == NULL) { | |
643 | if (oldest_element == nullptr) { | |
644 | 644 | LOG(ERROR) << "oldest SessionElement is NULL"; |
645 | 645 | return false; |
646 | 646 | } |
670 | 670 | } |
671 | 671 | |
672 | 672 | session::SessionInterface *session = NewSession(); |
673 | if (session == NULL) { | |
673 | if (session == nullptr) { | |
674 | 674 | LOG(ERROR) << "Cannot allocate new Session"; |
675 | 675 | return false; |
676 | 676 | } |
681 | 681 | command->mutable_output()->set_id(new_id); |
682 | 682 | |
683 | 683 | // The oldes item should be reused |
684 | DCHECK(oldest_element == NULL || oldest_element == element); | |
684 | DCHECK(oldest_element == nullptr || oldest_element == element); | |
685 | 685 | |
686 | 686 | if (command->input().has_capability()) { |
687 | 687 | session->set_client_capability(command->input().capability()); |
689 | 689 | |
690 | 690 | if (command->input().has_application_info()) { |
691 | 691 | session->set_application_info(command->input().application_info()); |
692 | #ifdef OS_NACL | |
693 | if (command->input().application_info().has_timezone_offset()) { | |
694 | Clock::SetTimezoneOffset( | |
695 | command->input().application_info().timezone_offset()); | |
696 | } | |
697 | #endif // OS_NACL | |
698 | 692 | } |
699 | 693 | |
700 | 694 | // Ensure the onmemory config is same as the locally stored one |
761 | 755 | std::vector<SessionID> remove_ids; |
762 | 756 | for (SessionElement *element = |
763 | 757 | const_cast<SessionElement *>(session_map_->Head()); |
764 | element != NULL; element = element->next) { | |
758 | element != nullptr; element = element->next) { | |
765 | 759 | session::SessionInterface *session = element->value; |
766 | 760 | if (!IsApplicationAlive(session)) { |
767 | 761 | VLOG(2) << "Application is not alive. Removing: " << element->key; |
846 | 840 | |
847 | 841 | bool SessionHandler::DeleteSessionID(SessionID id) { |
848 | 842 | session::SessionInterface **session = session_map_->MutableLookup(id); |
849 | if (session == NULL || *session == NULL) { | |
843 | if (session == nullptr || *session == nullptr) { | |
850 | 844 | LOG_IF(WARNING, id != 0) << "cannot find SessionID " << id; |
851 | 845 | return false; |
852 | 846 | } |
25 | 25 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
26 | 26 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 | 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | ||
29 | #ifndef OS_NACL | |
30 | // Disabled on NaCl since it uses a mock file system. | |
31 | 28 | |
32 | 29 | #include <memory> |
33 | 30 | |
612 | 609 | #undef EXPECT_NOT_IN_ALL_CANDIDATE_WORDS |
613 | 610 | |
614 | 611 | } // namespace |
615 | ||
616 | #endif // !OS_NACL |
77 | 77 | Scheduler::SetSchedulerHandler(job_recorder.get()); |
78 | 78 | std::unique_ptr<SessionServer> session_server(new SessionServer); |
79 | 79 | EXPECT_EQ(0, job_recorder->job_settings().size()); |
80 | Scheduler::SetSchedulerHandler(NULL); | |
80 | Scheduler::SetSchedulerHandler(nullptr); | |
81 | 81 | } |
82 | 82 | } // namespace mozc |
2841 | 2841 | // "page2-cand8" |
2842 | 2842 | { |
2843 | 2843 | Segments segments; |
2844 | Segment *segment = NULL; | |
2844 | Segment *segment = nullptr; | |
2845 | 2845 | segment = segments.add_segment(); |
2846 | 2846 | segment->set_key("あいうえお"); |
2847 | 2847 | for (int page_index = 0; page_index < 3; ++page_index) { |
3840 | 3840 | // Global mode should be kept as HIRAGANA |
3841 | 3841 | EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode()); |
3842 | 3842 | |
3843 | #ifndef OS_NACL | |
3844 | // NaCl doesn't support OFF key. | |
3845 | ||
3846 | 3843 | // When the IME is deactivated, the temporary composition mode is reset. |
3847 | 3844 | EXPECT_TRUE(SendKey("OFF", session.get(), &command)); // "あAaあA" |
3848 | 3845 | ASSERT_TRUE(command.output().has_status()); |
3853 | 3850 | EXPECT_EQ(commands::DIRECT, command.output().mode()); |
3854 | 3851 | EXPECT_EQ(commands::HIRAGANA, command.output().status().mode()); |
3855 | 3852 | EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode()); |
3856 | #endif // !OS_NACL | |
3857 | 3853 | } |
3858 | 3854 | |
3859 | 3855 | { // Katakana mode + Shift key |
3882 | 3878 | // Global mode should be kept as FULL_KATAKANA |
3883 | 3879 | EXPECT_EQ(commands::FULL_KATAKANA, |
3884 | 3880 | command.output().status().comeback_mode()); |
3885 | ||
3886 | #ifndef OS_NACL | |
3887 | // NaCl doesn't support OFF key. | |
3888 | 3881 | |
3889 | 3882 | // When the IME is deactivated, the temporary composition mode is reset. |
3890 | 3883 | EXPECT_TRUE(SendKey("OFF", session.get(), &command)); // "アA" |
3897 | 3890 | EXPECT_EQ(commands::FULL_KATAKANA, command.output().status().mode()); |
3898 | 3891 | EXPECT_EQ(commands::FULL_KATAKANA, |
3899 | 3892 | command.output().status().comeback_mode()); |
3900 | #endif // !OS_NACL | |
3901 | 3893 | } |
3902 | 3894 | } |
3903 | 3895 | |
5601 | 5593 | EXPECT_FALSE(command.output().has_result()); |
5602 | 5594 | } |
5603 | 5595 | |
5604 | #ifndef OS_NACL | |
5605 | // NaCl doesn't support Eisu key | |
5606 | 5596 | TEST_F(SessionTest, Issue2223755) { |
5607 | 5597 | // This is a unittest against http://b/2223755. |
5608 | 5598 | // - F6 and F7 convert space to half-width. |
5660 | 5650 | EXPECT_EQ("ア イ", GetComposition(command)); // fullwidth space |
5661 | 5651 | } |
5662 | 5652 | } |
5663 | #endif // !OS_NACL | |
5664 | 5653 | |
5665 | 5654 | TEST_F(SessionTest, Issue2269058) { |
5666 | 5655 | // This is a unittest against http://b/2269058. |
5881 | 5870 | EXPECT_EQ(commands::FULL_KATAKANA, command.output().mode()); |
5882 | 5871 | } |
5883 | 5872 | |
5884 | #ifndef OS_NACL | |
5885 | // NaCl doesn't support hankaku/zenkaku key. | |
5886 | 5873 | TEST_F(SessionTest, Issue2791640) { |
5887 | 5874 | // This is a unittest against http://b/2791640. |
5888 | 5875 | // Existing preedit should be committed when IME is turned off. |
5902 | 5889 | |
5903 | 5890 | ASSERT_FALSE(command.output().has_preedit()); |
5904 | 5891 | } |
5905 | #endif // !OS_NACL | |
5906 | ||
5907 | #ifndef OS_NACL | |
5908 | // NaCl doesn't support hankaku/zenkaku key. | |
5892 | ||
5909 | 5893 | TEST_F(SessionTest, CommitExistingPreeditWhenIMEIsTurnedOff) { |
5910 | 5894 | // Existing preedit should be committed when IME is turned off. |
5911 | 5895 | |
5945 | 5929 | ASSERT_FALSE(command.output().has_preedit()); |
5946 | 5930 | } |
5947 | 5931 | } |
5948 | #endif // !OS_NACL | |
5949 | 5932 | |
5950 | 5933 | TEST_F(SessionTest, SendKeyDirectInputStateTest) { |
5951 | 5934 | // InputModeChange commands from direct mode are supported only for Windows |
6200 | 6183 | EXPECT_TRUE(command.output().has_preedit()); |
6201 | 6184 | } |
6202 | 6185 | |
6203 | #ifndef OS_NACL | |
6204 | // NaCl doesn't support KeyEvent::ON|OFF. | |
6205 | 6186 | TEST_F(SessionTest, PerformedCommand) { |
6206 | 6187 | std::unique_ptr<Session> session(new Session(engine_.get())); |
6207 | 6188 | InitSessionToPrecomposition(session.get()); |
6249 | 6230 | EXPECT_COUNT_STATS("Performed_Conversion_Commit", 1); |
6250 | 6231 | } |
6251 | 6232 | } |
6252 | #endif // !OS_NACL | |
6253 | 6233 | |
6254 | 6234 | TEST_F(SessionTest, ResetContext) { |
6255 | 6235 | std::unique_ptr<MockConverterEngineForReset> engine( |
64 | 64 | |
65 | 65 | SessionWatchDog::SessionWatchDog(int32 interval_sec) |
66 | 66 | : interval_sec_(interval_sec), |
67 | client_(NULL), | |
68 | cpu_stats_(NULL), | |
67 | client_(nullptr), | |
68 | cpu_stats_(nullptr), | |
69 | 69 | event_(new UnnamedEvent) { |
70 | 70 | // allow [1..600]. |
71 | 71 | interval_sec_ = std::max(1, std::min(interval_sec_, 600)); |
97 | 97 | |
98 | 98 | void SessionWatchDog::Run() { |
99 | 99 | std::unique_ptr<client::ClientInterface> client_impl; |
100 | if (client_ == NULL) { | |
100 | if (client_ == nullptr) { | |
101 | 101 | VLOG(2) << "default client is used"; |
102 | 102 | client_impl.reset(client::ClientFactory::NewClient()); |
103 | 103 | client_ = client_impl.get(); |
104 | 104 | } |
105 | 105 | |
106 | 106 | std::unique_ptr<CPUStatsInterface> cpu_stats_impl; |
107 | if (cpu_stats_ == NULL) { | |
107 | if (cpu_stats_ == nullptr) { | |
108 | 108 | VLOG(2) << "default cpu_stats is used"; |
109 | 109 | cpu_stats_impl.reset(new CPUStats); |
110 | 110 | cpu_stats_ = cpu_stats_impl.get(); |
113 | 113 | |
114 | 114 | // Allocate full blocks |
115 | 115 | for (size_t i = 0; i < num_blocks_ - 1; ++i) { |
116 | block_[i] = is_mutable_ ? new uint32[kBlockWords] : NULL; | |
116 | block_[i] = is_mutable_ ? new uint32[kBlockWords] : nullptr; | |
117 | 117 | } |
118 | 118 | |
119 | 119 | // Allocate the last block |
125 | 125 | CHECK_EQ(bytes_in_last_ % sizeof(uint32), 0); |
126 | 126 | |
127 | 127 | block_[num_blocks_ - 1] = |
128 | is_mutable_ ? new uint32[bytes_in_last_ / sizeof(uint32)] : NULL; | |
128 | is_mutable_ ? new uint32[bytes_in_last_ / sizeof(uint32)] : nullptr; | |
129 | 129 | } |
130 | 130 | |
131 | 131 | ExistenceFilter::BlockBitmap::~BlockBitmap() { |
283 | 283 | << expected_nelts_ << " num_hashes " << num_hashes_; |
284 | 284 | |
285 | 285 | // write bitmap |
286 | char **fragment_ptr = NULL; | |
286 | char **fragment_ptr = nullptr; | |
287 | 287 | size_t bytes = 0; |
288 | 288 | size_t write = 0; |
289 | 289 | for (uint32 iter = 0; |
317 | 317 | sizeof(header.m) + sizeof(header.n) + sizeof(header.k); |
318 | 318 | if (size < header_bytes) { |
319 | 319 | LOG(ERROR) << "Not enough bufsize: could not read header"; |
320 | return NULL; | |
320 | return nullptr; | |
321 | 321 | } |
322 | 322 | |
323 | 323 | if (!ReadHeader(buf, &header)) { |
324 | 324 | LOG(ERROR) << "Invalid format: could not read header"; |
325 | return NULL; | |
325 | return nullptr; | |
326 | 326 | } |
327 | 327 | buf += header_bytes; |
328 | 328 | |
333 | 333 | |
334 | 334 | if (size < header_bytes + filter_bytes) { |
335 | 335 | LOG(ERROR) << "Not enough bufsize: could not read filter"; |
336 | return NULL; | |
336 | return nullptr; | |
337 | 337 | } |
338 | 338 | |
339 | 339 | ExistenceFilter *filter = ExistenceFilter::CreateImmutableExietenceFilter( |
340 | 340 | header.m, header.n, header.k); |
341 | char **ptr = NULL; | |
341 | char **ptr = nullptr; | |
342 | 342 | size_t n = 0; |
343 | 343 | size_t read = 0; |
344 | 344 | for (uint32 iter = 0; filter->rep_->GetMutableFragment(&iter, &ptr, &n);) { |
349 | 349 | if (read != filter_bytes) { |
350 | 350 | LOG(ERROR) << "Read " << read << " bytes instead of " << filter_bytes; |
351 | 351 | delete filter; |
352 | return NULL; | |
352 | return nullptr; | |
353 | 353 | } |
354 | 354 | return filter; |
355 | 355 | } |
72 | 72 | |
73 | 73 | CheckValues(filter, m, n); |
74 | 74 | |
75 | char *buf = NULL; | |
75 | char *buf = nullptr; | |
76 | 76 | size_t size = 0; |
77 | 77 | filter->Write(&buf, &size); |
78 | 78 | LOG(INFO) << "write size: " << size; |
116 | 116 | filter->Insert(Hash::Fingerprint(words[i])); |
117 | 117 | } |
118 | 118 | |
119 | char *buf = NULL; | |
119 | char *buf = nullptr; | |
120 | 120 | size_t size = 0; |
121 | 121 | filter->Write(&buf, &size); |
122 | 122 | std::unique_ptr<ExistenceFilter> filter_read( |
62 | 62 | index_.Reset(); |
63 | 63 | base_length_ = 0; |
64 | 64 | step_length_ = 0; |
65 | data_ = 0; | |
65 | data_ = nullptr; | |
66 | 66 | } |
67 | 67 | |
68 | 68 | const char *BitVectorBasedArray::Get(size_t index, size_t *length) const { |
167 | 167 | // Add new elements to free list |
168 | 168 | for (size_t i = 0; i < next_block_size_; ++i) { |
169 | 169 | Element* e = &((blocks_[block_count_])[i]); |
170 | e->prev = NULL; // free list is not doubly linked | |
170 | e->prev = nullptr; // free list is not doubly linked | |
171 | 171 | e->next = free_list_; |
172 | 172 | free_list_ = e; |
173 | 173 | } |
188 | 188 | |
189 | 189 | template <typename Key, typename Value> |
190 | 190 | void LRUCache<Key, Value>::PushFreeList(Element* element) { |
191 | element->prev = NULL; | |
191 | element->prev = nullptr; | |
192 | 192 | element->next = free_list_; |
193 | 193 | free_list_ = element; |
194 | 194 | } |
196 | 196 | template <typename Key, typename Value> |
197 | 197 | typename LRUCache<Key, Value>::Element* LRUCache<Key, Value>::PopFreeList() { |
198 | 198 | Element* r = free_list_; |
199 | if (r != NULL) { | |
200 | CHECK(r->prev == NULL); | |
199 | if (r != nullptr) { | |
200 | CHECK(r->prev == nullptr); | |
201 | 201 | free_list_ = r->next; |
202 | if (free_list_ != NULL) { | |
203 | free_list_->prev = NULL; | |
202 | if (free_list_ != nullptr) { | |
203 | free_list_->prev = nullptr; | |
204 | 204 | } |
205 | r->next = NULL; | |
205 | r->next = nullptr; | |
206 | 206 | } |
207 | 207 | return r; |
208 | 208 | } |
211 | 211 | typename LRUCache<Key, Value>::Element* |
212 | 212 | LRUCache<Key, Value>::NextFreeElement() { |
213 | 213 | Element* r = PopFreeList(); |
214 | if (r == NULL) { | |
214 | if (r == nullptr) { | |
215 | 215 | AddBlock(); |
216 | 216 | r = PopFreeList(); |
217 | 217 | } |
225 | 225 | if (iter != table_->end()) { |
226 | 226 | return iter->second; |
227 | 227 | } |
228 | return NULL; | |
228 | return nullptr; | |
229 | 229 | } |
230 | 230 | |
231 | 231 | template <typename Key, typename Value> |
236 | 236 | if (lru_tail_ == element) { |
237 | 237 | lru_tail_ = element->prev; |
238 | 238 | } |
239 | if (element->prev != NULL) { | |
239 | if (element->prev != nullptr) { | |
240 | 240 | element->prev->next = element->next; |
241 | 241 | } |
242 | if (element->next != NULL) { | |
242 | if (element->next != nullptr) { | |
243 | 243 | element->next->prev = element->prev; |
244 | 244 | } |
245 | element->prev = NULL; | |
246 | element->next = NULL; | |
245 | element->prev = nullptr; | |
246 | element->next = nullptr; | |
247 | 247 | } |
248 | 248 | |
249 | 249 | template <typename Key, typename Value> |
255 | 255 | RemoveFromLRU(element); |
256 | 256 | element->next = lru_head_; |
257 | 257 | lru_head_ = element; |
258 | if (element->next != NULL) { | |
258 | if (element->next != nullptr) { | |
259 | 259 | element->next->prev = element; |
260 | 260 | } |
261 | if (lru_tail_ == NULL) { | |
261 | if (lru_tail_ == nullptr) { | |
262 | 262 | lru_tail_ = element; |
263 | 263 | } |
264 | 264 | } |
265 | 265 | |
266 | 266 | template <typename Key, typename Value> |
267 | 267 | bool LRUCache<Key, Value>::Evict(Element* e) { |
268 | if (e != NULL) { | |
268 | if (e != nullptr) { | |
269 | 269 | int erased = table_->erase(e->key); |
270 | 270 | CHECK_EQ(erased, 1); |
271 | 271 | RemoveFromLRU(e); |
277 | 277 | |
278 | 278 | template <typename Key, typename Value> |
279 | 279 | LRUCache<Key, Value>::LRUCache(size_t max_elements) |
280 | : free_list_(NULL), | |
281 | lru_head_(NULL), | |
282 | lru_tail_(NULL), | |
280 | : free_list_(nullptr), | |
281 | lru_head_(nullptr), | |
282 | lru_tail_(nullptr), | |
283 | 283 | block_count_(0), |
284 | 284 | block_capacity_(0), |
285 | 285 | max_elements_(max_elements) { |
315 | 315 | template <typename Key, typename Value> |
316 | 316 | void LRUCache<Key, Value>::Insert(const Key& key, const Value& value) { |
317 | 317 | Element* e = Insert(key); |
318 | if (e != NULL) { | |
318 | if (e != nullptr) { | |
319 | 319 | e->value = value; |
320 | 320 | } |
321 | 321 | } |
325 | 325 | const Key& key) { |
326 | 326 | bool erased = false; |
327 | 327 | Element* e = LookupInternal(key); |
328 | if (e != NULL) { | |
328 | if (e != nullptr) { | |
329 | 329 | erased = Evict(e); |
330 | 330 | CHECK(erased); |
331 | 331 | } |
332 | 332 | |
333 | 333 | e = NextFreeElement(); |
334 | if (e == NULL) { | |
334 | if (e == nullptr) { | |
335 | 335 | // no free elements, I have to replace an existing element |
336 | 336 | e = lru_tail_; |
337 | 337 | erased = Evict(e); |
338 | 338 | CHECK(erased); |
339 | 339 | e = NextFreeElement(); |
340 | CHECK(e != NULL); | |
340 | CHECK(e != nullptr); | |
341 | 341 | } |
342 | 342 | e->key = key; |
343 | 343 | (*table_)[key] = e; |
349 | 349 | template <typename Key, typename Value> |
350 | 350 | Value* LRUCache<Key, Value>::MutableLookup(const Key& key) { |
351 | 351 | Element* e = LookupInternal(key); |
352 | if (e != NULL) { | |
352 | if (e != nullptr) { | |
353 | 353 | PushLRUHead(e); |
354 | 354 | return &(e->value); |
355 | 355 | } |
356 | return NULL; | |
356 | return nullptr; | |
357 | 357 | } |
358 | 358 | |
359 | 359 | template <typename Key, typename Value> |
364 | 364 | template <typename Key, typename Value> |
365 | 365 | Value* LRUCache<Key, Value>::MutableLookupWithoutInsert(const Key& key) const { |
366 | 366 | Element* e = LookupInternal(key); |
367 | if (e != NULL) { | |
367 | if (e != nullptr) { | |
368 | 368 | return &(e->value); |
369 | 369 | } |
370 | return NULL; | |
370 | return nullptr; | |
371 | 371 | } |
372 | 372 | |
373 | 373 | template <typename Key, typename Value> |
385 | 385 | void LRUCache<Key, Value>::Clear() { |
386 | 386 | table_->clear(); |
387 | 387 | Element* e = lru_head_; |
388 | while (e != NULL) { | |
388 | while (e != nullptr) { | |
389 | 389 | Element* next = e->next; |
390 | 390 | PushFreeList(e); |
391 | 391 | e = next; |
392 | 392 | } |
393 | lru_head_ = lru_tail_ = NULL; | |
393 | lru_head_ = lru_tail_ = nullptr; | |
394 | 394 | } |
395 | 395 | |
396 | 396 | template <typename Key, typename Value> |
87 | 87 | const uint32 *v2 = reinterpret_cast<const uint32 *>( |
88 | 88 | storage->Lookup(values[i].first, &last_access_time)); |
89 | 89 | const uint32 *v3 = reinterpret_cast<const uint32 *>(value_list[i].data()); |
90 | EXPECT_TRUE(v1 != NULL); | |
90 | EXPECT_TRUE(v1 != nullptr); | |
91 | 91 | EXPECT_EQ(*v1, values[i].second); |
92 | EXPECT_TRUE(v2 != NULL); | |
92 | EXPECT_TRUE(v2 != nullptr); | |
93 | 93 | EXPECT_EQ(*v2, values[i].second); |
94 | EXPECT_TRUE(v3 != NULL); | |
94 | EXPECT_TRUE(v3 != nullptr); | |
95 | 95 | EXPECT_EQ(*v3, values[i].second); |
96 | 96 | } |
97 | 97 | |
99 | 99 | const uint32 *v1 = cache.Lookup(values[i].first); |
100 | 100 | const uint32 *v2 = reinterpret_cast<const uint32 *>( |
101 | 101 | storage->Lookup(values[i].first, &last_access_time)); |
102 | EXPECT_TRUE(v1 == NULL); | |
103 | EXPECT_TRUE(v2 == NULL); | |
102 | EXPECT_TRUE(v1 == nullptr); | |
103 | EXPECT_TRUE(v2 == nullptr); | |
104 | 104 | } |
105 | 105 | } |
106 | 106 | |
333 | 333 | |
334 | 334 | TEST_F(LRUStorageTest, InvalidFileOpenTest) { |
335 | 335 | LRUStorage storage; |
336 | EXPECT_FALSE(storage.Insert("test", NULL)); | |
336 | EXPECT_FALSE(storage.Insert("test", nullptr)); | |
337 | 337 | |
338 | 338 | const std::string filename = GetTemporaryFilePath(); |
339 | 339 | FileUtil::Unlink(filename); |
340 | 340 | |
341 | 341 | // cannot open |
342 | 342 | EXPECT_FALSE(storage.Open(filename.c_str())); |
343 | EXPECT_FALSE(storage.Insert("test", NULL)); | |
343 | EXPECT_FALSE(storage.Insert("test", nullptr)); | |
344 | 344 | } |
345 | 345 | |
346 | 346 | TEST_F(LRUStorageTest, OpenOrCreateTest) { |
53 | 53 | class StorageInitializer { |
54 | 54 | public: |
55 | 55 | StorageInitializer() |
56 | : default_storage_(TinyStorage::New()), current_storage_(NULL) { | |
56 | : default_storage_(TinyStorage::New()), current_storage_(nullptr) { | |
57 | 57 | if (!default_storage_->Open(FileUtil::JoinPath( |
58 | 58 | SystemUtil::GetUserProfileDirectory(), kRegistryFileName))) { |
59 | 59 | LOG(ERROR) << "cannot open registry"; |
61 | 61 | } |
62 | 62 | |
63 | 63 | StorageInterface *GetStorage() const { |
64 | if (current_storage_ == NULL) { | |
64 | if (current_storage_ == nullptr) { | |
65 | 65 | return default_storage_.get(); |
66 | 66 | } else { |
67 | 67 | return current_storage_; |
327 | 327 | std::unique_ptr<TinyStorageImpl> storage(new TinyStorageImpl); |
328 | 328 | if (!storage->Open(filename)) { |
329 | 329 | LOG(ERROR) << "cannot open " << filename; |
330 | return NULL; | |
330 | return nullptr; | |
331 | 331 | } |
332 | 332 | return storage.release(); |
333 | 333 | } |
32 | 32 | #include "testing/base/public/googletest.h" |
33 | 33 | #include "testing/base/public/gunit.h" |
34 | 34 | |
35 | #ifdef OS_NACL | |
36 | #include "testing/base/public/nacl_mock_module.h" | |
37 | #endif // OS_NACL | |
38 | ||
39 | 35 | int main(int argc, char **argv) { |
40 | 36 | // TODO(yukawa, team): Implement b/2805528 so that you can specify any option |
41 | 37 | // given by gunit. |
52 | 48 | // See b/2805521 for details. |
53 | 49 | testing::GTEST_FLAG(catch_exceptions) = true; |
54 | 50 | |
55 | #ifdef OS_NACL | |
56 | mozc::testing::WorkAroundEmptyFunctionToAvoidLinkError(); | |
57 | #endif // OS_NACL | |
58 | ||
59 | 51 | return RUN_ALL_TESTS(); |
60 | 52 | } |
61 | 53 |
26 | 26 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 | 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | 28 | |
29 | #ifdef OS_NACL | |
30 | ||
31 | #include <errno.h> | |
32 | #include <pthread.h> | |
33 | #include <sys/types.h> | |
34 | ||
35 | #include <ppapi/cpp/instance.h> | |
36 | #include <ppapi/cpp/module.h> | |
37 | #include <ppapi/cpp/url_loader.h> | |
38 | #include <ppapi/cpp/url_request_info.h> | |
39 | #include <ppapi/utility/completion_callback_factory.h> | |
40 | ||
41 | #include <cstring> | |
42 | #include <memory> | |
43 | ||
44 | #include "base/init_mozc.h" | |
45 | #include "base/logging.h" | |
46 | #include "base/port.h" | |
47 | #include "testing/base/public/googletest.h" | |
48 | #include "testing/base/public/gunit.h" | |
49 | ||
50 | namespace mozc { | |
51 | namespace testing { | |
52 | ||
53 | void WorkAroundEmptyFunctionToAvoidLinkError() {} | |
54 | ||
55 | } // namespace testing | |
56 | } // namespace mozc | |
57 | ||
58 | namespace pp { | |
59 | namespace { | |
60 | ||
61 | class NaclTestInstance : public pp::Instance { | |
62 | public: | |
63 | explicit NaclTestInstance(PP_Instance instance) : pp::Instance(instance) { | |
64 | cc_factory_.Initialize(this); | |
65 | pthread_create(&thread_handle_, 0, &NaclTestInstance::ThreadFunc, | |
66 | static_cast<void *>(this)); | |
67 | } | |
68 | virtual ~NaclTestInstance() {} | |
69 | virtual void HandleMessage(const pp::Var &var_message) {} | |
70 | ||
71 | private: | |
72 | static void *ThreadFunc(void *ptr); | |
73 | void TestFinish(int32_t result); | |
74 | void OnUrlLoaderOpen(int32_t result); | |
75 | pthread_t thread_handle_; | |
76 | pp::CompletionCallbackFactory<NaclTestInstance> cc_factory_; | |
77 | std::unique_ptr<pp::URLRequestInfo> url_request_; | |
78 | std::unique_ptr<pp::URLLoader> url_loader_; | |
79 | ||
80 | DISALLOW_COPY_AND_ASSIGN(NaclTestInstance); | |
81 | }; | |
82 | ||
83 | void *NaclTestInstance::ThreadFunc(void *ptr) { | |
84 | mozc::InitTestFlags(); | |
85 | NaclTestInstance *self = static_cast<NaclTestInstance *>(ptr); | |
86 | const int ret = RUN_ALL_TESTS(); | |
87 | pp::Module::Get()->core()->CallOnMainThread( | |
88 | 0, self->cc_factory_.NewCallback(&NaclTestInstance::TestFinish), ret); | |
89 | return nullptr; | |
90 | } | |
91 | ||
92 | void NaclTestInstance::TestFinish(int32_t result) { | |
93 | url_request_.reset(new pp::URLRequestInfo(this)); | |
94 | url_loader_.reset(new pp::URLLoader(this)); | |
95 | if (result == 0) { | |
96 | url_request_->SetURL("http://127.0.0.1:9999/TEST_FIN?result=success"); | |
97 | } else { | |
98 | url_request_->SetURL("http://127.0.0.1:9999/TEST_FIN?result=failed"); | |
99 | } | |
100 | url_request_->SetMethod("GET"); | |
101 | url_loader_->Open(*url_request_, cc_factory_.NewCallback( | |
102 | &NaclTestInstance::OnUrlLoaderOpen)); | |
103 | } | |
104 | ||
105 | void NaclTestInstance::OnUrlLoaderOpen(int32_t result) { | |
106 | // Do Nothing | |
107 | } | |
108 | ||
109 | class NaclTestModule : public pp::Module { | |
110 | public: | |
111 | NaclTestModule() : pp::Module() {} | |
112 | virtual ~NaclTestModule() {} | |
113 | ||
114 | protected: | |
115 | virtual pp::Instance *CreateInstance(PP_Instance instance) { | |
116 | return new NaclTestInstance(instance); | |
117 | } | |
118 | ||
119 | private: | |
120 | DISALLOW_COPY_AND_ASSIGN(NaclTestModule); | |
121 | }; | |
122 | ||
123 | } // namespace | |
124 | ||
125 | Module *CreateModule() { | |
126 | int argc = 1; | |
127 | char argv0[] = "NaclModule"; | |
128 | char *argv_body[] = {argv0, nullptr}; | |
129 | char **argv = argv_body; | |
130 | mozc::InitMozc(argv[0], &argc, &argv); | |
131 | testing::InitGoogleTest(&argc, argv); | |
132 | ||
133 | return new NaclTestModule(); | |
134 | } | |
135 | ||
136 | } // namespace pp | |
137 | ||
138 | #endif // OS_NACL |
29 | 29 | #ifndef MOZC_TESTING_BASE_PUBLIC_NACL_MOCK_MODULE_H_ |
30 | 30 | #define MOZC_TESTING_BASE_PUBLIC_NACL_MOCK_MODULE_H_ |
31 | 31 | |
32 | #ifdef OS_NACL | |
33 | ||
34 | namespace mozc { | |
35 | namespace testing { | |
36 | ||
37 | // This method does nothing, and is just for avoiding link errors. | |
38 | // | |
39 | // This method should be called in somewhere. Otherwise, the object file | |
40 | // generated from this file will be avoided by clang++ since there is no code | |
41 | // which uses this module. | |
42 | // Actually, pp::CreateModule() in this module is called if NaCl module is | |
43 | // loaded on Chrome, so we need to link this module. | |
44 | // TODO(hsumita): Remove this workaround. | |
45 | void WorkAroundEmptyFunctionToAvoidLinkError(); | |
46 | ||
47 | } // namespace testing | |
48 | } // namespace mozc | |
49 | ||
50 | #endif // OS_NACL | |
51 | ||
52 | 32 | #endif // MOZC_TESTING_BASE_PUBLIC_NACL_MOCK_MODULE_H_ |
32 | 32 | #include "unix/ibus/engine_interface.h" |
33 | 33 | |
34 | 34 | namespace { |
35 | mozc::ibus::EngineInterface *g_engine = NULL; | |
35 | mozc::ibus::EngineInterface *g_engine = nullptr; | |
36 | 36 | } |
37 | 37 | |
38 | 38 | namespace mozc { |
40 | 40 | |
41 | 41 | bool EngineRegistrar::Register(EngineInterface *engine, |
42 | 42 | IBusEngineClass *engine_class) { |
43 | DCHECK(engine) << "engine is NULL"; | |
43 | DCHECK(engine) << "engine is nullptr"; | |
44 | 44 | DCHECK(!g_engine) << "engine is already registered"; |
45 | 45 | |
46 | 46 | g_engine = engine; |
71 | 71 | EngineInterface *EngineRegistrar::Unregister(IBusEngineClass *engine_class) { |
72 | 72 | DCHECK(g_engine) << "engine is not registered"; |
73 | 73 | |
74 | engine_class->cursor_down = NULL; | |
75 | engine_class->candidate_clicked = NULL; | |
76 | engine_class->cursor_down = NULL; | |
77 | engine_class->cursor_up = NULL; | |
78 | engine_class->disable = NULL; | |
79 | engine_class->enable = NULL; | |
80 | engine_class->focus_in = NULL; | |
81 | engine_class->focus_out = NULL; | |
82 | engine_class->page_down = NULL; | |
83 | engine_class->page_up = NULL; | |
84 | engine_class->process_key_event = NULL; | |
85 | engine_class->property_activate = NULL; | |
86 | engine_class->property_hide = NULL; | |
87 | engine_class->property_show = NULL; | |
88 | engine_class->reset = NULL; | |
89 | engine_class->set_capabilities = NULL; | |
90 | engine_class->set_cursor_location = NULL; | |
74 | engine_class->cursor_down = nullptr; | |
75 | engine_class->candidate_clicked = nullptr; | |
76 | engine_class->cursor_down = nullptr; | |
77 | engine_class->cursor_up = nullptr; | |
78 | engine_class->disable = nullptr; | |
79 | engine_class->enable = nullptr; | |
80 | engine_class->focus_in = nullptr; | |
81 | engine_class->focus_out = nullptr; | |
82 | engine_class->page_down = nullptr; | |
83 | engine_class->page_up = nullptr; | |
84 | engine_class->process_key_event = nullptr; | |
85 | engine_class->property_activate = nullptr; | |
86 | engine_class->property_hide = nullptr; | |
87 | engine_class->property_show = nullptr; | |
88 | engine_class->reset = nullptr; | |
89 | engine_class->set_capabilities = nullptr; | |
90 | engine_class->set_cursor_location = nullptr; | |
91 | 91 | #if defined(MOZC_ENABLE_IBUS_INPUT_PURPOSE) |
92 | engine_class->set_content_type = NULL; | |
92 | engine_class->set_content_type = nullptr; | |
93 | 93 | #endif // MOZC_ENABLE_IBUS_INPUT_PURPOSE |
94 | 94 | |
95 | 95 | mozc::ibus::EngineInterface *previous = g_engine; |
96 | g_engine = NULL; | |
96 | g_engine = nullptr; | |
97 | 97 | return previous; |
98 | 98 | } |
99 | 99 |
50 | 50 | if (g_variant_classify(value) != G_VARIANT_CLASS_STRING) { |
51 | 51 | return false; |
52 | 52 | } |
53 | *out_string = static_cast<const char *>(g_variant_get_string(value, NULL)); | |
53 | *out_string = static_cast<const char *>(g_variant_get_string(value, nullptr)); | |
54 | 54 | return true; |
55 | 55 | } |
56 | 56 |
41 | 41 | namespace { |
42 | 42 | |
43 | 43 | // Returns an IBusText used for showing the auxiliary text in the candidate |
44 | // window. Returns NULL if no text has to be shown. Caller must release the | |
44 | // window. Returns nullptr if no text has to be shown. Caller must release the | |
45 | 45 | // returned IBusText object. |
46 | 46 | IBusText *ComposeAuxiliaryText(const commands::Candidates &candidates) { |
47 | 47 | if (!candidates.has_footer()) { |
48 | 48 | // We don't have to show the auxiliary text. |
49 | return NULL; | |
49 | return nullptr; | |
50 | 50 | } |
51 | 51 | const commands::Footer &footer = candidates.footer(); |
52 | 52 | |
73 | 73 | auxiliary_text += index_buf; |
74 | 74 | } |
75 | 75 | return auxiliary_text.empty() |
76 | ? NULL | |
76 | ? nullptr | |
77 | 77 | : ibus_text_new_from_string(auxiliary_text.c_str()); |
78 | 78 | } |
79 | 79 | } // namespace |
306 | 306 | config::Config::PreeditMethod method, |
307 | 307 | bool layout_is_jp, |
308 | 308 | commands::KeyEvent *out_event) const { |
309 | DCHECK(out_event) << "out_event is NULL"; | |
309 | DCHECK(out_event) << "out_event is nullptr"; | |
310 | 310 | out_event->Clear(); |
311 | 311 | |
312 | 312 | // Due to historical reasons, many linux ditributions set Hiragana_Katakana |
41 | 41 | |
42 | 42 | namespace { |
43 | 43 | |
44 | IBusBus *g_bus = NULL; | |
44 | IBusBus *g_bus = nullptr; | |
45 | 45 | |
46 | 46 | #ifndef MOZC_NO_LOGGING |
47 | 47 | void EnableVerboseLog() { |
58 | 58 | sa.sa_handler = SIG_IGN; |
59 | 59 | ::sigemptyset(&sa.sa_mask); |
60 | 60 | sa.sa_flags = 0; |
61 | CHECK_EQ(0, ::sigaction(SIGCHLD, &sa, NULL)); | |
61 | CHECK_EQ(0, ::sigaction(SIGCHLD, &sa, nullptr)); | |
62 | 62 | // TODO(taku): move this function inside client::Session::LaunchTool |
63 | 63 | } |
64 | 64 | |
84 | 84 | void InitIBusComponent(bool executed_by_ibus_daemon) { |
85 | 85 | g_bus = ibus_bus_new(); |
86 | 86 | g_signal_connect(g_bus, "disconnected", |
87 | G_CALLBACK(mozc::ibus::MozcEngine::Disconnected), NULL); | |
87 | G_CALLBACK(mozc::ibus::MozcEngine::Disconnected), nullptr); | |
88 | 88 | |
89 | 89 | IBusComponent *component = GetIBusComponent(); |
90 | 90 | IBusFactory *factory = ibus_factory_new(ibus_bus_get_connection(g_bus)); |
113 | 113 | mozc::ibus::MozcEngine *engine; |
114 | 114 | }; |
115 | 115 | |
116 | IBusEngineClass *g_parent_class = NULL; | |
116 | IBusEngineClass *g_parent_class = nullptr; | |
117 | 117 | |
118 | 118 | GObject *MozcEngineClassConstructor( |
119 | 119 | GType type, guint n_construct_properties, |
175 | 175 | guint anchor_pos = 0; |
176 | 176 | // DO NOT call g_object_unref against this. |
177 | 177 | // http://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#gobject-The-Base-Object-Type.description |
178 | IBusText *text = NULL; | |
178 | IBusText *text = nullptr; | |
179 | 179 | ibus_engine_get_surrounding_text(engine, &text, &cursor_pos, &anchor_pos); |
180 | 180 | const std::string surrounding_text(ibus_text_get_text(text)); |
181 | 181 | |
182 | 182 | #ifdef MOZC_ENABLE_X11_SELECTION_MONITOR |
183 | if (cursor_pos == anchor_pos && selection_monitor != NULL) { | |
183 | if (cursor_pos == anchor_pos && selection_monitor != nullptr) { | |
184 | 184 | const SelectionInfo &info = selection_monitor->GetSelectionInfo(); |
185 | 185 | guint new_anchor_pos = 0; |
186 | 186 | if (SurroundingTextUtil::GetAnchorPosFromSelection( |
252 | 252 | ibus_candidate_window_handler_(new IBusCandidateWindowHandler()), |
253 | 253 | preedit_method_(config::Config::ROMAN) { |
254 | 254 | #ifdef MOZC_ENABLE_X11_SELECTION_MONITOR |
255 | if (selection_monitor_.get() != NULL) { | |
255 | if (selection_monitor_ != nullptr) { | |
256 | 256 | selection_monitor_->StartMonitoring(); |
257 | 257 | } |
258 | 258 | #endif // MOZC_ENABLE_X11_SELECTION_MONITOR |
307 | 307 | |
308 | 308 | // If engine wants to use surrounding text, we should call |
309 | 309 | // ibus_engine_get_surrounding_text once when the engine enabled. |
310 | ibus_engine_get_surrounding_text(engine, NULL, NULL, NULL); | |
310 | ibus_engine_get_surrounding_text(engine, nullptr, nullptr, nullptr); | |
311 | 311 | } |
312 | 312 | |
313 | 313 | void MozcEngine::FocusIn(IBusEngine *engine) { |
431 | 431 | static GType type = 0; |
432 | 432 | |
433 | 433 | static const GTypeInfo type_info = { |
434 | sizeof(IBusMozcEngineClass), NULL, NULL, | |
435 | MozcEngineClassInit, NULL, NULL, | |
436 | sizeof(IBusMozcEngine), 0, MozcEngineInstanceInit, | |
434 | sizeof(IBusMozcEngineClass), nullptr, nullptr, | |
435 | MozcEngineClassInit, nullptr, nullptr, | |
436 | sizeof(IBusMozcEngine), 0, MozcEngineInstanceInit, | |
437 | 437 | }; |
438 | 438 | |
439 | 439 | if (type == 0) { |
521 | 521 | } |
522 | 522 | |
523 | 523 | void MozcEngine::SyncData(bool force) { |
524 | if (client_.get() == NULL) { | |
524 | if (client_ == nullptr) { | |
525 | 525 | return; |
526 | 526 | } |
527 | 527 |
104 | 104 | "Tool.AboutDialog", |
105 | 105 | "about_dialog", |
106 | 106 | "About Mozc", |
107 | NULL, | |
107 | nullptr, | |
108 | 108 | }, |
109 | 109 | }; |
110 | 110 | } // namespace |
43 | 43 | const char *icon; |
44 | 44 | }; |
45 | 45 | |
46 | // This pointer should be NULL when properties size is 0. | |
46 | // This pointer should be nullptr when properties size is 0. | |
47 | 47 | extern const MozcEngineProperty *kMozcEngineProperties; |
48 | 48 | extern const size_t kMozcEnginePropertiesSize; |
49 | 49 | |
50 | // If kMozcEnginePropertiesIMEOffState is NULL, it means IME should be always | |
50 | // If kMozcEnginePropertiesIMEOffState is nullptr, it means IME should be always | |
51 | 51 | // On. |
52 | 52 | extern const MozcEngineProperty *kMozcEnginePropertyIMEOffState; |
53 | 53 | |
60 | 60 | const char *icon; // icon |
61 | 61 | }; |
62 | 62 | |
63 | // This pointer should be NULL when properties size is 0. | |
63 | // This pointer should be nullptr when properties size is 0. | |
64 | 64 | extern const MozcEngineToolProperty *kMozcEngineToolProperties; |
65 | 65 | extern const size_t kMozcEngineToolPropertiesSize; |
66 | 66 |
89 | 89 | PropertyHandler::PropertyHandler(MessageTranslatorInterface *translator, |
90 | 90 | client::ClientInterface *client) |
91 | 91 | : prop_root_(ibus_prop_list_new()), |
92 | prop_composition_mode_(NULL), | |
93 | prop_mozc_tool_(NULL), | |
92 | prop_composition_mode_(nullptr), | |
93 | prop_mozc_tool_(nullptr), | |
94 | 94 | client_(client), |
95 | 95 | translator_(translator), |
96 | 96 | original_composition_mode_(kMozcEngineInitialCompositionMode), |
120 | 120 | if (prop_composition_mode_) { |
121 | 121 | // The ref counter will drop to one. |
122 | 122 | g_object_unref(prop_composition_mode_); |
123 | prop_composition_mode_ = NULL; | |
123 | prop_composition_mode_ = nullptr; | |
124 | 124 | } |
125 | 125 | |
126 | 126 | if (prop_mozc_tool_) { |
127 | 127 | // The ref counter will drop to one. |
128 | 128 | g_object_unref(prop_mozc_tool_); |
129 | prop_mozc_tool_ = NULL; | |
129 | prop_mozc_tool_ = nullptr; | |
130 | 130 | } |
131 | 131 | |
132 | 132 | if (prop_root_) { |
133 | 133 | // Destroy all objects under the root. |
134 | 134 | g_object_unref(prop_root_); |
135 | prop_root_ = NULL; | |
135 | prop_root_ = nullptr; | |
136 | 136 | } |
137 | 137 | } |
138 | 138 | |
143 | 143 | |
144 | 144 | // TODO(nona): do not use kMozcEngine*** directory. |
145 | 145 | void PropertyHandler::AppendCompositionPropertyToPanel() { |
146 | if (kMozcEngineProperties == NULL || kMozcEnginePropertiesSize == 0) { | |
146 | if (kMozcEngineProperties == nullptr || kMozcEnginePropertiesSize == 0) { | |
147 | 147 | return; |
148 | 148 | } |
149 | 149 | |
157 | 157 | : kMozcEnginePropertyIMEOffState->composition_mode; |
158 | 158 | |
159 | 159 | std::string icon_path_for_panel; |
160 | const char *mode_symbol = NULL; | |
160 | const char *mode_symbol = nullptr; | |
161 | 161 | for (size_t i = 0; i < kMozcEnginePropertiesSize; ++i) { |
162 | 162 | const MozcEngineProperty &entry = kMozcEngineProperties[i]; |
163 | 163 | IBusText *label = ibus_text_new_from_string( |
169 | 169 | mode_symbol = entry.label_for_panel; |
170 | 170 | } |
171 | 171 | IBusProperty *item = ibus_property_new( |
172 | entry.key, PROP_TYPE_RADIO, label, NULL /* icon */, NULL /* tooltip */, | |
173 | TRUE /* sensitive */, TRUE /* visible */, state, NULL /* sub props */); | |
172 | entry.key, PROP_TYPE_RADIO, label, nullptr /* icon */, | |
173 | nullptr /* tooltip */, TRUE /* sensitive */, TRUE /* visible */, state, | |
174 | nullptr /* sub props */); | |
174 | 175 | g_object_set_data(G_OBJECT(item), kGObjectDataKey, (gpointer)&entry); |
175 | 176 | ibus_prop_list_append(sub_prop_list, item); |
176 | 177 | // |sub_prop_list| owns |item| by calling g_object_ref_sink for the |item|. |
177 | 178 | } |
178 | 179 | DCHECK(!icon_path_for_panel.empty()); |
179 | DCHECK(mode_symbol != NULL); | |
180 | DCHECK(mode_symbol != nullptr); | |
180 | 181 | |
181 | 182 | const std::string &mode_label = |
182 | 183 | translator_->MaybeTranslate("Input Mode") + " (" + mode_symbol + ")"; |
189 | 190 | // See /usr/share/gnome-shell/js/ui/status/keyboard.js for details. |
190 | 191 | prop_composition_mode_ = ibus_property_new( |
191 | 192 | "InputMode", PROP_TYPE_MENU, label, icon_path_for_panel.c_str(), |
192 | NULL /* tooltip */, TRUE /* sensitive */, TRUE /* visible */, | |
193 | nullptr /* tooltip */, TRUE /* sensitive */, TRUE /* visible */, | |
193 | 194 | PROP_STATE_UNCHECKED, sub_prop_list); |
194 | 195 | |
195 | 196 | // Gnome shell uses symbol property for the mode indicator text icon iff the |
230 | 231 | |
231 | 232 | // TODO(nona): do not use kMozcEngine*** directory. |
232 | 233 | void PropertyHandler::AppendToolPropertyToPanel() { |
233 | if (kMozcEngineToolProperties == NULL || kMozcEngineToolPropertiesSize == 0 || | |
234 | if (kMozcEngineToolProperties == nullptr || | |
235 | kMozcEngineToolPropertiesSize == 0 || | |
234 | 236 | !IsMozcToolAvailable()) { |
235 | 237 | return; |
236 | 238 | } |
245 | 247 | translator_->MaybeTranslate(entry.label).c_str()); |
246 | 248 | // TODO(yusukes): It would be better to use entry.icon here? |
247 | 249 | IBusProperty *item = ibus_property_new( |
248 | entry.mode, PROP_TYPE_NORMAL, label, NULL /* icon */, | |
249 | NULL /* tooltip */, TRUE, TRUE, PROP_STATE_UNCHECKED, NULL); | |
250 | entry.mode, PROP_TYPE_NORMAL, label, nullptr /* icon */, | |
251 | nullptr /* tooltip */, TRUE, TRUE, PROP_STATE_UNCHECKED, nullptr); | |
250 | 252 | g_object_set_data(G_OBJECT(item), kGObjectDataKey, (gpointer)&entry); |
251 | 253 | ibus_prop_list_append(sub_prop_list, item); |
252 | 254 | } |
255 | 257 | ibus_text_new_from_string(translator_->MaybeTranslate("Tools").c_str()); |
256 | 258 | const std::string icon_path = GetIconPath(kMozcToolIconPath); |
257 | 259 | prop_mozc_tool_ = ibus_property_new("MozcTool", PROP_TYPE_MENU, tool_label, |
258 | icon_path.c_str(), NULL /* tooltip */, | |
260 | icon_path.c_str(), nullptr /* tooltip */, | |
259 | 261 | TRUE /* sensitive */, TRUE /* visible */, |
260 | 262 | PROP_STATE_UNCHECKED, sub_prop_list); |
261 | 263 | |
290 | 292 | |
291 | 293 | void PropertyHandler::UpdateCompositionModeIcon( |
292 | 294 | IBusEngine *engine, const commands::CompositionMode new_composition_mode) { |
293 | if (prop_composition_mode_ == NULL) { | |
294 | return; | |
295 | } | |
296 | ||
297 | const MozcEngineProperty *entry = NULL; | |
295 | if (prop_composition_mode_ == nullptr) { | |
296 | return; | |
297 | } | |
298 | ||
299 | const MozcEngineProperty *entry = nullptr; | |
298 | 300 | for (size_t i = 0; i < kMozcEnginePropertiesSize; ++i) { |
299 | 301 | if (kMozcEngineProperties[i].composition_mode == new_composition_mode) { |
300 | 302 | entry = &(kMozcEngineProperties[i]); |
306 | 308 | for (guint prop_index = 0;; ++prop_index) { |
307 | 309 | IBusProperty *prop = ibus_prop_list_get( |
308 | 310 | ibus_property_get_sub_props(prop_composition_mode_), prop_index); |
309 | if (prop == NULL) { | |
311 | if (prop == nullptr) { | |
310 | 312 | break; |
311 | 313 | } |
312 | 314 | if (!g_strcmp0(entry->key, ibus_property_get_key(prop))) { |
345 | 347 | // composition_mode. However in IBus we can only control composition mode, not |
346 | 348 | // IMEOn/IMEOff. So we use one composition state as IMEOff and the others as |
347 | 349 | // IMEOn. This setting can be configured with setting |
348 | // kMozcEnginePropertyIMEOffState. If kMozcEnginePropertyIMEOffState is NULL, | |
349 | // it means current IME should not be off. | |
350 | // kMozcEnginePropertyIMEOffState. If kMozcEnginePropertyIMEOffState is | |
351 | // nullptr, it means current IME should not be off. | |
350 | 352 | if (kMozcEnginePropertyIMEOffState && is_activated_ && |
351 | 353 | composition_mode == kMozcEnginePropertyIMEOffState->composition_mode) { |
352 | 354 | command.set_type(commands::SessionCommand::TURN_OFF_IME); |
373 | 375 | for (guint prop_index = 0;; ++prop_index) { |
374 | 376 | IBusProperty *prop = ibus_prop_list_get( |
375 | 377 | ibus_property_get_sub_props(prop_mozc_tool_), prop_index); |
376 | if (prop == NULL) { | |
378 | if (prop == nullptr) { | |
377 | 379 | break; |
378 | 380 | } |
379 | 381 | if (!g_strcmp0(property_name, ibus_property_get_key(prop))) { |
397 | 399 | for (guint prop_index = 0;; ++prop_index) { |
398 | 400 | IBusProperty *prop = ibus_prop_list_get( |
399 | 401 | ibus_property_get_sub_props(prop_composition_mode_), prop_index); |
400 | if (prop == NULL) { | |
402 | if (prop == nullptr) { | |
401 | 403 | break; |
402 | 404 | } |
403 | 405 | if (!g_strcmp0(property_name, ibus_property_get_key(prop))) { |
50 | 50 | |
51 | 51 | class ScopedXcbGenericError { |
52 | 52 | public: |
53 | ScopedXcbGenericError() : error_(NULL) {} | |
53 | ScopedXcbGenericError() : error_(nullptr) {} | |
54 | 54 | ~ScopedXcbGenericError() { |
55 | 55 | free(error_); |
56 | error_ = NULL; | |
56 | error_ = nullptr; | |
57 | 57 | } |
58 | 58 | const xcb_generic_error_t *get() const { return error_; } |
59 | 59 | xcb_generic_error_t **mutable_get() { return &error_; } |
98 | 98 | class SelectionMonitorServer { |
99 | 99 | public: |
100 | 100 | SelectionMonitorServer() |
101 | : connection_(NULL), | |
101 | : connection_(nullptr), | |
102 | 102 | requestor_window_(0), |
103 | 103 | root_window_(0), |
104 | 104 | xfixes_first_event_(0), |
107 | 107 | ~SelectionMonitorServer() { Release(); } |
108 | 108 | |
109 | 109 | bool Init() { |
110 | connection_ = ::xcb_connect(NULL, NULL); | |
111 | if (connection_ == NULL) { | |
110 | connection_ = ::xcb_connect(nullptr, nullptr); | |
111 | if (connection_ == nullptr) { | |
112 | 112 | return false; |
113 | 113 | } |
114 | 114 | |
149 | 149 | } |
150 | 150 | if (::xcb_connection_has_error(connection_)) { |
151 | 151 | LOG(ERROR) << "XCB connection has error."; |
152 | connection_ = NULL; | |
152 | connection_ = nullptr; | |
153 | 153 | return false; |
154 | 154 | } |
155 | 155 | return true; |
165 | 165 | unique_ptr<xcb_generic_event_t, void (*)(void *)> event( |
166 | 166 | ::xcb_wait_for_event(connection_), &std::free); |
167 | 167 | |
168 | if (event.get() == NULL) { | |
169 | LOG(ERROR) << "NULL event returned."; | |
168 | if (event.get() == nullptr) { | |
169 | LOG(ERROR) << "nullptr event returned."; | |
170 | 170 | return false; |
171 | 171 | } |
172 | 172 | |
208 | 208 | void Release() { |
209 | 209 | if (connection_) { |
210 | 210 | ::xcb_disconnect(connection_); |
211 | connection_ = NULL; | |
211 | connection_ = nullptr; | |
212 | 212 | } |
213 | 213 | } |
214 | 214 | |
219 | 219 | ::xcb_intern_atom(connection_, false, name.size(), name.c_str()); |
220 | 220 | ScopedXcbInternAtomReply reply( |
221 | 221 | ::xcb_intern_atom_reply(connection_, cookie, 0)); |
222 | if (reply.get() == NULL) { | |
223 | LOG(ERROR) << "xcb_intern_atom_reply returned NULL reply."; | |
222 | if (reply.get() == nullptr) { | |
223 | LOG(ERROR) << "xcb_intern_atom_reply returned nullptr reply."; | |
224 | 224 | return false; |
225 | 225 | } |
226 | 226 | if (reply->atom == XCB_NONE) { |
241 | 241 | bool InitXFixes() { |
242 | 242 | const xcb_query_extension_reply_t *ext_reply = |
243 | 243 | ::xcb_get_extension_data(connection_, &xcb_xfixes_id); |
244 | if (ext_reply == NULL) { | |
245 | LOG(ERROR) << "xcb_get_extension_data returns NULL."; | |
244 | if (ext_reply == nullptr) { | |
245 | LOG(ERROR) << "xcb_get_extension_data returns nullptr."; | |
246 | 246 | return false; |
247 | 247 | } |
248 | 248 | |
253 | 253 | ScopedXcbXFixesQueqyVersionReply xfixes_query( |
254 | 254 | ::xcb_xfixes_query_version_reply(connection_, xfixes_query_cookie, |
255 | 255 | xcb_error.mutable_get())); |
256 | if (xcb_error.get() != NULL) { | |
256 | if (xcb_error.get() != nullptr) { | |
257 | 257 | LOG(ERROR) << "xcb_xfixes_query_version_reply failed. error_code: " |
258 | 258 | << static_cast<uint32>(xcb_error.get()->error_code); |
259 | 259 | return false; |
260 | 260 | } |
261 | if (xfixes_query.get() == NULL) { | |
261 | if (xfixes_query.get() == nullptr) { | |
262 | 262 | return false; |
263 | 263 | } |
264 | 264 | |
283 | 283 | ScopedXcbGenericError xcb_error; |
284 | 284 | ScopedXcbGetAtomNameReply reply(::xcb_get_atom_name_reply( |
285 | 285 | connection_, cookie, xcb_error.mutable_get())); |
286 | if (xcb_error.get() != NULL) { | |
286 | if (xcb_error.get() != nullptr) { | |
287 | 287 | LOG(ERROR) << "xcb_get_atom_name_reply failed. error_code: " |
288 | 288 | << static_cast<uint32>(xcb_error.get()->error_code); |
289 | 289 | return ""; |
290 | 290 | } |
291 | if (reply.get() == NULL) { | |
292 | VLOG(2) << "reply is NULL"; | |
291 | if (reply.get() == nullptr) { | |
292 | VLOG(2) << "reply is nullptr"; | |
293 | 293 | return ""; |
294 | 294 | } |
295 | 295 | |
310 | 310 | connection_, false, window, property_atom, property_type_atom, 0, 0); |
311 | 311 | ScopedXcbGetPropertyReply reply( |
312 | 312 | ::xcb_get_property_reply(connection_, cookie, 0)); |
313 | if (reply.get() == NULL) { | |
314 | VLOG(2) << "reply is NULL"; | |
313 | if (reply.get() == nullptr) { | |
314 | VLOG(2) << "reply is nullptr"; | |
315 | 315 | return false; |
316 | 316 | } |
317 | 317 | if (reply->type == XCB_NONE) { |
352 | 352 | property_type_atom, byte_offset, max_bytes); |
353 | 353 | ScopedXcbGetPropertyReply reply( |
354 | 354 | ::xcb_get_property_reply(connection_, cookie, 0)); |
355 | if (reply.get() == NULL) { | |
356 | VLOG(2) << "reply is NULL"; | |
355 | if (reply.get() == nullptr) { | |
356 | VLOG(2) << "reply is nullptr"; | |
357 | 357 | return false; |
358 | 358 | } |
359 | 359 | if (reply->format != element_bit_size) { |
379 | 379 | XCB_ATOM_CARDINAL, 0, sizeof(T) * 8); |
380 | 380 | ScopedXcbGetPropertyReply reply( |
381 | 381 | ::xcb_get_property_reply(connection_, cookie, 0)); |
382 | if (reply.get() == NULL) { | |
383 | VLOG(2) << "reply is NULL"; | |
382 | if (reply.get() == nullptr) { | |
383 | VLOG(2) << "reply is nullptr"; | |
384 | 384 | return false; |
385 | 385 | } |
386 | 386 | |
563 | 563 | size_t max_text_bytes) { |
564 | 564 | unique_ptr<SelectionMonitorServer> server(new SelectionMonitorServer()); |
565 | 565 | if (!server->Init()) { |
566 | return NULL; | |
566 | return nullptr; | |
567 | 567 | } |
568 | 568 | return new SelectionMonitorImpl(server.release(), max_text_bytes); |
569 | 569 | } |
182 | 182 | bool ConversionModeUtil::ToMozcMode(uint32 flag, |
183 | 183 | mozc::commands::CompositionMode *mode) { |
184 | 184 | if (mode == nullptr) { |
185 | LOG(ERROR) << "|mode| is NULL"; | |
185 | LOG(ERROR) << "|mode| is nullptr"; | |
186 | 186 | return false; |
187 | 187 | } |
188 | 188 |
162 | 162 | DWORD value_name_length = kMaxValueNameLength; |
163 | 163 | DWORD value_length = kMaxValueLength; |
164 | 164 | LONG result = RegEnumValue(preload_key, i, value_name, &value_name_length, |
165 | nullptr, // reserved (must be NULL) | |
165 | nullptr, // reserved (must be nullptr) | |
166 | 166 | nullptr, // type (optional) |
167 | 167 | value, &value_length); |
168 | 168 | |
225 | 225 | continue; |
226 | 226 | } |
227 | 227 | // ImmSetHotKey fails when both 2nd and 3rd arguments are valid while 4th |
228 | // argument is NULL. To remove the HotKey, pass 0 to them. | |
228 | // argument is nullptr. To remove the HotKey, pass 0 to them. | |
229 | 229 | result = ::ImmSetHotKey(id, 0, 0, nullptr); |
230 | 230 | if (result == FALSE) { |
231 | 231 | succeeded = false; |
65 | 65 | class CandidateInfoUtil { |
66 | 66 | public: |
67 | 67 | // Returns an Input Method Context Component (IMCC) handle with initializing |
68 | // it with an empty CANDIDATEINFO data. Returns NULL if fails. | |
68 | // it with an empty CANDIDATEINFO data. Returns nullptr if fails. | |
69 | 69 | // You can specify the previously used handle in |current_handle| to transfer |
70 | 70 | // the ownership so that this method can reuse the handle and its memory |
71 | // block. If NULL is specified in |current_handle|, this method allocates a | |
72 | // new memory block. The caller is responsible for the lifetime management | |
71 | // block. If nullptr is specified in |current_handle|, this method allocates | |
72 | // a new memory block. The caller is responsible for the lifetime management | |
73 | 73 | // of the returned handle either way. |
74 | 74 | static HIMCC Initialize(HIMCC current_handle); |
75 | 75 | |
76 | 76 | // Returns an Input Method Context Component (IMCC) handle with filling |
77 | 77 | // candidate list information based on the Mozc output specified in |output|. |
78 | // Returns NULL if fails. | |
78 | // Returns nullptr if fails. | |
79 | 79 | // You can specify the previously used handle in |current_handle| to transfer |
80 | 80 | // the ownership so that this method can reuse the handle and its memory |
81 | // block. If NULL is specified in |current_handle|, this method allocates a | |
82 | // new memory block. The caller is responsible for the lifetime management | |
81 | // block. If nullptr is specified in |current_handle|, this method allocates | |
82 | // a new memory block. The caller is responsible for the lifetime management | |
83 | 83 | // of the returned handle either way. |
84 | 84 | static HIMCC Update(HIMCC current_handle, |
85 | 85 | const mozc::commands::Output &output, |
140 | 140 | // - hCandInfo |
141 | 141 | // - hPrivate |
142 | 142 | // Based on which field is actually updated, this function generates |
143 | // UI messages into |message_queue|. If |message_queue| is NULL, this | |
143 | // UI messages into |message_queue|. If |message_queue| is nullptr, this | |
144 | 144 | // function will not generate any UI message. |
145 | 145 | // Returns true if the operation completed successfully. |
146 | 146 | static bool UpdateContext(HIMC himc, const InputState &next_state, |
154 | 154 | STDMETHODIMP QueryInterfaceBase(REFIID guid, void** object); |
155 | 155 | |
156 | 156 | // Returns the i-th data in the language bar menu. |
157 | // Returns NULL if i is out of bounds. | |
157 | // Returns nullptr if i is out of bounds. | |
158 | 158 | ImeLangBarMenuData* menu_data(size_t i); |
159 | 159 | |
160 | 160 | // Returns the size of the language bar menu. |
47 | 47 | class TipCompositionUtil { |
48 | 48 | public: |
49 | 49 | // Returns composition view object if there is an composition which belongs |
50 | // to Mozc in |context|. Otherwise returns NULL. | |
50 | // to Mozc in |context|. Otherwise returns nullptr. | |
51 | 51 | static ATL::CComPtr<ITfCompositionView> GetComposition( |
52 | 52 | ATL::CComPtr<ITfContext> context, TfEditCookie edit_cookie); |
53 | 53 |
167 | 167 | void SetDescription(const std::wstring &description); |
168 | 168 | |
169 | 169 | // Returns the i-th data in the language bar menu. |
170 | // Returns NULL if i is out of bounds. | |
170 | // Returns nullptr if i is out of bounds. | |
171 | 171 | TipLangBarMenuData *menu_data(size_t i); |
172 | 172 | |
173 | 173 | // Returns the size of the language bar menu. |
186 | 186 | } |
187 | 187 | |
188 | 188 | CComQIPtr<ITfInputScope> input_scope = variant.punkVal; |
189 | InputScope *input_scopes_buffer = NULL; | |
189 | InputScope *input_scopes_buffer = nullptr; | |
190 | 190 | UINT num_input_scopes = 0; |
191 | 191 | result = input_scope->GetInputScopes(&input_scopes_buffer, &num_input_scopes); |
192 | 192 | if (FAILED(result)) { |
428 | 428 | } |
429 | 429 | return ::DefWindowProcW(window_handle, message, wparam, lparam); |
430 | 430 | case WM_SETCURSOR: |
431 | ::SetCursor(::LoadCursor(NULL, IDC_ARROW)); | |
431 | ::SetCursor(::LoadCursor(nullptr, IDC_ARROW)); | |
432 | 432 | return 0; |
433 | 433 | default: |
434 | 434 | return ::DefWindowProcW(window_handle, message, wparam, lparam); |