• 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 #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