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