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