* 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_WRITEABLE_H
#define DISTRIBUTEDDATAMGR_PASTEBOARD_TLV_WRITEABLE_H
#include "endian_converter.h"
#include "tlv_countable.h"
#include "uri.h"
namespace OHOS::MiscServices {
bool IsRemoteEncode();
class WriteOnlyBuffer;
class TLVWriteable : public TLVCountable {
public:
virtual ~TLVWriteable() = default;
virtual bool EncodeTLV(WriteOnlyBuffer& buffer) const = 0;
API_EXPORT bool Encode(std::vector<uint8_t>& buffer, bool isRemote = false) const;
API_EXPORT bool Encode(size_t len, std::vector<uint8_t>& buffer, bool isRemote = false) const;
API_EXPORT size_t Count(bool isRemote = false) const;
};
class WriteOnlyBuffer : public TLVBuffer {
public:
explicit WriteOnlyBuffer(size_t len) : TLVBuffer(len), data_(len) {}
const uint8_t* Data() const
{
return data_.data();
}
size_t Size() const
{
return cursor_;
}
template<typename T>
bool Write(uint16_t type, const std::vector<T>& value)
{
if (!HasExpectBuffer(sizeof(TLVHead))) {
return false;
}
auto tagCursor = cursor_;
cursor_ += sizeof(TLVHead);
auto valueCursor = cursor_;
bool ret = WriteValue(value);
WriteHead(type, tagCursor, cursor_ - valueCursor);
return ret;
}
template<typename T>
bool Write(uint16_t type, const std::shared_ptr<T>& value)
{
if (value == nullptr) {
return true;
}
return Write(type, *value);
}
bool Write(uint16_t type, std::monostate value);
bool Write(uint16_t type, const void* value);
bool Write(uint16_t type, bool value);
bool Write(uint16_t type, double value);
bool Write(uint16_t type, int8_t value);
bool Write(uint16_t type, int16_t value);
bool Write(uint16_t type, int32_t value);
bool Write(uint16_t type, int64_t value);
bool Write(uint16_t type, uint32_t value);
bool Write(uint16_t type, const std::string& value);
bool Write(uint16_t type, const Object& value);
bool Write(uint16_t type, const AAFwk::Want& value);
bool Write(uint16_t type, const Media::PixelMap& value);
bool Write(uint16_t type, const RawMem& value);
bool Write(uint16_t type, const TLVWriteable& value);
bool Write(uint16_t type, const std::vector<uint8_t>& value);
bool Write(uint16_t type, const std::map<std::string, std::vector<uint8_t>>& value);
bool Write(uint16_t type, const Details& value);
template<typename _InTp>
bool WriteVariant(uint16_t type, uint32_t step, const _InTp& input);
template<typename _InTp, typename _First, typename... _Rest>
bool WriteVariant(uint16_t type, uint32_t step, const _InTp& input);
template<typename... _Types>
bool Write(uint16_t type, const std::variant<_Types...>& input);
template<>
bool Write(uint16_t type, const EntryValue& input);
private:
void WriteHead(uint16_t type, size_t tagCursor, uint32_t len)
{
if (tagCursor + sizeof(TLVHead) > data_.size()) {
return;
}
auto* tlvHead = reinterpret_cast<TLVHead*>(data_.data() + tagCursor);
tlvHead->tag = HostToNet(type);
tlvHead->len = HostToNet(len);
}
template<typename T>
bool WriteBasic(uint16_t type, T value)
{
if (!HasExpectBuffer(sizeof(TLVHead) + sizeof(value))) {
return false;
}
auto* tlvHead = reinterpret_cast<TLVHead*>(data_.data() + cursor_);
tlvHead->tag = HostToNet(type);
tlvHead->len = HostToNet((uint32_t)sizeof(value));
auto valueBuff = HostToNet(value);
auto ret = memcpy_s(tlvHead->value, total_ - cursor_ - sizeof(TLVHead), &valueBuff, sizeof(value));
if (ret != EOK) {
return false;
}
cursor_ += sizeof(TLVHead) + sizeof(value);
return true;
}
template<typename T>
bool WriteValue(const std::vector<T>& value)
{
bool ret = true;
for (const T& item : value) {
ret = ret && Write(TAG_VECTOR_ITEM, item);
}
return ret;
}
friend class TLVWriteable;
std::vector<uint8_t> data_;
};
}
#endif