1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "tlv_writeable.h"
17 #include <thread>
18 #include "pasteboard_hilog.h"
19
20 namespace OHOS::MiscServices {
21
22 thread_local bool g_isRemoteEncode = false;
23
IsRemoteEncode()24 bool IsRemoteEncode()
25 {
26 return g_isRemoteEncode;
27 }
28
Encode(std::vector<uint8_t> & buffer,bool isRemote) const29 bool TLVWriteable::Encode(std::vector<uint8_t> &buffer, bool isRemote) const
30 {
31 g_isRemoteEncode = isRemote;
32 size_t len = CountTLV();
33 WriteOnlyBuffer buff(len);
34 bool ret = EncodeTLV(buff);
35 buffer = std::move(buff.data_);
36 return ret;
37 }
38
Write(uint16_t type,std::monostate value)39 bool WriteOnlyBuffer::Write(uint16_t type, std::monostate value)
40 {
41 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead)), false,
42 PASTEBOARD_MODULE_COMMON, "write monostate failed, type=%{public}hu", type);
43 cursor_ += sizeof(TLVHead);
44 return true;
45 }
46
Write(uint16_t type,const void * value)47 bool WriteOnlyBuffer::Write(uint16_t type, const void *value)
48 {
49 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead)), false,
50 PASTEBOARD_MODULE_COMMON, "write void* failed, type=%{public}hu", type);
51 cursor_ += sizeof(TLVHead);
52 return true;
53 }
54
Write(uint16_t type,bool value)55 bool WriteOnlyBuffer::Write(uint16_t type, bool value)
56 {
57 return WriteBasic(type, static_cast<int8_t>(value));
58 }
59
Write(uint16_t type,int8_t value)60 bool WriteOnlyBuffer::Write(uint16_t type, int8_t value)
61 {
62 return WriteBasic(type, value);
63 }
64
Write(uint16_t type,int16_t value)65 bool WriteOnlyBuffer::Write(uint16_t type, int16_t value)
66 {
67 return WriteBasic(type, value);
68 }
69
Write(uint16_t type,double value)70 bool WriteOnlyBuffer::Write(uint16_t type, double value)
71 {
72 return WriteBasic(type, value);
73 }
74
Write(uint16_t type,int32_t value)75 bool WriteOnlyBuffer::Write(uint16_t type, int32_t value)
76 {
77 return WriteBasic(type, value);
78 }
79
Write(uint16_t type,int64_t value)80 bool WriteOnlyBuffer::Write(uint16_t type, int64_t value)
81 {
82 return WriteBasic(type, value);
83 }
84
Write(uint16_t type,uint32_t value)85 bool WriteOnlyBuffer::Write(uint16_t type, uint32_t value)
86 {
87 return WriteBasic(type, value);
88 }
89
Write(uint16_t type,const std::string & value)90 bool WriteOnlyBuffer::Write(uint16_t type, const std::string &value)
91 {
92 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead) + value.size()), false,
93 PASTEBOARD_MODULE_COMMON, "write string failed, type=%{public}hu", type);
94
95 auto *tlvHead = reinterpret_cast<TLVHead *>(data_.data() + cursor_);
96 tlvHead->tag = HostToNet(type);
97 tlvHead->len = HostToNet(static_cast<uint32_t>(value.size()));
98
99 if (!value.empty()) {
100 auto err = memcpy_s(tlvHead->value, value.size(), value.c_str(), value.size());
101 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE((err == EOK), false, PASTEBOARD_MODULE_COMMON,
102 "copy string failed, type=%{public}hu", type);
103 }
104
105 cursor_ += sizeof(TLVHead) + value.size();
106 return true;
107 }
108
Write(uint16_t type,const RawMem & value)109 bool WriteOnlyBuffer::Write(uint16_t type, const RawMem &value)
110 {
111 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead) + value.bufferLen), false,
112 PASTEBOARD_MODULE_COMMON, "write RawMem failed, type=%{public}hu", type);
113
114 auto *tlvHead = reinterpret_cast<TLVHead *>(data_.data() + cursor_);
115 tlvHead->tag = HostToNet(type);
116 tlvHead->len = HostToNet(static_cast<uint32_t>(value.bufferLen));
117 cursor_ += sizeof(TLVHead);
118
119 if (value.bufferLen != 0 && reinterpret_cast<const void *>(value.buffer) != nullptr) {
120 auto err = memcpy_s(data_.data() + cursor_, total_ - cursor_,
121 reinterpret_cast<const void *>(value.buffer), value.bufferLen);
122 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(err == EOK, false, PASTEBOARD_MODULE_COMMON,
123 "copy RawMem failed, type=%{public}hu", type);
124 }
125
126 cursor_ += value.bufferLen;
127 return true;
128 }
129
Write(uint16_t type,const AAFwk::Want & value)130 bool WriteOnlyBuffer::Write(uint16_t type, const AAFwk::Want &value)
131 {
132 return Write(type, TLVUtils::Parcelable2Raw(&value));
133 }
134
Write(uint16_t type,const Media::PixelMap & value)135 bool WriteOnlyBuffer::Write(uint16_t type, const Media::PixelMap &value)
136 {
137 std::vector<std::uint8_t> rawData;
138 if (!value.EncodeTlv(rawData)) {
139 return false;
140 }
141 return Write(type, rawData);
142 }
143
Write(uint16_t type,const Object & value)144 bool WriteOnlyBuffer::Write(uint16_t type, const Object &value)
145 {
146 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead)), false,
147 PASTEBOARD_MODULE_COMMON, "write object failed, type=%{public}hu", type);
148
149 auto tagCursor = cursor_;
150 cursor_ += sizeof(TLVHead);
151 auto valueCursor = cursor_;
152
153 bool ret = true;
154 for (const auto &[key, val] : value.value_) {
155 ret = ret && Write(TAG_MAP_KEY, key);
156 ret = ret && Write(TAG_MAP_VALUE_TYPE, val);
157 }
158 WriteHead(type, tagCursor, cursor_ - valueCursor);
159 return ret;
160 }
161
Write(uint16_t type,const std::map<std::string,std::vector<uint8_t>> & value)162 bool WriteOnlyBuffer::Write(uint16_t type, const std::map<std::string, std::vector<uint8_t>> &value)
163 {
164 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead)), false,
165 PASTEBOARD_MODULE_COMMON, "write vector failed, type=%{public}hu", type);
166
167 auto tagCursor = cursor_;
168 cursor_ += sizeof(TLVHead);
169 auto valueCursor = cursor_;
170
171 bool ret = true;
172 for (auto &item : value) {
173 ret = ret && Write(TAG_MAP_KEY, item.first);
174 ret = ret && Write(TAG_MAP_VALUE, item.second);
175 }
176 WriteHead(type, tagCursor, cursor_ - valueCursor);
177 return ret;
178 }
179
180 template<typename _InTp>
WriteVariant(uint16_t type,uint32_t step,const _InTp & input)181 bool WriteOnlyBuffer::WriteVariant(uint16_t type, uint32_t step, const _InTp &input)
182 {
183 (void)type;
184 (void)step;
185 (void)input;
186 return true;
187 }
188
189 template<typename _InTp, typename _First, typename... _Rest>
WriteVariant(uint16_t type,uint32_t step,const _InTp & input)190 bool WriteOnlyBuffer::WriteVariant(uint16_t type, uint32_t step, const _InTp &input)
191 {
192 if (step == input.index()) {
193 auto val = std::get<_First>(input);
194 return Write(type, val);
195 }
196 return WriteVariant<_InTp, _Rest...>(type, step + 1, input);
197 }
198
199 template<typename... _Types>
Write(uint16_t type,const std::variant<_Types...> & input)200 bool WriteOnlyBuffer::Write(uint16_t type, const std::variant<_Types...> &input)
201 {
202 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead)), false,
203 PASTEBOARD_MODULE_COMMON, "write variant failed, type=%{public}hu", type);
204
205 auto tagCursor = cursor_;
206 cursor_ += sizeof(TLVHead);
207 auto valueCursor = cursor_;
208
209 uint32_t index = static_cast<uint32_t>(input.index());
210 if (!Write(TAG_VARIANT_INDEX, index)) {
211 return false;
212 }
213 WriteVariant<decltype(input), _Types...>(TAG_VARIANT_VALUE, 0, input);
214 WriteHead(type, tagCursor, cursor_ - valueCursor);
215 return true;
216 }
217
218 template<>
Write(uint16_t type,const EntryValue & input)219 bool WriteOnlyBuffer::Write(uint16_t type, const EntryValue &input)
220 {
221 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead)), false,
222 PASTEBOARD_MODULE_COMMON, "write UDMF::ValueType failed, type=%{public}hu", type);
223
224 auto tagCursor = cursor_;
225 cursor_ += sizeof(TLVHead);
226 auto valueCursor = cursor_;
227
228 uint32_t index = static_cast<uint32_t>(input.index());
229 if (!Write(TAG_VARIANT_INDEX, index)) {
230 return false;
231 }
232 WriteVariant<decltype(input), std::monostate, int32_t, int64_t, double, bool, std::string, std::vector<uint8_t>,
233 std::shared_ptr<OHOS::AAFwk::Want>, std::shared_ptr<OHOS::Media::PixelMap>, std::shared_ptr<Object>, nullptr_t>(
234 TAG_VARIANT_VALUE, 0, input);
235 WriteHead(type, tagCursor, cursor_ - valueCursor);
236 return true;
237 }
238
Write(uint16_t type,const Details & value)239 bool WriteOnlyBuffer::Write(uint16_t type, const Details &value)
240 {
241 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead)), false,
242 PASTEBOARD_MODULE_COMMON, "write Details failed, type=%{public}hu", type);
243
244 auto tagCursor = cursor_;
245 cursor_ += sizeof(TLVHead);
246 auto valueCursor = cursor_;
247
248 bool ret = true;
249 for (const auto &[key, val] : value) {
250 ret = ret && Write(TAG_MAP_KEY, key);
251 ret = ret && Write(TAG_MAP_VALUE_TYPE, val);
252 }
253 WriteHead(type, tagCursor, cursor_ - valueCursor);
254 return ret;
255 }
256
Write(uint16_t type,const TLVWriteable & value)257 bool WriteOnlyBuffer::Write(uint16_t type, const TLVWriteable &value)
258 {
259 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead)), false,
260 PASTEBOARD_MODULE_COMMON, "write TLVWriteable failed, type=%{public}hu", type);
261
262 auto tagCursor = cursor_;
263 cursor_ += sizeof(TLVHead);
264 auto valueCursor = cursor_;
265
266 bool ret = value.EncodeTLV(*this);
267 WriteHead(type, tagCursor, cursor_ - valueCursor);
268 return ret;
269 }
270
Write(uint16_t type,const std::vector<uint8_t> & value)271 bool WriteOnlyBuffer::Write(uint16_t type, const std::vector<uint8_t> &value)
272 {
273 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead) + value.size()), false,
274 PASTEBOARD_MODULE_COMMON, "write uint8 vector failed, type=%{public}hu", type);
275
276 WriteHead(type, cursor_, value.size());
277 cursor_ += sizeof(TLVHead);
278
279 if (!value.empty()) {
280 auto err = memcpy_s(data_.data() + cursor_, total_ - cursor_, value.data(), value.size());
281 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(err == EOK, false, PASTEBOARD_MODULE_COMMON,
282 "copy uint8 vector failed, type=%{public}hu", type);
283 }
284 cursor_ += value.size();
285 return true;
286 }
287 } // namespace OHOS::MiscServices
288