* 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.
*/
#ifndef DISTRIBUTEDDATAMGR_PASTEBOARD_TLV_READABLE_H
#define DISTRIBUTEDDATAMGR_PASTEBOARD_TLV_READABLE_H
#include "endian_converter.h"
#include "tlv_buffer.h"
#include "tlv_utils.h"
#include "uri.h"
namespace OHOS::MiscServices {
class ReadOnlyBuffer;
class TLVReadable {
public:
virtual ~TLVReadable() = default;
virtual bool DecodeTLV(ReadOnlyBuffer& buffer) = 0;
API_EXPORT bool Decode(const std::vector<uint8_t>& buffer);
};
class ReadOnlyBuffer : public TLVBuffer {
public:
explicit ReadOnlyBuffer(const std::vector<uint8_t>& data) : TLVBuffer(data.size()), data_(data) {}
template<typename T>
bool ReadValue(std::vector<T>& value, const TLVHead& head)
{
if (cursor_ > UINT32_MAX - head.len) {
return false;
}
auto vectorEnd = cursor_ + head.len;
if (vectorEnd > data_.size()) {
return false;
}
RecursiveGuard guard;
if (!guard.IsValid()) {
return false;
}
for (; cursor_ < vectorEnd;) {
TLVHead valueHead {};
bool ret = ReadHead(valueHead);
T item {};
ret = ret && ReadValue(item, valueHead);
if (!ret) {
return false;
}
value.push_back(item);
}
return true;
}
template<typename T>
bool ReadValue(std::shared_ptr<T>& value, const TLVHead& head)
{
RecursiveGuard guard;
if (!guard.IsValid()) {
return false;
}
value = std::make_shared<T>();
if (value == nullptr) {
return false;
}
return ReadValue(*value, head);
}
bool ReadHead(TLVHead& head);
bool ReadValue(std::monostate& value, const TLVHead& head);
bool ReadValue(void* value, const TLVHead& head);
bool ReadValue(bool& value, const TLVHead& head);
bool ReadValue(int8_t& value, const TLVHead& head);
bool ReadValue(int16_t& value, const TLVHead& head);
bool ReadValue(int32_t& value, const TLVHead& head);
bool ReadValue(int64_t& value, const TLVHead& head);
bool ReadValue(double& value, const TLVHead& head);
bool ReadValue(uint32_t& value, const TLVHead& head);
bool ReadValue(std::string& value, const TLVHead& head);
bool ReadValue(RawMem& rawMem, const TLVHead& head);
bool ReadValue(TLVReadable& value, const TLVHead& head);
bool ReadValue(std::vector<uint8_t>& value, const TLVHead& head);
bool ReadValue(Object& value, const TLVHead& head);
bool ReadValue(std::shared_ptr<OHOS::Uri>& value, const TLVHead& head);
bool ReadValue(std::shared_ptr<AAFwk::Want>& value, const TLVHead& head);
bool ReadValue(std::shared_ptr<Media::PixelMap>& value, const TLVHead& head);
bool ReadValue(std::map<std::string, std::vector<uint8_t>>& value, const TLVHead& head);
bool ReadValue(Details& value, const TLVHead& head);
template<typename _InTp>
bool ReadVariant(uint32_t step, uint32_t index, _InTp& input, const TLVHead& head);
template<typename _InTp, typename _First, typename... _Rest>
bool ReadVariant(uint32_t step, uint32_t index, _InTp& input, const TLVHead& head);
template<typename... _Types>
bool ReadValue(std::variant<_Types...>& value, const TLVHead& head);
template<>
bool ReadValue(EntryValue& value, const TLVHead& head);
private:
bool ReadBasicValue(bool& value, const TLVHead& head)
{
if (head.len != sizeof(bool) || head.len == 0) {
return false;
}
if (!HasExpectBuffer(head.len)) {
return false;
}
uint8_t rawValue = 0;
auto ret = memcpy_s(&rawValue, sizeof(bool), data_.data() + cursor_, sizeof(bool));
if (ret != EOK) {
return false;
}
if (rawValue > 1) {
return false;
}
value = NetToHost(rawValue);
cursor_ += sizeof(bool);
return true;
}
template<typename T>
bool ReadBasicValue(T& value, const TLVHead& head)
{
if (head.len != sizeof(T) || head.len == 0) {
return false;
}
if (!HasExpectBuffer(head.len)) {
return false;
}
auto ret = memcpy_s(&value, sizeof(T), data_.data() + cursor_, sizeof(T));
if (ret != EOK) {
return false;
}
value = NetToHost(value);
cursor_ += sizeof(T);
return true;
}
const std::vector<uint8_t> data_;
};
}
#endif