• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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