| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <iostream> |
| |
| #include "fuchsia/examples/intl/wisdom/cpp/fidl.h" |
| #include "intl_wisdom_client.h" |
| #include "lib/async-loop/cpp/loop.h" |
| #include "lib/async/default.h" |
| #include "lib/component/cpp/startup_context.h" |
| #include "lib/fxl/command_line.h" |
| #include "lib/icu_data/cpp/icu_data.h" |
| #include "lib/svc/cpp/services.h" |
| #include "lib/zx/process.h" |
| #include "third_party/icu/source/common/unicode/unistr.h" |
| #include "third_party/icu/source/i18n/unicode/gregocal.h" |
| #include "third_party/icu/source/i18n/unicode/smpdtfmt.h" |
| #include "zircon/processargs.h" |
| |
| using icu::GregorianCalendar; |
| using icu::ParsePosition; |
| using icu::SimpleDateFormat; |
| using icu::TimeZone; |
| using icu::UnicodeString; |
| |
| // The default is an arbitrary afternoon in October. |
| constexpr char kDefaultTimeString[] = "2018-10-30T15:30:00-07:00"; |
| constexpr char kDefaultTimeZoneString[] = "Etc/Unknown"; |
| |
| std::unique_ptr<TimeZone> ParseOrGetDefaultTimeZone( |
| const std::string& time_zone_id) { |
| auto time_zone = std::unique_ptr<TimeZone>( |
| TimeZone::createTimeZone(UnicodeString::fromUTF8(time_zone_id))); |
| if (TimeZone::getUnknown() == *time_zone) { |
| time_zone = std::unique_ptr<TimeZone>(TimeZone::detectHostTimeZone()); |
| } |
| return time_zone; |
| } |
| |
| zx::time ParseTimestamp(const std::string& time_string) { |
| UnicodeString time_string_unic = UnicodeString::fromUTF8(time_string); |
| |
| UErrorCode error_code = U_ZERO_ERROR; |
| SimpleDateFormat time_parser(UnicodeString("yyyy-MM-dd'T'HH:mm:ssXX"), |
| error_code); |
| ZX_ASSERT(U_SUCCESS(error_code)); |
| |
| // Uses the system time zone |
| GregorianCalendar calendar(error_code); |
| ZX_ASSERT(U_SUCCESS(error_code)); |
| |
| ParsePosition parse_position; |
| time_parser.parse(time_string_unic, calendar, parse_position); |
| UDate parsed_time = calendar.getTime(error_code); |
| |
| if (U_FAILURE(error_code) || parse_position.getErrorIndex() != -1) { |
| ZX_PANIC("Failed to parse '%s'", time_string.c_str()); |
| } |
| |
| zx::time timestamp(static_cast<zx_time_t>(parsed_time)); |
| return timestamp; |
| } |
| |
| int main(int argc, const char** argv) { |
| const auto command_line = fxl::CommandLineFromArgcArgv(argc, argv); |
| const std::string server_url = command_line.GetOptionValueWithDefault( |
| "server", |
| "fuchsia-pkg://fuchsia.com/intl_wisdom#meta/intl_wisdom_server.cmx"); |
| const std::string time_string = |
| command_line.GetOptionValueWithDefault("timestamp", kDefaultTimeString); |
| const std::string time_zone_id = command_line.GetOptionValueWithDefault( |
| "timezone", kDefaultTimeZoneString); |
| |
| // We need to initialize ICU data in order to be able to parse |time_string|. |
| ZX_ASSERT(icu_data::Initialize(nullptr, nullptr)); |
| |
| zx::time timestamp = ParseTimestamp(time_string); |
| auto time_zone = ParseOrGetDefaultTimeZone(time_zone_id); |
| |
| async::Loop loop(&kAsyncLoopConfigAttachToThread); |
| intl_wisdom::IntlWisdomClient client( |
| component::StartupContext::CreateFromStartupInfo()); |
| client.Start(server_url); |
| client.SendRequest(timestamp, *time_zone, [&loop](fidl::StringPtr response) { |
| printf("Response:\n%s\n", response->data()); |
| loop.Quit(); |
| }); |
| |
| loop.Run(); |
| return 0; |
| } |