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