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