Codebase list mozc / cfd05a0
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
136 changed file(s) with 1131 addition(s) and 3588 deletion(s). Raw diff Collapse all Expand all
268268 deps = [":port"],
269269 )
270270
271 LOGGING_APP_BUILD_DEPS = [
272 ":const",
273 ":clock",
274 ":flags",
275 ":mutex",
276 ":singleton",
277 ]
278
279271 cc_library_mozc(
280272 name = "logging",
281273 srcs = ["logging.cc"],
285277 android = ["-llog"],
286278 ),
287279 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 ],
289288 default = [
290289 "//base",
291290 "//base:logging_extensions",
456455 cc_library_mozc(
457456 name = "mozc_hash_map",
458457 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"],
467460 )
468461
469462 cc_library_mozc(
470463 name = "mozc_hash_set",
471464 hdrs = ["mozc_hash_set.h"],
472465 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"],
478467 )
479468
480469 py_binary_mozc(
541530 deps = [
542531 ":port",
543532 ":singleton",
533 "@com_google_absl//absl/time",
544534 ],
545535 )
546536
745735 deps = [
746736 ":port",
747737 ":util",
738 "@com_google_absl//absl/time",
748739 ],
749740 )
750741
4646 '<(absl_srcdir)/base/internal/thread_identity.cc',
4747 '<(absl_srcdir)/base/internal/throw_delegate.cc',
4848 '<(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',
4952 ],
5053 'msvs_disabled_warnings': [
5154 # 'type' : forcing value to bool 'true' or 'false'
109112 'absl_strings_internal',
110113 ],
111114 },
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 },
112145 ],
113146 }
117117 'mutex',
118118 'singleton',
119119 'absl.gyp:absl_strings',
120 'absl.gyp:absl_time',
120121 ],
121122 'conditions': [
122123 ['OS=="win"', {
201202 ],
202203 'dependencies': [
203204 'singleton',
205 'absl.gyp:absl_time',
204206 ],
205207 },
206208 {
146146 'sources': [
147147 'clock_mock.cc'
148148 ],
149 'dependencies': [
150 'absl.gyp:absl_time',
151 ],
149152 },
150153 {
151154 'target_name': 'clock_mock_test',
4141 #endif // OS_WIN
4242
4343 #include "base/singleton.h"
44 #include "absl/time/clock.h"
4445
4546 namespace mozc {
4647 namespace {
4748
4849 class ClockImpl : public ClockInterface {
4950 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()) {}
5652 ~ClockImpl() override {}
5753
5854 void GetTimeOfDay(uint64 *sec, uint32 *usec) override {
9086 #endif // OS_WIN
9187 }
9288
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();
11291 }
11392
11493 uint64 GetFrequency() override {
152131 #endif // platforms (OS_WIN, __APPLE__, OS_LINUX, ...)
153132 }
154133
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 {
157139 timezone_offset_sec_ = timezone_offset_sec;
140 timezone_ = absl::FixedTimeZone(timezone_offset_sec);
158141 }
159142
160143 private:
161144 int32 timezone_offset_sec_;
162 #endif // OS_NACL
145 absl::TimeZone timezone_;
163146 };
164147
165148 ClockInterface *g_clock = nullptr;
176159
177160 uint64 Clock::GetTime() { return GetClock()->GetTime(); }
178161
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(); }
182163
183164 uint64 Clock::GetFrequency() { return GetClock()->GetFrequency(); }
184165
185166 uint64 Clock::GetTicks() { return GetClock()->GetTicks(); }
186167
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();
190170 }
191 #endif // OS_NACL
171
172 void Clock::SetTimeZoneOffset(int32 timezone_offset_sec) {
173 return GetClock()->SetTimeZoneOffset(timezone_offset_sec);
174 }
192175
193176 void Clock::SetClockForUnitTest(ClockInterface *clock) { g_clock = clock; }
194177
178
195179 } // namespace mozc
3232 #include <ctime>
3333
3434 #include "base/port.h"
35 #include "absl/time/time.h"
3536
3637 namespace mozc {
3738
4142
4243 virtual void GetTimeOfDay(uint64 *sec, uint32 *usec) = 0;
4344 virtual uint64 GetTime() = 0;
44 virtual bool GetTmWithOffsetSecond(time_t offset_sec, tm *output) = 0;
45 virtual absl::Time GetAbslTime() = 0;
4546
4647 // High accuracy clock.
4748 virtual uint64 GetFrequency() = 0;
4849 virtual uint64 GetTicks() = 0;
4950
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;
5353
5454 protected:
5555 ClockInterface() {}
6767 // For Linux/Mac, time() is used.
6868 static uint64 GetTime();
6969
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();
7872
7973 // Gets the system frequency to calculate the time from ticks.
8074 static uint64 GetFrequency();
8478 // GetFrequency().
8579 static uint64 GetTicks();
8680
87 #ifdef OS_NACL
81 // Returns the timezone. LocalTimeZone is usually returned.
82 static const absl::TimeZone& GetTimeZone();
83
8884 // Sets the time difference between local time and UTC time in seconds.
8985 // We use this function in NaCl Mozc because we can't know the local timezone
9086 // in NaCl environment.
91 static void SetTimezoneOffset(int32 timezone_offset_sec);
92 #endif // OS_NACL
87 static void SetTimeZoneOffset(int32 timezone_offset_sec);
9388
9489 // TESTONLY: The behavior of global system clock can be overridden by using
9590 // this method. Set to nullptr to restore the default clock. This method
3737 micro_seconds_(usec),
3838 frequency_(1000000000),
3939 ticks_(0),
40 #ifdef OS_NACL
40 timezone_(absl::UTCTimeZone()),
4141 timezone_offset_sec_(0),
42 #endif // OS_NACL
4342 delta_seconds_(0),
4443 delta_micro_seconds_(0) {
4544 }
5857 return ret_sec;
5958 }
6059
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_);
7962 PutClockForward(delta_seconds_, delta_micro_seconds_);
80
81 return true;
63 return at;
8264 }
8365
8466 uint64 ClockMock::GetFrequency() { return frequency_; }
8567
8668 uint64 ClockMock::GetTicks() { return ticks_; }
8769
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) {
9075 timezone_offset_sec_ = timezone_offset_sec;
76 timezone_ = absl::FixedTimeZone(timezone_offset_sec);
9177 }
92 #endif // OS_NACL
9378
9479 void ClockMock::PutClockForward(uint64 delta_sec, uint32 delta_usec) {
9580 const uint32 one_second = 1000000u;
4747
4848 void GetTimeOfDay(uint64 *sec, uint32 *usec) override;
4949 uint64 GetTime() override;
50 bool GetTmWithOffsetSecond(time_t offset_sec, tm *output) override;
50 absl::Time GetAbslTime() override;
5151 uint64 GetFrequency() override;
5252 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;
5656
5757 // Puts this clock forward.
5858 // It has no impact on ticks.
7575 uint32 micro_seconds_;
7676 uint64 frequency_;
7777 uint64 ticks_;
78 #ifdef OS_NACL
78 absl::TimeZone timezone_;
7979 int32 timezone_offset_sec_;
80 #endif // OS_NACL
8180 // Everytime user requests time clock, following time is added to the
8281 // internal clock.
8382 uint64 delta_seconds_;
6363 // 2020-12-23 13:24:00 (Wed)
6464 ClockMock mock(kTestSeconds, kTestMicroSeconds);
6565 const int offset = -35;
66 tm current_tm;
67
68 EXPECT_TRUE(mock.GetTmWithOffsetSecond(offset, &current_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) {
8081 // 2020-12-23 13:24:00 (Wed)
8182 ClockMock mock(kTestSeconds, kTestMicroSeconds);
82 mock.SetTimezoneOffset(3600);
83 mock.SetTimeZoneOffset(3600);
8384 const int offset = -35;
84 tm current_tm;
85
86 EXPECT_TRUE(mock.GetTmWithOffsetSecond(offset, &current_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 }
9698
9799 TEST(ClockMockTest, GetFrequencyAndTicks) {
98100 ClockMock mock(0, 0);
189191 ClockMock mock(kTestSeconds, kTestMicroSeconds);
190192 mock.SetAutoPutClockForward(kDeltaSeconds, kDeltaMicroSeconds);
191193 const int offset = -35;
192 tm current_tm;
193
194 EXPECT_TRUE(mock.GetTmWithOffsetSecond(offset, &current_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, &current_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));
211216 }
212217 }
213218
5555 EXPECT_EQ(kTestMicroSeconds, current_usec);
5656 }
5757
58 // GetCurrentTm
58 // GetAbslTime
5959 // 2020-12-23 13:24:35 (Wed)
6060 {
61 tm current_tm;
62 Clock::GetCurrentTm(&current_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));
7072 }
7173
72 // GetTmWithoutOffsetSecond
74 // GetAbslTime + offset
7375 // 2024/02/23 23:11:15 (Fri)
7476 {
7577 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));
8588 }
8689
8790 // GetFrequency / GetTicks
4141 // base/embedded_file.h is embedded as kEmbeddedFileTestData.
4242 #include "base/embedded_file_test_data.inc"
4343
44 #ifndef OS_NACL
45 // NaCl test doesn't support real file system, so currently disabled.
4644 TEST(EmbeddedFileTest, Basic) {
4745 const std::string expected =
4846 InputFileStream(
5149 .Read();
5250 EXPECT_EQ(expected, LoadEmbeddedFile(kEmbeddedFileTestData));
5351 }
54 #endif // OS_NACL
5552
5653 } // namespace
5754 } // namespace mozc
8383 static bool FileExists(const std::string &filename);
8484
8585 // Returns true if the directory exists.
86 static bool DirectoryExists(const std::string &filename);
86 static bool DirectoryExists(const std::string &dirname);
8787
8888 #ifdef OS_WIN
8989 // Adds file attributes to the file to hide it.
5959 #include "base/flags.h"
6060 #include "base/mutex.h"
6161 #include "base/singleton.h"
62 #include "absl/strings/str_cat.h"
6263
6364 DEFINE_bool(colored_log, true, "Enables colored log messages on tty devices");
6465 DEFINE_bool(logtostderr, false,
9192
9293 // Use the same implementation both for Opt and Debug.
9394 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
13596 // On Android, other records are not needed because they are added by
13697 // 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
141130 #endif // OS_ANDROID
142131 }
143132
280269 delete real_log_stream_;
281270 real_log_stream_ = nullptr;
282271 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)
288273 // Android uses Android's log library.
289274 use_cerr_ = false;
290275 support_color_ = false;
294279 // TODO(team): Considers to use SetConsoleTextAttribute on Windows.
295280 use_cerr_ = FLAGS_logtostderr;
296281 support_color_ = false;
297 #else // OS_NACL, OS_ANDROID, OS_WIN
282 #else // OS_ANDROID, OS_WIN
298283 use_cerr_ = FLAGS_logtostderr;
299284 support_color_ = use_cerr_ && FLAGS_colored_log && ::isatty(::fileno(stderr));
300 #endif // OS_NACL, OS_ANDROID, OS_WIN
285 #endif // OS_ANDROID, OS_WIN
301286 }
302287
303288 LogStreamImpl::~LogStreamImpl() { Reset(); }
4646 #include "base/port.h"
4747 #include "base/util.h"
4848
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)
5550 #include "base/scoped_handle.h"
56 #endif // !OS_NACL
51 #endif // OS_WIN
5752
5853 namespace mozc {
5954
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)
14656
14757 Mmap::Mmap() : text_(nullptr), size_(0) {}
14858
203113 size_ = 0;
204114 }
205115
206 #else // !OS_NACL || !OS_WIN
116 #else // !OS_WIN
207117
208118 Mmap::Mmap() : text_(nullptr), size_(0) {}
209119
276186 text_ = nullptr;
277187 size_ = 0;
278188 }
279 #endif // !OS_NACL || !OS_WIN
189 #endif // !OS_WIN
280190
281191 // Define a macro (MOZC_HAVE_MLOCK) to indicate mlock support.
282192
3434 #include "base/mmap_sync_interface.h"
3535 #include "base/port.h"
3636
37 #ifdef OS_NACL
38 #include <memory>
39 #endif // OS_NACL
4037
4138 namespace mozc {
4239
4340 class Mmap : public MmapSyncInterface {
4441 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
5042 Mmap();
5143 ~Mmap() override { Close(); }
5244
6860 static int MaybeMLock(const void *addr, size_t len);
6961 static int MaybeMUnlock(const void *addr, size_t len);
7062
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
7963 char &operator[](size_t n) { return *(text_ + n); }
8064 char operator[](size_t n) const { return *(text_ + n); }
8165 char *begin() { return text_; }
8266 const char *begin() const { return text_; }
8367 char *end() { return text_ + size_; }
8468 const char *end() const { return text_ + size_; }
85 #endif // !OS_NACL
8669
8770 size_t size() const { return size_; }
8871
8972 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
9673 char *text_;
97 #endif // OS_NACL
9874 size_t size_;
9975
10076 DISALLOW_COPY_AND_ASSIGN(Mmap);
2929 #ifndef MOZC_BASE_MOZC_HASH_MAP_H_
3030 #define MOZC_BASE_MOZC_HASH_MAP_H_
3131
32 #include <unordered_map>
32 #include "absl/container/flat_hash_map.h"
3333
3434 namespace mozc {
3535
3636 template <typename K, typename V, typename Hash = std::hash<K>,
3737 typename Eq = std::equal_to<K>,
3838 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>;
4040
4141 } // namespace mozc
4242
2929 #ifndef MOZC_BASE_MOZC_HASH_SET_H_
3030 #define MOZC_BASE_MOZC_HASH_SET_H_
3131
32 #include <unordered_set>
32 #include "absl/container/flat_hash_set.h"
3333
3434 namespace mozc {
3535
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,
3839 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>;
4041
4142 } // namespace mozc
4243
4949 #endif // OS_ANDROID
5050
5151 #ifdef OS_NACL
52 #define MOZC_OS_DEFINED
52 #error "We no longer support NaCl. Still need? Report to b/158959918 ASAP."
5353 #endif // OS_NACL
5454
5555 #ifdef OS_LINUX
202202 #endif // OS_WIN
203203
204204 UserProfileDirectoryImpl::UserProfileDirectoryImpl() {
205 #if defined(OS_NACL) || defined(OS_CHROMEOS)
205 #if defined(OS_CHROMEOS)
206206 // TODO(toka): Must use passed in user profile dir which passed in. If mojo
207207 // platform the user profile is determined on runtime.
208208 // It's hack, the user profile dir should be passed in. Although the value in
209209 // NaCL platform is correct.
210210 dir_ = "/mutable";
211211 return;
212 #endif // OS_NACL || OS_CHROMEOS
212 #endif // OS_CHROMEOS
213213
214214 #if defined(OS_WASM)
215215 // Do nothing for WebAssembly.
445445 }
446446
447447 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
453448 #if defined(OS_WIN)
454449 wchar_t wusername[UNLEN + 1];
455450 DWORD name_size = UNLEN + 1;
6060 SystemUtil::IS_WINDOWS_X64_DEFAULT_MODE);
6161 }
6262
63 #ifndef OS_NACL
6463 TEST_F(SystemUtilTest, GetTotalPhysicalMemoryTest) {
6564 EXPECT_GT(SystemUtil::GetTotalPhysicalMemory(), 0);
6665 }
67 #endif // OS_NACL
6866
6967 #ifdef OS_ANDROID
7068 TEST_F(SystemUtilTest, GetOSVersionStringTestForAndroid) {
140140 state_->is_running = false;
141141 state_->handle.reset();
142142 } 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
148146 pthread_setname_np(thread_name.c_str());
149 #else // !(OS_NACL | __APPLE__)
147 #else // !(OS_WASM | __APPLE__)
150148 pthread_setname_np(*state_->handle, thread_name.c_str());
151 #endif // !(OS_NACL | __APPLE__)
149 #endif // !(OS_WASM | __APPLE__)
152150 }
153151 }
154152
4949 // Does AES256 CBC transformation.
5050 // CAVEATS: See the above comment.
5151 static void TransformCBC(const uint8 (&key)[kKeyBytes],
52 const uint8 (&iv)[kBlockBytes], uint8 *buffer,
52 const uint8 (&iv)[kBlockBytes], uint8 *block,
5353 size_t block_count);
5454
5555 // Does AES256 CBC inverse transformation.
5656 // CAVEATS: See the above comment.
5757 static void InverseTransformCBC(const uint8 (&key)[kKeyBytes],
58 const uint8 (&iv)[kBlockBytes], uint8 *buffer,
58 const uint8 (&iv)[kBlockBytes], uint8 *block,
5959 size_t block_count);
6060
6161 protected:
6262 // Does AES256 ECB transformation.
6363 // CAVEATS: See the above comment.
6464 static void TransformECB(const uint8 (&w)[kKeyScheduleBytes],
65 uint8 buffer[kBlockBytes]);
65 uint8 block[kBlockBytes]);
6666
6767 // Does AES256 ECB inverse transformation.
6868 // CAVEATS: See the above comment.
6969 static void InverseTransformECB(const uint8 (&w)[kKeyScheduleBytes],
70 uint8 buffer[kBlockBytes]);
70 uint8 block[kBlockBytes]);
7171
7272 // Declared as protected for unit test.
7373 static void MakeKeySchedule(const uint8 (&key)[kKeyBytes],
7474 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]);
8181
8282 private:
8383 DISALLOW_IMPLICIT_CONSTRUCTORS(UnverifiedAES256);
4242 #include <mach/mach_time.h>
4343 #endif // __APPLE__
4444
45 #if defined(OS_NACL)
46 #include <irt.h>
47 #endif // OS_NACL
48
4945 #ifndef OS_WIN
5046 #include <sys/mman.h>
5147 #include <sys/time.h>
472468 return kUTF8LenTbl[*reinterpret_cast<const uint8 *>(src)];
473469 }
474470
475 size_t Util::CharsLen(const char *src, size_t length) {
471 size_t Util::CharsLen(const char *src, size_t size) {
476472 const char *begin = src;
477 const char *end = src + length;
478 int result = 0;
473 const char *end = src + size;
474 int length = 0;
479475 while (begin < end) {
480 ++result;
476 ++length;
481477 begin += OneCharLen(begin);
482478 }
483 return result;
479 return length;
484480 }
485481
486482 char32 Util::UTF8ToUCS4(const char *begin, const char *end, size_t *mblen) {
841837 return true;
842838 #endif // OS_WIN
843839
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
866840 #if defined(OS_CHROMEOS)
867841 // TODO(googleo): b/171939770 Accessing "/dev/urandom" is not allowed in
868842 // "ime" sandbox. Returns false to use the self-implemented random number
12571231 }
12581232 }
12591233
1260 void Util::DecodeURI(const std::string &src, std::string *output) {
1234 void Util::DecodeURI(const std::string &input, std::string *output) {
12611235 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();
12641238 while (p < end) {
12651239 if (*p == '%' && p + 2 < end) {
12661240 const char h = toupper(p[1]);
119119 static void SplitStringToUtf8Chars(absl::string_view str,
120120 std::vector<std::string> *output);
121121
122 static void SplitCSV(const std::string &str,
122 static void SplitCSV(const std::string &input,
123123 std::vector<std::string> *output);
124124
125125 template <typename Range>
152152 absl::string_view newsub, bool replace_all,
153153 std::string *res);
154154
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);
157157
158158 // Transforms the first character to the upper case and tailing characters to
159159 // the lower cases. ex. "abCd" => "Abcd".
160 static void CapitalizeString(std::string *output);
160 static void CapitalizeString(std::string *str);
161161
162162 // Returns true if the characters in [first, last) are all in lower case
163163 // ASCII.
182182 // Strips the leading/trailing white spaces from the input and stores it to
183183 // the output. If the input does not have such white spaces, this method just
184184 // 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);
186186
187187 static size_t OneCharLen(const char *src);
188188
189 // Returns the lengths of [src, src+size] encoded in UTF8.
189190 static size_t CharsLen(const char *src, size_t size);
190191
191192 static size_t CharsLen(absl::string_view str) {
341342 static bool IsKanaSymbolContained(const std::string &input);
342343
343344 // 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);
345346
346347 static void NormalizeVoicedSoundMark(absl::string_view input,
347348 std::string *output);
4747 namespace mozc {
4848 namespace {
4949
50 #ifndef OS_NACL
51 // Disabled on NaCl since it uses a mock file system.
5250 void FillTestCharacterSetMap(std::map<char32, Util::CharacterSet> *test_map) {
5351 CHECK(test_map);
5452 const std::string &path = testing::GetSourceFileOrDie(
8583 test_map->insert(std::make_pair(ucs4, itr->second));
8684 }
8785 }
88 #endif // !OS_NACL
8986
9087 Util::CharacterSet GetExpectedCharacterSet(
9188 const std::map<char32, Util::CharacterSet> &test_map, char32 ucs4) {
14731470 EXPECT_EQ(Util::HALF_WIDTH, Util::GetFormType("@!#"));
14741471 }
14751472
1476 #ifndef OS_NACL
14771473 // We have a snapshot of the result of |Util::GetCharacterSet(ucs4)| in
14781474 // data/test/character_set/character_set.tsv.
14791475 // Compare the result for each character just in case.
1480 //
1481 // Disabled on NaCl since it uses a mock file system.
14821476 TEST(UtilTest, CharacterSetFullTest) {
14831477 std::map<char32, Util::CharacterSet> test_set;
14841478 FillTestCharacterSetMap(&test_set);
14911485 << "Character set changed at " << ucs4;
14921486 }
14931487 }
1494 #endif // OS_NACL
14951488
14961489 TEST(UtilTest, CharacterSet_gen_character_set) {
14971490 // [0x00, 0x7f] are ASCII
2626 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2727 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2828
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
2929 #ifndef MOZC_CHROME_NACL_DICTIONARY_DOWNLOADER_H_
3030 #define MOZC_CHROME_NACL_DICTIONARY_DOWNLOADER_H_
3131
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
8032 #endif // MOZC_CHROME_NACL_DICTIONARY_DOWNLOADER_H_
2828
2929 // TODO(horo): write tests.
3030
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
2626 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2727 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2828
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
2929 #ifndef MOZC_CHROME_NACL_URL_LOADER_UTIL_H_
3030 #define MOZC_CHROME_NACL_URL_LOADER_UTIL_H_
3131
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
6632 #endif // MOZC_CHROME_NACL_URL_LOADER_UTIL_H_
123123 "//base:init_mozc",
124124 "//base:logging",
125125 "//base:process",
126 "@com_google_absl//absl/flags:flag",
126127 ],
127128 )
128129
141142 "//protocol:renderer_proto",
142143 "//renderer:renderer_client",
143144 "//session:random_keyevents_generator",
145 "@com_google_absl//absl/flags:flag",
144146 ],
145147 )
146148
162164 "//protocol:commands_proto",
163165 "//protocol:renderer_proto",
164166 "//renderer:renderer_client",
167 "@com_google_absl//absl/flags:flag",
165168 "@com_google_absl//absl/strings",
166169 ],
167170 )
184187 "//config:config_handler",
185188 "//protocol:commands_proto",
186189 "//session:random_keyevents_generator",
190 "@com_google_absl//absl/flags:flag",
187191 ],
188192 )
189193
232236 "//base:util",
233237 "//evaluation:scorer",
234238 "//protocol:commands_proto",
239 "@com_google_absl//absl/flags:flag",
235240 "@com_google_absl//absl/strings",
236241 ],
237242 )
4545 #include "config/config_handler.h"
4646 #include "protocol/commands.pb.h"
4747 #include "session/random_keyevents_generator.h"
48 #include "absl/flags/flag.h"
4849
4950 DEFINE_string(server_path, "", "specify server path");
5051 DEFINE_string(log_path, "", "specify log output file path");
9899 virtual void Run(Result *result) = 0;
99100
100101 TestScenarioInterface() {
101 if (!FLAGS_server_path.empty()) {
102 if (!mozc::GetFlag(FLAGS_server_path).empty()) {
102103 client_.set_server_program(FLAGS_server_path);
103104 }
104105 CHECK(client_.IsValidRunLevel()) << "IsValidRunLevel failed";
376377 CHECK_EQ(results.size(), tests.size());
377378
378379 std::ostream *ofs = &std::cout;
379 if (!FLAGS_log_path.empty()) {
380 if (!mozc::GetFlag(FLAGS_log_path).empty()) {
380381 ofs = new mozc::OutputFileStream(FLAGS_log_path.c_str());
381382 }
382383
4646 // Test data automatically generated by gen_client_quality_test_data.py
4747 // TestCase test_cases[] is defined.
4848 #include "client/client_quality_test_data.inc"
49 #include "absl/flags/flag.h"
4950
5051 DEFINE_string(server_path, "", "specify server path");
5152 DEFINE_string(log_path, "", "specify log output file path");
201202 mozc::InitMozc(argv[0], &argc, &argv);
202203
203204 mozc::client::Client client;
204 if (!FLAGS_server_path.empty()) {
205 if (!mozc::GetFlag(FLAGS_server_path).empty()) {
205206 client.set_server_program(FLAGS_server_path);
206207 }
207208
220221 if (scores.find(source) == scores.end()) {
221222 scores[source] = std::vector<double>();
222223 }
223 if (scores[source].size() >= FLAGS_max_case_for_source) {
224 if (scores[source].size() >= mozc::GetFlag(FLAGS_max_case_for_source)) {
224225 continue;
225226 }
226227
246247 }
247248
248249 std::ostream* ofs = &std::cout;
249 if (!FLAGS_log_path.empty()) {
250 if (!mozc::GetFlag(FLAGS_log_path).empty()) {
250251 ofs = new mozc::OutputFileStream(FLAGS_log_path.c_str());
251252 }
252253
4949 #include "protocol/commands.pb.h"
5050 #include "protocol/renderer_command.pb.h"
5151 #include "renderer/renderer_client.h"
52 #include "absl/flags/flag.h"
5253 #include "absl/strings/match.h"
5354
5455 DEFINE_string(input, "", "Input file");
9495
9596 int Loop(std::istream *input) {
9697 mozc::client::Client client;
97 if (!FLAGS_server_path.empty()) {
98 if (!mozc::GetFlag(FLAGS_server_path).empty()) {
9899 client.set_server_program(FLAGS_server_path);
99100 }
100101
105106 std::unique_ptr<mozc::renderer::RendererClient> renderer_client;
106107 mozc::commands::RendererCommand renderer_command;
107108
108 if (FLAGS_test_renderer) {
109 if (mozc::GetFlag(FLAGS_test_renderer)) {
109110 #if defined(OS_WIN) || defined(__APPLE__)
110111 #ifdef OS_WIN
111112 renderer_command.mutable_application_info()->set_process_id(
136137 while (ReadKeys(input, &keys, &answer)) {
137138 CHECK(client.NoOperation()) << "Server is not responding";
138139 for (size_t i = 0; i < keys.size(); ++i) {
139 Util::Sleep(FLAGS_key_duration);
140 Util::Sleep(mozc::GetFlag(FLAGS_key_duration));
140141
141 if (FLAGS_test_testsendkey) {
142 if (mozc::GetFlag(FLAGS_test_testsendkey)) {
142143 VLOG(2) << "Sending to Server: " << keys[i].DebugString();
143144 client.TestSendKey(keys[i], &output);
144145 VLOG(2) << "Output of TestSendKey: " << output.DebugString();
172173 int main(int argc, char **argv) {
173174 mozc::InitMozc(argv[0], &argc, &argv);
174175
175 if (!FLAGS_profile_dir.empty()) {
176 if (!mozc::GetFlag(FLAGS_profile_dir).empty()) {
176177 mozc::FileUtil::CreateDirectory(FLAGS_profile_dir);
177178 mozc::SystemUtil::SetUserProfileDirectory(FLAGS_profile_dir);
178179 }
180181 std::unique_ptr<mozc::InputFileStream> input_file;
181182 std::istream *input = nullptr;
182183
183 if (!FLAGS_input.empty()) {
184 if (!mozc::GetFlag(FLAGS_input).empty()) {
184185 // Batch mode loading the input file.
185186 input_file.reset(new mozc::InputFileStream(FLAGS_input.c_str()));
186187 if (input_file->fail()) {
2929 #include <iostream>
3030
3131 #include "client/client.h"
32 #include "absl/flags/flag.h"
3233
3334 #ifdef OS_WIN
3435 #include <windows.h>
6667 mozc::SetFlag(&FLAGS_logtostderr, true);
6768
6869 mozc::client::Client client;
69 if (!FLAGS_server_path.empty()) {
70 if (!mozc::GetFlag(FLAGS_server_path).empty()) {
7071 client.set_server_program(FLAGS_server_path);
7172 }
7273
7778 std::unique_ptr<mozc::renderer::RendererClient> renderer_client;
7879 mozc::commands::RendererCommand renderer_command;
7980
80 if (FLAGS_test_renderer) {
81 if (mozc::GetFlag(FLAGS_test_renderer)) {
8182 #if defined(OS_WIN) || defined(__APPLE__)
8283 #ifdef OS_WIN
8384 renderer_command.mutable_application_info()->set_process_id(
109110 mozc::session::RandomKeyEventsGenerator::GenerateSequence(&keys);
110111 CHECK(client.NoOperation()) << "Server is not responding";
111112 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));
113114 keyevents_size++;
114115 if (keyevents_size % 100 == 0) {
115116 std::cout << keyevents_size << " key events finished" << std::endl;
116117 }
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;
120121 return 0;
121122 }
122 if (FLAGS_test_testsendkey) {
123 if (mozc::GetFlag(FLAGS_test_testsendkey)) {
123124 VLOG(2) << "Sending to Server: " << keys[i].DebugString();
124125 client.TestSendKey(keys[i], &output);
125126 VLOG(2) << "Output of TestSendKey: " << output.DebugString();
3232 #include "base/init_mozc.h"
3333 #include "base/logging.h"
3434 #include "client/client.h"
35 #include "absl/flags/flag.h"
3536
3637 DEFINE_bool(shutdown, false, "shutdown server if mozc_server is running");
3738
4041 mozc::InitMozc(argv[0], &argc, &argv);
4142 mozc::client::Client client;
4243
43 if (FLAGS_shutdown) {
44 if (mozc::GetFlag(FLAGS_shutdown)) {
4445 client.Shutdown();
4546 }
4647
243243 };
244244 #endif // OS_ANDROID
245245
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
263246 #endif // GOOGLE_JAPANESE_INPUT_BUILD
264247
265248 class NullStatsConfigUtilImpl : public StatsConfigUtilInterface {
206206 if (!status.ok()) {
207207 return status;
208208 }
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
214209 return connector;
215 #endif // OS_NACL
216210 }
217211
218212 Connector::Connector() = default;
5050 int cost;
5151 };
5252
53 #ifndef OS_NACL
54 // Disabled on NaCl since it uses a mock file system.
5553 TEST(ConnectorTest, CompareWithRawData) {
5654 const std::string path = testing::GetSourceFileOrDie(
5755 {"data_manager", "testing", "connection.data"});
139137 EXPECT_FALSE(status.ok());
140138 }
141139 }
142 #endif // !OS_NACL
143140
144141 } // namespace
145142 } // namespace mozc
2525 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2626 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2727 // 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.
3128
3229 #include "converter/pos_id_printer.h"
3330
7471
7572 } // namespace internal
7673 } // namespace mozc
77
78 #endif // !OS_NACL
469469 // Let converter know the maximum size of
470470 // candidates converter can generate.
471471 // 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.
473473 // Default setting is 200.
474474 void set_max_conversion_candidates_size(size_t size);
475475 size_t max_conversion_candidates_size() const;
3232 MINOR = 25
3333
3434 # Number to be increased. This value may be replaced by other tools.
35 BUILD = 4180
35 BUILD = 4190
3636
3737 # Represent the platform and release channel.
3838 REVISION = 100
8282 'gen_system_dictionary_data_main.cc',
8383 ],
8484 'dependencies': [
85 '../base/absl.gyp:absl_base',
8586 '../base/absl.gyp:absl_strings',
8687 '../base/base.gyp:base',
8788 '../data_manager/data_manager_base.gyp:data_manager',
176176 "//dictionary/file:codec_interface",
177177 "//storage/louds:bit_vector_based_array_builder",
178178 "//storage/louds:louds_trie_builder",
179 "@com_google_absl//absl/flags:flag",
179180 ],
180181 )
181182
198199 ":system_dictionary",
199200 ":system_dictionary_builder",
200201 "//base:file_util",
202 "//base:flags",
201203 "//base:logging",
202204 "//base:port",
203205 "//base:stl_util",
214216 "//request:conversion_request",
215217 "//testing:gunit_main",
216218 "//testing:mozctest",
219 "@com_google_absl//absl/flags:flag",
217220 "@com_google_absl//absl/strings",
218221 ],
219222 )
474474 return mozc::UnknownError("Failed to create system dictionary");
475475 }
476476
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
482477 return instance;
483 #endif // OS_NACL
484478 }
485479
486480 SystemDictionary::SystemDictionary(
4848 #include "dictionary/text_dictionary_loader.h"
4949 #include "storage/louds/bit_vector_based_array_builder.h"
5050 #include "storage/louds/louds_trie_builder.h"
51 #include "absl/flags/flag.h"
5152
5253 DEFINE_bool(preserve_intermediate_dictionary, false,
5354 "preserve inetemediate dictionary file.");
161162 file_codec_->GetSectionName(codec_->GetSectionNameForPos()));
162163 sections.push_back(frequent_pos_section);
163164
164 if (FLAGS_preserve_intermediate_dictionary &&
165 if (mozc::GetFlag(FLAGS_preserve_intermediate_dictionary) &&
165166 !intermediate_output_file_base_path.empty()) {
166167 // Write out intermediate results to files.
167168 const std::string &basepath = intermediate_output_file_base_path;
363364 for (size_t i = 0; i < key_info->tokens.size(); ++i) {
364365 TokenInfo *token_info = &key_info->tokens[i];
365366 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)) {
367369 token_info->cost_type = TokenInfo::CAN_USE_SMALL_ENCODING;
368370 }
369371 }
3636 #include <utility>
3737 #include <vector>
3838
39 #include "base/flags.h"
3940 #include "base/file_util.h"
4041 #include "base/logging.h"
4142 #include "base/port.h"
7475 dic_fn_(FileUtil::JoinPath(FLAGS_test_tmpdir, "mozc.dic")) {
7576 const std::string dic_path = mozc::testing::GetSourceFileOrDie(
7677 {"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));
7880
7981 convreq_.set_request(&request_);
8082 convreq_.set_config(&config_);
8385 void SetUp() override {
8486 // Don't use small cost encoding by default.
8587 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());
8991
9092 request_.Clear();
9193 config::ConfigHandler::GetDefaultConfig(&config_);
9294 }
9395
9496 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_);
9799
98100 // This config initialization will be removed once ConversionRequest can
99101 // take config as an injected argument.
259261 t0->lid = 50;
260262 t0->rid = 70;
261263 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));
263266
264267 std::unique_ptr<SystemDictionary> system_dic =
265268 SystemDictionary::Builder(dic_fn_).Build().value();
315318 for (size_t i = 0; i < tokens.size(); ++i) {
316319 source_tokens.push_back(&tokens[i]);
317320 }
318 BuildSystemDictionary(source_tokens, FLAGS_dictionary_test_size);
321 BuildSystemDictionary(source_tokens,
322 mozc::GetFlag(FLAGS_dictionary_test_size));
319323
320324 std::unique_ptr<SystemDictionary> system_dic =
321325 SystemDictionary::Builder(dic_fn_).Build().value();
329333
330334 TEST_F(SystemDictionaryTest, LookupAllWords) {
331335 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));
333338
334339 std::unique_ptr<SystemDictionary> system_dic =
335340 SystemDictionary::Builder(dic_fn_).Build().value();
699704 SystemDictionary::Builder(dic_fn_).Build().value();
700705 ASSERT_TRUE(system_dic) << "Failed to open dictionary source:" << dic_fn_;
701706 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)),
703709 source_tokens.size());
704710 for (size_t source_index = 0; source_index < test_size; ++source_index) {
705711 const Token &source_token = *source_tokens[source_index];
757763
758764 TEST_F(SystemDictionaryTest, LookupReverseIndex) {
759765 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));
761768
762769 std::unique_ptr<SystemDictionary> system_dic_without_index =
763770 SystemDictionary::Builder(dic_fn_)
775782 << "Failed to open dictionary source:" << dic_fn_;
776783
777784 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);
779786 for (it = source_tokens.begin(); size > 0 && it != source_tokens.end();
780787 ++it, --size) {
781788 const Token &t = **it;
140140
141141 void UserDictionarySessionHandler::ClearStorage(
142142 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
147143 // Note: session_ might not be created when ClearStorage is called. So create
148144 // a local session to clear the storage.
149145 UserDictionarySession session(dictionary_path_);
150146 session.ClearDictionariesAndUndoHistory();
151147 status->set_status(session.Save());
152 #endif // OS_NACL
153148 }
154149
155150 void UserDictionarySessionHandler::CreateSession(
222222 }
223223
224224 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
231225 // Set up a user dictionary.
232226 {
233227 Clear();
261255 ">\n",
262256 *status_);
263257 }
264 #endif // OS_NACL
265258 }
266259
267260 TEST_F(UserDictionarySessionHandlerTest, CreateDeleteSession) {
338338 while (id == kInvalidDictionaryId) {
339339 Util::GetRandomSequence(reinterpret_cast<char *>(&id), sizeof(id));
340340
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
347341 // Duplication check.
348342 for (int i = 0; i < storage.dictionaries_size(); ++i) {
349343 if (storage.dictionaries(i).id() == id) {
143143 if (!status.ok()) {
144144 return status;
145145 }
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
151146 return engine;
152 #endif // OS_NACL
153147 }
154148
155149 mozc::StatusOr<std::unique_ptr<Engine>> Engine::CreateMobileEngine(
160154 if (!status.ok()) {
161155 return status;
162156 }
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
167157 return engine;
168 #endif // OS_NACL
169158 }
170159
171160 Engine::Engine() = default;
6262 const testing::ScopedTmpUserProfileDirectory scoped_profile_dir_;
6363 };
6464
65 // Most of tests are disabled on NaCl as it uses mock file system for tests.
66 #ifndef OS_NACL
67
6865 TEST_F(EngineBuilderTest, PrepareAsync) {
6966 {
7067 // Test request without install.
211208 ASSERT_EQ(EngineReloadResponse::DATA_BROKEN, response_.status());
212209 }
213210
214 #endif // !OS_NACL
215
216211 TEST_F(EngineBuilderTest, FailureCase_FileDoesNotExist) {
217212 // Test the case where input file doesn't exist.
218213 request_.set_engine_type(EngineReloadRequest::MOBILE);
5757 #include "gui/base/util.h"
5858 #include "gui/config_dialog/keymap_editor.h"
5959 #include "gui/config_dialog/roman_table_editor.h"
60 #include "protocol/commands.pb.h"
6160 #include "protocol/config.pb.h"
6261 #include "session/internal/keymap.h"
6362
3030
3131 #include "net/http_client_null.h"
3232
33 #ifdef OS_NACL
34 #include <ppapi/cpp/instance.h>
35 #endif // OS_NACL
36
3733 #include "base/logging.h"
3834
3935 namespace mozc {
5349 return false;
5450 }
5551
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
6552 } // namespace mozc
6653
6754 #endif // !GOOGLE_JAPANESE_INPUT_BUILD
3636 #include "net/http_client.h"
3737 #include "net/http_client_common.h"
3838
39 #ifdef OS_NACL
40 namespace pp {
41 class Instance;
42 } // namespace pp
43 #endif // OS_NACL
44
4539 namespace mozc {
4640 class NullHTTPRequestHandler {
4741 public:
5347 DISALLOW_IMPLICIT_CONSTRUCTORS(NullHTTPRequestHandler);
5448 };
5549
56 #ifdef OS_NACL
57 void RegisterPepperInstanceForHTTPClient(pp::Instance *instance);
58 pp::Instance *GetPepperInstanceForHTTPClient();
59 #endif // OS_NACL
60
6150 } // namespace mozc
6251
6352 #endif // !GOOGLE_JAPANESE_INPUT_BUILD
181181 '(_toolset=="host" and (compiler_host=="clang" or compiler_host=="gcc"))', {
182182 'cflags': [
183183 '-Wno-tautological-constant-out-of-range-compare',
184 '-Wno-unused-const-variable',
184185 '-Wno-unused-function',
185186 ],
186187 }],
924924 required CommandType type = 1;
925925
926926 // Session ID created by CREATE_SESSION.
927 optional uint64 id = 2;
927 optional uint64 id = 2 [jstype = JS_STRING];
928928
929929 // Key combinations used for SEND_KEY or TEST_SEND_KEY.
930930 optional KeyEvent key = 3;
10991099 }
11001100
11011101 message Output {
1102 optional uint64 id = 1;
1102 optional uint64 id = 1 [jstype = JS_STRING];
11031103
11041104 // This variable is going to be obsolete.
11051105 optional CompositionMode mode = 2;
4747 optional string last_modified_product_version = 2 [default = "0.0.0.0"];
4848
4949 // 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];
5151
5252 // These fields are not used now
5353 // platform of machine that wrote this config
3131 package mozc.converter;
3232
3333 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];
3636 }
3636
3737 message SessionState {
3838 // session id
39 required uint64 id = 1;
39 required uint64 id = 1 [jstype = JS_STRING];
4040 // session created time
41 optional uint64 created_time = 2;
41 optional uint64 created_time = 2 [jstype = JS_STRING];
4242
4343 // whether session is just after commitment
4444 optional bool committed = 3 [default = false];
4747
4848 reserved 5; // Deprecated mode
4949
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];
5555
5656 // last preedit state
5757 optional mozc.commands.Preedit preedit = 20;
8787 }
8888
8989 // ID of this dictionary
90 optional uint64 id = 1 [default = 0];
90 optional uint64 id = 1 [default = 0, jstype = JS_STRING];
9191
9292 // set false if this dictionary is not used.
9393 // Even if |enabled| is false, the dictionary
253253 }
254254
255255 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];
258258 optional string dictionary_name = 4;
259259 repeated int32 entry_index = 5;
260260 optional UserDictionary.Entry entry = 6;
316316 }
317317
318318 required Status status = 1;
319 optional uint64 session_id = 2;
319 optional uint64 session_id = 2 [jstype = JS_STRING];
320320 optional UserDictionaryStorage storage = 3;
321321 // Use entries field instead.
322322 reserved 4; // Deprecated entry
323 optional uint64 dictionary_id = 5;
323 optional uint64 dictionary_id = 5 [jstype = JS_STRING];
324324 optional uint32 entry_size = 6;
325325 repeated UserDictionary.Entry entries = 7;
326326 }
243243 "//request:conversion_request",
244244 "//testing:gunit_prod",
245245 "@com_google_absl//absl/strings",
246 "@com_google_absl//absl/time",
246247 ],
247248 alwayslink = 1,
248249 )
238238 return true;
239239 }
240240
241 CalculatorInterface *g_calculator = NULL;
241 CalculatorInterface *g_calculator = nullptr;
242242 } // namespace
243243
244244 CalculatorInterface *CalculatorFactory::GetCalculator() {
245 if (g_calculator == NULL) {
245 if (g_calculator == nullptr) {
246246 return Singleton<CalculatorImpl>::get();
247247 } else {
248248 return g_calculator;
323323
324324 #ifndef NDEBUG
325325 #include <stdio.h>
326 static FILE *yyTraceFILE = 0;
327 static char *yyTracePrompt = 0;
326 static FILE *yyTraceFILE = nullptr;
327 static char *yyTracePrompt = nullptr;
328328 #endif /* NDEBUG */
329329
330330 #ifndef NDEBUG
507507 void (*freeProc)(void*) /* Function used to reclaim memory */
508508 ){
509509 yyParser *pParser = (yyParser*)p;
510 if( pParser==0 ) return;
510 if (pParser == nullptr) return;
511511 while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
512512 #if YYSTACKDEPTH<=0
513513 free(pParser->yystack);
142142 for (int n = 0; n < 2; ++n) {
143143 int current_offset = offset + n;
144144 Segment::Candidate *candidate = segment->insert_candidate(current_offset);
145 if (candidate == NULL) {
145 if (candidate == nullptr) {
146146 LOG(ERROR) << "cannot insert candidate at " << current_offset;
147147 return false;
148148 }
124124
125125 virtual void TearDown() {
126126 // Clear the mock test calculator
127 CalculatorFactory::SetCalculator(NULL);
127 CalculatorFactory::SetCalculator(nullptr);
128128 }
129129
130130 ConversionRequest convreq_;
151151 {kPat7, arraysize(kPat7) - 1},
152152 {kPat8, arraysize(kPat8) - 1},
153153 {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) {
157157 const absl::string_view particle(kParticles[i].pat, kParticles[i].len);
158158 absl::string_view first_content, second;
159159 if (!ParseCompound(top_value, particle, &first_content, &second)) {
550550 : pos_matcher_(data_manager->GetPOSMatcherData()),
551551 first_name_id_(pos_matcher_.GetFirstNameId()),
552552 last_name_id_(pos_matcher_.GetLastNameId()) {
553 const char *data = NULL;
553 const char *data = nullptr;
554554 size_t size = 0;
555555
556556 data_manager->GetCollocationData(&data, &size);
175175
176176 bool CommandRewriter::Rewrite(const ConversionRequest &request,
177177 Segments *segments) const {
178 if (segments == NULL || segments->conversion_segments_size() != 1) {
178 if (segments == nullptr || segments->conversion_segments_size() != 1) {
179179 return false;
180180 }
181181
3838
3939 #include <algorithm>
4040 #include <cstdio>
41 #include <ctime>
4241 #include <string>
4342 #include <vector>
4443
5554 #include "request/conversion_request.h"
5655 #include "absl/strings/str_cat.h"
5756 #include "absl/strings/string_view.h"
57 #include "absl/time/time.h"
5858
5959 namespace mozc {
6060 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,
6768 };
6869
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[] = "時刻";
138130
139131 struct YearData {
140132 int ad; // AD year
144136
145137 const YearData kEraData[] = {
146138 // "元徳", "建武" 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, "令和", "れいわ"}};
1312371
1313372 const YearData kNorthEraData[] = {
1314373 // "元徳", "建武" 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, "明徳", "めいとく"}};
1417393
1418394 bool PrintUint32(const char *format, uint32 num, char *buf, size_t buf_size) {
1419395 const int ret = std::snprintf(buf, buf_size, format, num);
1524500 c->description = description;
1525501 }
1526502 }
1527
1528 enum {
1529 REWRITE_YEAR,
1530 REWRITE_DATE,
1531 REWRITE_MONTH,
1532 REWRITE_CURRENT_TIME,
1533 REWRITE_DATE_AND_CURRENT_TIME
1534 };
1535503
1536504 bool AdToEraForCourt(const YearData *data, int size, int year,
1537505 std::vector<std::string> *results) {
1770738 // The order is south to north.
1771739 std::vector<std::string> eras;
1772740 bool r = false;
1773 r = AdToEraForCourt(kEraData, arraysize(kEraData), year, &eras);
741 r = AdToEraForCourt(kEraData, std::size(kEraData), year, &eras);
1774742 if (year > 1331 && year < 1393) {
1775 r |= AdToEraForCourt(kNorthEraData, arraysize(kNorthEraData), year, &eras);
743 r |= AdToEraForCourt(kNorthEraData, std::size(kNorthEraData), year, &eras);
1776744 }
1777745 // 1334 requires dedupe
1778746 for (int i = 0; i < eras.size(); ++i) {
1794762 std::vector<std::string> *descriptions) {
1795763 bool ret = false;
1796764 // 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,
1798766 descriptions);
1799 ret |= EraToAdForCourt(kNorthEraData, arraysize(kNorthEraData), key, results,
767 ret |= EraToAdForCourt(kNorthEraData, std::size(kNorthEraData), key, results,
1800768 descriptions);
1801769 return ret;
1802770 }
1841809 return true;
1842810 }
1843811
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));
1875873 }
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;
1892874 }
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, &times);
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
1957899
1958900 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;
2043939 }
2044940
2045941 bool DateRewriter::RewriteEra(Segment *current_segment,
2085981 kInsertPosition, static_cast<int>(current_segment->candidates_size()));
2086982
2087983 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,
2090986 current_segment);
2091987 current_segment->mutable_candidate(position)->attributes &=
2092988 ~Segment::Candidate::NO_VARIANTS_EXPANSION;
24031299 return false;
24041300 }
24051301
2406 if (RewriteDate(seg) || RewriteWeekday(seg) || RewriteMonth(seg) ||
2407 RewriteYear(seg) || RewriteCurrentTime(seg) ||
2408 RewriteDateAndCurrentTime(seg)) {
1302 if (RewriteDate(seg)) {
24091303 modified = true;
24101304 } else if (i + 1 < segments->segments_size() &&
24111305 RewriteEra(seg, segments->segment(i + 1))) {
6262 bool Rewrite(const ConversionRequest &request,
6363 Segments *segments) const override;
6464
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 };
10672
10773 // In general, Japanese era can be identified without the month.
10874 // However, during the era migration time, we have to check the month., i.e.,
161127 // 2000: 2 : 29 -> "平成12年2月29日,2000年2月29日,2000-02-29,2000/02/29"
162128 static bool ConvertDateWithYear(uint32 year, uint32 month, uint32 day,
163129 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);
164158 };
165159
166160 } // namespace mozc
5959 size_t offset = std::min(insert_pos, segment->candidates_size());
6060
6161 Segment::Candidate *c = segment->insert_candidate(offset);
62 if (c == NULL) {
62 if (c == nullptr) {
6363 LOG(ERROR) << "cannot insert candidate at " << offset;
6464 return false;
6565 }
8989 DictionaryGenerator::~DictionaryGenerator() {}
9090
9191 void DictionaryGenerator::AddToken(const Token &token) {
92 Token *new_token = NULL;
92 Token *new_token = nullptr;
9393 std::map<uint64, Token *>::const_iterator it =
9494 token_map_->find(token.GetID());
9595 if (it != token_map_->end()) {
6969 absl::string_view description, int cost, Segment *segment,
7070 size_t *insert_position) {
7171 Segment::Candidate *candidate = segment->insert_candidate(*insert_position);
72 if (candidate == NULL) {
72 if (candidate == nullptr) {
7373 LOG(ERROR) << "cannot insert candidate at " << insert_position
7474 << "th position nor tail of candidates.";
7575 return false;
198198 return false;
199199 }
200200
201 CHECK(segments != NULL);
201 CHECK(segments != nullptr);
202202 return RewriteCandidates(segments);
203203 }
204204
140140
141141 bool FocusCandidateRewriter::Focus(Segments *segments, size_t segment_index,
142142 int candidate_index) const {
143 if (segments == NULL) {
143 if (segments == nullptr) {
144144 LOG(ERROR) << "Segments is NULL";
145145 return false;
146146 }
177177 int num_nest = 1;
178178 for (size_t i = segment_index + 1; i < segments->segments_size(); ++i) {
179179 Segment *target_right_seg = segments->mutable_segment(i);
180 if (target_right_seg == NULL ||
180 if (target_right_seg == nullptr ||
181181 target_right_seg->candidates_size() <= 0) {
182182 LOG(WARNING) << "target right seg is not valid";
183183 return false;
213213 int num_nest = 1;
214214 for (int i = segment_index - 1; i >= 0; --i) {
215215 Segment *target_left_seg = segments->mutable_segment(i);
216 if (target_left_seg == NULL ||
216 if (target_left_seg == nullptr ||
217217 target_left_seg->candidates_size() <= 0) {
218218 LOG(WARNING) << "target left seg is not valid";
219219 return false;
244244 int distance = 0;
245245 for (size_t i = segment_index + 1; i < segments->segments_size(); ++i) {
246246 Segment *target_right_seg = segments->mutable_segment(i);
247 if (target_right_seg == NULL ||
247 if (target_right_seg == nullptr ||
248248 target_right_seg->candidates_size() <= 0) {
249249 LOG(WARNING) << "target right seg is not valid";
250250 return false;
6565
6666 class FortuneData {
6767 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) {
7269 ChangeFortune();
7370 }
7471
7572 void ChangeFortune() {
7673 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;
9695 }
9796 uint32 random = 0;
9897 Util::GetRandomSequence(reinterpret_cast<char *>(&random), sizeof(random));
9998 const int level = random % kMaxLevel;
100 for (int i = 0; i < arraysize(kNormalLevels); ++i) {
99 for (int i = 0; i < std::size(kNormalLevels); ++i) {
101100 if (level <= levels[i]) {
102101 fortune_type_ = static_cast<FortuneType>(i);
103102 break;
110109
111110 private:
112111 FortuneType fortune_type_;
113 int last_update_yday_;
114 int last_update_year_;
112 absl::CivilDay last_updated_day_;
115113 };
116114
117115 // Insert Fortune message into the |segment|
128126 size_t offset = std::min(insert_pos, segment->candidates_size());
129127
130128 Segment::Candidate *c = segment->insert_candidate(offset);
131 if (c == NULL) {
129 if (c == nullptr) {
132130 LOG(ERROR) << "cannot insert candidate at " << offset;
133131 return false;
134132 }
6969 void OutputExistenceHeader(const std::vector<std::string> &entries,
7070 const std::string &data_namespace, std::ostream *ofs,
7171 double error_rate) {
72 char *existence_data = NULL;
72 char *existence_data = nullptr;
7373 size_t existence_data_size = 0;
7474 GenExistenceData(entries, error_rate, &existence_data, &existence_data_size);
7575
8888
8989 void OutputExistenceBinary(const std::vector<std::string> &entries,
9090 std::ostream *ofs, double error_rate) {
91 char *existence_data = NULL;
91 char *existence_data = nullptr;
9292 size_t existence_data_size = 0;
9393 GenExistenceData(entries, error_rate, &existence_data, &existence_data_size);
9494 ofs->write(existence_data, existence_data_size);
8888 std::vector<std::string> fields;
8989 Util::SplitStringUsing(line, "\t ", &fields);
9090 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);
9292 std::string utf8;
9393 Util::UCS4ToUTF8(ucs4, &utf8);
9494 if (sorting_map->find(utf8) != sorting_map->end()) {
4949 // return true if rewriter can be called with the segments.
5050 bool CheckCapablity(const ConversionRequest &request, Segments *segments,
5151 RewriterInterface *rewriter) const {
52 if (segments == NULL) {
52 if (segments == nullptr) {
5353 return false;
5454 }
5555 switch (segments->request_type()) {
263263 merger.AddRewriter(new TestRewriter(&call_result, "a", false));
264264 merger.AddRewriter(new TestRewriter(&call_result, "b", false));
265265 merger.AddRewriter(new TestRewriter(&call_result, "c", false));
266 EXPECT_FALSE(merger.Focus(NULL, 0, 0));
266 EXPECT_FALSE(merger.Focus(nullptr, 0, 0));
267267 EXPECT_EQ(
268268 "a.Focus();"
269269 "b.Focus();"
271271 call_result);
272272 merger.AddRewriter(new TestRewriter(&call_result, "d", true));
273273 call_result.clear();
274 EXPECT_TRUE(merger.Focus(NULL, 0, 0));
274 EXPECT_TRUE(merger.Focus(nullptr, 0, 0));
275275 EXPECT_EQ(
276276 "a.Focus();"
277277 "b.Focus();"
287287 merger.AddRewriter(new TestRewriter(&call_result, "a", false));
288288 merger.AddRewriter(new TestRewriter(&call_result, "b", false));
289289 merger.AddRewriter(new TestRewriter(&call_result, "c", false));
290 merger.Finish(request, NULL);
290 merger.Finish(request, nullptr);
291291 EXPECT_EQ(
292292 "a.Finish();"
293293 "b.Finish();"
7676 ],
7777 'dependencies': [
7878 '../base/absl.gyp:absl_strings',
79 '../base/absl.gyp:absl_time',
7980 '../base/base.gyp:base',
8081 '../base/base.gyp:config_file_stream',
8182 '../base/base.gyp:serialized_string_array',
117117 void ModifyT13nsForGodan(const std::string &key,
118118 std::vector<std::string> *t13ns) {
119119 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,
132136 };
133137
134138 const std::string &src = (*t13ns)[transliteration::HALF_ASCII];
137141 using IsNonnegativeAndLessThanType = IsNonnegativeAndLessThan<
138142 std::is_unsigned<std::string::value_type>::type>;
139143 if (IsNonnegativeAndLessThanType()(*c, arraysize(kKeycodeToT13nMap)) &&
140 kKeycodeToT13nMap[*c] != NULL) {
144 kKeycodeToT13nMap[*c] != nullptr) {
141145 dst.append(kKeycodeToT13nMap[*c]);
142146 } else {
143147 dst.append(1, *c);
232232 TEST_F(UnicodeRewriterTest, RewriteToUnicodeCharFormat) {
233233 UnicodeRewriter rewriter(engine_->GetConverter());
234234 { // Typical case
235 composer::Composer composer(NULL, &default_request(), &default_config());
235 composer::Composer composer(nullptr, &default_request(), &default_config());
236236 composer.set_source_text("A");
237237 ConversionRequest request(&composer, &default_request(), &default_config());
238238
244244 }
245245
246246 { // 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());
248248 ConversionRequest request(&composer, &default_request(), &default_config());
249249
250250 Segments segments;
256256
257257 { // If source_text is not a single character, this rewrite is not
258258 // triggered.
259 composer::Composer composer(NULL, &default_request(), &default_config());
259 composer::Composer composer(nullptr, &default_request(), &default_config());
260260 composer.set_source_text("AB");
261261 ConversionRequest request(&composer, &default_request(), &default_config());
262262
267267 }
268268
269269 { // Multibyte character is also supported.
270 composer::Composer composer(NULL, &default_request(), &default_config());
270 composer::Composer composer(nullptr, &default_request(), &default_config());
271271 composer.set_source_text("愛");
272272 ConversionRequest request(&composer, &default_request(), &default_config());
273273
207207 ++usage_id_for_user_comment;
208208
209209 // First, search the user dictionary for comment.
210 if (dictionary_ != NULL) {
210 if (dictionary_ != nullptr) {
211211 if (dictionary_->LookupComment(segment->candidate(j).content_key,
212212 segment->candidate(j).content_value,
213213 request, &comment)) {
134134 return;
135135 }
136136
137 if (storage_.get() == NULL) {
137 if (storage_.get() == nullptr) {
138138 VLOG(2) << "storage is NULL";
139139 return;
140140 }
174174 return false;
175175 }
176176
177 if (storage_.get() == NULL) {
177 if (storage_.get() == nullptr) {
178178 VLOG(2) << "storage is NULL";
179179 return false;
180180 }
272272 if (type == RESIZE) {
273273 const LengthArray *value =
274274 reinterpret_cast<const LengthArray *>(storage_->Lookup(key));
275 if (value != NULL) {
275 if (value != nullptr) {
276276 LengthArray orig_value;
277277 orig_value.CopyFromUCharArray(length_array);
278278 if (!value->Equal(orig_value)) {
324324 }
325325
326326 void UserBoundaryHistoryRewriter::Clear() {
327 if (storage_.get() != NULL) {
327 if (storage_.get() != nullptr) {
328328 VLOG(1) << "Clearing user segment data";
329329 storage_->Clear();
330330 }
4646 void AddCandidate(const std::string &value, bool is_user_dictionary,
4747 Segments *segments) {
4848 segments->set_request_type(Segments::CONVERSION);
49 Segment *seg = NULL;
49 Segment *seg = nullptr;
5050 if (segments->segments_size() == 0) {
5151 seg = segments->push_back_segment();
5252 seg->set_key("test");
461461 NormalizeCandidate(segment, old_position, &normalized_value);
462462
463463 if (normalized_value != candidate->value) {
464 const Segment::Candidate *normalized_cand = NULL;
464 const Segment::Candidate *normalized_cand = nullptr;
465465 for (size_t l = 0; l < segment->candidates_size(); ++l) {
466466 if (segment->candidate(l).value == normalized_value) {
467467 normalized_cand = &segment->candidate(l);
469469 }
470470 }
471471
472 if (normalized_cand != NULL) {
472 if (normalized_cand != nullptr) {
473473 if (seen.find(normalized_value) == seen.end()) {
474474 const int pos = segment->indexOf(normalized_cand);
475475 DCHECK(pos != segment->candidates_size());
758758 return false;
759759 }
760760
761 if (storage_.get() == NULL) {
761 if (storage_.get() == nullptr) {
762762 VLOG(2) << "storage is NULL";
763763 return false;
764764 }
849849 const KeyTriggerValue *v1 = reinterpret_cast<const KeyTriggerValue *>(
850850 storage_->Lookup(segment.key()));
851851
852 const KeyTriggerValue *v2 = NULL;
852 const KeyTriggerValue *v2 = nullptr;
853853 if (segment.key() != segment.candidate(0).content_key) {
854854 v2 = reinterpret_cast<const KeyTriggerValue *>(
855855 storage_->Lookup(segment.candidate(0).content_key));
856856 }
857857
858858 const size_t v1_size =
859 (v1 == NULL || !v1->IsValid()) ? 0 : v1->candidates_size();
859 (v1 == nullptr || !v1->IsValid()) ? 0 : v1->candidates_size();
860860 const size_t v2_size =
861 (v2 == NULL || !v2->IsValid()) ? 0 : v2->candidates_size();
861 (v2 == nullptr || !v2->IsValid()) ? 0 : v2->candidates_size();
862862
863863 *max_candidates_size = std::max(v1_size, v2_size);
864864
908908 GetFeatureN(segment->candidate(j).style, &feature_key);
909909 const FeatureValue *v = reinterpret_cast<const FeatureValue *>(
910910 storage_->Lookup(feature_key, &last_access_time));
911 if (v != NULL && v->IsValid()) {
911 if (v != nullptr && v->IsValid()) {
912912 score = 10;
913913 // Workaround for separated arabic.
914914 // Because separated arabic and normal number is learned at the
10161016 }
10171017
10181018 void UserSegmentHistoryRewriter::Clear() {
1019 if (storage_.get() != NULL) {
1019 if (storage_.get() != nullptr) {
10201020 VLOG(1) << "Clearing user segment data";
10211021 storage_->Clear();
10221022 }
123123 }
124124 CharacterFormManager::GetCharacterFormManager()->ReloadConfig(config_);
125125
126 Clock::SetClockForUnitTest(NULL);
126 Clock::SetClockForUnitTest(nullptr);
127127
128128 pos_matcher_.Set(mock_data_manager_.GetPOSMatcherData());
129129 pos_group_.reset(new PosGroup(mock_data_manager_.GetPosGroupData()));
130 ASSERT_TRUE(pos_group_.get() != NULL);
130 ASSERT_TRUE(pos_group_.get() != nullptr);
131131 }
132132
133133 void TearDown() override {
134 Clock::SetClockForUnitTest(NULL);
134 Clock::SetClockForUnitTest(nullptr);
135135
136136 std::unique_ptr<UserSegmentHistoryRewriter> rewriter(
137137 CreateUserSegmentHistoryRewriter());
7777
7878 const size_t offset = std::min(insert_pos, segment->candidates_size());
7979 Segment::Candidate *candidate = segment->insert_candidate(offset);
80 if (candidate == NULL) {
80 if (candidate == nullptr) {
8181 LOG(ERROR) << "cannot insert candidate at " << offset;
8282 return false;
8383 }
5959 "//config:stats_config_util",
6060 "//session",
6161 "//session:session_server",
62 "@com_google_absl//absl/flags:flag",
6263 ],
6364 )
6465
7778 "//session:random_keyevents_generator",
7879 "//session:session_handler",
7980 "//session:session_usage_observer",
81 "@com_google_absl//absl/flags:flag",
8082 ],
8183 )
2626 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2727 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2828
29 #include "absl/flags/flag.h"
2930 #ifdef OS_WIN
3031 #include <windows.h>
3132 #include <ws2tcpip.h>
142143 #endif
143144
144145 ::memset(&sin, 0, sizeof(sin));
145 sin.sin_port = htons(FLAGS_port);
146 sin.sin_port = htons(mozc::GetFlag(FLAGS_port));
146147 sin.sin_family = AF_INET;
147148 sin.sin_addr.s_addr = htonl(INADDR_ANY);
148149
180181 uint32 request_size = 0;
181182 // Receive the size of data.
182183 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))) {
184185 LOG(ERROR) << "Cannot receive request_size header.";
185186 CloseSocket(client_socket);
186187 continue;
192193 // Receive the body of serialized protobuf.
193194 std::unique_ptr<char[]> request_str(new char[request_size]);
194195 if (!Recv(client_socket, request_str.get(), request_size,
195 FLAGS_rpc_timeout)) {
196 mozc::GetFlag(FLAGS_rpc_timeout))) {
196197 LOG(ERROR) << "cannot receive body of request.";
197198 CloseSocket(client_socket);
198199 continue;
218219 output_size = htonl(output_size);
219220
220221 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)) ||
222223 !Send(client_socket, output_str.data(), output_str.size(),
223 FLAGS_rpc_timeout)) {
224 mozc::GetFlag(FLAGS_rpc_timeout))) {
224225 LOG(ERROR) << "Cannot send reply.";
225226 }
226227
282283 hints.ai_socktype = SOCK_STREAM;
283284 hints.ai_family = AF_INET;
284285
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),
287289 0)
288290 << "getaddrinfo failed";
289291
301303 request_size = htonl(request_size);
302304
303305 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)));
305307 CHECK(Send(client_socket, request_str.data(), request_str.size(),
306 FLAGS_rpc_timeout));
308 mozc::GetFlag(FLAGS_rpc_timeout)));
307309
308310 uint32 output_size = 0;
309311 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)));
311313 output_size = ntohl(output_size);
312314 CHECK_GT(output_size, 0);
313315 CHECK_LT(output_size, kMaxOutputSize);
314316
315317 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)));
318320
319321 CHECK(output->ParseFromArray(output_str.get(), output_size));
320322
352354
353355 mozc::ScopedWSAData wsadata;
354356
355 if (!FLAGS_user_profile_directory.empty()) {
357 if (!mozc::GetFlag(FLAGS_user_profile_directory).empty()) {
356358 LOG(INFO) << "Setting user profile directory to "
357359 << FLAGS_user_profile_directory;
358360 mozc::SystemUtil::SetUserProfileDirectory(FLAGS_user_profile_directory);
359361 }
360362
361 if (FLAGS_client) {
363 if (mozc::GetFlag(FLAGS_client)) {
362364 mozc::RPCClient client;
363365 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) {
365367 std::vector<mozc::commands::KeyEvent> keys;
366368 mozc::session::RandomKeyEventsGenerator::GenerateSequence(&keys);
367369 for (size_t i = 0; i < keys.size(); ++i) {
373375 }
374376 CHECK(client.DeleteSession());
375377 return 0;
376 } else if (FLAGS_server) {
378 } else if (mozc::GetFlag(FLAGS_server)) {
377379 mozc::RPCServer server;
378380 server.Loop();
379381 } else {
2727 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2828
2929 #include "server/mozc_server.h"
30
31 #include "absl/flags/flag.h"
3032
3133 #ifdef OS_WIN
3234 #include <windows.h>
8991
9092 if (run_level == mozc::RunLevel::RESTRICTED) {
9193 VLOG(1) << "Mozc server starts with timeout mode";
92 FLAGS_restricted = true;
94 mozc::SetFlag(&FLAGS_restricted, true);
9395 }
9496 }
9597
4444
4545 mozc::Mutex g_storage_ensure_mutex;
4646
47 mozc::GenericStorageManagerInterface *g_storage_manager = NULL;
47 mozc::GenericStorageManagerInterface *g_storage_manager = nullptr;
4848
4949 const char kSymbolStorageFileName[] = "user://symbol_history.db";
5050 // 32 characters * 3 bytes(typical byte size per character)
105105 default:
106106 LOG(WARNING) << "Invalid storage type";
107107 }
108 return NULL;
108 return nullptr;
109109 }
110110
111111 bool GenericStorageManagerImpl::SyncAll() {
180180
181181 const char *GenericLruStorage::Lookup(const std::string &key) {
182182 if (!EnsureStorage()) {
183 return NULL;
183 return nullptr;
184184 }
185185 return lru_storage_->Lookup(key);
186186 }
7676 }
7777
7878 // First inserted entry is already pushed out.
79 EXPECT_EQ(NULL, storage.Lookup("0"));
79 EXPECT_EQ(nullptr, storage.Lookup("0"));
8080 for (size_t i = 1; i < kSize + 1; ++i) {
8181 const std::string value = Util::StringPrintf(kPrintFormat, i);
8282 const std::string key = std::string("key") + value;
4646 Candidate::Candidate()
4747 : id_(0),
4848 attributes_(NO_ATTRIBUTES),
49 subcandidate_list_(NULL),
49 subcandidate_list_(nullptr),
5050 subcandidate_list_owner_(false) {}
5151
5252 Candidate::~Candidate() {}
5454 void Candidate::Clear() {
5555 id_ = 0;
5656 attributes_ = NO_ATTRIBUTES;
57 if (subcandidate_list_owner_ && subcandidate_list_ != NULL) {
57 if (subcandidate_list_owner_ && subcandidate_list_ != nullptr) {
5858 delete subcandidate_list_;
5959 }
60 subcandidate_list_ = NULL;
60 subcandidate_list_ = nullptr;
6161 subcandidate_list_owner_ = false;
6262 }
6363
8080 }
8181
8282 bool Candidate::IsSubcandidateList() const {
83 return (subcandidate_list_ != NULL);
83 return (subcandidate_list_ != nullptr);
8484 }
8585
8686 const CandidateList &Candidate::subcandidate_list() const {
5959 // Don't access composer().
6060 // Before using composer, set_composer() must be called with non-null-value.
6161
62 EXPECT_TRUE(NULL == context.mutable_converter());
62 EXPECT_TRUE(nullptr == context.mutable_converter());
6363
6464 EXPECT_EQ(ImeContext::NONE, context.state());
6565
8080
8181 // The ownership of composer is moved to context.
8282 composer::Composer *composer =
83 new composer::Composer(NULL, &request, &config);
83 new composer::Composer(nullptr, &request, &config);
8484 context.set_composer(composer);
8585 EXPECT_EQ(composer, &context.composer());
8686 EXPECT_EQ(composer, context.mutable_composer());
227227 // Set composer
228228 const commands::Request request;
229229 composer::Composer *composer =
230 new composer::Composer(NULL, &request, &config);
230 new composer::Composer(nullptr, &request, &config);
231231 context.set_composer(composer);
232232
233233 // Set converter
9696 }
9797
9898 bool KeyEventTransformer::TransformKeyEvent(KeyEvent *key_event) const {
99 if (key_event == NULL) {
99 if (key_event == nullptr) {
100100 LOG(ERROR) << "key_event is NULL";
101101 return false;
102102 }
8787 Reset();
8888
8989 const char *keymap_file = GetKeyMapFileName(keymap);
90 if (keymap != config::Config::CUSTOM && keymap_file != NULL &&
90 if (keymap != config::Config::CUSTOM && keymap_file != nullptr &&
9191 LoadFile(keymap_file)) {
9292 return true;
9393 }
166166
167167 bool KeyMapManager::LoadFile(const char *filename) {
168168 std::unique_ptr<std::istream> ifs(ConfigFileStream::LegacyOpen(filename));
169 if (ifs.get() == NULL) {
169 if (ifs.get() == nullptr) {
170170 LOG(WARNING) << "cannot load keymap table: " << filename;
171171 return false;
172172 }
9292 std::vector<KeyInformation> ExtractSortedDirectModeKeysFromFile(
9393 const std::string &filename) {
9494 std::unique_ptr<std::istream> ifs(ConfigFileStream::LegacyOpen(filename));
95 if (ifs.get() == NULL) {
95 if (ifs.get() == nullptr) {
9696 DLOG(FATAL) << "could not open file: " << filename;
9797 return std::vector<KeyInformation>();
9898 }
3737 bool OutputUtil::GetCandidateIndexById(const commands::Output &output,
3838 int32 mozc_candidate_id,
3939 int32 *candidate_index) {
40 if (candidate_index == NULL) {
40 if (candidate_index == nullptr) {
4141 return false;
4242 }
4343 if (!output.has_all_candidate_words()) {
5151 continue;
5252 }
5353 if (word.id() == mozc_candidate_id) {
54 DCHECK(NULL != candidate_index);
54 DCHECK(nullptr != candidate_index);
5555 *candidate_index = word.index();
5656 return true;
5757 }
6262 bool OutputUtil::GetCandidateIdByIndex(const commands::Output &output,
6363 int32 candidate_index,
6464 int32 *mozc_candidate_id) {
65 if (mozc_candidate_id == NULL) {
65 if (mozc_candidate_id == nullptr) {
6666 return false;
6767 }
6868 if (!output.has_all_candidate_words()) {
7676 continue;
7777 }
7878 if (word.index() == candidate_index) {
79 DCHECK(NULL != mozc_candidate_id);
79 DCHECK(nullptr != mozc_candidate_id);
8080 *mozc_candidate_id = word.id();
8181 return true;
8282 }
8686
8787 bool OutputUtil::GetFocusedCandidateId(const commands::Output &output,
8888 int32 *mozc_candidate_id) {
89 if (mozc_candidate_id == NULL) {
89 if (mozc_candidate_id == nullptr) {
9090 return false;
9191 }
9292 if (!output.has_all_candidate_words()) {
104104 continue;
105105 }
106106 if (word.index() == focused_index) {
107 DCHECK(NULL != mozc_candidate_id);
107 DCHECK(nullptr != mozc_candidate_id);
108108 *mozc_candidate_id = word.id();
109109 return true;
110110 }
211211 void Session::InitContext(ImeContext *context) const {
212212 context->set_create_time(Clock::GetTime());
213213 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(),
215215 &context->GetConfig()));
216216 context->set_converter(new SessionConverter(
217217 engine_->GetConverter(), &context->GetRequest(), &context->GetConfig()));
15051505 std::unique_ptr<composer::Composer> temporary_composer;
15061506 if (input.has_key() && input.key().has_mode()) {
15071507 // 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));
15091509 // Copy the current composer state just in case.
15101510 temporary_composer->CopyFrom(context_->composer());
15111511 ApplyInputMode(input.key().mode(), temporary_composer.get());
18681868 context_->mutable_converter()->Reset();
18691869
18701870 commands::Result *result = command->mutable_output()->mutable_result();
1871 DCHECK(result != NULL);
1871 DCHECK(result != nullptr);
18721872 result->set_type(commands::Result::STRING);
18731873 result->mutable_key()->append(key);
18741874 result->mutable_value()->append(preedit);
8989 mozc::InitMozc(argv[0], &argc, &argv);
9090 std::unique_ptr<mozc::InputFileStream> input_file;
9191 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;
9494
9595 if (!FLAGS_profile_dir.empty()) {
9696 // TODO(komatsu): Make a tmp dir and use it.
25712571 { // validation
25722572 // Copy and validate
25732573 std::unique_ptr<SessionConverter> dest(src.Clone());
2574 ASSERT_TRUE(dest.get() != NULL);
2574 ASSERT_TRUE(dest.get() != nullptr);
25752575 ExpectSameSessionConverter(src, *dest);
25762576
25772577 // Convert source
25842584
25852585 // Copy converted and validate
25862586 dest.reset(src.Clone());
2587 ASSERT_TRUE(dest.get() != NULL);
2587 ASSERT_TRUE(dest.get() != nullptr);
25882588 ExpectSameSessionConverter(src, *dest);
25892589 }
25902590 }
588588 bool SessionHandler::SendKey(commands::Command *command) {
589589 const SessionID id = command->input().id();
590590 session::SessionInterface **session = session_map_->MutableLookup(id);
591 if (session == NULL || *session == NULL) {
591 if (session == nullptr || *session == nullptr) {
592592 LOG(WARNING) << "SessionID " << id << " is not available";
593593 return false;
594594 }
600600 bool SessionHandler::TestSendKey(commands::Command *command) {
601601 const SessionID id = command->input().id();
602602 session::SessionInterface **session = session_map_->MutableLookup(id);
603 if (session == NULL || *session == NULL) {
603 if (session == nullptr || *session == nullptr) {
604604 LOG(WARNING) << "SessionID " << id << " is not available";
605605 return false;
606606 }
612612 const SessionID id = command->input().id();
613613 session::SessionInterface **session =
614614 const_cast<session::SessionInterface **>(session_map_->Lookup(id));
615 if (session == NULL || *session == NULL) {
615 if (session == nullptr || *session == nullptr) {
616616 LOG(WARNING) << "SessionID " << id << " is not available";
617617 return false;
618618 }
637637 last_create_session_time_ = current_time;
638638
639639 // if session map is FULL, remove the oldest item from the LRU
640 SessionElement *oldest_element = NULL;
640 SessionElement *oldest_element = nullptr;
641641 if (session_map_->Size() >= max_session_size_) {
642642 oldest_element = const_cast<SessionElement *>(session_map_->Tail());
643 if (oldest_element == NULL) {
643 if (oldest_element == nullptr) {
644644 LOG(ERROR) << "oldest SessionElement is NULL";
645645 return false;
646646 }
670670 }
671671
672672 session::SessionInterface *session = NewSession();
673 if (session == NULL) {
673 if (session == nullptr) {
674674 LOG(ERROR) << "Cannot allocate new Session";
675675 return false;
676676 }
681681 command->mutable_output()->set_id(new_id);
682682
683683 // The oldes item should be reused
684 DCHECK(oldest_element == NULL || oldest_element == element);
684 DCHECK(oldest_element == nullptr || oldest_element == element);
685685
686686 if (command->input().has_capability()) {
687687 session->set_client_capability(command->input().capability());
689689
690690 if (command->input().has_application_info()) {
691691 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
698692 }
699693
700694 // Ensure the onmemory config is same as the locally stored one
761755 std::vector<SessionID> remove_ids;
762756 for (SessionElement *element =
763757 const_cast<SessionElement *>(session_map_->Head());
764 element != NULL; element = element->next) {
758 element != nullptr; element = element->next) {
765759 session::SessionInterface *session = element->value;
766760 if (!IsApplicationAlive(session)) {
767761 VLOG(2) << "Application is not alive. Removing: " << element->key;
846840
847841 bool SessionHandler::DeleteSessionID(SessionID id) {
848842 session::SessionInterface **session = session_map_->MutableLookup(id);
849 if (session == NULL || *session == NULL) {
843 if (session == nullptr || *session == nullptr) {
850844 LOG_IF(WARNING, id != 0) << "cannot find SessionID " << id;
851845 return false;
852846 }
2525 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2626 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2727 // 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.
3128
3229 #include <memory>
3330
612609 #undef EXPECT_NOT_IN_ALL_CANDIDATE_WORDS
613610
614611 } // namespace
615
616 #endif // !OS_NACL
7777 Scheduler::SetSchedulerHandler(job_recorder.get());
7878 std::unique_ptr<SessionServer> session_server(new SessionServer);
7979 EXPECT_EQ(0, job_recorder->job_settings().size());
80 Scheduler::SetSchedulerHandler(NULL);
80 Scheduler::SetSchedulerHandler(nullptr);
8181 }
8282 } // namespace mozc
28412841 // "page2-cand8"
28422842 {
28432843 Segments segments;
2844 Segment *segment = NULL;
2844 Segment *segment = nullptr;
28452845 segment = segments.add_segment();
28462846 segment->set_key("あいうえお");
28472847 for (int page_index = 0; page_index < 3; ++page_index) {
38403840 // Global mode should be kept as HIRAGANA
38413841 EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode());
38423842
3843 #ifndef OS_NACL
3844 // NaCl doesn't support OFF key.
3845
38463843 // When the IME is deactivated, the temporary composition mode is reset.
38473844 EXPECT_TRUE(SendKey("OFF", session.get(), &command)); // "あAaあA"
38483845 ASSERT_TRUE(command.output().has_status());
38533850 EXPECT_EQ(commands::DIRECT, command.output().mode());
38543851 EXPECT_EQ(commands::HIRAGANA, command.output().status().mode());
38553852 EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode());
3856 #endif // !OS_NACL
38573853 }
38583854
38593855 { // Katakana mode + Shift key
38823878 // Global mode should be kept as FULL_KATAKANA
38833879 EXPECT_EQ(commands::FULL_KATAKANA,
38843880 command.output().status().comeback_mode());
3885
3886 #ifndef OS_NACL
3887 // NaCl doesn't support OFF key.
38883881
38893882 // When the IME is deactivated, the temporary composition mode is reset.
38903883 EXPECT_TRUE(SendKey("OFF", session.get(), &command)); // "アA"
38973890 EXPECT_EQ(commands::FULL_KATAKANA, command.output().status().mode());
38983891 EXPECT_EQ(commands::FULL_KATAKANA,
38993892 command.output().status().comeback_mode());
3900 #endif // !OS_NACL
39013893 }
39023894 }
39033895
56015593 EXPECT_FALSE(command.output().has_result());
56025594 }
56035595
5604 #ifndef OS_NACL
5605 // NaCl doesn't support Eisu key
56065596 TEST_F(SessionTest, Issue2223755) {
56075597 // This is a unittest against http://b/2223755.
56085598 // - F6 and F7 convert space to half-width.
56605650 EXPECT_EQ("ア イ", GetComposition(command)); // fullwidth space
56615651 }
56625652 }
5663 #endif // !OS_NACL
56645653
56655654 TEST_F(SessionTest, Issue2269058) {
56665655 // This is a unittest against http://b/2269058.
58815870 EXPECT_EQ(commands::FULL_KATAKANA, command.output().mode());
58825871 }
58835872
5884 #ifndef OS_NACL
5885 // NaCl doesn't support hankaku/zenkaku key.
58865873 TEST_F(SessionTest, Issue2791640) {
58875874 // This is a unittest against http://b/2791640.
58885875 // Existing preedit should be committed when IME is turned off.
59025889
59035890 ASSERT_FALSE(command.output().has_preedit());
59045891 }
5905 #endif // !OS_NACL
5906
5907 #ifndef OS_NACL
5908 // NaCl doesn't support hankaku/zenkaku key.
5892
59095893 TEST_F(SessionTest, CommitExistingPreeditWhenIMEIsTurnedOff) {
59105894 // Existing preedit should be committed when IME is turned off.
59115895
59455929 ASSERT_FALSE(command.output().has_preedit());
59465930 }
59475931 }
5948 #endif // !OS_NACL
59495932
59505933 TEST_F(SessionTest, SendKeyDirectInputStateTest) {
59515934 // InputModeChange commands from direct mode are supported only for Windows
62006183 EXPECT_TRUE(command.output().has_preedit());
62016184 }
62026185
6203 #ifndef OS_NACL
6204 // NaCl doesn't support KeyEvent::ON|OFF.
62056186 TEST_F(SessionTest, PerformedCommand) {
62066187 std::unique_ptr<Session> session(new Session(engine_.get()));
62076188 InitSessionToPrecomposition(session.get());
62496230 EXPECT_COUNT_STATS("Performed_Conversion_Commit", 1);
62506231 }
62516232 }
6252 #endif // !OS_NACL
62536233
62546234 TEST_F(SessionTest, ResetContext) {
62556235 std::unique_ptr<MockConverterEngineForReset> engine(
6464
6565 SessionWatchDog::SessionWatchDog(int32 interval_sec)
6666 : interval_sec_(interval_sec),
67 client_(NULL),
68 cpu_stats_(NULL),
67 client_(nullptr),
68 cpu_stats_(nullptr),
6969 event_(new UnnamedEvent) {
7070 // allow [1..600].
7171 interval_sec_ = std::max(1, std::min(interval_sec_, 600));
9797
9898 void SessionWatchDog::Run() {
9999 std::unique_ptr<client::ClientInterface> client_impl;
100 if (client_ == NULL) {
100 if (client_ == nullptr) {
101101 VLOG(2) << "default client is used";
102102 client_impl.reset(client::ClientFactory::NewClient());
103103 client_ = client_impl.get();
104104 }
105105
106106 std::unique_ptr<CPUStatsInterface> cpu_stats_impl;
107 if (cpu_stats_ == NULL) {
107 if (cpu_stats_ == nullptr) {
108108 VLOG(2) << "default cpu_stats is used";
109109 cpu_stats_impl.reset(new CPUStats);
110110 cpu_stats_ = cpu_stats_impl.get();
113113
114114 // Allocate full blocks
115115 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;
117117 }
118118
119119 // Allocate the last block
125125 CHECK_EQ(bytes_in_last_ % sizeof(uint32), 0);
126126
127127 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;
129129 }
130130
131131 ExistenceFilter::BlockBitmap::~BlockBitmap() {
283283 << expected_nelts_ << " num_hashes " << num_hashes_;
284284
285285 // write bitmap
286 char **fragment_ptr = NULL;
286 char **fragment_ptr = nullptr;
287287 size_t bytes = 0;
288288 size_t write = 0;
289289 for (uint32 iter = 0;
317317 sizeof(header.m) + sizeof(header.n) + sizeof(header.k);
318318 if (size < header_bytes) {
319319 LOG(ERROR) << "Not enough bufsize: could not read header";
320 return NULL;
320 return nullptr;
321321 }
322322
323323 if (!ReadHeader(buf, &header)) {
324324 LOG(ERROR) << "Invalid format: could not read header";
325 return NULL;
325 return nullptr;
326326 }
327327 buf += header_bytes;
328328
333333
334334 if (size < header_bytes + filter_bytes) {
335335 LOG(ERROR) << "Not enough bufsize: could not read filter";
336 return NULL;
336 return nullptr;
337337 }
338338
339339 ExistenceFilter *filter = ExistenceFilter::CreateImmutableExietenceFilter(
340340 header.m, header.n, header.k);
341 char **ptr = NULL;
341 char **ptr = nullptr;
342342 size_t n = 0;
343343 size_t read = 0;
344344 for (uint32 iter = 0; filter->rep_->GetMutableFragment(&iter, &ptr, &n);) {
349349 if (read != filter_bytes) {
350350 LOG(ERROR) << "Read " << read << " bytes instead of " << filter_bytes;
351351 delete filter;
352 return NULL;
352 return nullptr;
353353 }
354354 return filter;
355355 }
7272
7373 CheckValues(filter, m, n);
7474
75 char *buf = NULL;
75 char *buf = nullptr;
7676 size_t size = 0;
7777 filter->Write(&buf, &size);
7878 LOG(INFO) << "write size: " << size;
116116 filter->Insert(Hash::Fingerprint(words[i]));
117117 }
118118
119 char *buf = NULL;
119 char *buf = nullptr;
120120 size_t size = 0;
121121 filter->Write(&buf, &size);
122122 std::unique_ptr<ExistenceFilter> filter_read(
6262 index_.Reset();
6363 base_length_ = 0;
6464 step_length_ = 0;
65 data_ = 0;
65 data_ = nullptr;
6666 }
6767
6868 const char *BitVectorBasedArray::Get(size_t index, size_t *length) const {
167167 // Add new elements to free list
168168 for (size_t i = 0; i < next_block_size_; ++i) {
169169 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
171171 e->next = free_list_;
172172 free_list_ = e;
173173 }
188188
189189 template <typename Key, typename Value>
190190 void LRUCache<Key, Value>::PushFreeList(Element* element) {
191 element->prev = NULL;
191 element->prev = nullptr;
192192 element->next = free_list_;
193193 free_list_ = element;
194194 }
196196 template <typename Key, typename Value>
197197 typename LRUCache<Key, Value>::Element* LRUCache<Key, Value>::PopFreeList() {
198198 Element* r = free_list_;
199 if (r != NULL) {
200 CHECK(r->prev == NULL);
199 if (r != nullptr) {
200 CHECK(r->prev == nullptr);
201201 free_list_ = r->next;
202 if (free_list_ != NULL) {
203 free_list_->prev = NULL;
202 if (free_list_ != nullptr) {
203 free_list_->prev = nullptr;
204204 }
205 r->next = NULL;
205 r->next = nullptr;
206206 }
207207 return r;
208208 }
211211 typename LRUCache<Key, Value>::Element*
212212 LRUCache<Key, Value>::NextFreeElement() {
213213 Element* r = PopFreeList();
214 if (r == NULL) {
214 if (r == nullptr) {
215215 AddBlock();
216216 r = PopFreeList();
217217 }
225225 if (iter != table_->end()) {
226226 return iter->second;
227227 }
228 return NULL;
228 return nullptr;
229229 }
230230
231231 template <typename Key, typename Value>
236236 if (lru_tail_ == element) {
237237 lru_tail_ = element->prev;
238238 }
239 if (element->prev != NULL) {
239 if (element->prev != nullptr) {
240240 element->prev->next = element->next;
241241 }
242 if (element->next != NULL) {
242 if (element->next != nullptr) {
243243 element->next->prev = element->prev;
244244 }
245 element->prev = NULL;
246 element->next = NULL;
245 element->prev = nullptr;
246 element->next = nullptr;
247247 }
248248
249249 template <typename Key, typename Value>
255255 RemoveFromLRU(element);
256256 element->next = lru_head_;
257257 lru_head_ = element;
258 if (element->next != NULL) {
258 if (element->next != nullptr) {
259259 element->next->prev = element;
260260 }
261 if (lru_tail_ == NULL) {
261 if (lru_tail_ == nullptr) {
262262 lru_tail_ = element;
263263 }
264264 }
265265
266266 template <typename Key, typename Value>
267267 bool LRUCache<Key, Value>::Evict(Element* e) {
268 if (e != NULL) {
268 if (e != nullptr) {
269269 int erased = table_->erase(e->key);
270270 CHECK_EQ(erased, 1);
271271 RemoveFromLRU(e);
277277
278278 template <typename Key, typename Value>
279279 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),
283283 block_count_(0),
284284 block_capacity_(0),
285285 max_elements_(max_elements) {
315315 template <typename Key, typename Value>
316316 void LRUCache<Key, Value>::Insert(const Key& key, const Value& value) {
317317 Element* e = Insert(key);
318 if (e != NULL) {
318 if (e != nullptr) {
319319 e->value = value;
320320 }
321321 }
325325 const Key& key) {
326326 bool erased = false;
327327 Element* e = LookupInternal(key);
328 if (e != NULL) {
328 if (e != nullptr) {
329329 erased = Evict(e);
330330 CHECK(erased);
331331 }
332332
333333 e = NextFreeElement();
334 if (e == NULL) {
334 if (e == nullptr) {
335335 // no free elements, I have to replace an existing element
336336 e = lru_tail_;
337337 erased = Evict(e);
338338 CHECK(erased);
339339 e = NextFreeElement();
340 CHECK(e != NULL);
340 CHECK(e != nullptr);
341341 }
342342 e->key = key;
343343 (*table_)[key] = e;
349349 template <typename Key, typename Value>
350350 Value* LRUCache<Key, Value>::MutableLookup(const Key& key) {
351351 Element* e = LookupInternal(key);
352 if (e != NULL) {
352 if (e != nullptr) {
353353 PushLRUHead(e);
354354 return &(e->value);
355355 }
356 return NULL;
356 return nullptr;
357357 }
358358
359359 template <typename Key, typename Value>
364364 template <typename Key, typename Value>
365365 Value* LRUCache<Key, Value>::MutableLookupWithoutInsert(const Key& key) const {
366366 Element* e = LookupInternal(key);
367 if (e != NULL) {
367 if (e != nullptr) {
368368 return &(e->value);
369369 }
370 return NULL;
370 return nullptr;
371371 }
372372
373373 template <typename Key, typename Value>
385385 void LRUCache<Key, Value>::Clear() {
386386 table_->clear();
387387 Element* e = lru_head_;
388 while (e != NULL) {
388 while (e != nullptr) {
389389 Element* next = e->next;
390390 PushFreeList(e);
391391 e = next;
392392 }
393 lru_head_ = lru_tail_ = NULL;
393 lru_head_ = lru_tail_ = nullptr;
394394 }
395395
396396 template <typename Key, typename Value>
8787 const uint32 *v2 = reinterpret_cast<const uint32 *>(
8888 storage->Lookup(values[i].first, &last_access_time));
8989 const uint32 *v3 = reinterpret_cast<const uint32 *>(value_list[i].data());
90 EXPECT_TRUE(v1 != NULL);
90 EXPECT_TRUE(v1 != nullptr);
9191 EXPECT_EQ(*v1, values[i].second);
92 EXPECT_TRUE(v2 != NULL);
92 EXPECT_TRUE(v2 != nullptr);
9393 EXPECT_EQ(*v2, values[i].second);
94 EXPECT_TRUE(v3 != NULL);
94 EXPECT_TRUE(v3 != nullptr);
9595 EXPECT_EQ(*v3, values[i].second);
9696 }
9797
9999 const uint32 *v1 = cache.Lookup(values[i].first);
100100 const uint32 *v2 = reinterpret_cast<const uint32 *>(
101101 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);
104104 }
105105 }
106106
333333
334334 TEST_F(LRUStorageTest, InvalidFileOpenTest) {
335335 LRUStorage storage;
336 EXPECT_FALSE(storage.Insert("test", NULL));
336 EXPECT_FALSE(storage.Insert("test", nullptr));
337337
338338 const std::string filename = GetTemporaryFilePath();
339339 FileUtil::Unlink(filename);
340340
341341 // cannot open
342342 EXPECT_FALSE(storage.Open(filename.c_str()));
343 EXPECT_FALSE(storage.Insert("test", NULL));
343 EXPECT_FALSE(storage.Insert("test", nullptr));
344344 }
345345
346346 TEST_F(LRUStorageTest, OpenOrCreateTest) {
5353 class StorageInitializer {
5454 public:
5555 StorageInitializer()
56 : default_storage_(TinyStorage::New()), current_storage_(NULL) {
56 : default_storage_(TinyStorage::New()), current_storage_(nullptr) {
5757 if (!default_storage_->Open(FileUtil::JoinPath(
5858 SystemUtil::GetUserProfileDirectory(), kRegistryFileName))) {
5959 LOG(ERROR) << "cannot open registry";
6161 }
6262
6363 StorageInterface *GetStorage() const {
64 if (current_storage_ == NULL) {
64 if (current_storage_ == nullptr) {
6565 return default_storage_.get();
6666 } else {
6767 return current_storage_;
327327 std::unique_ptr<TinyStorageImpl> storage(new TinyStorageImpl);
328328 if (!storage->Open(filename)) {
329329 LOG(ERROR) << "cannot open " << filename;
330 return NULL;
330 return nullptr;
331331 }
332332 return storage.release();
333333 }
3232 #include "testing/base/public/googletest.h"
3333 #include "testing/base/public/gunit.h"
3434
35 #ifdef OS_NACL
36 #include "testing/base/public/nacl_mock_module.h"
37 #endif // OS_NACL
38
3935 int main(int argc, char **argv) {
4036 // TODO(yukawa, team): Implement b/2805528 so that you can specify any option
4137 // given by gunit.
5248 // See b/2805521 for details.
5349 testing::GTEST_FLAG(catch_exceptions) = true;
5450
55 #ifdef OS_NACL
56 mozc::testing::WorkAroundEmptyFunctionToAvoidLinkError();
57 #endif // OS_NACL
58
5951 return RUN_ALL_TESTS();
6052 }
6153
2626 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2727 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2828
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
2929 #ifndef MOZC_TESTING_BASE_PUBLIC_NACL_MOCK_MODULE_H_
3030 #define MOZC_TESTING_BASE_PUBLIC_NACL_MOCK_MODULE_H_
3131
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
5232 #endif // MOZC_TESTING_BASE_PUBLIC_NACL_MOCK_MODULE_H_
3232 #include "unix/ibus/engine_interface.h"
3333
3434 namespace {
35 mozc::ibus::EngineInterface *g_engine = NULL;
35 mozc::ibus::EngineInterface *g_engine = nullptr;
3636 }
3737
3838 namespace mozc {
4040
4141 bool EngineRegistrar::Register(EngineInterface *engine,
4242 IBusEngineClass *engine_class) {
43 DCHECK(engine) << "engine is NULL";
43 DCHECK(engine) << "engine is nullptr";
4444 DCHECK(!g_engine) << "engine is already registered";
4545
4646 g_engine = engine;
7171 EngineInterface *EngineRegistrar::Unregister(IBusEngineClass *engine_class) {
7272 DCHECK(g_engine) << "engine is not registered";
7373
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;
9191 #if defined(MOZC_ENABLE_IBUS_INPUT_PURPOSE)
92 engine_class->set_content_type = NULL;
92 engine_class->set_content_type = nullptr;
9393 #endif // MOZC_ENABLE_IBUS_INPUT_PURPOSE
9494
9595 mozc::ibus::EngineInterface *previous = g_engine;
96 g_engine = NULL;
96 g_engine = nullptr;
9797 return previous;
9898 }
9999
5050 if (g_variant_classify(value) != G_VARIANT_CLASS_STRING) {
5151 return false;
5252 }
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));
5454 return true;
5555 }
5656
4141 namespace {
4242
4343 // 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
4545 // returned IBusText object.
4646 IBusText *ComposeAuxiliaryText(const commands::Candidates &candidates) {
4747 if (!candidates.has_footer()) {
4848 // We don't have to show the auxiliary text.
49 return NULL;
49 return nullptr;
5050 }
5151 const commands::Footer &footer = candidates.footer();
5252
7373 auxiliary_text += index_buf;
7474 }
7575 return auxiliary_text.empty()
76 ? NULL
76 ? nullptr
7777 : ibus_text_new_from_string(auxiliary_text.c_str());
7878 }
7979 } // namespace
306306 config::Config::PreeditMethod method,
307307 bool layout_is_jp,
308308 commands::KeyEvent *out_event) const {
309 DCHECK(out_event) << "out_event is NULL";
309 DCHECK(out_event) << "out_event is nullptr";
310310 out_event->Clear();
311311
312312 // Due to historical reasons, many linux ditributions set Hiragana_Katakana
4141
4242 namespace {
4343
44 IBusBus *g_bus = NULL;
44 IBusBus *g_bus = nullptr;
4545
4646 #ifndef MOZC_NO_LOGGING
4747 void EnableVerboseLog() {
5858 sa.sa_handler = SIG_IGN;
5959 ::sigemptyset(&sa.sa_mask);
6060 sa.sa_flags = 0;
61 CHECK_EQ(0, ::sigaction(SIGCHLD, &sa, NULL));
61 CHECK_EQ(0, ::sigaction(SIGCHLD, &sa, nullptr));
6262 // TODO(taku): move this function inside client::Session::LaunchTool
6363 }
6464
8484 void InitIBusComponent(bool executed_by_ibus_daemon) {
8585 g_bus = ibus_bus_new();
8686 g_signal_connect(g_bus, "disconnected",
87 G_CALLBACK(mozc::ibus::MozcEngine::Disconnected), NULL);
87 G_CALLBACK(mozc::ibus::MozcEngine::Disconnected), nullptr);
8888
8989 IBusComponent *component = GetIBusComponent();
9090 IBusFactory *factory = ibus_factory_new(ibus_bus_get_connection(g_bus));
113113 mozc::ibus::MozcEngine *engine;
114114 };
115115
116 IBusEngineClass *g_parent_class = NULL;
116 IBusEngineClass *g_parent_class = nullptr;
117117
118118 GObject *MozcEngineClassConstructor(
119119 GType type, guint n_construct_properties,
175175 guint anchor_pos = 0;
176176 // DO NOT call g_object_unref against this.
177177 // 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;
179179 ibus_engine_get_surrounding_text(engine, &text, &cursor_pos, &anchor_pos);
180180 const std::string surrounding_text(ibus_text_get_text(text));
181181
182182 #ifdef MOZC_ENABLE_X11_SELECTION_MONITOR
183 if (cursor_pos == anchor_pos && selection_monitor != NULL) {
183 if (cursor_pos == anchor_pos && selection_monitor != nullptr) {
184184 const SelectionInfo &info = selection_monitor->GetSelectionInfo();
185185 guint new_anchor_pos = 0;
186186 if (SurroundingTextUtil::GetAnchorPosFromSelection(
252252 ibus_candidate_window_handler_(new IBusCandidateWindowHandler()),
253253 preedit_method_(config::Config::ROMAN) {
254254 #ifdef MOZC_ENABLE_X11_SELECTION_MONITOR
255 if (selection_monitor_.get() != NULL) {
255 if (selection_monitor_ != nullptr) {
256256 selection_monitor_->StartMonitoring();
257257 }
258258 #endif // MOZC_ENABLE_X11_SELECTION_MONITOR
307307
308308 // If engine wants to use surrounding text, we should call
309309 // 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);
311311 }
312312
313313 void MozcEngine::FocusIn(IBusEngine *engine) {
431431 static GType type = 0;
432432
433433 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,
437437 };
438438
439439 if (type == 0) {
521521 }
522522
523523 void MozcEngine::SyncData(bool force) {
524 if (client_.get() == NULL) {
524 if (client_ == nullptr) {
525525 return;
526526 }
527527
104104 "Tool.AboutDialog",
105105 "about_dialog",
106106 "About Mozc",
107 NULL,
107 nullptr,
108108 },
109109 };
110110 } // namespace
4343 const char *icon;
4444 };
4545
46 // This pointer should be NULL when properties size is 0.
46 // This pointer should be nullptr when properties size is 0.
4747 extern const MozcEngineProperty *kMozcEngineProperties;
4848 extern const size_t kMozcEnginePropertiesSize;
4949
50 // If kMozcEnginePropertiesIMEOffState is NULL, it means IME should be always
50 // If kMozcEnginePropertiesIMEOffState is nullptr, it means IME should be always
5151 // On.
5252 extern const MozcEngineProperty *kMozcEnginePropertyIMEOffState;
5353
6060 const char *icon; // icon
6161 };
6262
63 // This pointer should be NULL when properties size is 0.
63 // This pointer should be nullptr when properties size is 0.
6464 extern const MozcEngineToolProperty *kMozcEngineToolProperties;
6565 extern const size_t kMozcEngineToolPropertiesSize;
6666
8989 PropertyHandler::PropertyHandler(MessageTranslatorInterface *translator,
9090 client::ClientInterface *client)
9191 : 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),
9494 client_(client),
9595 translator_(translator),
9696 original_composition_mode_(kMozcEngineInitialCompositionMode),
120120 if (prop_composition_mode_) {
121121 // The ref counter will drop to one.
122122 g_object_unref(prop_composition_mode_);
123 prop_composition_mode_ = NULL;
123 prop_composition_mode_ = nullptr;
124124 }
125125
126126 if (prop_mozc_tool_) {
127127 // The ref counter will drop to one.
128128 g_object_unref(prop_mozc_tool_);
129 prop_mozc_tool_ = NULL;
129 prop_mozc_tool_ = nullptr;
130130 }
131131
132132 if (prop_root_) {
133133 // Destroy all objects under the root.
134134 g_object_unref(prop_root_);
135 prop_root_ = NULL;
135 prop_root_ = nullptr;
136136 }
137137 }
138138
143143
144144 // TODO(nona): do not use kMozcEngine*** directory.
145145 void PropertyHandler::AppendCompositionPropertyToPanel() {
146 if (kMozcEngineProperties == NULL || kMozcEnginePropertiesSize == 0) {
146 if (kMozcEngineProperties == nullptr || kMozcEnginePropertiesSize == 0) {
147147 return;
148148 }
149149
157157 : kMozcEnginePropertyIMEOffState->composition_mode;
158158
159159 std::string icon_path_for_panel;
160 const char *mode_symbol = NULL;
160 const char *mode_symbol = nullptr;
161161 for (size_t i = 0; i < kMozcEnginePropertiesSize; ++i) {
162162 const MozcEngineProperty &entry = kMozcEngineProperties[i];
163163 IBusText *label = ibus_text_new_from_string(
169169 mode_symbol = entry.label_for_panel;
170170 }
171171 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 */);
174175 g_object_set_data(G_OBJECT(item), kGObjectDataKey, (gpointer)&entry);
175176 ibus_prop_list_append(sub_prop_list, item);
176177 // |sub_prop_list| owns |item| by calling g_object_ref_sink for the |item|.
177178 }
178179 DCHECK(!icon_path_for_panel.empty());
179 DCHECK(mode_symbol != NULL);
180 DCHECK(mode_symbol != nullptr);
180181
181182 const std::string &mode_label =
182183 translator_->MaybeTranslate("Input Mode") + " (" + mode_symbol + ")";
189190 // See /usr/share/gnome-shell/js/ui/status/keyboard.js for details.
190191 prop_composition_mode_ = ibus_property_new(
191192 "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 */,
193194 PROP_STATE_UNCHECKED, sub_prop_list);
194195
195196 // Gnome shell uses symbol property for the mode indicator text icon iff the
230231
231232 // TODO(nona): do not use kMozcEngine*** directory.
232233 void PropertyHandler::AppendToolPropertyToPanel() {
233 if (kMozcEngineToolProperties == NULL || kMozcEngineToolPropertiesSize == 0 ||
234 if (kMozcEngineToolProperties == nullptr ||
235 kMozcEngineToolPropertiesSize == 0 ||
234236 !IsMozcToolAvailable()) {
235237 return;
236238 }
245247 translator_->MaybeTranslate(entry.label).c_str());
246248 // TODO(yusukes): It would be better to use entry.icon here?
247249 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);
250252 g_object_set_data(G_OBJECT(item), kGObjectDataKey, (gpointer)&entry);
251253 ibus_prop_list_append(sub_prop_list, item);
252254 }
255257 ibus_text_new_from_string(translator_->MaybeTranslate("Tools").c_str());
256258 const std::string icon_path = GetIconPath(kMozcToolIconPath);
257259 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 */,
259261 TRUE /* sensitive */, TRUE /* visible */,
260262 PROP_STATE_UNCHECKED, sub_prop_list);
261263
290292
291293 void PropertyHandler::UpdateCompositionModeIcon(
292294 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;
298300 for (size_t i = 0; i < kMozcEnginePropertiesSize; ++i) {
299301 if (kMozcEngineProperties[i].composition_mode == new_composition_mode) {
300302 entry = &(kMozcEngineProperties[i]);
306308 for (guint prop_index = 0;; ++prop_index) {
307309 IBusProperty *prop = ibus_prop_list_get(
308310 ibus_property_get_sub_props(prop_composition_mode_), prop_index);
309 if (prop == NULL) {
311 if (prop == nullptr) {
310312 break;
311313 }
312314 if (!g_strcmp0(entry->key, ibus_property_get_key(prop))) {
345347 // composition_mode. However in IBus we can only control composition mode, not
346348 // IMEOn/IMEOff. So we use one composition state as IMEOff and the others as
347349 // 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.
350352 if (kMozcEnginePropertyIMEOffState && is_activated_ &&
351353 composition_mode == kMozcEnginePropertyIMEOffState->composition_mode) {
352354 command.set_type(commands::SessionCommand::TURN_OFF_IME);
373375 for (guint prop_index = 0;; ++prop_index) {
374376 IBusProperty *prop = ibus_prop_list_get(
375377 ibus_property_get_sub_props(prop_mozc_tool_), prop_index);
376 if (prop == NULL) {
378 if (prop == nullptr) {
377379 break;
378380 }
379381 if (!g_strcmp0(property_name, ibus_property_get_key(prop))) {
397399 for (guint prop_index = 0;; ++prop_index) {
398400 IBusProperty *prop = ibus_prop_list_get(
399401 ibus_property_get_sub_props(prop_composition_mode_), prop_index);
400 if (prop == NULL) {
402 if (prop == nullptr) {
401403 break;
402404 }
403405 if (!g_strcmp0(property_name, ibus_property_get_key(prop))) {
5050
5151 class ScopedXcbGenericError {
5252 public:
53 ScopedXcbGenericError() : error_(NULL) {}
53 ScopedXcbGenericError() : error_(nullptr) {}
5454 ~ScopedXcbGenericError() {
5555 free(error_);
56 error_ = NULL;
56 error_ = nullptr;
5757 }
5858 const xcb_generic_error_t *get() const { return error_; }
5959 xcb_generic_error_t **mutable_get() { return &error_; }
9898 class SelectionMonitorServer {
9999 public:
100100 SelectionMonitorServer()
101 : connection_(NULL),
101 : connection_(nullptr),
102102 requestor_window_(0),
103103 root_window_(0),
104104 xfixes_first_event_(0),
107107 ~SelectionMonitorServer() { Release(); }
108108
109109 bool Init() {
110 connection_ = ::xcb_connect(NULL, NULL);
111 if (connection_ == NULL) {
110 connection_ = ::xcb_connect(nullptr, nullptr);
111 if (connection_ == nullptr) {
112112 return false;
113113 }
114114
149149 }
150150 if (::xcb_connection_has_error(connection_)) {
151151 LOG(ERROR) << "XCB connection has error.";
152 connection_ = NULL;
152 connection_ = nullptr;
153153 return false;
154154 }
155155 return true;
165165 unique_ptr<xcb_generic_event_t, void (*)(void *)> event(
166166 ::xcb_wait_for_event(connection_), &std::free);
167167
168 if (event.get() == NULL) {
169 LOG(ERROR) << "NULL event returned.";
168 if (event.get() == nullptr) {
169 LOG(ERROR) << "nullptr event returned.";
170170 return false;
171171 }
172172
208208 void Release() {
209209 if (connection_) {
210210 ::xcb_disconnect(connection_);
211 connection_ = NULL;
211 connection_ = nullptr;
212212 }
213213 }
214214
219219 ::xcb_intern_atom(connection_, false, name.size(), name.c_str());
220220 ScopedXcbInternAtomReply reply(
221221 ::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.";
224224 return false;
225225 }
226226 if (reply->atom == XCB_NONE) {
241241 bool InitXFixes() {
242242 const xcb_query_extension_reply_t *ext_reply =
243243 ::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.";
246246 return false;
247247 }
248248
253253 ScopedXcbXFixesQueqyVersionReply xfixes_query(
254254 ::xcb_xfixes_query_version_reply(connection_, xfixes_query_cookie,
255255 xcb_error.mutable_get()));
256 if (xcb_error.get() != NULL) {
256 if (xcb_error.get() != nullptr) {
257257 LOG(ERROR) << "xcb_xfixes_query_version_reply failed. error_code: "
258258 << static_cast<uint32>(xcb_error.get()->error_code);
259259 return false;
260260 }
261 if (xfixes_query.get() == NULL) {
261 if (xfixes_query.get() == nullptr) {
262262 return false;
263263 }
264264
283283 ScopedXcbGenericError xcb_error;
284284 ScopedXcbGetAtomNameReply reply(::xcb_get_atom_name_reply(
285285 connection_, cookie, xcb_error.mutable_get()));
286 if (xcb_error.get() != NULL) {
286 if (xcb_error.get() != nullptr) {
287287 LOG(ERROR) << "xcb_get_atom_name_reply failed. error_code: "
288288 << static_cast<uint32>(xcb_error.get()->error_code);
289289 return "";
290290 }
291 if (reply.get() == NULL) {
292 VLOG(2) << "reply is NULL";
291 if (reply.get() == nullptr) {
292 VLOG(2) << "reply is nullptr";
293293 return "";
294294 }
295295
310310 connection_, false, window, property_atom, property_type_atom, 0, 0);
311311 ScopedXcbGetPropertyReply reply(
312312 ::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";
315315 return false;
316316 }
317317 if (reply->type == XCB_NONE) {
352352 property_type_atom, byte_offset, max_bytes);
353353 ScopedXcbGetPropertyReply reply(
354354 ::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";
357357 return false;
358358 }
359359 if (reply->format != element_bit_size) {
379379 XCB_ATOM_CARDINAL, 0, sizeof(T) * 8);
380380 ScopedXcbGetPropertyReply reply(
381381 ::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";
384384 return false;
385385 }
386386
563563 size_t max_text_bytes) {
564564 unique_ptr<SelectionMonitorServer> server(new SelectionMonitorServer());
565565 if (!server->Init()) {
566 return NULL;
566 return nullptr;
567567 }
568568 return new SelectionMonitorImpl(server.release(), max_text_bytes);
569569 }
182182 bool ConversionModeUtil::ToMozcMode(uint32 flag,
183183 mozc::commands::CompositionMode *mode) {
184184 if (mode == nullptr) {
185 LOG(ERROR) << "|mode| is NULL";
185 LOG(ERROR) << "|mode| is nullptr";
186186 return false;
187187 }
188188
162162 DWORD value_name_length = kMaxValueNameLength;
163163 DWORD value_length = kMaxValueLength;
164164 LONG result = RegEnumValue(preload_key, i, value_name, &value_name_length,
165 nullptr, // reserved (must be NULL)
165 nullptr, // reserved (must be nullptr)
166166 nullptr, // type (optional)
167167 value, &value_length);
168168
225225 continue;
226226 }
227227 // 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.
229229 result = ::ImmSetHotKey(id, 0, 0, nullptr);
230230 if (result == FALSE) {
231231 succeeded = false;
6565 class CandidateInfoUtil {
6666 public:
6767 // 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.
6969 // You can specify the previously used handle in |current_handle| to transfer
7070 // 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
7373 // of the returned handle either way.
7474 static HIMCC Initialize(HIMCC current_handle);
7575
7676 // Returns an Input Method Context Component (IMCC) handle with filling
7777 // candidate list information based on the Mozc output specified in |output|.
78 // Returns NULL if fails.
78 // Returns nullptr if fails.
7979 // You can specify the previously used handle in |current_handle| to transfer
8080 // 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
8383 // of the returned handle either way.
8484 static HIMCC Update(HIMCC current_handle,
8585 const mozc::commands::Output &output,
140140 // - hCandInfo
141141 // - hPrivate
142142 // 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
144144 // function will not generate any UI message.
145145 // Returns true if the operation completed successfully.
146146 static bool UpdateContext(HIMC himc, const InputState &next_state,
154154 STDMETHODIMP QueryInterfaceBase(REFIID guid, void** object);
155155
156156 // 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.
158158 ImeLangBarMenuData* menu_data(size_t i);
159159
160160 // Returns the size of the language bar menu.
4747 class TipCompositionUtil {
4848 public:
4949 // 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.
5151 static ATL::CComPtr<ITfCompositionView> GetComposition(
5252 ATL::CComPtr<ITfContext> context, TfEditCookie edit_cookie);
5353
167167 void SetDescription(const std::wstring &description);
168168
169169 // 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.
171171 TipLangBarMenuData *menu_data(size_t i);
172172
173173 // Returns the size of the language bar menu.
186186 }
187187
188188 CComQIPtr<ITfInputScope> input_scope = variant.punkVal;
189 InputScope *input_scopes_buffer = NULL;
189 InputScope *input_scopes_buffer = nullptr;
190190 UINT num_input_scopes = 0;
191191 result = input_scope->GetInputScopes(&input_scopes_buffer, &num_input_scopes);
192192 if (FAILED(result)) {
428428 }
429429 return ::DefWindowProcW(window_handle, message, wparam, lparam);
430430 case WM_SETCURSOR:
431 ::SetCursor(::LoadCursor(NULL, IDC_ARROW));
431 ::SetCursor(::LoadCursor(nullptr, IDC_ARROW));
432432 return 0;
433433 default:
434434 return ::DefWindowProcW(window_handle, message, wparam, lparam);