18bf80f4bSopenharmony_ci/*
28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License.
58bf80f4bSopenharmony_ci * You may obtain a copy of the License at
68bf80f4bSopenharmony_ci *
78bf80f4bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88bf80f4bSopenharmony_ci *
98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and
138bf80f4bSopenharmony_ci * limitations under the License.
148bf80f4bSopenharmony_ci */
158bf80f4bSopenharmony_ci#include "call_context.h"
168bf80f4bSopenharmony_ci
178bf80f4bSopenharmony_ciMETA_BEGIN_NAMESPACE()
188bf80f4bSopenharmony_ci
198bf80f4bSopenharmony_ciDefaultCallContext::~DefaultCallContext() = default;
208bf80f4bSopenharmony_ci
218bf80f4bSopenharmony_ciDefaultCallContext::DefaultCallContext() = default;
228bf80f4bSopenharmony_ci
238bf80f4bSopenharmony_ciDefaultCallContext::DefaultCallContext(const DefaultCallContext& other) noexcept : succeeded_(other.succeeded_)
248bf80f4bSopenharmony_ci{
258bf80f4bSopenharmony_ci    if (auto p = interface_cast<ICloneable>(other.result_)) {
268bf80f4bSopenharmony_ci        result_ = interface_pointer_cast<IAny>(p->GetClone());
278bf80f4bSopenharmony_ci    }
288bf80f4bSopenharmony_ci    params_.resize(other.params_.size());
298bf80f4bSopenharmony_ci    for (int i = 0; i != params_.size(); ++i) {
308bf80f4bSopenharmony_ci        params_[i].name = other.params_[i].name;
318bf80f4bSopenharmony_ci        if (auto p = interface_cast<ICloneable>(other.params_[i].value)) {
328bf80f4bSopenharmony_ci            params_[i].value = interface_pointer_cast<IAny>(p->GetClone());
338bf80f4bSopenharmony_ci        }
348bf80f4bSopenharmony_ci    }
358bf80f4bSopenharmony_ci}
368bf80f4bSopenharmony_ci
378bf80f4bSopenharmony_ciDefaultCallContext::DefaultCallContext(DefaultCallContext&& other) noexcept
388bf80f4bSopenharmony_ci    : params_(std::move(other.params_)), succeeded_(other.succeeded_), result_(std::move(other.result_))
398bf80f4bSopenharmony_ci{}
408bf80f4bSopenharmony_ci
418bf80f4bSopenharmony_ciDefaultCallContext& DefaultCallContext::operator=(const DefaultCallContext& other) noexcept
428bf80f4bSopenharmony_ci{
438bf80f4bSopenharmony_ci    if (&other == this) {
448bf80f4bSopenharmony_ci        return *this;
458bf80f4bSopenharmony_ci    }
468bf80f4bSopenharmony_ci    if (auto p = interface_cast<ICloneable>(other.result_)) {
478bf80f4bSopenharmony_ci        result_ = interface_pointer_cast<IAny>(p->GetClone());
488bf80f4bSopenharmony_ci    } else {
498bf80f4bSopenharmony_ci        result_.reset();
508bf80f4bSopenharmony_ci    }
518bf80f4bSopenharmony_ci    params_.clear();
528bf80f4bSopenharmony_ci    params_.resize(other.params_.size());
538bf80f4bSopenharmony_ci    for (int i = 0; i != params_.size(); ++i) {
548bf80f4bSopenharmony_ci        params_[i].name = other.params_[i].name;
558bf80f4bSopenharmony_ci        if (auto p = interface_cast<ICloneable>(other.params_[i].value)) {
568bf80f4bSopenharmony_ci            params_[i].value = interface_pointer_cast<IAny>(p->GetClone());
578bf80f4bSopenharmony_ci        }
588bf80f4bSopenharmony_ci    }
598bf80f4bSopenharmony_ci    return *this;
608bf80f4bSopenharmony_ci}
618bf80f4bSopenharmony_ci
628bf80f4bSopenharmony_ciDefaultCallContext& DefaultCallContext::operator=(DefaultCallContext&& other) noexcept
638bf80f4bSopenharmony_ci{
648bf80f4bSopenharmony_ci    if (&other == this) {
658bf80f4bSopenharmony_ci        return *this;
668bf80f4bSopenharmony_ci    }
678bf80f4bSopenharmony_ci    result_ = std::move(other.result_);
688bf80f4bSopenharmony_ci    params_ = std::move(other.params_);
698bf80f4bSopenharmony_ci    return *this;
708bf80f4bSopenharmony_ci}
718bf80f4bSopenharmony_ci
728bf80f4bSopenharmony_ciconst CORE_NS::IInterface* DefaultCallContext::GetInterface(const BASE_NS::Uid& uid) const
738bf80f4bSopenharmony_ci{
748bf80f4bSopenharmony_ci    if (uid == CORE_NS::IInterface::UID || uid == ICallContext::UID) {
758bf80f4bSopenharmony_ci        return static_cast<const ICallContext*>(this);
768bf80f4bSopenharmony_ci    }
778bf80f4bSopenharmony_ci    if (uid == ICloneable::UID) {
788bf80f4bSopenharmony_ci        return static_cast<const ICloneable*>(this);
798bf80f4bSopenharmony_ci    }
808bf80f4bSopenharmony_ci    return nullptr;
818bf80f4bSopenharmony_ci}
828bf80f4bSopenharmony_ci
838bf80f4bSopenharmony_ciCORE_NS::IInterface* DefaultCallContext::GetInterface(const BASE_NS::Uid& uid)
848bf80f4bSopenharmony_ci{
858bf80f4bSopenharmony_ci    const auto* me = this;
868bf80f4bSopenharmony_ci    return const_cast<CORE_NS::IInterface*>(me->DefaultCallContext::GetInterface(uid));
878bf80f4bSopenharmony_ci}
888bf80f4bSopenharmony_ci
898bf80f4bSopenharmony_ciBASE_NS::shared_ptr<CORE_NS::IInterface> DefaultCallContext::GetClone() const
908bf80f4bSopenharmony_ci{
918bf80f4bSopenharmony_ci    BASE_NS::shared_ptr<DefaultCallContext> p(new DefaultCallContext(*this));
928bf80f4bSopenharmony_ci    return interface_pointer_cast<CORE_NS::IInterface>(p);
938bf80f4bSopenharmony_ci}
948bf80f4bSopenharmony_ci
958bf80f4bSopenharmony_cibool DefaultCallContext::DefineParameter(BASE_NS::string_view name, const IAny::Ptr& value)
968bf80f4bSopenharmony_ci{
978bf80f4bSopenharmony_ci    if (!name.empty() && Get(name)) {
988bf80f4bSopenharmony_ci        return false;
998bf80f4bSopenharmony_ci    }
1008bf80f4bSopenharmony_ci    params_.push_back(ArgumentNameValue { BASE_NS::string(name), value });
1018bf80f4bSopenharmony_ci    return true;
1028bf80f4bSopenharmony_ci}
1038bf80f4bSopenharmony_ci
1048bf80f4bSopenharmony_cibool DefaultCallContext::Set(BASE_NS::string_view name, const IAny& value)
1058bf80f4bSopenharmony_ci{
1068bf80f4bSopenharmony_ci    for (auto&& v : params_) {
1078bf80f4bSopenharmony_ci        if (v.name == name) {
1088bf80f4bSopenharmony_ci            return v.value->CopyFrom(value);
1098bf80f4bSopenharmony_ci        }
1108bf80f4bSopenharmony_ci    }
1118bf80f4bSopenharmony_ci    return false;
1128bf80f4bSopenharmony_ci}
1138bf80f4bSopenharmony_ci
1148bf80f4bSopenharmony_ciIAny::Ptr DefaultCallContext::Get(BASE_NS::string_view name) const
1158bf80f4bSopenharmony_ci{
1168bf80f4bSopenharmony_ci    if (!name.empty()) {
1178bf80f4bSopenharmony_ci        for (auto&& v : params_) {
1188bf80f4bSopenharmony_ci            if (v.name == name) {
1198bf80f4bSopenharmony_ci                return v.value;
1208bf80f4bSopenharmony_ci            }
1218bf80f4bSopenharmony_ci        }
1228bf80f4bSopenharmony_ci    }
1238bf80f4bSopenharmony_ci    return nullptr;
1248bf80f4bSopenharmony_ci}
1258bf80f4bSopenharmony_ci
1268bf80f4bSopenharmony_ciBASE_NS::array_view<const ArgumentNameValue> DefaultCallContext::GetParameters() const
1278bf80f4bSopenharmony_ci{
1288bf80f4bSopenharmony_ci    return params_;
1298bf80f4bSopenharmony_ci}
1308bf80f4bSopenharmony_ci
1318bf80f4bSopenharmony_cibool DefaultCallContext::Succeeded() const
1328bf80f4bSopenharmony_ci{
1338bf80f4bSopenharmony_ci    return succeeded_;
1348bf80f4bSopenharmony_ci}
1358bf80f4bSopenharmony_ci
1368bf80f4bSopenharmony_cibool DefaultCallContext::DefineResult(const IAny::Ptr& value)
1378bf80f4bSopenharmony_ci{
1388bf80f4bSopenharmony_ci    result_ = value;
1398bf80f4bSopenharmony_ci    return true;
1408bf80f4bSopenharmony_ci}
1418bf80f4bSopenharmony_ci
1428bf80f4bSopenharmony_cibool DefaultCallContext::SetResult(const IAny& value)
1438bf80f4bSopenharmony_ci{
1448bf80f4bSopenharmony_ci    succeeded_ = result_ && result_->CopyFrom(value);
1458bf80f4bSopenharmony_ci    if (!succeeded_) {
1468bf80f4bSopenharmony_ci        ReportError("Invalid return type for meta function call");
1478bf80f4bSopenharmony_ci    }
1488bf80f4bSopenharmony_ci    return succeeded_;
1498bf80f4bSopenharmony_ci}
1508bf80f4bSopenharmony_ci
1518bf80f4bSopenharmony_cibool DefaultCallContext::SetResult()
1528bf80f4bSopenharmony_ci{
1538bf80f4bSopenharmony_ci    // null for void, or otherwise return type
1548bf80f4bSopenharmony_ci    succeeded_ = !result_;
1558bf80f4bSopenharmony_ci    if (!succeeded_) {
1568bf80f4bSopenharmony_ci        ReportError("Invalid return type for meta function call");
1578bf80f4bSopenharmony_ci    }
1588bf80f4bSopenharmony_ci    return succeeded_;
1598bf80f4bSopenharmony_ci}
1608bf80f4bSopenharmony_ci
1618bf80f4bSopenharmony_ciIAny::Ptr DefaultCallContext::GetResult() const
1628bf80f4bSopenharmony_ci{
1638bf80f4bSopenharmony_ci    return result_;
1648bf80f4bSopenharmony_ci}
1658bf80f4bSopenharmony_ci
1668bf80f4bSopenharmony_civoid DefaultCallContext::Reset()
1678bf80f4bSopenharmony_ci{
1688bf80f4bSopenharmony_ci    succeeded_ = false;
1698bf80f4bSopenharmony_ci}
1708bf80f4bSopenharmony_ci
1718bf80f4bSopenharmony_civoid DefaultCallContext::ReportError(BASE_NS::string_view error)
1728bf80f4bSopenharmony_ci{
1738bf80f4bSopenharmony_ci    // make sure it is null terminated
1748bf80f4bSopenharmony_ci    CORE_LOG_W("Call context error: %s", BASE_NS::string(error).c_str());
1758bf80f4bSopenharmony_ci}
1768bf80f4bSopenharmony_ci
1778bf80f4bSopenharmony_ciMETA_END_NAMESPACE()
178