* Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
* 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 "tlv_utils.h"
#include <json/json.h>
#include "pasteboard_hilog.h"
#include "want.h"
#include "pixel_map.h"
namespace OHOS::MiscServices {
namespace {
const std::string BUNDLE_NAME_KEY = "bundleName";
const std::string ABILITY_NAME_KEY = "abilityName";
const std::string MODULE_NAME_KEY = "moduleName";
const std::string TYPE_KEY = "type";
const std::string JSON_CONFIG_INDENTATION = "indentation";
const std::string JSON_CONFIG_COLLECT_COMMENTS = "collectComments";
const std::string JSON_CONFIG_COMMENT_STYLE = "commentStyle";
const std::string JSON_CONFIG_EMIT_UTF8 = "emitUTF8";
}
RawMem TLVUtils::Parcelable2Raw(const Parcelable* value)
{
RawMem rawMem {};
if (value == nullptr) {
return rawMem;
}
rawMem.parcel = std::make_shared<Parcel>(nullptr);
bool ret = value->Marshalling(*rawMem.parcel);
PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, rawMem, PASTEBOARD_MODULE_COMMON, "Marshalling failed");
rawMem.buffer = rawMem.parcel->GetData();
rawMem.bufferLen = rawMem.parcel->GetDataSize();
return rawMem;
}
bool TLVUtils::Raw2Parcel(const RawMem& rawMem, Parcel& parcel)
{
if (rawMem.buffer == 0 || rawMem.bufferLen == 0) {
return false;
}
auto* temp = malloc(rawMem.bufferLen);
if (temp == nullptr) {
PASTEBOARD_HILOGE(PASTEBOARD_MODULE_COMMON, "malloc failed, size=%{public}zu", rawMem.bufferLen);
return false;
}
auto err = memcpy_s(temp, rawMem.bufferLen, reinterpret_cast<const void*>(rawMem.buffer), rawMem.bufferLen);
if (err != EOK) {
PASTEBOARD_HILOGE(PASTEBOARD_MODULE_COMMON, "memcpy RawMem failed, size=%{public}zu", rawMem.bufferLen);
free(temp);
return false;
}
bool ret = parcel.ParseFrom(reinterpret_cast<uintptr_t>(temp), rawMem.bufferLen);
if (!ret) {
PASTEBOARD_HILOGE(PASTEBOARD_MODULE_COMMON, "parse from RawMem failed, size=%{public}zu", rawMem.bufferLen);
free(temp);
return false;
}
return true;
}
std::shared_ptr<Media::PixelMap> TLVUtils::Vector2PixelMap(std::vector<std::uint8_t>& value)
{
return value.empty() ? nullptr : std::shared_ptr<Media::PixelMap>(Media::PixelMap::DecodeTlv(value));
}
std::vector<std::uint8_t> TLVUtils::PixelMap2Vector(std::shared_ptr<Media::PixelMap> pixelMap)
{
if (pixelMap == nullptr) {
return {};
}
std::vector<std::uint8_t> value;
bool ret = pixelMap->EncodeTlv(value);
PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, {}, PASTEBOARD_MODULE_COMMON, "EncodeTlv failed");
return value;
}
std::string TLVUtils::Want2Json(const AAFwk::Want& want)
{
Json::Value root;
const std::string wantJson = want.ToJson();
Json::CharReaderBuilder readerBuilder;
readerBuilder[JSON_CONFIG_COLLECT_COMMENTS] = false;
std::unique_ptr<Json::CharReader> reader(readerBuilder.newCharReader());
if (reader != nullptr) {
Json::Value parsed;
std::string errs;
if (reader->parse(wantJson.data(), wantJson.data() + wantJson.size(), &parsed, &errs) && parsed.isObject()) {
root = std::move(parsed);
}
}
if (!root.isObject()) {
root = Json::Value(Json::objectValue);
}
root[BUNDLE_NAME_KEY] = want.GetBundleName();
root[ABILITY_NAME_KEY] = want.GetAbilityName();
root[MODULE_NAME_KEY] = want.GetModuleName();
root[TYPE_KEY] = want.GetType();
Json::StreamWriterBuilder writerBuilder;
writerBuilder[JSON_CONFIG_COMMENT_STYLE] = "None";
writerBuilder[JSON_CONFIG_INDENTATION] = "";
writerBuilder[JSON_CONFIG_EMIT_UTF8] = true;
std::string out = Json::writeString(writerBuilder, root);
if (!out.empty() && out.back() == '\n') {
out.pop_back();
}
return out;
}
std::shared_ptr<AAFwk::Want> TLVUtils::Json2Want(const std::string& json)
{
if (json.empty()) {
return nullptr;
}
Json::CharReaderBuilder readerBuilder;
readerBuilder[JSON_CONFIG_COLLECT_COMMENTS] = false;
std::unique_ptr<Json::CharReader> reader(readerBuilder.newCharReader());
if (reader == nullptr) {
return nullptr;
}
Json::Value root;
std::string errs;
if (!reader->parse(json.data(), json.data() + json.size(), &root, &errs) || !root.isObject()) {
return nullptr;
}
auto want = std::make_shared<AAFwk::Want>();
if (want == nullptr) {
return nullptr;
}
want->ParseJson(json);
const auto& bundleName = root[BUNDLE_NAME_KEY];
if (bundleName.isString()) {
want->SetBundleName(bundleName.asString());
}
const auto& abilityName = root[ABILITY_NAME_KEY];
if (abilityName.isString()) {
want->SetAbilityName(abilityName.asString());
}
const auto& moduleName = root[MODULE_NAME_KEY];
if (moduleName.isString()) {
want->SetModuleName(moduleName.asString());
}
const auto& type = root[TYPE_KEY];
if (type.isString()) {
want->SetType(type.asString());
}
return want;
}
}