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
18 #include "pasteboard_hilog.h"
19
20 namespace OHOS::MiscServices {
21
Encode(std::vector<uint8_t> & buffer) const22 bool TLVWriteable::Encode(std::vector<uint8_t> &buffer) const
23 {
24 size_t len = CountTLV();
25 WriteOnlyBuffer buff(len);
26 bool ret = EncodeTLV(buff);
27 buffer = std::move(buff.data_);
28 return ret;
29 }
30
Write(uint16_t type,std::monostate value)31 bool WriteOnlyBuffer::Write(uint16_t type, std::monostate value)
32 {
33 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead)), false,
34 PASTEBOARD_MODULE_COMMON, "write monostate failed, type=%{public}hu", type);
35 cursor_ += sizeof(TLVHead);
36 return true;
37 }
38
Write(uint16_t type,const void * value)39 bool WriteOnlyBuffer::Write(uint16_t type, const void *value)
40 {
41 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead)), false,
42 PASTEBOARD_MODULE_COMMON, "write void* failed, type=%{public}hu", type);
43 cursor_ += sizeof(TLVHead);
44 return true;
45 }
46
Write(uint16_t type,bool value)47 bool WriteOnlyBuffer::Write(uint16_t type, bool value)
48 {
49 return WriteBasic(type, static_cast<int8_t>(value));
50 }
51
Write(uint16_t type,int8_t value)52 bool WriteOnlyBuffer::Write(uint16_t type, int8_t value)
53 {
54 return WriteBasic(type, value);
55 }
56
Write(uint16_t type,int16_t value)57 bool WriteOnlyBuffer::Write(uint16_t type, int16_t value)
58 {
59 return WriteBasic(type, value);
60 }
61
Write(uint16_t type,double value)62 bool WriteOnlyBuffer::Write(uint16_t type, double value)
63 {
64 return WriteBasic(type, value);
65 }
66
Write(uint16_t type,int32_t value)67 bool WriteOnlyBuffer::Write(uint16_t type, int32_t value)
68 {
69 return WriteBasic(type, value);
70 }
71
Write(uint16_t type,int64_t value)72 bool WriteOnlyBuffer::Write(uint16_t type, int64_t value)
73 {
74 return WriteBasic(type, value);
75 }
76
Write(uint16_t type,uint32_t value)77 bool WriteOnlyBuffer::Write(uint16_t type, uint32_t value)
78 {
79 return WriteBasic(type, value);
80 }
81
Write(uint16_t type,const std::string & value)82 bool WriteOnlyBuffer::Write(uint16_t type, const std::string &value)
83 {
84 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead) + value.size()), false,
85 PASTEBOARD_MODULE_COMMON, "write string failed, type=%{public}hu", type);
86
87 auto *tlvHead = reinterpret_cast<TLVHead *>(data_.data() + cursor_);
88 tlvHead->tag = HostToNet(type);
89 tlvHead->len = HostToNet(static_cast<uint32_t>(value.size()));
90
91 if (!value.empty()) {
92 auto err = memcpy_s(tlvHead->value, value.size(), value.c_str(), value.size());
93 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE((err == EOK), false, PASTEBOARD_MODULE_COMMON,
94 "copy string failed, type=%{public}hu", type);
95 }
96
97 cursor_ += sizeof(TLVHead) + value.size();
98 return true;
99 }
100
Write(uint16_t type,const RawMem & value)101 bool WriteOnlyBuffer::Write(uint16_t type, const RawMem &value)
102 {
103 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead) + value.bufferLen), false,
104 PASTEBOARD_MODULE_COMMON, "write RawMem failed, type=%{public}hu", type);
105
106 auto *tlvHead = reinterpret_cast<TLVHead *>(data_.data() + cursor_);
107 tlvHead->tag = HostToNet(type);
108 tlvHead->len = HostToNet(static_cast<uint32_t>(value.bufferLen));
109 cursor_ += sizeof(TLVHead);
110
111 if (value.bufferLen != 0 && value.buffer != 0) {
112 auto err = memcpy_s(data_.data() + cursor_, total_ - cursor_,
113 reinterpret_cast<const void *>(value.buffer), value.bufferLen);
114 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(err == EOK, false, PASTEBOARD_MODULE_COMMON,
115 "copy RawMem failed, type=%{public}hu", type);
116 }
117
118 cursor_ += value.bufferLen;
119 return true;
120 }
121
Write(uint16_t type,const AAFwk::Want & value)122 bool WriteOnlyBuffer::Write(uint16_t type, const AAFwk::Want &value)
123 {
124 return Write(type, TLVUtils::Parcelable2Raw(&value));
125 }
126
Write(uint16_t type,const Media::PixelMap & value)127 bool WriteOnlyBuffer::Write(uint16_t type, const Media::PixelMap &value)
128 {
129 std::vector<std::uint8_t> rawData;
130 if (!value.EncodeTlv(rawData)) {
131 return false;
132 }
133 return Write(type, rawData);
134 }
135
Write(uint16_t type,const Object & value)136 bool WriteOnlyBuffer::Write(uint16_t type, const Object &value)
137 {
138 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead)), false,
139 PASTEBOARD_MODULE_COMMON, "write object failed, type=%{public}hu", type);
140
141 auto tagCursor = cursor_;
142 cursor_ += sizeof(TLVHead);
143 auto valueCursor = cursor_;
144
145 bool ret = true;
146 for (const auto &[key, val] : value.value_) {
147 ret = ret && Write(TAG_MAP_KEY, key);
148 ret = ret && Write(TAG_MAP_VALUE_TYPE, val);
149 }
150 WriteHead(type, tagCursor, cursor_ - valueCursor);
151 return ret;
152 }
153
Write(uint16_t type,const std::map<std::string,std::vector<uint8_t>> & value)154 bool WriteOnlyBuffer::Write(uint16_t type, const std::map<std::string, std::vector<uint8_t>> &value)
155 {
156 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead)), false,
157 PASTEBOARD_MODULE_COMMON, "write vector failed, type=%{public}hu", type);
158
159 auto tagCursor = cursor_;
160 cursor_ += sizeof(TLVHead);
161 auto valueCursor = cursor_;
162
163 bool ret = true;
164 for (auto &item : value) {
165 ret = ret && Write(TAG_MAP_KEY, item.first);
166 ret = ret && Write(TAG_MAP_VALUE, item.second);
167 }
168 WriteHead(type, tagCursor, cursor_ - valueCursor);
169 return ret;
170 }
171
172 template<typename _InTp>
WriteVariant(uint16_t type,uint32_t step,const _InTp & input)173 bool WriteOnlyBuffer::WriteVariant(uint16_t type, uint32_t step, const _InTp &input)
174 {
175 (void)type;
176 (void)step;
177 (void)input;
178 return true;
179 }
180
181 template<typename _InTp, typename _First, typename... _Rest>
WriteVariant(uint16_t type,uint32_t step,const _InTp & input)182 bool WriteOnlyBuffer::WriteVariant(uint16_t type, uint32_t step, const _InTp &input)
183 {
184 if (step == input.index()) {
185 auto val = std::get<_First>(input);
186 return Write(type, val);
187 }
188 return WriteVariant<_InTp, _Rest...>(type, step + 1, input);
189 }
190
191 template<typename... _Types>
Write(uint16_t type,const std::variant<_Types...> & input)192 bool WriteOnlyBuffer::Write(uint16_t type, const std::variant<_Types...> &input)
193 {
194 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead)), false,
195 PASTEBOARD_MODULE_COMMON, "write variant failed, type=%{public}hu", type);
196
197 auto tagCursor = cursor_;
198 cursor_ += sizeof(TLVHead);
199 auto valueCursor = cursor_;
200
201 uint32_t index = static_cast<uint32_t>(input.index());
202 if (!Write(TAG_VARIANT_INDEX, index)) {
203 return false;
204 }
205 WriteVariant<decltype(input), _Types...>(TAG_VARIANT_VALUE, 0, input);
206 WriteHead(type, tagCursor, cursor_ - valueCursor);
207 return true;
208 }
209
210 template<>
Write(uint16_t type,const EntryValue & input)211 bool WriteOnlyBuffer::Write(uint16_t type, const EntryValue &input)
212 {
213 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead)), false,
214 PASTEBOARD_MODULE_COMMON, "write UDMF::ValueType failed, type=%{public}hu", type);
215
216 auto tagCursor = cursor_;
217 cursor_ += sizeof(TLVHead);
218 auto valueCursor = cursor_;
219
220 uint32_t index = static_cast<uint32_t>(input.index());
221 if (!Write(TAG_VARIANT_INDEX, index)) {
222 return false;
223 }
224 WriteVariant<decltype(input), std::monostate, int32_t, int64_t, double, bool, std::string, std::vector<uint8_t>,
225 std::shared_ptr<OHOS::AAFwk::Want>, std::shared_ptr<OHOS::Media::PixelMap>, std::shared_ptr<Object>, nullptr_t>(
226 TAG_VARIANT_VALUE, 0, input);
227 WriteHead(type, tagCursor, cursor_ - valueCursor);
228 return true;
229 }
230
Write(uint16_t type,const Details & value)231 bool WriteOnlyBuffer::Write(uint16_t type, const Details &value)
232 {
233 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead)), false,
234 PASTEBOARD_MODULE_COMMON, "write Details failed, type=%{public}hu", type);
235
236 auto tagCursor = cursor_;
237 cursor_ += sizeof(TLVHead);
238 auto valueCursor = cursor_;
239
240 bool ret = true;
241 for (const auto &[key, val] : value) {
242 ret = ret && Write(TAG_MAP_KEY, key);
243 ret = ret && Write(TAG_MAP_VALUE_TYPE, val);
244 }
245 WriteHead(type, tagCursor, cursor_ - valueCursor);
246 return ret;
247 }
248
Write(uint16_t type,const TLVWriteable & value)249 bool WriteOnlyBuffer::Write(uint16_t type, const TLVWriteable &value)
250 {
251 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead)), false,
252 PASTEBOARD_MODULE_COMMON, "write TLVWriteable failed, type=%{public}hu", type);
253
254 auto tagCursor = cursor_;
255 cursor_ += sizeof(TLVHead);
256 auto valueCursor = cursor_;
257
258 bool ret = value.EncodeTLV(*this);
259 WriteHead(type, tagCursor, cursor_ - valueCursor);
260 return ret;
261 }
262
Write(uint16_t type,const std::vector<uint8_t> & value)263 bool WriteOnlyBuffer::Write(uint16_t type, const std::vector<uint8_t> &value)
264 {
265 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(HasExpectBuffer(sizeof(TLVHead) + value.size()), false,
266 PASTEBOARD_MODULE_COMMON, "write uint8 vector failed, type=%{public}hu", type);
267
268 WriteHead(type, cursor_, value.size());
269 cursor_ += sizeof(TLVHead);
270
271 if (!value.empty()) {
272 auto err = memcpy_s(data_.data() + cursor_, total_ - cursor_, value.data(), value.size());
273 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(err == EOK, false, PASTEBOARD_MODULE_COMMON,
274 "copy uint8 vector failed, type=%{public}hu", type);
275 }
276 cursor_ += value.size();
277 return true;
278 }
279 } // namespace OHOS::MiscServices
280