• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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_object.h"
17 #include <string>
18 #include <map>
19 
20 namespace OHOS {
21 namespace UDMF {
TLVObject(std::vector<std::uint8_t> & buffer)22 TLVObject::TLVObject(std::vector<std::uint8_t> &buffer)
23 {
24     total_ += buffer.size();
25     buffer_ = &buffer;
26     cursor_ = 0;
27     file_ = nullptr;
28 }
29 
SetFile(std::FILE * file)30 void TLVObject::SetFile(std::FILE *file)
31 {
32     file_ = file;
33 }
34 
UpdateSize()35 void TLVObject::UpdateSize()
36 {
37     if (file_ != nullptr) {
38         return;
39     }
40     buffer_->resize(total_);
41 }
42 
GetBuffer()43 std::vector<std::uint8_t> TLVObject::GetBuffer()
44 {
45     return *buffer_;
46 }
47 
Count(const uint32_t value)48 void TLVObject::Count(const uint32_t value)
49 {
50     total_ += sizeof(value) + sizeof(TLVHead);
51 }
52 
Count(const uint64_t value)53 void TLVObject::Count(const uint64_t value)
54 {
55     total_ += sizeof(value) + sizeof(TLVHead);
56 }
57 
Count(const int32_t value)58 void TLVObject::Count(const int32_t value)
59 {
60     total_ += sizeof(value) + sizeof(TLVHead);
61 }
62 
Count(const int64_t value)63 void TLVObject::Count(const int64_t value)
64 {
65     total_ += sizeof(value) + sizeof(TLVHead);
66 }
67 
Count(const float value)68 void TLVObject::Count(const float value)
69 {
70     total_ += sizeof(value) + sizeof(TLVHead);
71 }
72 
Count(const double value)73 void TLVObject::Count(const double value)
74 {
75     total_ += sizeof(value) + sizeof(TLVHead);
76 }
77 
Count(const std::string & value)78 void TLVObject::Count(const std::string &value)
79 {
80     total_ += value.size() + sizeof(TLVHead);
81 }
82 
Count(const std::vector<uint8_t> & value)83 void TLVObject::Count(const std::vector<uint8_t> &value)
84 {
85     std::size_t expectSize = sizeof(TLVHead);
86     expectSize += value.size();
87     total_ += expectSize;
88 }
89 
Count(const UDVariant & value)90 void TLVObject::Count(const UDVariant &value)
91 {
92     total_ += sizeof(TLVHead);
93     auto int32Value = std::get_if<int32_t>(&value);
94     if (int32Value != nullptr) {
95         Count(std::get<int32_t>(value));
96         return;
97     }
98     auto int64Value = std::get_if<int64_t>(&value);
99     if (int64Value != nullptr) {
100         Count(std::get<int64_t>(value));
101         return;
102     }
103     auto boolValue = std::get_if<bool>(&value);
104     if (boolValue != nullptr) {
105         Count(std::get<bool>(value));
106         return;
107     }
108     auto doubleValue = std::get_if<double>(&value);
109     if (doubleValue != nullptr) {
110         Count(std::get<double>(value));
111         return;
112     }
113     auto strValue = std::get_if<std::string>(&value);
114     if (strValue != nullptr) {
115         Count(std::get<std::string>(value));
116         return;
117     }
118     auto vecValue = std::get_if<std::vector<uint8_t>>(&value);
119     if (vecValue != nullptr) {
120         Count(std::get<std::vector<uint8_t>>(value));
121         return;
122     }
123     total_ += sizeof(TLVHead);
124 }
125 
Count(const UDDetails & value)126 void TLVObject::Count(const UDDetails &value)
127 {
128     for (auto &item : value) {
129         Count(item.first);
130         Count(item.second);
131     }
132     total_ += sizeof(TLVHead);
133 }
134 
Count(const UnifiedKey & value)135 void TLVObject::Count(const UnifiedKey &value)
136 {
137     Count(value.key);
138     Count(value.intention);
139     Count(value.bundleName);
140     Count(value.groupId);
141 }
142 
Count(const Privilege & value)143 void TLVObject::Count(const Privilege &value)
144 {
145     Count(value.tokenId);
146     Count(value.readPermission);
147     Count(value.writePermission);
148 }
149 
WriteString(const std::string & value)150 bool TLVObject::WriteString(const std::string &value)
151 {
152     PrepareBuffer(sizeof(TLVHead) + value.size());
153     if (!HasExpectBuffer(sizeof(TLVHead) + value.size())) {
154         return false;
155     }
156     auto *tlvHead = reinterpret_cast<TLVHead *>(buffer_->data() + cursor_);
157     tlvHead->tag = HostToNet(static_cast<uint16_t>(TAG::TAG_STRING));
158     tlvHead->len = HostToNet((uint32_t)value.size());
159     if (!value.empty()) {
160         auto err = memcpy_s(tlvHead->value, value.size(), value.c_str(), value.size());
161         if (err != EOK) {
162             return false;
163         }
164     }
165     if (!SaveBufferToFile()) {
166         return false;
167     }
168     cursor_ += sizeof(TLVHead) + value.size();
169     return true;
170 }
171 
ReadString(std::string & value)172 bool TLVObject::ReadString(std::string &value)
173 {
174     TLVHead head {};
175     if (!ReadHead(head)) {
176         return false;
177     }
178     if (!HasExpectBuffer(head.len)) {
179         return false;
180     }
181     if (!LoadBufferFormFile(head.len)) {
182         return false;
183     }
184     value.append(reinterpret_cast<const char *>(buffer_->data() + cursor_), head.len);
185     cursor_ += head.len;
186     if (file_ != nullptr) {
187         cursor_ += sizeof(TLVHead);
188     }
189     return true;
190 }
191 
WriteVector(const std::vector<uint8_t> & value)192 bool TLVObject::WriteVector(const std::vector<uint8_t> &value)
193 {
194     PrepareBuffer(sizeof(TLVHead) + value.size());
195     if (!HasExpectBuffer(sizeof(TLVHead) + value.size())) {
196         return false;
197     }
198     WriteHead(static_cast<uint16_t>(TAG::TAG_VECTOR), cursor_, value.size());
199     cursor_ += sizeof(TLVHead);
200 
201     if (!value.empty()) {
202         auto err = memcpy_s(buffer_->data() + cursor_, buffer_->size() - cursor_, value.data(), value.size());
203         if (err != EOK) {
204             return false;
205         }
206     }
207     if (!SaveBufferToFile()) {
208         return false;
209     }
210     cursor_ += value.size();
211     return true;
212 }
213 
ReadVector(std::vector<uint8_t> & value)214 bool TLVObject::ReadVector(std::vector<uint8_t> &value)
215 {
216     TLVHead head {};
217     if (!ReadHead(head)) {
218         return false;
219     }
220     if (!HasExpectBuffer(head.len)) {
221         return false;
222     }
223     if (!LoadBufferFormFile(head.len)) {
224         return false;
225     }
226     std::vector<uint8_t> buff(buffer_->data() + cursor_, buffer_->data() + cursor_ + head.len);
227     value = std::move(buff);
228     cursor_ += head.len;
229     if (file_ != nullptr) {
230         cursor_ += sizeof(TLVHead);
231     }
232     return true;
233 }
234 
WriteVariantInner(TAG & tag,const UDVariant & value)235 bool TLVObject::WriteVariantInner(TAG &tag, const UDVariant &value)
236 {
237     auto int32Value = std::get_if<int32_t>(&value);
238     if (int32Value != nullptr) {
239         if (!WriteBasic(TAG::TAG_INT32, std::get<int32_t>(value))) {
240             return false;
241         }
242         tag = TAG::TAG_INT32;
243     }
244     auto int64Value = std::get_if<int64_t>(&value);
245     if (int64Value != nullptr) {
246         if (!WriteBasic(TAG::TAG_INT64, std::get<int64_t>(value))) {
247             return false;
248         }
249         tag = TAG::TAG_INT64;
250     }
251     auto boolValue = std::get_if<bool>(&value);
252     if (boolValue != nullptr) {
253         if (!WriteBasic(TAG::TAG_BOOL, std::get<bool>(value))) {
254             return false;
255         }
256         tag = TAG::TAG_BOOL;
257     }
258     auto doubleValue = std::get_if<double>(&value);
259     if (doubleValue != nullptr) {
260         if (!WriteBasic(TAG::TAG_DOUBLE, std::get<double>(value))) {
261             return false;
262         }
263         tag = TAG::TAG_DOUBLE;
264     }
265     auto stringValue = std::get_if<std::string>(&value);
266     if (stringValue != nullptr) {
267         if (!WriteString(std::get<std::string>(value))) {
268             return false;
269         }
270         tag = TAG::TAG_STRING;
271     }
272     auto vectorValue = std::get_if<std::vector<uint8_t>>(&value);
273     if (vectorValue != nullptr) {
274         if (!WriteVector(std::get<std::vector<uint8_t>>(value))) {
275             return false;
276         }
277         tag = TAG::TAG_VECTOR;
278     }
279     return true;
280 }
281 
WriteVariant(const UDVariant & value)282 bool TLVObject::WriteVariant(const UDVariant &value)
283 {
284     if (!HasExpectBuffer(sizeof(TLVHead))) {
285         return false;
286     }
287     if (file_ != nullptr) {
288         std::vector<uint8_t> reserved {};
289         reserved.resize(sizeof(TLVHead));
290         if (fwrite(reserved.data(), sizeof(uint8_t), reserved.size(), file_) != reserved.size()) {
291             return false;
292         }
293     }
294     auto tagCursor = cursor_;
295     cursor_ += sizeof(TLVHead);
296     auto valueCursor = cursor_;
297     TAG tag = TAG::TAG_BUTT;
298     if (!WriteVariantInner(tag, value)) {
299         return false;
300     }
301     PrepareHeader(cursor_, tagCursor, valueCursor);
302     WriteHead(static_cast<uint16_t>(tag), tagCursor, cursor_ - valueCursor);
303     if (!SaveBufferToFile()) {
304         return false;
305     }
306     if (file_ != nullptr) {
307         fseek(file_, 0, SEEK_END);
308         cursor_ += sizeof(TLVHead);
309     }
310     return true;
311 }
312 
ReadVariantInner(uint16_t tag,UDVariant & value)313 bool TLVObject::ReadVariantInner(uint16_t tag, UDVariant &value)
314 {
315     switch (tag) {
316         case static_cast<uint16_t>(TAG::TAG_INT32): {
317             int32_t int32Value;
318             if (!ReadBasic(int32Value)) {
319                 return false;
320             }
321             value.emplace<int32_t>(int32Value);
322             break;
323         }
324         case static_cast<uint16_t>(TAG::TAG_INT64): {
325             int64_t int64Value;
326             if (!ReadBasic(int64Value)) {
327                 return false;
328             }
329             value.emplace<int64_t>(int64Value);
330             break;
331         }
332         case static_cast<uint16_t>(TAG::TAG_BOOL): {
333             bool boolValue;
334             if (!ReadBasic(boolValue)) {
335                 return false;
336             }
337             value.emplace<bool>(boolValue);
338             break;
339         }
340         case static_cast<uint16_t>(TAG::TAG_DOUBLE): {
341             double doubleValue;
342             if (!ReadBasic(doubleValue)) {
343                 return false;
344             }
345             value.emplace<double>(doubleValue);
346             break;
347         }
348         default: {
349             return false;
350         }
351     }
352     return true;
353 }
354 
ReadVariant(UDVariant & value)355 bool TLVObject::ReadVariant(UDVariant &value)
356 {
357     TLVHead head {};
358     if (!ReadHead(head)) {
359         return false;
360     }
361     if (!HasExpectBuffer(head.len)) {
362         return false;
363     }
364     switch (head.tag) {
365         case static_cast<uint16_t>(TAG::TAG_INT32):
366         case static_cast<uint16_t>(TAG::TAG_INT64):
367         case static_cast<uint16_t>(TAG::TAG_BOOL):
368         case static_cast<uint16_t>(TAG::TAG_DOUBLE): {
369             if (!ReadVariantInner(head.tag, value)) {
370                 return false;
371             }
372             break;
373         }
374         case static_cast<uint16_t>(TAG::TAG_STRING): {
375             std::string stringValue;
376             if (!ReadString(stringValue)) {
377                 return false;
378             }
379             value.emplace<std::string>(stringValue);
380             break;
381         }
382         case static_cast<uint16_t>(TAG::TAG_VECTOR): {
383             std::vector<uint8_t> vectorValue;
384             if (!ReadVector(vectorValue)) {
385                 return false;
386             }
387             value.emplace<std::vector<uint8_t>>(vectorValue);
388             break;
389         }
390         default: {
391             return false;
392         }
393     }
394 
395     if (file_ != nullptr) {
396         cursor_ += sizeof(TLVHead);
397     }
398     return true;
399 }
400 
WriteMap(const UDDetails & value)401 bool TLVObject::WriteMap(const UDDetails &value)
402 {
403     if (!HasExpectBuffer(sizeof(TLVHead))) {
404         return false;
405     }
406     if (file_ != nullptr) {
407         std::vector<uint8_t> reserved {};
408         reserved.resize(sizeof(TLVHead));
409         if (fwrite(reserved.data(), sizeof(uint8_t), reserved.size(), file_) != reserved.size()) {
410             return false;
411         }
412     }
413 
414     auto tagCursor = cursor_;
415     cursor_ += sizeof(TLVHead);
416     auto valueCursor = cursor_;
417 
418     size_t total = 0;
419     for (const auto &item : value) {
420         if (!WriteString(item.first)) {
421             return false;
422         }
423         total += cursor_;
424 
425         if (!WriteVariant(item.second)) {
426             return false;
427         }
428         total += cursor_;
429     }
430     PrepareHeader(total, tagCursor, valueCursor);
431     WriteHead(static_cast<uint16_t>(TAG::TAG_MAP), tagCursor, cursor_ - valueCursor);
432     if (!SaveBufferToFile()) {
433         return false;
434     }
435     if (file_ != nullptr) {
436         fseek(file_, 0, SEEK_END);
437     }
438     return true;
439 }
440 
ReadMap(UDDetails & value)441 bool TLVObject::ReadMap(UDDetails &value)
442 {
443     TLVHead head {};
444     if (!ReadHead(head)) {
445         return false;
446     }
447     if (!HasExpectBuffer(head.len)) {
448         return false;
449     }
450     if (file_ != nullptr) {
451         cursor_ = 0;
452     }
453     auto mapEnd = cursor_ + head.len;
454     size_t total = 0;
455     while ((file_ == nullptr && cursor_ < mapEnd) || (file_ != nullptr && total < head.len)) {
456         std::string itemKey = "";
457         if (!ReadString(itemKey)) {
458             return false;
459         }
460         total += cursor_;
461         UDVariant itemValue;
462         if (!ReadVariant(itemValue)) {
463             return false;
464         }
465         total += cursor_;
466         value.emplace(itemKey, itemValue);
467     }
468     return true;
469 }
470 
ReadHead(TLVHead & head)471 bool TLVObject::ReadHead(TLVHead &head)
472 {
473     if (!LoadBufferFormFile(sizeof(TLVHead))) {
474         return false;
475     }
476     if (!HasExpectBuffer(sizeof(TLVHead))) {
477         return false;
478     }
479     const auto *pHead = reinterpret_cast<const TLVHead *>(buffer_->data() + cursor_);
480     if (!HasExpectBuffer(NetToHost(pHead->len)) &&
481         !HasExpectBuffer(NetToHost(pHead->len) + sizeof(TLVHead))) {
482         return false;
483     }
484     head.tag = NetToHost(pHead->tag);
485     head.len = NetToHost(pHead->len);
486     cursor_ += sizeof(TLVHead);
487     return true;
488 }
489 
WriteHead(uint16_t type,size_t tagCursor,uint32_t len)490 void TLVObject::WriteHead(uint16_t type, size_t tagCursor, uint32_t len)
491 {
492     auto *tlvHead = reinterpret_cast<TLVHead *>(buffer_->data() + tagCursor);
493     tlvHead->tag = HostToNet(type);
494     tlvHead->len = HostToNet(len);
495 }
496 
HasExpectBuffer(const uint32_t expectLen) const497 bool TLVObject::HasExpectBuffer(const uint32_t expectLen) const
498 {
499     if (file_ != nullptr) {
500         return true;
501     }
502     if (buffer_== nullptr) {
503         return false;
504     }
505     return buffer_->size() >= cursor_ && buffer_->size() - cursor_ >= expectLen;
506 }
507 
PrepareHeader(size_t size,size_t & tagCursor,size_t & valueCursor)508 void TLVObject::PrepareHeader(size_t size, size_t &tagCursor, size_t &valueCursor)
509 {
510     if (file_ != nullptr) {
511         cursor_ = size;
512         fseek(file_, -cursor_ - sizeof(TLVHead), SEEK_CUR);
513         buffer_->resize(sizeof(TLVHead));
514         tagCursor  = 0;
515         valueCursor = 0;
516     }
517 }
518 
PrepareBuffer(size_t size)519 void TLVObject::PrepareBuffer(size_t size)
520 {
521     if (file_ == nullptr) {
522         return;
523     }
524     buffer_->resize(size);
525     cursor_ = 0;
526 }
527 
SaveBufferToFile()528 bool TLVObject::SaveBufferToFile()
529 {
530     if (file_ == nullptr) {
531         return true;
532     }
533     auto count = fwrite(buffer_->data(), sizeof(uint8_t), buffer_->size(), file_);
534     if (count != buffer_->size()) {
535         return false;
536     }
537     return true;
538 }
539 
LoadBufferFormFile(size_t size)540 bool TLVObject::LoadBufferFormFile(size_t size)
541 {
542     if (file_ == nullptr) {
543         return true;
544     }
545     buffer_->resize(size);
546     auto count = fread(buffer_->data(), sizeof(uint8_t), buffer_->size(), file_);
547     if (count != buffer_->size()) {
548         return false;
549     }
550     cursor_ = 0;
551     return true;
552 }
553 } // namespace UDMF
554 } // namespace OHOS