|  | // Copyright 2020 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 "lookup.h" | 
|  |  | 
|  | #include <lib/fit/result.h> | 
|  |  | 
|  | #include <memory> | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | namespace intl { | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | std::vector<char*> AsCStrings(const std::vector<std::string>& strings) { | 
|  | std::vector<char*> cstrings; | 
|  | cstrings.reserve(strings.size()); | 
|  | for (const auto& id : strings) { | 
|  | cstrings.push_back(const_cast<char*>(id.c_str())); | 
|  | } | 
|  | return cstrings; | 
|  | } | 
|  |  | 
|  | }  // namespace | 
|  |  | 
|  | fit::result<std::unique_ptr<Lookup>, Lookup::Status> Lookup::NewForTest( | 
|  | const std::vector<std::string>& locale_ids) { | 
|  | return Lookup::NewForTest(locale_ids, intl_lookup_ops_t{ | 
|  | .op_new = intl_lookup_new_fake_for_test, | 
|  | .op_delete = intl_lookup_delete_fake_for_test, | 
|  | .op_string = intl_lookup_string_fake_for_test, | 
|  | }); | 
|  | } | 
|  |  | 
|  | fit::result<std::unique_ptr<Lookup>, Lookup::Status> Lookup::NewForTest( | 
|  | const std::vector<std::string>& locale_ids, intl_lookup_ops_t ops) { | 
|  | auto status = Lookup::Status::OK; | 
|  | std::vector<char*> cstrings = AsCStrings(locale_ids); | 
|  | auto* raw_lookup = | 
|  | ops.op_new(locale_ids.size(), &cstrings[0], reinterpret_cast<int8_t*>(&status)); | 
|  | if (status != Lookup::Status::OK) { | 
|  | return fit::error(status); | 
|  | } | 
|  | // make_unique does not work here since Lookup constructor is private. | 
|  | std::unique_ptr<Lookup> impl(new Lookup(raw_lookup, ops)); | 
|  | return fit::ok(std::move(impl)); | 
|  | } | 
|  |  | 
|  | fit::result<std::unique_ptr<Lookup>, Lookup::Status> Lookup::New( | 
|  | const std::vector<std::string>& locale_ids) { | 
|  | return Lookup::NewForTest(locale_ids, intl_lookup_ops_t{ | 
|  | .op_new = intl_lookup_new, | 
|  | .op_delete = intl_lookup_delete, | 
|  | .op_string = intl_lookup_string, | 
|  | }); | 
|  | } | 
|  |  | 
|  | Lookup::Lookup(intl_lookup_t* impl, intl_lookup_ops_t ops_for_test) | 
|  | : ops_(ops_for_test), impl_(impl) {} | 
|  |  | 
|  | Lookup::~Lookup() { | 
|  | ops_.op_delete(impl_); | 
|  | impl_ = nullptr; | 
|  | } | 
|  |  | 
|  | fit::result<std::string_view, Lookup::Status> Lookup::String(uint64_t message_id) { | 
|  | auto status = Lookup::Status::OK; | 
|  | char* result = ops_.op_string(impl_, message_id, reinterpret_cast<int8_t*>(&status)); | 
|  | if (status != Lookup::Status::OK) { | 
|  | return fit::error(status); | 
|  | } | 
|  | return fit::ok(std::string_view(result)); | 
|  | } | 
|  |  | 
|  | };  // namespace intl |