1 /*
2 * Copyright (C) 2022 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 #include "property.h"
16 #include "media_log.h"
17 #include "mtp_packet_tools.h"
18 using namespace std;
19 namespace OHOS {
20 namespace Media {
21 static const std::map<uint32_t, std::string> FormMap = {
22     { Property::Form::None, "None" },
23     { Property::Form::Range, "Range" },
24     { Property::Form::Enum, "Enum" },
25     { Property::Form::DateTime, "DateTime" },
26 };
27 
Value()28 Property::Value::Value()
29 {
30     bin_.ui128[OFFSET_0] = 0;
31     bin_.ui128[OFFSET_1] = 0;
32     bin_.ui128[OFFSET_2] = 0;
33     bin_.ui128[OFFSET_3] = 0;
34 }
35 
Dump(uint32_t valueType)36 void Property::Value::Dump(uint32_t valueType)
37 {
38     MEDIA_DEBUG_LOG("%{private}s", ToString(valueType).c_str());
39 }
40 
ToString(uint32_t valueType)41 std::string Property::Value::ToString(uint32_t valueType)
42 {
43     std::string outStr;
44     CHECK_AND_RETURN_RET(!StrToString(valueType, outStr), outStr);
45     CHECK_AND_RETURN_RET(!BinToString(valueType, outStr), outStr);
46     outStr.assign("unknown type ");
47     outStr.append(std::to_string(valueType));
48     return outStr;
49 }
50 
BinToString(uint32_t valueType,std::string & outStr)51 bool Property::Value::BinToString(uint32_t valueType, std::string &outStr)
52 {
53     std::string valueStr;
54 
55     bool res = false;
56     if (valueType == MTP_TYPE_INT8_CODE) {
57         res = MtpPacketTool::Int8ToString(bin_.i8, valueStr);
58     } else if (valueType == MTP_TYPE_UINT8_CODE) {
59         res = MtpPacketTool::UInt8ToString(bin_.ui8, valueStr);
60     } else if (valueType == MTP_TYPE_INT16_CODE) {
61         res = MtpPacketTool::Int16ToString(bin_.i16, valueStr);
62     } else if (valueType == MTP_TYPE_UINT16_CODE) {
63         res = MtpPacketTool::UInt16ToString(bin_.ui16, valueStr);
64     } else if (valueType == MTP_TYPE_INT32_CODE) {
65         res = MtpPacketTool::Int32ToString(bin_.i32, valueStr);
66     } else if (valueType == MTP_TYPE_UINT32_CODE) {
67         res = MtpPacketTool::UInt32ToString(bin_.ui32, valueStr);
68     } else if (valueType == MTP_TYPE_INT64_CODE) {
69         res = MtpPacketTool::Int64ToString(bin_.i64, valueStr);
70     } else if (valueType == MTP_TYPE_UINT64_CODE) {
71         res = MtpPacketTool::UInt64ToString(bin_.ui64, valueStr);
72     } else if (valueType == MTP_TYPE_INT128_CODE) {
73         res = MtpPacketTool::Int128ToString(bin_.i128, valueStr);
74     } else if (valueType == MTP_TYPE_UINT128_CODE) {
75         res = MtpPacketTool::UInt128ToString(bin_.ui128, valueStr);
76     } else {
77         return false;
78     }
79 
80     if (!res) {
81         outStr.assign("bin_={}");
82         return true;
83     }
84 
85     outStr.assign("bin_={");
86     outStr.append("type=");
87     outStr.append(MtpPacketTool::GetDataTypeName(valueType));
88     outStr.append(", ");
89     outStr.append(valueStr);
90     outStr.append("}");
91     return true;
92 }
93 
StrToString(uint32_t valueType,std::string & outStr)94 bool Property::Value::StrToString(uint32_t valueType, std::string &outStr)
95 {
96     CHECK_AND_RETURN_RET(valueType == MTP_TYPE_STRING_CODE, false);
97     outStr.assign("str={");
98     if (str_ == nullptr) {
99         outStr.append("nullptr");
100     } else {
101         outStr.append(MtpPacketTool::StrToString(*str_));
102     }
103     outStr.append("}");
104     return true;
105 }
106 
Property()107 Property::Property()
108 {
109     defaultValue = std::make_shared<Value>();
110     currentValue = std::make_shared<Value>();
111     minValue = std::make_shared<Value>();
112     maxValue = std::make_shared<Value>();
113     stepSize = std::make_shared<Value>();
114 }
115 
Property(uint16_t propCode,uint16_t propType,bool propWriteable,int value)116 Property::Property(uint16_t propCode, uint16_t propType, bool propWriteable, int value)
117     : code_(propCode), type_(propType), writeable_(propWriteable)
118 {
119     defaultValue = std::make_shared<Value>();
120     currentValue = std::make_shared<Value>();
121     minValue = std::make_shared<Value>();
122     maxValue = std::make_shared<Value>();
123     stepSize = std::make_shared<Value>();
124 
125     if (value) {
126         switch (type_) {
127             case MTP_TYPE_INT8_CODE:
128                 defaultValue->bin_.i8 = static_cast<int8_t>(value);
129                 break;
130             case MTP_TYPE_UINT8_CODE:
131                 defaultValue->bin_.ui8 = static_cast<uint8_t>(value);
132                 break;
133             case MTP_TYPE_INT16_CODE:
134                 defaultValue->bin_.i16 = static_cast<int16_t>(value);
135                 break;
136             case MTP_TYPE_UINT16_CODE:
137                 defaultValue->bin_.ui16 = static_cast<uint16_t>(value);
138                 break;
139             case MTP_TYPE_INT32_CODE:
140                 defaultValue->bin_.i32 = static_cast<int32_t>(value);
141                 break;
142             case MTP_TYPE_UINT32_CODE:
143                 defaultValue->bin_.ui32 = static_cast<uint32_t>(value);
144                 break;
145             case MTP_TYPE_INT64_CODE:
146                 defaultValue->bin_.i64 = static_cast<int64_t>(value);
147                 break;
148             case MTP_TYPE_UINT64_CODE:
149                 defaultValue->bin_.ui64 = static_cast<uint64_t>(value);
150                 break;
151             default:
152                 MEDIA_ERR_LOG("Property::Property unknown type %{private}u", type_);
153                 break;
154         }
155     }
156 }
157 
~Property()158 Property::~Property()
159 {
160 }
161 
GetPropertyCode() const162 uint16_t Property::GetPropertyCode() const
163 {
164     return code_;
165 }
166 
GetDataType() const167 uint16_t Property::GetDataType() const
168 {
169     return type_;
170 }
171 
Read(const std::vector<uint8_t> & buffer,size_t & offset)172 bool Property::Read(const std::vector<uint8_t> &buffer, size_t &offset)
173 {
174     CHECK_AND_RETURN_RET_LOG(MtpPacketTool::GetUInt16(buffer, offset, code_), false,
175         "Property::read code error");
176     CHECK_AND_RETURN_RET_LOG(MtpPacketTool::GetUInt16(buffer, offset, type_), false,
177         "Property::read type error");
178     uint8_t tmpVar = 0;
179     CHECK_AND_RETURN_RET_LOG(MtpPacketTool::GetUInt8(buffer, offset, tmpVar), false,
180         "Property::read tmpVar error");
181     writeable_ = (tmpVar == 1);
182     CHECK_AND_RETURN_RET_LOG(ReadValueData(buffer, offset), false,
183         "Property::read valuedata error");
184     bool deviceProp = IsDeviceProperty();
185     bool cond = (!deviceProp && !MtpPacketTool::GetUInt32(buffer, offset, groupCode_));
186     CHECK_AND_RETURN_RET_LOG(!cond, false, "Property::read group error");
187     CHECK_AND_RETURN_RET_LOG(ReadFormData(buffer, offset), false, "Property::read formdata error");
188     return true;
189 }
190 
Write(std::vector<uint8_t> & buffer)191 void Property::Write(std::vector<uint8_t> &buffer)
192 {
193     MtpPacketTool::PutUInt16(buffer, code_);
194     MtpPacketTool::PutUInt16(buffer, type_);
195     MtpPacketTool::PutUInt8(buffer, writeable_ ? 1 : 0);
196 
197     WriteValueData(buffer);
198 
199     bool deviceProp = IsDeviceProperty();
200     MEDIA_DEBUG_LOG("Property::write deviceProp=%{private}u", deviceProp);
201     if (!deviceProp) {
202         MtpPacketTool::PutUInt32(buffer, groupCode_);
203     }
204 
205     WriteFormData(buffer);
206 }
207 
SetDefaultValue(const std::shared_ptr<std::string> & str)208 void Property::SetDefaultValue(const std::shared_ptr<std::string> &str)
209 {
210     defaultValue->str_ = str;
211 }
212 
SetCurrentValue(const std::shared_ptr<std::string> & str)213 void Property::SetCurrentValue(const std::shared_ptr<std::string> &str)
214 {
215     currentValue->str_ = str;
216 }
217 
GetCurrentValue()218 const std::shared_ptr<Property::Value> Property::GetCurrentValue()
219 {
220     return currentValue;
221 }
222 
SetFormRange(int min,int max,int step)223 void Property::SetFormRange(int min, int max, int step)
224 {
225     formFlag_ = Form::Range;
226     switch (type_) {
227         case MTP_TYPE_INT8_CODE:
228             minValue->bin_.i8 = static_cast<int8_t>(min);
229             maxValue->bin_.i8 = static_cast<int8_t>(max);
230             stepSize->bin_.i8 = static_cast<int8_t>(step);
231             break;
232         case MTP_TYPE_UINT8_CODE:
233             minValue->bin_.ui8 = static_cast<uint8_t>(min);
234             maxValue->bin_.ui8 = static_cast<uint8_t>(max);
235             stepSize->bin_.ui8 = static_cast<uint8_t>(step);
236             break;
237         case MTP_TYPE_INT16_CODE:
238             minValue->bin_.i16 = static_cast<int16_t>(min);
239             maxValue->bin_.i16 = static_cast<int16_t>(max);
240             stepSize->bin_.i16 = static_cast<int16_t>(step);
241             break;
242         case MTP_TYPE_UINT16_CODE:
243             minValue->bin_.ui16 = static_cast<uint16_t>(min);
244             maxValue->bin_.ui16 = static_cast<uint16_t>(max);
245             stepSize->bin_.ui16 = static_cast<uint16_t>(step);
246             break;
247         case MTP_TYPE_INT32_CODE:
248             minValue->bin_.i32 = static_cast<int32_t>(min);
249             maxValue->bin_.i32 = static_cast<int32_t>(max);
250             stepSize->bin_.i32 = static_cast<int32_t>(step);
251             break;
252         case MTP_TYPE_UINT32_CODE:
253             minValue->bin_.ui32 = static_cast<uint32_t>(min);
254             maxValue->bin_.ui32 = static_cast<uint32_t>(max);
255             stepSize->bin_.ui32 = static_cast<uint32_t>(step);
256             break;
257         case MTP_TYPE_INT64_CODE:
258             minValue->bin_.i64 = static_cast<int64_t>(min);
259             maxValue->bin_.i64 = static_cast<int64_t>(max);
260             stepSize->bin_.i64 = static_cast<int64_t>(step);
261             break;
262         case MTP_TYPE_UINT64_CODE:
263             minValue->bin_.ui64 = static_cast<uint64_t>(min);
264             maxValue->bin_.ui64 = static_cast<uint64_t>(max);
265             stepSize->bin_.ui64 = static_cast<uint64_t>(step);
266             break;
267         default:
268             MEDIA_ERR_LOG("Property::setFormRange unsupported type %{private}u", type_);
269             break;
270     }
271 }
272 
SetFormEnum(const std::vector<int> & values)273 void Property::SetFormEnum(const std::vector<int> &values)
274 {
275     formFlag_ = Form::Enum;
276     enumValues = std::make_shared<std::vector<Value>>();
277 
278     Value v;
279     for (auto value : values) {
280         switch (type_) {
281             case MTP_TYPE_INT8_CODE:
282                 v.bin_.i8 = static_cast<int8_t>(value);
283                 break;
284             case MTP_TYPE_UINT8_CODE:
285                 v.bin_.ui8 = static_cast<uint8_t>(value);
286                 break;
287             case MTP_TYPE_INT16_CODE:
288                 v.bin_.i16 = static_cast<int16_t>(value);
289                 break;
290             case MTP_TYPE_UINT16_CODE:
291                 v.bin_.ui16 = static_cast<uint16_t>(value);
292                 break;
293             case MTP_TYPE_INT32_CODE:
294                 v.bin_.i32 = static_cast<int32_t>(value);
295                 break;
296             case MTP_TYPE_UINT32_CODE:
297                 v.bin_.ui32 = static_cast<uint32_t>(value);
298                 break;
299             case MTP_TYPE_INT64_CODE:
300                 v.bin_.i64 = static_cast<int64_t>(value);
301                 break;
302             case MTP_TYPE_UINT64_CODE:
303                 v.bin_.ui64 = static_cast<uint64_t>(value);
304                 break;
305             default:
306                 MEDIA_ERR_LOG("Property::setFormEnum unsupported type %{private}u", type_);
307                 break;
308         }
309         enumValues->push_back(v);
310     }
311 }
312 
SetFormDateTime()313 void Property::SetFormDateTime()
314 {
315     formFlag_ = Form::DateTime;
316 }
317 
IsDeviceProperty() const318 bool Property::IsDeviceProperty() const
319 {
320     // bit values defined by protocol, check if code is device property
321     return (((code_ & 0xF000) == 0x5000) || ((code_ & 0xF800) == 0xD000));
322 }
323 
IsArrayType() const324 bool Property::IsArrayType() const
325 {
326     return ((type_ >= MTP_DEVICE_PROP_DESC_TYPE_AINT8) && (type_ <= MTP_DEVICE_PROP_DESC_TYPE_AUINT128));
327 }
328 
ReadValueData(const std::vector<uint8_t> & buffer,size_t & offset)329 bool Property::ReadValueData(const std::vector<uint8_t> &buffer, size_t &offset)
330 {
331     bool deviceProp = IsDeviceProperty();
332     switch (type_) {
333         case MTP_TYPE_AINT8_CODE:
334         case MTP_TYPE_AUINT8_CODE:
335         case MTP_TYPE_AINT16_CODE:
336         case MTP_TYPE_AUINT16_CODE:
337         case MTP_TYPE_AINT32_CODE:
338         case MTP_TYPE_AUINT32_CODE:
339         case MTP_TYPE_AINT64_CODE:
340         case MTP_TYPE_AUINT64_CODE:
341         case MTP_TYPE_AINT128_CODE:
342         case MTP_TYPE_AUINT128_CODE: {
343             CHECK_AND_RETURN_RET_LOG(ReadArrayValues(buffer, offset, defaultValues), false,
344                 "Property::readValueData defaultValues error");
345             if (deviceProp) {
346                 CHECK_AND_RETURN_RET_LOG(ReadArrayValues(buffer, offset, currentValues), false,
347                     "Property::readValueData currentValues error");
348             }
349             break;
350         }
351         default: {
352             CHECK_AND_RETURN_RET_LOG(ReadValue(buffer, offset, *defaultValue), false,
353                 "Property::readValueData defaultValue error");
354             if (deviceProp) {
355                 CHECK_AND_RETURN_RET_LOG(ReadValue(buffer, offset, *currentValue), false,
356                     "Property::readValueData currentValues error");
357             }
358         }
359     }
360     return true;
361 }
362 
ReadFormData(const std::vector<uint8_t> & buffer,size_t & offset)363 bool Property::ReadFormData(const std::vector<uint8_t> &buffer, size_t &offset)
364 {
365     CHECK_AND_RETURN_RET_LOG(MtpPacketTool::GetUInt8(buffer, offset, formFlag_), false,
366         "Property::readFormData flag error");
367 
368     if (formFlag_ == Form::Range) {
369         CHECK_AND_RETURN_RET_LOG(ReadValue(buffer, offset, *minValue), false, "Property::readFormData minValue error");
370         CHECK_AND_RETURN_RET_LOG(ReadValue(buffer, offset, *maxValue), false, "Property::readFormData maxValue error");
371         CHECK_AND_RETURN_RET_LOG(ReadValue(buffer, offset, *stepSize), false, "Property::readFormData stepSize error");
372     } else if (formFlag_ == Form::Enum) {
373         uint16_t len = 0;
374         CHECK_AND_RETURN_RET_LOG(MtpPacketTool::GetUInt16(buffer, offset, len), false,
375             "Property::readFormData len error");
376         enumValues = std::make_shared<std::vector<Value>>();
377         Value value;
378         for (int i = 0; i < len; i++) {
379             CHECK_AND_RETURN_RET_LOG(ReadValue(buffer, offset, value), false,
380                 "Property::readFormData i=%{private}u", i);
381             enumValues->push_back(value);
382         }
383     }
384 
385     return true;
386 }
387 
WriteValueData(std::vector<uint8_t> & buffer)388 void Property::WriteValueData(std::vector<uint8_t> &buffer)
389 {
390     switch (type_) {
391         case MTP_TYPE_AINT8_CODE:
392         case MTP_TYPE_AUINT8_CODE:
393         case MTP_TYPE_AINT16_CODE:
394         case MTP_TYPE_AUINT16_CODE:
395         case MTP_TYPE_AINT32_CODE:
396         case MTP_TYPE_AUINT32_CODE:
397         case MTP_TYPE_AINT64_CODE:
398         case MTP_TYPE_AUINT64_CODE:
399         case MTP_TYPE_AINT128_CODE:
400         case MTP_TYPE_AUINT128_CODE: {
401             WriteArrayValues(buffer, defaultValues);
402             if (IsDeviceProperty()) {
403                 WriteArrayValues(buffer, currentValues);
404             }
405             break;
406         }
407         default: {
408             WriteValue(buffer, *defaultValue);
409             if (IsDeviceProperty()) {
410                 WriteValue(buffer, *currentValue);
411             }
412         }
413     }
414 }
415 
WriteFormData(std::vector<uint8_t> & buffer)416 void Property::WriteFormData(std::vector<uint8_t> &buffer)
417 {
418     MtpPacketTool::PutUInt8(buffer, formFlag_);
419     if (formFlag_ == Form::Range) {
420         WriteValue(buffer, *minValue);
421         WriteValue(buffer, *maxValue);
422         WriteValue(buffer, *stepSize);
423     } else if (formFlag_ == Form::Enum) {
424         uint32_t valueSum = (enumValues == nullptr) ? 0 : enumValues->size();
425         MtpPacketTool::PutUInt16(buffer, valueSum);
426         for (uint32_t i = 0; i < valueSum; i++) {
427             WriteValue(buffer, (*enumValues)[i]);
428         }
429     }
430 }
431 
ReadValue(const std::vector<uint8_t> & buffer,size_t & offset,Value & value)432 bool Property::ReadValue(const std::vector<uint8_t> &buffer, size_t &offset, Value &value)
433 {
434     switch (type_) {
435         case MTP_TYPE_INT8_CODE:
436         case MTP_TYPE_AINT8_CODE:
437             if (!MtpPacketTool::GetInt8(buffer, offset, value.bin_.i8)) {
438                 return false;
439             }
440             break;
441         case MTP_TYPE_UINT8_CODE:
442         case MTP_TYPE_AUINT8_CODE:
443             if (!MtpPacketTool::GetUInt8(buffer, offset, value.bin_.ui8)) {
444                 return false;
445             }
446             break;
447         case MTP_TYPE_INT16_CODE:
448         case MTP_TYPE_AINT16_CODE:
449             if (!MtpPacketTool::GetInt16(buffer, offset, value.bin_.i16)) {
450                 return false;
451             }
452             break;
453         case MTP_TYPE_UINT16_CODE:
454         case MTP_TYPE_AUINT16_CODE:
455             if (!MtpPacketTool::GetUInt16(buffer, offset, value.bin_.ui16)) {
456                 return false;
457             }
458             break;
459         case MTP_TYPE_INT32_CODE:
460         case MTP_TYPE_AINT32_CODE:
461             if (!MtpPacketTool::GetInt32(buffer, offset, value.bin_.i32)) {
462                 return false;
463             }
464             break;
465         case MTP_TYPE_UINT32_CODE:
466         case MTP_TYPE_AUINT32_CODE:
467             if (!MtpPacketTool::GetUInt32(buffer, offset, value.bin_.ui32)) {
468                 return false;
469             }
470             break;
471         default: {
472             if (!ReadValueEx(buffer, offset, value)) {
473                 return false;
474             }
475             break;
476         }
477     }
478     return true;
479 }
480 
ReadValueEx(const std::vector<uint8_t> & buffer,size_t & offset,Value & value)481 bool Property::ReadValueEx(const std::vector<uint8_t> &buffer, size_t &offset, Value &value)
482 {
483     switch (type_) {
484         case MTP_TYPE_INT64_CODE:
485         case MTP_TYPE_AINT64_CODE: {
486             CHECK_AND_RETURN_RET(MtpPacketTool::GetInt64(buffer, offset,
487                 value.bin_.i64), false);
488             break;
489         }
490         case MTP_TYPE_UINT64_CODE:
491         case MTP_TYPE_AUINT64_CODE: {
492             CHECK_AND_RETURN_RET(MtpPacketTool::GetUInt64(buffer, offset,
493                 value.bin_.ui64), false);
494             break;
495         }
496         case MTP_TYPE_INT128_CODE:
497         case MTP_TYPE_AINT128_CODE: {
498             CHECK_AND_RETURN_RET(MtpPacketTool::GetInt128(buffer, offset,
499                 value.bin_.i128), false);
500             break;
501         }
502         case MTP_TYPE_UINT128_CODE:
503         case MTP_TYPE_AUINT128_CODE: {
504             CHECK_AND_RETURN_RET(MtpPacketTool::GetUInt128(buffer, offset,
505                 value.bin_.ui128), false);
506             break;
507         }
508         case MTP_TYPE_STRING_CODE: {
509             std::string str;
510             CHECK_AND_RETURN_RET(MtpPacketTool::GetString(buffer, offset, str), false);
511             value.str_ = std::make_shared<std::string>(str);
512             break;
513         }
514         default:
515             MEDIA_ERR_LOG("unknown type %{private}u in Property::ReadValue", type_);
516             return false;
517     }
518     return true;
519 }
520 
WriteValue(std::vector<uint8_t> & buffer,const Value & value)521 void Property::WriteValue(std::vector<uint8_t> &buffer, const Value &value)
522 {
523     switch (type_) {
524         case MTP_TYPE_INT8_CODE:
525         case MTP_TYPE_AINT8_CODE:
526             MtpPacketTool::PutUInt8(buffer, static_cast<uint8_t>(value.bin_.i8));
527             break;
528         case MTP_TYPE_UINT8_CODE:
529         case MTP_TYPE_AUINT8_CODE:
530             MtpPacketTool::PutUInt8(buffer, value.bin_.ui8);
531             break;
532         case MTP_TYPE_INT16_CODE:
533         case MTP_TYPE_AINT16_CODE:
534             MtpPacketTool::PutUInt16(buffer, static_cast<uint16_t>(value.bin_.i16));
535             break;
536         case MTP_TYPE_UINT16_CODE:
537         case MTP_TYPE_AUINT16_CODE:
538             MtpPacketTool::PutUInt16(buffer, value.bin_.ui16);
539             break;
540         case MTP_TYPE_INT32_CODE:
541         case MTP_TYPE_AINT32_CODE:
542             MtpPacketTool::PutUInt32(buffer, static_cast<uint32_t>(value.bin_.i32));
543             break;
544         case MTP_TYPE_UINT32_CODE:
545         case MTP_TYPE_AUINT32_CODE:
546             MtpPacketTool::PutUInt32(buffer, value.bin_.ui32);
547             break;
548         default: {
549             WriteValueEx(buffer, value);
550             break;
551         }
552     }
553 }
554 
WriteValueEx(std::vector<uint8_t> & buffer,const Value & value)555 void Property::WriteValueEx(std::vector<uint8_t> &buffer, const Value &value)
556 {
557     switch (type_) {
558         case MTP_TYPE_INT64_CODE:
559         case MTP_TYPE_AINT64_CODE:
560             MtpPacketTool::PutUInt64(buffer, static_cast<uint64_t>(value.bin_.i64));
561             break;
562         case MTP_TYPE_UINT64_CODE:
563         case MTP_TYPE_AUINT64_CODE:
564             MtpPacketTool::PutUInt64(buffer, value.bin_.ui64);
565             break;
566         case MTP_TYPE_INT128_CODE:
567         case MTP_TYPE_AINT128_CODE:
568             MtpPacketTool::PutInt128(buffer, value.bin_.i128);
569             break;
570         case MTP_TYPE_UINT128_CODE:
571         case MTP_TYPE_AUINT128_CODE:
572             MtpPacketTool::PutUInt128(buffer, value.bin_.ui128);
573             break;
574         case MTP_TYPE_STRING_CODE:
575             if (value.str_ == nullptr) {
576                 MtpPacketTool::PutUInt8(buffer, 0);
577             } else {
578                 MtpPacketTool::PutString(buffer, *(value.str_));
579             }
580             break;
581         default:
582             MEDIA_ERR_LOG("Property::writeValue unknown type %{private}u", type_);
583     }
584 }
585 
ReadArrayValues(const std::vector<uint8_t> & buffer,size_t & offset,std::shared_ptr<std::vector<Value>> & values)586 bool Property::ReadArrayValues(const std::vector<uint8_t> &buffer, size_t &offset,
587     std::shared_ptr<std::vector<Value>> &values)
588 {
589     uint32_t length = 0;
590     CHECK_AND_RETURN_RET(MtpPacketTool::GetUInt32(buffer, offset, length), false);
591     bool cond = (length == 0 || (length >= (INT32_MAX / sizeof(Value))));
592     CHECK_AND_RETURN_RET(!cond, false);
593     if (values == nullptr) {
594         values = std::make_shared<std::vector<Value>>();
595     }
596 
597     values->clear();
598     for (uint32_t i = 0; i < length; i++) {
599         Value value;
600         CHECK_AND_RETURN_RET(ReadValue(buffer, offset, value), false);
601         values->push_back(value);
602     }
603     return true;
604 }
605 
WriteArrayValues(std::vector<uint8_t> & buffer,const std::shared_ptr<std::vector<Value>> & values)606 void Property::WriteArrayValues(std::vector<uint8_t> &buffer,
607     const std::shared_ptr<std::vector<Value>> &values)
608 {
609     uint32_t valueSum = (values == nullptr) ? 0 : values->size();
610     MtpPacketTool::PutUInt32(buffer, valueSum);
611     for (uint32_t i = 0; i < valueSum; i++) {
612         WriteValue(buffer, (*values)[i]);
613     }
614 }
615 
Dump()616 void Property::Dump()
617 {
618     int indent = 1;
619     std::string indentStr = MtpPacketTool::GetIndentBlank(indent);
620 
621     MEDIA_DEBUG_LOG("handle=%{private}x", handle_);
622     MEDIA_DEBUG_LOG("### Property {property=%{private}s(%{private}x)} begin ###",
623         MtpPacketTool::GetObjectPropName(code_).c_str(), code_);
624     MEDIA_DEBUG_LOG("%{private}stype=[%{private}s](%{private}x)}, writeable_=%{private}d",
625         indentStr.c_str(), MtpPacketTool::GetDataTypeName(type_).c_str(), type_, writeable_);
626 
627     if (!IsArrayType()) {
628         DumpValue(indent, defaultValue, "defaultValue");
629         DumpValue(indent, currentValue, "currentValue");
630     } else {
631         DumpValues(indent, defaultValues, "defaultValues");
632         DumpValues(indent, currentValues, "currentValues");
633     }
634 
635     MEDIA_DEBUG_LOG("%{private}sgroupCode=%{private}u", indentStr.c_str(), groupCode_);
636     DumpForm(indent);
637     MEDIA_DEBUG_LOG("+++ Property end +++");
638 }
639 
DumpValue(uint8_t indent,const std::shared_ptr<Value> & value,const std::string & name)640 void Property::DumpValue(uint8_t indent, const std::shared_ptr<Value> &value, const std::string &name)
641 {
642     std::string indentStr = MtpPacketTool::GetIndentBlank(indent);
643 
644     MEDIA_DEBUG_LOG("%{private}s%{private}s=%{private}s", indentStr.c_str(), name.c_str(),
645         (value == nullptr) ? "nullptr" : value->ToString(type_).c_str());
646 }
647 
DumpValues(uint8_t indent,const std::shared_ptr<std::vector<Value>> & values,const std::string & name)648 void Property::DumpValues(uint8_t indent, const std::shared_ptr<std::vector<Value>> &values, const std::string &name)
649 {
650     std::string indentStr = MtpPacketTool::GetIndentBlank(indent);
651 
652     if (values == nullptr) {
653         MEDIA_DEBUG_LOG("%{private}s%{private}s=nullptr", indentStr.c_str(), name.c_str());
654     } else {
655         std::string indentStr2 = MtpPacketTool::GetIndentBlank(indent + 1);
656         for (auto &v : (*values)) {
657             MEDIA_DEBUG_LOG("%{private}s%{private}s", indentStr2.c_str(), v.ToString(type_).c_str());
658         }
659         MEDIA_DEBUG_LOG("%{private}s--- value end ---", indentStr.c_str());
660     }
661 }
662 
DumpForm(uint8_t indent)663 void Property::DumpForm(uint8_t indent)
664 {
665     std::string indentStr = MtpPacketTool::GetIndentBlank(indent);
666 
667     MEDIA_DEBUG_LOG("%{private}sformFlag=%{private}s(%{private}u)",
668         indentStr.c_str(), MtpPacketTool::CodeToStrByMap(formFlag_, FormMap).c_str(), formFlag_);
669 
670     if (formFlag_ == Form::Range) {
671         DumpValue(indent + 1, minValue, "minValue");
672         DumpValue(indent + 1, maxValue, "maxValue");
673         DumpValue(indent + 1, stepSize, "stepSize");
674     } else if (formFlag_ == Form::Enum) {
675         DumpValues(indent + 1, enumValues, "enumValues");
676     } else if (formFlag_ == Form::DateTime) {
677         MEDIA_DEBUG_LOG("Form::DateTime");
678     } else {
679         MEDIA_DEBUG_LOG("unknow type");
680     }
681 }
682 } // namespace Media
683 } // namespace OHOS