blob: 126cb79051cff2a591daab4e8949f654fd13b09a [file] [log] [blame]
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -04001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -05008 * http://www.apache.org/licenses/LICENSE-2.0
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -04009 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040015 */
16
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -050017#define LOG_TAG "MtpProperty"
18
19#include <inttypes.h>
20#include <cutils/compiler.h>
21#include <iomanip>
22#include <sstream>
23#include <string>
24
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040025#include "MtpDataPacket.h"
26#include "MtpDebug.h"
27#include "MtpProperty.h"
28#include "MtpStringBuffer.h"
29#include "MtpUtils.h"
30
31MtpProperty::MtpProperty()
32 : mCode(0),
33 mType(0),
34 mWriteable(false),
35 mDefaultArrayLength(0),
36 mDefaultArrayValues(NULL),
37 mCurrentArrayLength(0),
38 mCurrentArrayValues(NULL),
39 mGroupCode(0),
40 mFormFlag(kFormNone),
41 mEnumLength(0),
42 mEnumValues(NULL)
43{
44 memset(&mDefaultValue, 0, sizeof(mDefaultValue));
45 memset(&mCurrentValue, 0, sizeof(mCurrentValue));
46 memset(&mMinimumValue, 0, sizeof(mMinimumValue));
47 memset(&mMaximumValue, 0, sizeof(mMaximumValue));
48}
49
50MtpProperty::MtpProperty(MtpPropertyCode propCode,
51 MtpDataType type,
52 bool writeable,
53 int defaultValue)
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -050054 : mCode(propCode),
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040055 mType(type),
56 mWriteable(writeable),
57 mDefaultArrayLength(0),
58 mDefaultArrayValues(NULL),
59 mCurrentArrayLength(0),
60 mCurrentArrayValues(NULL),
61 mGroupCode(0),
62 mFormFlag(kFormNone),
63 mEnumLength(0),
64 mEnumValues(NULL)
65{
66 memset(&mDefaultValue, 0, sizeof(mDefaultValue));
67 memset(&mCurrentValue, 0, sizeof(mCurrentValue));
68 memset(&mMinimumValue, 0, sizeof(mMinimumValue));
69 memset(&mMaximumValue, 0, sizeof(mMaximumValue));
70
71 if (defaultValue) {
72 switch (type) {
73 case MTP_TYPE_INT8:
74 mDefaultValue.u.i8 = defaultValue;
75 break;
76 case MTP_TYPE_UINT8:
77 mDefaultValue.u.u8 = defaultValue;
78 break;
79 case MTP_TYPE_INT16:
80 mDefaultValue.u.i16 = defaultValue;
81 break;
82 case MTP_TYPE_UINT16:
83 mDefaultValue.u.u16 = defaultValue;
84 break;
85 case MTP_TYPE_INT32:
86 mDefaultValue.u.i32 = defaultValue;
87 break;
88 case MTP_TYPE_UINT32:
89 mDefaultValue.u.u32 = defaultValue;
90 break;
91 case MTP_TYPE_INT64:
92 mDefaultValue.u.i64 = defaultValue;
93 break;
94 case MTP_TYPE_UINT64:
95 mDefaultValue.u.u64 = defaultValue;
96 break;
97 default:
98 MTPE("unknown type %04X in MtpProperty::MtpProperty", type);
99 }
100 }
101}
102
103MtpProperty::~MtpProperty() {
104 if (mType == MTP_TYPE_STR) {
105 // free all strings
106 free(mDefaultValue.str);
107 free(mCurrentValue.str);
108 free(mMinimumValue.str);
109 free(mMaximumValue.str);
110 if (mDefaultArrayValues) {
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500111 for (uint32_t i = 0; i < mDefaultArrayLength; i++)
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400112 free(mDefaultArrayValues[i].str);
113 }
114 if (mCurrentArrayValues) {
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500115 for (uint32_t i = 0; i < mCurrentArrayLength; i++)
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400116 free(mCurrentArrayValues[i].str);
117 }
118 if (mEnumValues) {
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500119 for (uint16_t i = 0; i < mEnumLength; i++)
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400120 free(mEnumValues[i].str);
121 }
122 }
123 delete[] mDefaultArrayValues;
124 delete[] mCurrentArrayValues;
125 delete[] mEnumValues;
126}
127
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500128bool MtpProperty::read(MtpDataPacket& packet) {
129 uint8_t temp8;
130
131 if (!packet.getUInt16(mCode)) return false;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400132 bool deviceProp = isDeviceProperty();
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500133 if (!packet.getUInt16(mType)) return false;
134 if (!packet.getUInt8(temp8)) return false;
135 mWriteable = (temp8 == 1);
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400136 switch (mType) {
137 case MTP_TYPE_AINT8:
138 case MTP_TYPE_AUINT8:
139 case MTP_TYPE_AINT16:
140 case MTP_TYPE_AUINT16:
141 case MTP_TYPE_AINT32:
142 case MTP_TYPE_AUINT32:
143 case MTP_TYPE_AINT64:
144 case MTP_TYPE_AUINT64:
145 case MTP_TYPE_AINT128:
146 case MTP_TYPE_AUINT128:
147 mDefaultArrayValues = readArrayValues(packet, mDefaultArrayLength);
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500148 if (!mDefaultArrayValues) return false;
149 if (deviceProp) {
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400150 mCurrentArrayValues = readArrayValues(packet, mCurrentArrayLength);
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500151 if (!mCurrentArrayValues) return false;
152 }
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400153 break;
154 default:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500155 if (!readValue(packet, mDefaultValue)) return false;
156 if (deviceProp) {
157 if (!readValue(packet, mCurrentValue)) return false;
158 }
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400159 }
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500160 if (!deviceProp) {
161 if (!packet.getUInt32(mGroupCode)) return false;
162 }
163 if (!packet.getUInt8(mFormFlag)) return false;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400164
165 if (mFormFlag == kFormRange) {
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500166 if (!readValue(packet, mMinimumValue)) return false;
167 if (!readValue(packet, mMaximumValue)) return false;
168 if (!readValue(packet, mStepSize)) return false;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400169 } else if (mFormFlag == kFormEnum) {
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500170 if (!packet.getUInt16(mEnumLength)) return false;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400171 mEnumValues = new MtpPropertyValue[mEnumLength];
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500172 for (int i = 0; i < mEnumLength; i++) {
173 if (!readValue(packet, mEnumValues[i])) return false;
174 }
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400175 }
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500176
177 return true;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400178}
179
180void MtpProperty::write(MtpDataPacket& packet) {
181 bool deviceProp = isDeviceProperty();
182
183 packet.putUInt16(mCode);
184 packet.putUInt16(mType);
185 packet.putUInt8(mWriteable ? 1 : 0);
186
187 switch (mType) {
188 case MTP_TYPE_AINT8:
189 case MTP_TYPE_AUINT8:
190 case MTP_TYPE_AINT16:
191 case MTP_TYPE_AUINT16:
192 case MTP_TYPE_AINT32:
193 case MTP_TYPE_AUINT32:
194 case MTP_TYPE_AINT64:
195 case MTP_TYPE_AUINT64:
196 case MTP_TYPE_AINT128:
197 case MTP_TYPE_AUINT128:
198 writeArrayValues(packet, mDefaultArrayValues, mDefaultArrayLength);
199 if (deviceProp)
200 writeArrayValues(packet, mCurrentArrayValues, mCurrentArrayLength);
201 break;
202 default:
203 writeValue(packet, mDefaultValue);
204 if (deviceProp)
205 writeValue(packet, mCurrentValue);
206 }
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400207 if (!deviceProp)
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500208 packet.putUInt32(mGroupCode);
209 packet.putUInt8(mFormFlag);
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400210 if (mFormFlag == kFormRange) {
211 writeValue(packet, mMinimumValue);
212 writeValue(packet, mMaximumValue);
213 writeValue(packet, mStepSize);
214 } else if (mFormFlag == kFormEnum) {
215 packet.putUInt16(mEnumLength);
216 for (int i = 0; i < mEnumLength; i++)
217 writeValue(packet, mEnumValues[i]);
218 }
219}
220
221void MtpProperty::setDefaultValue(const uint16_t* string) {
222 free(mDefaultValue.str);
223 if (string) {
224 MtpStringBuffer buffer(string);
225 mDefaultValue.str = strdup(buffer);
226 }
227 else
228 mDefaultValue.str = NULL;
229}
230
231void MtpProperty::setCurrentValue(const uint16_t* string) {
232 free(mCurrentValue.str);
233 if (string) {
234 MtpStringBuffer buffer(string);
235 mCurrentValue.str = strdup(buffer);
236 }
237 else
238 mCurrentValue.str = NULL;
239}
240
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500241void MtpProperty::setCurrentValue(MtpDataPacket& packet) {
242 free(mCurrentValue.str);
243 mCurrentValue.str = NULL;
244 readValue(packet, mCurrentValue);
245}
246
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400247void MtpProperty::setFormRange(int min, int max, int step) {
248 mFormFlag = kFormRange;
249 switch (mType) {
250 case MTP_TYPE_INT8:
251 mMinimumValue.u.i8 = min;
252 mMaximumValue.u.i8 = max;
253 mStepSize.u.i8 = step;
254 break;
255 case MTP_TYPE_UINT8:
256 mMinimumValue.u.u8 = min;
257 mMaximumValue.u.u8 = max;
258 mStepSize.u.u8 = step;
259 break;
260 case MTP_TYPE_INT16:
261 mMinimumValue.u.i16 = min;
262 mMaximumValue.u.i16 = max;
263 mStepSize.u.i16 = step;
264 break;
265 case MTP_TYPE_UINT16:
266 mMinimumValue.u.u16 = min;
267 mMaximumValue.u.u16 = max;
268 mStepSize.u.u16 = step;
269 break;
270 case MTP_TYPE_INT32:
271 mMinimumValue.u.i32 = min;
272 mMaximumValue.u.i32 = max;
273 mStepSize.u.i32 = step;
274 break;
275 case MTP_TYPE_UINT32:
276 mMinimumValue.u.u32 = min;
277 mMaximumValue.u.u32 = max;
278 mStepSize.u.u32 = step;
279 break;
280 case MTP_TYPE_INT64:
281 mMinimumValue.u.i64 = min;
282 mMaximumValue.u.i64 = max;
283 mStepSize.u.i64 = step;
284 break;
285 case MTP_TYPE_UINT64:
286 mMinimumValue.u.u64 = min;
287 mMaximumValue.u.u64 = max;
288 mStepSize.u.u64 = step;
289 break;
290 default:
291 MTPE("unsupported type for MtpProperty::setRange");
292 break;
293 }
294}
295
296void MtpProperty::setFormEnum(const int* values, int count) {
297 mFormFlag = kFormEnum;
298 delete[] mEnumValues;
299 mEnumValues = new MtpPropertyValue[count];
300 mEnumLength = count;
301
302 for (int i = 0; i < count; i++) {
303 int value = *values++;
304 switch (mType) {
305 case MTP_TYPE_INT8:
306 mEnumValues[i].u.i8 = value;
307 break;
308 case MTP_TYPE_UINT8:
309 mEnumValues[i].u.u8 = value;
310 break;
311 case MTP_TYPE_INT16:
312 mEnumValues[i].u.i16 = value;
313 break;
314 case MTP_TYPE_UINT16:
315 mEnumValues[i].u.u16 = value;
316 break;
317 case MTP_TYPE_INT32:
318 mEnumValues[i].u.i32 = value;
319 break;
320 case MTP_TYPE_UINT32:
321 mEnumValues[i].u.u32 = value;
322 break;
323 case MTP_TYPE_INT64:
324 mEnumValues[i].u.i64 = value;
325 break;
326 case MTP_TYPE_UINT64:
327 mEnumValues[i].u.u64 = value;
328 break;
329 default:
330 MTPE("unsupported type for MtpProperty::setEnum");
331 break;
332 }
333 }
334}
335
336void MtpProperty::setFormDateTime() {
337 mFormFlag = kFormDateTime;
338}
339
340void MtpProperty::print() {
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500341 std::string buffer;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400342 bool deviceProp = isDeviceProperty();
343 if (deviceProp)
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500344 MTPD(" %s (%04X)", MtpDebug::getDevicePropCodeName(mCode), mCode);
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400345 else
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500346 MTPD(" %s (%04X)", MtpDebug::getObjectPropCodeName(mCode), mCode);
347 MTPD(" type %04X", mType);
348 MTPD(" writeable %s", (mWriteable ? "true" : "false"));
349 buffer = " default value: ";
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400350 print(mDefaultValue, buffer);
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500351 MTPD("%s", buffer.c_str());
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400352 if (deviceProp) {
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500353 buffer = " current value: ";
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400354 print(mCurrentValue, buffer);
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500355 MTPD("%s", buffer.c_str());
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400356 }
357 switch (mFormFlag) {
358 case kFormNone:
359 break;
360 case kFormRange:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500361 buffer = " Range (";
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400362 print(mMinimumValue, buffer);
363 buffer += ", ";
364 print(mMaximumValue, buffer);
365 buffer += ", ";
366 print(mStepSize, buffer);
367 buffer += ")";
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500368 MTPD("%s", buffer.c_str());
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400369 break;
370 case kFormEnum:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500371 buffer = " Enum { ";
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400372 for (int i = 0; i < mEnumLength; i++) {
373 print(mEnumValues[i], buffer);
374 buffer += " ";
375 }
376 buffer += "}";
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500377 MTPD("%s", buffer.c_str());
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400378 break;
379 case kFormDateTime:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500380 MTPD(" DateTime\n");
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400381 break;
382 default:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500383 MTPD(" form %d\n", mFormFlag);
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400384 break;
385 }
386}
387
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500388void MtpProperty::print(MtpPropertyValue& value, std::string& buffer) {
389 std::ostringstream s;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400390 switch (mType) {
391 case MTP_TYPE_INT8:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500392 buffer += std::to_string(value.u.i8);
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400393 break;
394 case MTP_TYPE_UINT8:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500395 buffer += std::to_string(value.u.u8);
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400396 break;
397 case MTP_TYPE_INT16:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500398 buffer += std::to_string(value.u.i16);
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400399 break;
400 case MTP_TYPE_UINT16:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500401 buffer += std::to_string(value.u.u16);
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400402 break;
403 case MTP_TYPE_INT32:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500404 buffer += std::to_string(value.u.i32);
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400405 break;
406 case MTP_TYPE_UINT32:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500407 buffer += std::to_string(value.u.u32);
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400408 break;
409 case MTP_TYPE_INT64:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500410 buffer += std::to_string(value.u.i64);
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400411 break;
412 case MTP_TYPE_UINT64:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500413 buffer += std::to_string(value.u.u64);
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400414 break;
415 case MTP_TYPE_INT128:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500416 for (auto i : value.u.i128) {
417 s << std::hex << std::setfill('0') << std::uppercase << i;
418 }
419 buffer += s.str();
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400420 break;
421 case MTP_TYPE_UINT128:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500422 for (auto i : value.u.u128) {
423 s << std::hex << std::setfill('0') << std::uppercase << i;
424 }
425 buffer += s.str();
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400426 break;
427 case MTP_TYPE_STR:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500428 buffer += value.str;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400429 break;
430 default:
431 MTPE("unsupported type for MtpProperty::print\n");
432 break;
433 }
434}
435
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500436bool MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) {
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400437 MtpStringBuffer stringBuffer;
438
439 switch (mType) {
440 case MTP_TYPE_INT8:
441 case MTP_TYPE_AINT8:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500442 if (!packet.getInt8(value.u.i8)) return false;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400443 break;
444 case MTP_TYPE_UINT8:
445 case MTP_TYPE_AUINT8:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500446 if (!packet.getUInt8(value.u.u8)) return false;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400447 break;
448 case MTP_TYPE_INT16:
449 case MTP_TYPE_AINT16:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500450 if (!packet.getInt16(value.u.i16)) return false;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400451 break;
452 case MTP_TYPE_UINT16:
453 case MTP_TYPE_AUINT16:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500454 if (!packet.getUInt16(value.u.u16)) return false;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400455 break;
456 case MTP_TYPE_INT32:
457 case MTP_TYPE_AINT32:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500458 if (!packet.getInt32(value.u.i32)) return false;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400459 break;
460 case MTP_TYPE_UINT32:
461 case MTP_TYPE_AUINT32:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500462 if (!packet.getUInt32(value.u.u32)) return false;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400463 break;
464 case MTP_TYPE_INT64:
465 case MTP_TYPE_AINT64:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500466 if (!packet.getInt64(value.u.i64)) return false;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400467 break;
468 case MTP_TYPE_UINT64:
469 case MTP_TYPE_AUINT64:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500470 if (!packet.getUInt64(value.u.u64)) return false;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400471 break;
472 case MTP_TYPE_INT128:
473 case MTP_TYPE_AINT128:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500474 if (!packet.getInt128(value.u.i128)) return false;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400475 break;
476 case MTP_TYPE_UINT128:
477 case MTP_TYPE_AUINT128:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500478 if (!packet.getUInt128(value.u.u128)) return false;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400479 break;
480 case MTP_TYPE_STR:
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500481 if (!packet.getString(stringBuffer)) return false;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400482 value.str = strdup(stringBuffer);
483 break;
484 default:
485 MTPE("unknown type %04X in MtpProperty::readValue", mType);
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500486 return false;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400487 }
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500488 return true;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400489}
490
491void MtpProperty::writeValue(MtpDataPacket& packet, MtpPropertyValue& value) {
492 MtpStringBuffer stringBuffer;
493
494 switch (mType) {
495 case MTP_TYPE_INT8:
496 case MTP_TYPE_AINT8:
497 packet.putInt8(value.u.i8);
498 break;
499 case MTP_TYPE_UINT8:
500 case MTP_TYPE_AUINT8:
501 packet.putUInt8(value.u.u8);
502 break;
503 case MTP_TYPE_INT16:
504 case MTP_TYPE_AINT16:
505 packet.putInt16(value.u.i16);
506 break;
507 case MTP_TYPE_UINT16:
508 case MTP_TYPE_AUINT16:
509 packet.putUInt16(value.u.u16);
510 break;
511 case MTP_TYPE_INT32:
512 case MTP_TYPE_AINT32:
513 packet.putInt32(value.u.i32);
514 break;
515 case MTP_TYPE_UINT32:
516 case MTP_TYPE_AUINT32:
517 packet.putUInt32(value.u.u32);
518 break;
519 case MTP_TYPE_INT64:
520 case MTP_TYPE_AINT64:
521 packet.putInt64(value.u.i64);
522 break;
523 case MTP_TYPE_UINT64:
524 case MTP_TYPE_AUINT64:
525 packet.putUInt64(value.u.u64);
526 break;
527 case MTP_TYPE_INT128:
528 case MTP_TYPE_AINT128:
529 packet.putInt128(value.u.i128);
530 break;
531 case MTP_TYPE_UINT128:
532 case MTP_TYPE_AUINT128:
533 packet.putUInt128(value.u.u128);
534 break;
535 case MTP_TYPE_STR:
536 if (value.str)
537 packet.putString(value.str);
538 else
539 packet.putEmptyString();
540 break;
541 default:
542 MTPE("unknown type %04X in MtpProperty::writeValue", mType);
543 }
544}
545
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500546MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, uint32_t& length) {
547 if (!packet.getUInt32(length)) return NULL;
548
549 // Fail if resulting array is over 2GB. This is because the maximum array
550 // size may be less than SIZE_MAX on some platforms.
551 if ( CC_UNLIKELY(
552 length == 0 ||
553 length >= INT32_MAX / sizeof(MtpPropertyValue)) ) {
554 length = 0;
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400555 return NULL;
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500556 }
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400557 MtpPropertyValue* result = new MtpPropertyValue[length];
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500558 for (uint32_t i = 0; i < length; i++)
559 if (!readValue(packet, result[i])) {
560 delete [] result;
561 return NULL;
562 }
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400563 return result;
564}
565
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500566void MtpProperty::writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, uint32_t length) {
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400567 packet.putUInt32(length);
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -0500568 for (uint32_t i = 0; i < length; i++)
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -0400569 writeValue(packet, values[i]);
570}