/* * Copyright (c) 2021-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "distributed_want_params.h" #include "array_wrapper.h" #include "base_interfaces.h" #include "base_obj.h" #include "bool_wrapper.h" #include "byte_wrapper.h" #include "distributed_want_params_wrapper.h" #include "double_wrapper.h" #include "dtbschedmgr_log.h" #include "float_wrapper.h" #include "int_wrapper.h" #include "long_wrapper.h" #include "parcel.h" #include "securec.h" #include "short_wrapper.h" #include "string_ex.h" #include "string_wrapper.h" #include "want_params_wrapper.h" #include "zchar_wrapper.h" #include "remote_object_wrapper.h" namespace OHOS { namespace DistributedSchedule { namespace { const char* FD = "FD"; const char* REMOTE_OBJECT = "RemoteObject"; const char* TYPE_PROPERTY = "type"; const char* VALUE_PROPERTY = "value"; const std::string TAG = "DistributedUnsupportedData"; } std::map DistributedWantParams::interfaceQueryToStrMap = { std::map::value_type( DistributedWantParams::VALUE_TYPE_BOOLEAN, &DistributedWantParams::BooleanQueryToStr), std::map::value_type( DistributedWantParams::VALUE_TYPE_BYTE, &DistributedWantParams::ByteQueryToStr), std::map::value_type( DistributedWantParams::VALUE_TYPE_CHAR, &DistributedWantParams::CharQueryToStr), std::map::value_type( DistributedWantParams::VALUE_TYPE_SHORT, &DistributedWantParams::ShortQueryToStr), std::map::value_type( DistributedWantParams::VALUE_TYPE_INT, &DistributedWantParams::IntegerQueryToStr), std::map::value_type( DistributedWantParams::VALUE_TYPE_LONG, &DistributedWantParams::LongQueryToStr), std::map::value_type( DistributedWantParams::VALUE_TYPE_FLOAT, &DistributedWantParams::FloatQueryToStr), std::map::value_type( DistributedWantParams::VALUE_TYPE_DOUBLE, &DistributedWantParams::DoubleQueryToStr), std::map::value_type( DistributedWantParams::VALUE_TYPE_STRING, &DistributedWantParams::StringQueryToStr), std::map::value_type( DistributedWantParams::VALUE_TYPE_ARRAY, &DistributedWantParams::ArrayQueryToStr), std::map::value_type( DistributedWantParams::VALUE_TYPE_WANTPARAMS, &DistributedWantParams::DistributedWantParamsQueryToStr), }; std::map DistributedWantParams::interfaceQueryEqualsMap = { std::map::value_type( DistributedWantParams::VALUE_TYPE_BOOLEAN, &DistributedWantParams::BooleanQueryEquals), std::map::value_type( DistributedWantParams::VALUE_TYPE_BYTE, &DistributedWantParams::ByteQueryEquals), std::map::value_type( DistributedWantParams::VALUE_TYPE_CHAR, &DistributedWantParams::CharQueryEquals), std::map::value_type( DistributedWantParams::VALUE_TYPE_STRING, &DistributedWantParams::StringQueryEquals), std::map::value_type( DistributedWantParams::VALUE_TYPE_ARRAY, &DistributedWantParams::ArrayQueryEquals), std::map::value_type( DistributedWantParams::VALUE_TYPE_WANTPARAMS, &DistributedWantParams::DistributedWantParamsQueryEquals), std::map::value_type( DistributedWantParams::VALUE_TYPE_SHORT, &DistributedWantParams::ShortQueryEquals), std::map::value_type( DistributedWantParams::VALUE_TYPE_INT, &DistributedWantParams::IntegerQueryEquals), std::map::value_type( DistributedWantParams::VALUE_TYPE_LONG, &DistributedWantParams::LongQueryEquals), std::map::value_type( DistributedWantParams::VALUE_TYPE_FLOAT, &DistributedWantParams::FloatQueryEquals), std::map::value_type( DistributedWantParams::VALUE_TYPE_DOUBLE, &DistributedWantParams::DoubleQueryEquals), }; DistributedUnsupportedData::~DistributedUnsupportedData() { if (buffer != nullptr) { delete[] buffer; buffer = nullptr; } } DistributedUnsupportedData::DistributedUnsupportedData() = default; DistributedUnsupportedData::DistributedUnsupportedData(const DistributedUnsupportedData& other) : key(other.key), type(other.type), size(other.size) { buffer = new uint8_t[size]; int32_t ret = memcpy_s(buffer, size, other.buffer, size); if (ret != EOK) { HILOGE("memory copy failed, ret %{public}d", ret); key.clear(); type = 0; size = 0; delete[] buffer; buffer = nullptr; } } DistributedUnsupportedData::DistributedUnsupportedData(DistributedUnsupportedData&& other) : key(std::move(other.key)), type(other.type), size(other.size), buffer(other.buffer) { other.type = 0; other.size = 0; other.buffer = nullptr; } DistributedUnsupportedData& DistributedUnsupportedData::operator=(const DistributedUnsupportedData& other) { if (this == &other) { return *this; } key = other.key; type = other.type; size = other.size; buffer = new uint8_t[size]; int32_t ret = memcpy_s(buffer, size, other.buffer, size); if (ret != EOK) { HILOGE("memory copy failed, ret %{public}d", ret); key.clear(); type = 0; size = 0; delete[] buffer; buffer = nullptr; } return *this; } DistributedUnsupportedData& DistributedUnsupportedData::operator=(DistributedUnsupportedData&& other) { key = std::move(other.key); type = other.type; size = other.size; std::swap(buffer, other.buffer); other.type = 0; other.size = 0; if (other.buffer) { delete[] other.buffer; other.buffer = nullptr; } return *this; } std::string DistributedWantParams::BooleanQueryToStr(const sptr iIt) { AAFwk::IBoolean* obj = AAFwk::IBoolean::Query(iIt); return obj == nullptr ? "" : static_cast(obj)->ToString(); } std::string DistributedWantParams::ByteQueryToStr(const sptr iIt) { AAFwk::IByte* obj = AAFwk::IByte::Query(iIt); return obj == nullptr ? "" : static_cast(obj)->ToString(); } std::string DistributedWantParams::CharQueryToStr(const sptr iIt) { AAFwk::IChar* obj = AAFwk::IChar::Query(iIt); return obj == nullptr ? "" : static_cast(obj)->ToString(); } std::string DistributedWantParams::ShortQueryToStr(const sptr iIt) { AAFwk::IShort* obj = AAFwk::IShort::Query(iIt); return obj == nullptr ? "" : static_cast(obj)->ToString(); } std::string DistributedWantParams::IntegerQueryToStr(const sptr iIt) { AAFwk::IInteger* obj = AAFwk::IInteger::Query(iIt); return obj == nullptr ? "" : static_cast(obj)->ToString(); } std::string DistributedWantParams::LongQueryToStr(const sptr iIt) { AAFwk::ILong* obj = AAFwk::ILong::Query(iIt); return obj == nullptr ? "" : static_cast(obj)->ToString(); } std::string DistributedWantParams::FloatQueryToStr(const sptr iIt) { AAFwk::IFloat* obj = AAFwk::IFloat::Query(iIt); return obj == nullptr ? "" : static_cast(obj)->ToString(); } std::string DistributedWantParams::DoubleQueryToStr(const sptr iIt) { AAFwk::IDouble* obj = AAFwk::IDouble::Query(iIt); return obj == nullptr ? "" : static_cast(obj)->ToString(); } std::string DistributedWantParams::StringQueryToStr(const sptr iIt) { AAFwk::IString* obj = AAFwk::IString::Query(iIt); return obj == nullptr ? "" : static_cast(obj)->ToString(); } std::string DistributedWantParams::ArrayQueryToStr(const sptr iIt) { AAFwk::IArray* obj = AAFwk::IArray::Query(iIt); return obj == nullptr ? "" : static_cast(obj)->ToString(); } std::string DistributedWantParams::DistributedWantParamsQueryToStr(const sptr iIt) { IDistributedWantParams* obj = IDistributedWantParams::Query(iIt); return obj == nullptr ? "" : static_cast(obj)->ToString(); } bool DistributedWantParams::BooleanQueryEquals(const sptr iIt) { AAFwk::IBoolean* obj = AAFwk::IBoolean::Query(iIt); return obj == nullptr ? false : static_cast(obj)->Equals(*static_cast(obj)); } bool DistributedWantParams::ByteQueryEquals(const sptr iIt) { AAFwk::IByte* obj = AAFwk::IByte::Query(iIt); return obj == nullptr ? false : static_cast(obj)->Equals(*static_cast(obj)); } bool DistributedWantParams::CharQueryEquals(const sptr iIt) { AAFwk::IChar* obj = AAFwk::IChar::Query(iIt); return obj == nullptr ? false : static_cast(obj)->Equals(*static_cast(obj)); } bool DistributedWantParams::StringQueryEquals(const sptr iIt) { AAFwk::IString* obj = AAFwk::IString::Query(iIt); return obj == nullptr ? false : static_cast(obj)->Equals(*static_cast(obj)); } bool DistributedWantParams::ArrayQueryEquals(const sptr iIt) { AAFwk::IArray* obj = AAFwk::IArray::Query(iIt); return obj == nullptr ? false : static_cast(obj)->Equals(*static_cast(obj)); } bool DistributedWantParams::DistributedWantParamsQueryEquals(const sptr iIt) { IDistributedWantParams* obj = IDistributedWantParams::Query(iIt); return obj == nullptr ? false : static_cast(obj) ->Equals(*static_cast(obj)); } bool DistributedWantParams::ShortQueryEquals(const sptr iIt) { AAFwk::IShort* obj = AAFwk::IShort::Query(iIt); return obj == nullptr ? false : static_cast(obj)->Equals(*static_cast(obj)); } bool DistributedWantParams::IntegerQueryEquals(const sptr iIt) { AAFwk::IInteger* obj = AAFwk::IInteger::Query(iIt); return obj == nullptr ? false : static_cast(obj)->Equals(*static_cast(obj)); } bool DistributedWantParams::LongQueryEquals(const sptr iIt) { AAFwk::ILong* obj = AAFwk::ILong::Query(iIt); return obj == nullptr ? false : static_cast(obj)->Equals(*static_cast(obj)); } bool DistributedWantParams::FloatQueryEquals(const sptr iIt) { AAFwk::IFloat* obj = AAFwk::IFloat::Query(iIt); return obj == nullptr ? false : static_cast(obj)->Equals(*static_cast(obj)); } bool DistributedWantParams::DoubleQueryEquals(const sptr iIt) { AAFwk::IDouble* obj = AAFwk::IDouble::Query(iIt); return obj == nullptr ? false : static_cast(obj)->Equals(*static_cast(obj)); } std::string DistributedWantParams::GetStringByType(const sptr iIt, int typeId) { auto iter = interfaceQueryToStrMap.find(typeId); if (iter != interfaceQueryToStrMap.end()) { DistributedWantParams::InterfaceQueryToStrFunc &func = iter->second; return (*func)(iIt); } return ""; } template static void SetNewArray(const AAFwk::InterfaceID& id, AAFwk::IArray* orgIArray, sptr& ao); DistributedWantParams::DistributedWantParams(const DistributedWantParams& wantParams) { params_.clear(); NewParams(wantParams, *this); } // inner use function bool DistributedWantParams::NewParams(const DistributedWantParams& source, DistributedWantParams& dest) { // Deep copy for (auto it = source.params_.begin(); it != source.params_.end(); it++) { sptr o = it->second; if (AAFwk::IString::Query(o) != nullptr) { dest.params_[it->first] = AAFwk::String::Box(AAFwk::String::Unbox(AAFwk::IString::Query(o))); } else if (AAFwk::IBoolean::Query(o) != nullptr) { dest.params_[it->first] = AAFwk::Boolean::Box(AAFwk::Boolean::Unbox(AAFwk::IBoolean::Query(o))); } else if (AAFwk::IByte::Query(o) != nullptr) { dest.params_[it->first] = AAFwk::Byte::Box(AAFwk::Byte::Unbox(AAFwk::IByte::Query(o))); } else if (AAFwk::IChar::Query(o) != nullptr) { dest.params_[it->first] = AAFwk::Char::Box(AAFwk::Char::Unbox(AAFwk::IChar::Query(o))); } else if (AAFwk::IShort::Query(o) != nullptr) { dest.params_[it->first] = AAFwk::Short::Box(AAFwk::Short::Unbox(AAFwk::IShort::Query(o))); } else if (AAFwk::IInteger::Query(o) != nullptr) { dest.params_[it->first] = AAFwk::Integer::Box(AAFwk::Integer::Unbox(AAFwk::IInteger::Query(o))); } else if (AAFwk::ILong::Query(o) != nullptr) { dest.params_[it->first] = AAFwk::Long::Box(AAFwk::Long::Unbox(AAFwk::ILong::Query(o))); } else if (AAFwk::IFloat::Query(o) != nullptr) { dest.params_[it->first] = AAFwk::Float::Box(AAFwk::Float::Unbox(AAFwk::IFloat::Query(o))); } else if (AAFwk::IDouble::Query(o) != nullptr) { dest.params_[it->first] = AAFwk::Double::Box(AAFwk::Double::Unbox(AAFwk::IDouble::Query(o))); } else if (AAFwk::IRemoteObjectWrap::Query(o) != nullptr) { dest.params_[it->first] = AAFwk::RemoteObjectWrap::Box(AAFwk::RemoteObjectWrap::UnBox(AAFwk::IRemoteObjectWrap::Query(o))); } else if (IDistributedWantParams::Query(o) != nullptr) { DistributedWantParams newDest(DistributedWantParamWrapper::Unbox(IDistributedWantParams::Query(o))); dest.params_[it->first] = DistributedWantParamWrapper::Box(newDest); } else if (AAFwk::IArray::Query(o) != nullptr) { sptr destAO = nullptr; if (!NewArrayData(AAFwk::IArray::Query(o), destAO)) { continue; } dest.params_[it->first] = destAO; } } return true; } bool DistributedWantParams::NewArrayData(AAFwk::IArray* source, sptr& dest) { if (AAFwk::Array::IsBooleanArray(source)) { SetNewArray(AAFwk::g_IID_IBoolean, source, dest); } else if (AAFwk::Array::IsCharArray(source)) { SetNewArray(AAFwk::g_IID_IChar, source, dest); } else if (AAFwk::Array::IsByteArray(source)) { SetNewArray(AAFwk::g_IID_IByte, source, dest); } else if (AAFwk::Array::IsShortArray(source)) { SetNewArray(AAFwk::g_IID_IShort, source, dest); } else if (AAFwk::Array::IsIntegerArray(source)) { SetNewArray(AAFwk::g_IID_IInteger, source, dest); } else if (AAFwk::Array::IsLongArray(source)) { SetNewArray(AAFwk::g_IID_ILong, source, dest); } else if (AAFwk::Array::IsFloatArray(source)) { SetNewArray(AAFwk::g_IID_IFloat, source, dest); } else if (AAFwk::Array::IsDoubleArray(source)) { SetNewArray(AAFwk::g_IID_IDouble, source, dest); } else if (AAFwk::Array::IsStringArray(source)) { SetNewArray(AAFwk::g_IID_IString, source, dest); } else { return false; } if (dest == nullptr) { return false; } return true; } DistributedWantParams& DistributedWantParams::operator=(const DistributedWantParams& other) { if (this != &other) { params_.clear(); NewParams(other, *this); } return *this; } bool DistributedWantParams::operator==(const DistributedWantParams& other) { if (this->params_.size() != other.params_.size()) { return false; } for (auto itthis : this->params_) { auto itother = other.params_.find(itthis.first); if (itother == other.params_.end()) { return false; } if (!CompareInterface(itother->second, itthis.second, DistributedWantParams::GetDataType(itother->second))) { return false; } } return true; } int DistributedWantParams::GetDataType(const sptr iIt) { if (iIt != nullptr && AAFwk::IBoolean::Query(iIt) != nullptr) { return VALUE_TYPE_BOOLEAN; } else if (iIt != nullptr && AAFwk::IByte::Query(iIt) != nullptr) { return VALUE_TYPE_BYTE; } else if (iIt != nullptr && AAFwk::IChar::Query(iIt) != nullptr) { return VALUE_TYPE_CHAR; } else if (iIt != nullptr && AAFwk::IString::Query(iIt) != nullptr) { return VALUE_TYPE_STRING; } else if (iIt != nullptr && AAFwk::IArray::Query(iIt) != nullptr) { return VALUE_TYPE_ARRAY; } else if (iIt != nullptr && IDistributedWantParams::Query(iIt) != nullptr) { return VALUE_TYPE_WANTPARAMS; } else { return GetNumberDataType(iIt); } } int DistributedWantParams::GetNumberDataType(const sptr iIt) { if (iIt != nullptr && AAFwk::IShort::Query(iIt) != nullptr) { return VALUE_TYPE_SHORT; } else if (iIt != nullptr && AAFwk::IInteger::Query(iIt) != nullptr) { return VALUE_TYPE_INT; } else if (iIt != nullptr && AAFwk::ILong::Query(iIt) != nullptr) { return VALUE_TYPE_LONG; } else if (iIt != nullptr && AAFwk::IFloat::Query(iIt) != nullptr) { return VALUE_TYPE_FLOAT; } else if (iIt != nullptr && AAFwk::IDouble::Query(iIt) != nullptr) { return VALUE_TYPE_DOUBLE; } return VALUE_TYPE_NULL; } sptr DistributedWantParams::GetInterfaceByType(int typeId, const std::string& value) { if (typeId == VALUE_TYPE_BOOLEAN) { return AAFwk::Boolean::Parse(value); } else if (typeId == VALUE_TYPE_BYTE) { return AAFwk::Byte::Parse(value); } else if (typeId == VALUE_TYPE_CHAR) { return AAFwk::Char::Parse(value); } else if (typeId == VALUE_TYPE_SHORT) { return AAFwk::Short::Parse(value); } else if (typeId == VALUE_TYPE_INT) { return AAFwk::Integer::Parse(value); } else if (typeId == VALUE_TYPE_LONG) { return AAFwk::Long::Parse(value); } else if (typeId == VALUE_TYPE_FLOAT) { return AAFwk::Float::Parse(value); } else if (typeId == VALUE_TYPE_DOUBLE) { return AAFwk::Double::Parse(value); } else if (typeId == VALUE_TYPE_STRING) { return AAFwk::String::Parse(value); } else if (typeId == VALUE_TYPE_ARRAY) { return AAFwk::Array::Parse(value); } return nullptr; } bool DistributedWantParams::CompareInterface(const sptr iIt1, const sptr iIt2, int typeId) { bool flag = false; auto iter = interfaceQueryEqualsMap.find(typeId); if (iter != interfaceQueryEqualsMap.end()) { DistributedWantParams::InterfaceQueryEqualsFunc &func = iter->second; return (*func)(iIt1); } return flag; } void DistributedWantParams::SetParam(const std::string& key, IInterface* value) { params_[key] = value; } sptr DistributedWantParams::GetParam(const std::string& key) const { auto it = params_.find(key); if (it == params_.cend()) { return nullptr; } return it->second; } const std::map>& DistributedWantParams::GetParams() const { return params_; } const std::set DistributedWantParams::KeySet() const { std::set keySet; keySet.clear(); for (auto it : params_) { keySet.emplace(it.first); } return keySet; } void DistributedWantParams::Remove(const std::string& key) { params_.erase(key); } bool DistributedWantParams::HasParam(const std::string& key) const { return (params_.count(key) > 0); } int DistributedWantParams::Size() const { return params_.size(); } bool DistributedWantParams::IsEmpty() const { return (params_.size() == 0); } bool DistributedWantParams::WriteToParcelString(Parcel& parcel, sptr& o) const { std::string value = AAFwk::String::Unbox(AAFwk::IString::Query(o)); if (!parcel.WriteInt32(VALUE_TYPE_STRING)) { return false; } return parcel.WriteString16(Str8ToStr16(value)); } bool DistributedWantParams::WriteToParcelBool(Parcel& parcel, sptr& o) const { bool value = AAFwk::Boolean::Unbox(AAFwk::IBoolean::Query(o)); if (!parcel.WriteInt32(VALUE_TYPE_BOOLEAN)) { return false; } return parcel.WriteInt8(value); } bool DistributedWantParams::WriteToParcelWantParams(Parcel& parcel, sptr& o) const { DistributedWantParams value = DistributedWantParamWrapper::Unbox(IDistributedWantParams::Query(o)); auto dType = value.GetParam(TYPE_PROPERTY); AAFwk::IString *typeP = AAFwk::IString::Query(dType); if (typeP != nullptr) { std::string typeValue = AAFwk::String::Unbox(typeP); if (typeValue == FD) { return WriteToParcelFD(parcel, value); } if (typeValue == REMOTE_OBJECT) { return WriteToParcelRemoteObject(parcel, value); } } if (!parcel.WriteInt32(VALUE_TYPE_WANTPARAMS)) { return false; } auto wantParams = static_cast(IDistributedWantParams::Query(o)); if (wantParams == nullptr) { return false; } return parcel.WriteString16(Str8ToStr16(wantParams->ToString())); } bool DistributedWantParams::WriteToParcelFD(Parcel& parcel, const DistributedWantParams& value) const { if (!parcel.WriteInt32(VALUE_TYPE_FD)) { return false; } auto dFdWrap = value.GetParam(VALUE_PROPERTY); AAFwk::IInteger *fdIWrap = AAFwk::IInteger::Query(dFdWrap); if (fdIWrap != nullptr) { int fd = AAFwk::Integer::Unbox(fdIWrap); auto messageParcel = static_cast(&parcel); if (messageParcel == nullptr) { return false; } bool ret = messageParcel->WriteFileDescriptor(fd); return ret; } return false; } bool DistributedWantParams::WriteToParcelRemoteObject(Parcel& parcel, const DistributedWantParams& value) const { if (!parcel.WriteInt32(VALUE_TYPE_REMOTE_OBJECT)) { return false; } auto remoteObjWrap = value.GetParam(VALUE_PROPERTY); AAFwk::IRemoteObjectWrap *remoteObjectIWrap = AAFwk::IRemoteObjectWrap::Query(remoteObjWrap); if (remoteObjectIWrap != nullptr) { auto remoteObject = AAFwk::RemoteObjectWrap::UnBox(remoteObjectIWrap); auto messageParcel = static_cast(&parcel); if (messageParcel == nullptr) { return false; } bool ret = messageParcel->WriteRemoteObject(remoteObject); return ret; } return false; } bool DistributedWantParams::WriteToParcelByte(Parcel& parcel, sptr& o) const { AAFwk::byte value = AAFwk::Byte::Unbox(AAFwk::IByte::Query(o)); if (!parcel.WriteInt32(VALUE_TYPE_BYTE)) { return false; } return parcel.WriteInt8(value); } bool DistributedWantParams::WriteToParcelChar(Parcel& parcel, sptr& o) const { AAFwk::zchar value = AAFwk::Char::Unbox(AAFwk::IChar::Query(o)); if (!parcel.WriteInt32(VALUE_TYPE_CHAR)) { return false; } return parcel.WriteInt32(value); } bool DistributedWantParams::WriteToParcelShort(Parcel& parcel, sptr& o) const { short value = AAFwk::Short::Unbox(AAFwk::IShort::Query(o)); if (!parcel.WriteInt32(VALUE_TYPE_SHORT)) { return false; } return parcel.WriteInt16(value); } bool DistributedWantParams::WriteToParcelInt(Parcel& parcel, sptr& o) const { int value = AAFwk::Integer::Unbox(AAFwk::IInteger::Query(o)); if (!parcel.WriteInt32(VALUE_TYPE_INT)) { return false; } return parcel.WriteInt32(value); } bool DistributedWantParams::WriteToParcelLong(Parcel& parcel, sptr& o) const { long value = AAFwk::Long::Unbox(AAFwk::ILong::Query(o)); if (!parcel.WriteInt32(VALUE_TYPE_LONG)) { return false; } return parcel.WriteInt64(value); } bool DistributedWantParams::WriteToParcelFloat(Parcel& parcel, sptr& o) const { float value = AAFwk::Float::Unbox(AAFwk::IFloat::Query(o)); if (!parcel.WriteInt32(VALUE_TYPE_FLOAT)) { return false; } return parcel.WriteFloat(value); } bool DistributedWantParams::WriteToParcelDouble(Parcel& parcel, sptr& o) const { double value = AAFwk::Double::Unbox(AAFwk::IDouble::Query(o)); if (!parcel.WriteInt32(VALUE_TYPE_DOUBLE)) { return false; } return parcel.WriteDouble(value); } bool DistributedWantParams::WriteMarshalling(Parcel& parcel, sptr& o) const { if (AAFwk::IString::Query(o) != nullptr) { return WriteToParcelString(parcel, o); } else if (AAFwk::IBoolean::Query(o) != nullptr) { return WriteToParcelBool(parcel, o); } else if (AAFwk::IByte::Query(o) != nullptr) { return WriteToParcelByte(parcel, o); } else if (AAFwk::IChar::Query(o) != nullptr) { return WriteToParcelChar(parcel, o); } else if (AAFwk::IShort::Query(o) != nullptr) { return WriteToParcelShort(parcel, o); } else if (AAFwk::IInteger::Query(o) != nullptr) { return WriteToParcelInt(parcel, o); } else if (AAFwk::ILong::Query(o) != nullptr) { return WriteToParcelLong(parcel, o); } else if (AAFwk::IFloat::Query(o) != nullptr) { return WriteToParcelFloat(parcel, o); } else if (AAFwk::IDouble::Query(o) != nullptr) { return WriteToParcelDouble(parcel, o); } else if (IDistributedWantParams::Query(o) != nullptr) { return WriteToParcelWantParams(parcel, o); } else { AAFwk::IArray* ao = AAFwk::IArray::Query(o); if (ao != nullptr) { sptr array(ao); return WriteArrayToParcel(parcel, array); } else { return true; } } } bool DistributedWantParams::DoMarshalling(Parcel& parcel) const { size_t dSize = params_.size(); if (!cachedUnsupportedData_.empty()) { dSize += cachedUnsupportedData_.size(); } if (!parcel.WriteInt32(dSize)) { return false; } auto iter = params_.cbegin(); while (iter != params_.cend()) { std::string key = iter->first; sptr o = iter->second; if (!parcel.WriteString16(Str8ToStr16(key))) { return false; } if (!WriteMarshalling(parcel, o)) { return false; } iter++; } if (!cachedUnsupportedData_.empty()) { for (const DistributedUnsupportedData& dData : cachedUnsupportedData_) { if (!parcel.WriteString16(dData.key)) { return false; } if (!parcel.WriteInt32(dData.type)) { return false; } if (!parcel.WriteInt32(dData.size)) { return false; } // Corresponding to Parcel#writeByteArray() in Java. if (!parcel.WriteInt32(dData.size)) { return false; } if (!parcel.WriteBuffer(dData.buffer, dData.size)) { return false; } } } return true; } bool DistributedWantParams::Marshalling(Parcel& parcel) const { return DoMarshalling(parcel); } template static bool SetArray(const AAFwk::InterfaceID& id, const std::vector& value, sptr& ao) { typename std::vector::size_type size = value.size(); ao = new (std::nothrow) AAFwk::Array(size, id); if (ao != nullptr) { for (typename std::vector::size_type i = 0; i < size; i++) { ao->Set(i, className::Box(value[i])); } return true; } return false; } template static void FillArray(AAFwk::IArray* ao, std::vector&array) { auto func = [&](AAFwk::IInterface* object) { if (object != nullptr) { T3* value = T3::Query(object); if (value != nullptr) { array.push_back(T2::Unbox(value)); } } }; AAFwk::Array::ForEach(ao, func); } // inner use template function template static void SetNewArray(const AAFwk::InterfaceID& id, AAFwk::IArray* orgIArray, sptr& ao) { if (orgIArray == nullptr) { return; } std::vector dArray; auto func = [&dArray](AAFwk::IInterface* object) { if (object != nullptr) { T3* value = T3::Query(object); if (value != nullptr) { dArray.push_back(T2::Unbox(value)); } } }; AAFwk::Array::ForEach(orgIArray, func); typename std::vector::size_type size = dArray.size(); if (size > 0) { ao = new (std::nothrow) AAFwk::Array(size, id); if (ao != nullptr) { for (typename std::vector::size_type i = 0; i < size; i++) { ao->Set(i, T2::Box(dArray[i])); } } } } bool DistributedWantParams::WriteArrayToParcelString(Parcel& parcel, AAFwk::IArray* ao) const { if (ao == nullptr) { return false; } std::vector array; auto func = [&](IInterface* object) { std::string s = AAFwk::String::Unbox(AAFwk::IString::Query(object)); array.push_back(Str8ToStr16(s)); }; AAFwk::Array::ForEach(ao, func); if (!parcel.WriteInt32(VALUE_TYPE_STRINGARRAY)) { return false; } return parcel.WriteString16Vector(array); } bool DistributedWantParams::WriteArrayToParcelBool(Parcel& parcel, AAFwk::IArray* ao) const { if (ao == nullptr) { return false; } std::vector array; std::vector intArray; FillArray(ao, array); if (!parcel.WriteInt32(VALUE_TYPE_BOOLEANARRAY)) { return false; } for (std::vector::size_type i = 0; i < array.size(); i++) { intArray.push_back(array[i]); } return parcel.WriteInt32Vector(intArray); } bool DistributedWantParams::WriteArrayToParcelByte(Parcel& parcel, AAFwk::IArray* ao) const { if (ao == nullptr) { return false; } std::vector array; FillArray(ao, array); if (!parcel.WriteInt32(VALUE_TYPE_BYTEARRAY)) { return false; } return parcel.WriteInt8Vector(array); } bool DistributedWantParams::WriteArrayToParcelChar(Parcel& parcel, AAFwk::IArray* ao) const { if (ao == nullptr) { return false; } std::vector array; FillArray(ao, array); if (!parcel.WriteInt32(VALUE_TYPE_CHARARRAY)) { return false; } return parcel.WriteInt32Vector(array); } bool DistributedWantParams::WriteArrayToParcelShort(Parcel& parcel, AAFwk::IArray* ao) const { if (ao == nullptr) { return false; } std::vector array; FillArray(ao, array); if (!parcel.WriteInt32(VALUE_TYPE_SHORTARRAY)) { return false; } return parcel.WriteInt16Vector(array); } bool DistributedWantParams::WriteArrayToParcelInt(Parcel& parcel, AAFwk::IArray* ao) const { if (ao == nullptr) { return false; } std::vector array; FillArray(ao, array); if (!parcel.WriteInt32(VALUE_TYPE_INTARRAY)) { return false; } return parcel.WriteInt32Vector(array); } bool DistributedWantParams::WriteArrayToParcelLong(Parcel& parcel, AAFwk::IArray* ao) const { if (ao == nullptr) { return false; } std::vector array; FillArray(ao, array); if (!parcel.WriteInt32(VALUE_TYPE_LONGARRAY)) { return false; } return parcel.WriteInt64Vector(array); } bool DistributedWantParams::WriteArrayToParcelFloat(Parcel& parcel, AAFwk::IArray* ao) const { if (ao == nullptr) { return false; } std::vector array; FillArray(ao, array); if (!parcel.WriteInt32(VALUE_TYPE_FLOATARRAY)) { return false; } return parcel.WriteFloatVector(array); } bool DistributedWantParams::WriteArrayToParcelDouble(Parcel& parcel, AAFwk::IArray* ao) const { if (ao == nullptr) { return false; } std::vector array; FillArray(ao, array); if (!parcel.WriteInt32(VALUE_TYPE_DOUBLEARRAY)) { return false; } return parcel.WriteDoubleVector(array); } bool DistributedWantParams::WriteArrayToParcel(Parcel& parcel, AAFwk::IArray* ao) const { if (AAFwk::Array::IsStringArray(ao)) { return WriteArrayToParcelString(parcel, ao); } else if (AAFwk::Array::IsBooleanArray(ao)) { return WriteArrayToParcelBool(parcel, ao); } else if (AAFwk::Array::IsByteArray(ao)) { return WriteArrayToParcelByte(parcel, ao); } else if (AAFwk::Array::IsCharArray(ao)) { return WriteArrayToParcelChar(parcel, ao); } else if (AAFwk::Array::IsShortArray(ao)) { return WriteArrayToParcelShort(parcel, ao); } else if (AAFwk::Array::IsIntegerArray(ao)) { return WriteArrayToParcelInt(parcel, ao); } else if (AAFwk::Array::IsLongArray(ao)) { return WriteArrayToParcelLong(parcel, ao); } else if (AAFwk::Array::IsFloatArray(ao)) { return WriteArrayToParcelFloat(parcel, ao); } else if (AAFwk::Array::IsDoubleArray(ao)) { return WriteArrayToParcelDouble(parcel, ao); } else { return true; } } bool DistributedWantParams::ReadFromParcelArrayString(Parcel& parcel, sptr& ao) { std::vector value; if (!parcel.ReadString16Vector(&value)) { return false; } std::vector::size_type size = value.size(); ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IString); if (ao == nullptr) { return false; } if (ao != nullptr) { for (std::vector::size_type i = 0; i < size; i++) { ao->Set(i, AAFwk::String::Box(Str16ToStr8(value[i]))); } return true; } return false; } bool DistributedWantParams::ReadFromParcelArrayBool(Parcel& parcel, sptr& ao) { std::vector value; std::vector boolValue; if (!parcel.ReadInt32Vector(&value)) { return false; } std::vector::size_type size = value.size(); for (std::vector::size_type i = 0; i < size; i++) { boolValue.push_back(value[i]); } return SetArray(AAFwk::g_IID_IBoolean, boolValue, ao); } bool DistributedWantParams::ReadFromParcelArrayByte(Parcel& parcel, sptr& ao) { std::vector value; if (!parcel.ReadInt8Vector(&value)) { return false; } return SetArray(AAFwk::g_IID_IByte, value, ao); } bool DistributedWantParams::ReadFromParcelArrayChar(Parcel& parcel, sptr& ao) { std::vector value; if (!parcel.ReadInt32Vector(&value)) { return false; } return SetArray(AAFwk::g_IID_IChar, value, ao); } bool DistributedWantParams::ReadFromParcelArrayShort(Parcel& parcel, sptr& ao) { std::vector value; if (!parcel.ReadInt16Vector(&value)) { return false; } return SetArray(AAFwk::g_IID_IShort, value, ao); } bool DistributedWantParams::ReadFromParcelArrayInt(Parcel& parcel, sptr& ao) { std::vector value; if (!parcel.ReadInt32Vector(&value)) { return false; } return SetArray(AAFwk::g_IID_IInteger, value, ao); } bool DistributedWantParams::ReadFromParcelArrayLong(Parcel& parcel, sptr& ao) { std::vector value; if (!parcel.ReadInt64Vector(&value)) { return false; } #ifdef WANT_PARAM_USE_LONG return SetArray(g_IID_ILong, value, ao); #else std::vector strList; for (size_t i = 0; i < value.size(); i++) { strList.push_back(std::to_string(value[i])); } return SetArray(AAFwk::g_IID_IString, strList, ao); #endif } bool DistributedWantParams::ReadFromParcelArrayFloat(Parcel& parcel, sptr& ao) { std::vector value; if (!parcel.ReadFloatVector(&value)) { return false; } return SetArray(AAFwk::g_IID_IFloat, value, ao); } bool DistributedWantParams::ReadFromParcelArrayDouble(Parcel& parcel, sptr& ao) { std::vector value; if (!parcel.ReadDoubleVector(&value)) { return false; } return SetArray(AAFwk::g_IID_IDouble, value, ao); } bool DistributedWantParams::ReadArrayToParcel(Parcel& parcel, int type, sptr& ao) { switch (type) { case VALUE_TYPE_STRINGARRAY: case VALUE_TYPE_CHARSEQUENCEARRAY: return ReadFromParcelArrayString(parcel, ao); case VALUE_TYPE_BOOLEANARRAY: return ReadFromParcelArrayBool(parcel, ao); case VALUE_TYPE_BYTEARRAY: return ReadFromParcelArrayByte(parcel, ao); case VALUE_TYPE_CHARARRAY: return ReadFromParcelArrayChar(parcel, ao); case VALUE_TYPE_SHORTARRAY: return ReadFromParcelArrayShort(parcel, ao); case VALUE_TYPE_INTARRAY: return ReadFromParcelArrayInt(parcel, ao); case VALUE_TYPE_LONGARRAY: return ReadFromParcelArrayLong(parcel, ao); case VALUE_TYPE_FLOATARRAY: return ReadFromParcelArrayFloat(parcel, ao); case VALUE_TYPE_DOUBLEARRAY: return ReadFromParcelArrayDouble(parcel, ao); default: break; } return true; } bool DistributedWantParams::ReadFromParcelString(Parcel& parcel, const std::string& key) { std::u16string value = parcel.ReadString16(); std::string strValue(Str16ToStr8(value)); sptr intf = AAFwk::String::Box(Str16ToStr8(value)); if (intf) { SetParam(key, intf); } return true; } bool DistributedWantParams::ReadFromParcelBool(Parcel& parcel, const std::string& key) { int8_t value; if (parcel.ReadInt8(value)) { sptr intf = AAFwk::Boolean::Box(value); if (intf) { SetParam(key, intf); } return true; } else { return false; } } bool DistributedWantParams::ReadFromParcelInt8(Parcel& parcel, const std::string& key) { int8_t value; if (parcel.ReadInt8(value)) { sptr intf = AAFwk::Byte::Box(value); if (intf) { SetParam(key, intf); } return true; } else { return false; } } bool DistributedWantParams::ReadFromParcelChar(Parcel& parcel, const std::string& key) { int32_t value; if (parcel.ReadInt32(value)) { sptr intf = AAFwk::Char::Box(value); if (intf) { SetParam(key, intf); } return true; } else { return false; } } bool DistributedWantParams::ReadFromParcelShort(Parcel& parcel, const std::string& key) { short value; if (parcel.ReadInt16(value)) { sptr intf = AAFwk::Short::Box(value); if (intf) { SetParam(key, intf); } return true; } else { return false; } } bool DistributedWantParams::ReadFromParcelInt(Parcel& parcel, const std::string& key) { int value; if (parcel.ReadInt32(value)) { sptr intf = AAFwk::Integer::Box(value); if (intf) { SetParam(key, intf); } return true; } else { return false; } } bool DistributedWantParams::ReadFromParcelWantParamWrapper(Parcel& parcel, const std::string& key, int type) { if (type == VALUE_TYPE_FD) { return ReadFromParcelFD(parcel, key); } if (type == VALUE_TYPE_REMOTE_OBJECT) { return ReadFromParcelRemoteObject(parcel, key); } std::u16string value = parcel.ReadString16(); sptr intf = DistributedWantParamWrapper::Parse(Str16ToStr8(value)); if (intf) { SetParam(key, intf); } return true; } bool DistributedWantParams::ReadFromParcelFD(Parcel& parcel, const std::string& key) { auto messageParcel = static_cast(&parcel); if (messageParcel == nullptr) { return false; } auto fd = messageParcel->ReadFileDescriptor(); DistributedWantParams wp; wp.SetParam(TYPE_PROPERTY, AAFwk::String::Box(FD)); wp.SetParam(VALUE_PROPERTY, AAFwk::Integer::Box(fd)); sptr pWantParams = DistributedWantParamWrapper::Box(wp); SetParam(key, pWantParams); return true; } bool DistributedWantParams::ReadFromParcelRemoteObject(Parcel& parcel, const std::string& key) { auto messageParcel = static_cast(&parcel); if (messageParcel == nullptr) { return false; } auto remoteObject = messageParcel->ReadRemoteObject(); DistributedWantParams wp; wp.SetParam(TYPE_PROPERTY, AAFwk::String::Box(REMOTE_OBJECT)); wp.SetParam(VALUE_PROPERTY, AAFwk::RemoteObjectWrap::Box(remoteObject)); sptr pWantParams = DistributedWantParamWrapper::Box(wp); SetParam(key, pWantParams); return true; } bool DistributedWantParams::ReadFromParcelLong(Parcel& parcel, const std::string& key) { int64_t value; if (parcel.ReadInt64(value)) { std::string strValue(std::to_string(value)); #ifdef WANT_PARAM_USE_LONG sptr intf = Long::Box(value); #else sptr intf = AAFwk::String::Box(std::to_string(value)); #endif if (intf) { SetParam(key, intf); } return true; } else { return false; } } bool DistributedWantParams::ReadFromParcelFloat(Parcel& parcel, const std::string& key) { float value; if (parcel.ReadFloat(value)) { sptr intf = AAFwk::Float::Box(value); if (intf) { SetParam(key, intf); } return true; } else { return false; } } bool DistributedWantParams::ReadFromParcelDouble(Parcel& parcel, const std::string& key) { double value; if (parcel.ReadDouble(value)) { sptr intf = AAFwk::Double::Box(value); if (intf) { SetParam(key, intf); } return true; } else { return false; } } bool DistributedWantParams::ReadUnsupportedData(Parcel& parcel, const std::string& key, int type) { int bufferSize = 0; if (!parcel.ReadInt32(bufferSize)) { return false; } static constexpr int32_t maxAllowedSize = 100 * 1024 * 1024; if (bufferSize < 0 || bufferSize > maxAllowedSize) { return false; } int32_t length = 0; if (!parcel.ReadInt32(length)) { return false; } const uint8_t* bufferP = parcel.ReadUnpadBuffer(bufferSize); if (bufferP == nullptr) { return false; } DistributedUnsupportedData dData; dData.key = Str8ToStr16(key); dData.type = type; dData.size = bufferSize; dData.buffer = new (std::nothrow) uint8_t[bufferSize]; if (dData.buffer == nullptr) { return false; } int32_t ret = memcpy_s(dData.buffer, bufferSize, bufferP, bufferSize); if (ret != EOK) { HILOGE("memory copy failed, ret %{public}d", ret); return false; } cachedUnsupportedData_.emplace_back(std::move(dData)); return true; } bool DistributedWantParams::ReadFromParcelParam(Parcel& parcel, const std::string& key, int type) { switch (type) { case VALUE_TYPE_CHARSEQUENCE: case VALUE_TYPE_STRING: return ReadFromParcelString(parcel, key); case VALUE_TYPE_BOOLEAN: return ReadFromParcelBool(parcel, key); case VALUE_TYPE_BYTE: return ReadFromParcelInt8(parcel, key); case VALUE_TYPE_CHAR: return ReadFromParcelChar(parcel, key); case VALUE_TYPE_SHORT: return ReadFromParcelShort(parcel, key); case VALUE_TYPE_INT: return ReadFromParcelInt(parcel, key); case VALUE_TYPE_LONG: return ReadFromParcelLong(parcel, key); case VALUE_TYPE_FLOAT: return ReadFromParcelFloat(parcel, key); case VALUE_TYPE_DOUBLE: return ReadFromParcelDouble(parcel, key); case VALUE_TYPE_WANTPARAMS: case VALUE_TYPE_FD: case VALUE_TYPE_REMOTE_OBJECT: return ReadFromParcelWantParamWrapper(parcel, key, type); case VALUE_TYPE_NULL: break; case VALUE_TYPE_PARCELABLE: case VALUE_TYPE_PARCELABLEARRAY: case VALUE_TYPE_SERIALIZABLE: case VALUE_TYPE_LIST: if (!ReadUnsupportedData(parcel, key, type)) { return false; } break; default: { sptr ao = nullptr; if (!ReadArrayToParcel(parcel, type, ao)) { return false; } sptr dIntf = ao; if (dIntf) { SetParam(key, dIntf); } break; } } return true; } bool DistributedWantParams::ReadFromParcel(Parcel& parcel) { int32_t size; if (!parcel.ReadInt32(size)) { return false; } if (size > static_cast(parcel.GetDataSize())) { return false; } for (int32_t i = 0; i < size; i++) { std::u16string key = parcel.ReadString16(); int type; if (!parcel.ReadInt32(type)) { return false; } if (!ReadFromParcelParam(parcel, Str16ToStr8(key), type)) { return false; } } return true; } DistributedWantParams* DistributedWantParams::Unmarshalling(Parcel& parcel) { DistributedWantParams* wantParams = new (std::nothrow) DistributedWantParams(); if (wantParams != nullptr && !wantParams->ReadFromParcel(parcel)) { delete wantParams; wantParams = nullptr; } return wantParams; } AAFwk::WantParams DistributedWantParams::ToWantParams() { AAFwk::WantParams wantParams; std::map> data = GetParams(); for (auto it = data.begin(); it != data.end(); it++) { wantParams.SetParam(it->first, it->second); } return wantParams; } } // namespace DistributedSchedule } // namespace OHOS