blob: e105f24974778b7908750217ee15a0ecdf9d696e [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 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 *
16 * Copyright (C) 2014 TeamWin - bigbiff and Dees_Troy mtp database conversion to C++
17 */
18
19#include "MtpDataPacket.h"
20#include "MtpDebug.h"
21#include "MtpProperty.h"
22#include "MtpStringBuffer.h"
23#include "MtpUtils.h"
24
25MtpProperty::MtpProperty()
26 : mCode(0),
27 mType(0),
28 mWriteable(false),
29 mDefaultArrayLength(0),
30 mDefaultArrayValues(NULL),
31 mCurrentArrayLength(0),
32 mCurrentArrayValues(NULL),
33 mGroupCode(0),
34 mFormFlag(kFormNone),
35 mEnumLength(0),
36 mEnumValues(NULL)
37{
38 memset(&mDefaultValue, 0, sizeof(mDefaultValue));
39 memset(&mCurrentValue, 0, sizeof(mCurrentValue));
40 memset(&mMinimumValue, 0, sizeof(mMinimumValue));
41 memset(&mMaximumValue, 0, sizeof(mMaximumValue));
42}
43
44MtpProperty::MtpProperty(MtpPropertyCode propCode,
45 MtpDataType type,
46 bool writeable,
47 int defaultValue)
48 : mCode(propCode),
49 mType(type),
50 mWriteable(writeable),
51 mDefaultArrayLength(0),
52 mDefaultArrayValues(NULL),
53 mCurrentArrayLength(0),
54 mCurrentArrayValues(NULL),
55 mGroupCode(0),
56 mFormFlag(kFormNone),
57 mEnumLength(0),
58 mEnumValues(NULL)
59{
60 memset(&mDefaultValue, 0, sizeof(mDefaultValue));
61 memset(&mCurrentValue, 0, sizeof(mCurrentValue));
62 memset(&mMinimumValue, 0, sizeof(mMinimumValue));
63 memset(&mMaximumValue, 0, sizeof(mMaximumValue));
64
65 if (defaultValue) {
66 switch (type) {
67 case MTP_TYPE_INT8:
68 mDefaultValue.u.i8 = defaultValue;
69 break;
70 case MTP_TYPE_UINT8:
71 mDefaultValue.u.u8 = defaultValue;
72 break;
73 case MTP_TYPE_INT16:
74 mDefaultValue.u.i16 = defaultValue;
75 break;
76 case MTP_TYPE_UINT16:
77 mDefaultValue.u.u16 = defaultValue;
78 break;
79 case MTP_TYPE_INT32:
80 mDefaultValue.u.i32 = defaultValue;
81 break;
82 case MTP_TYPE_UINT32:
83 mDefaultValue.u.u32 = defaultValue;
84 break;
85 case MTP_TYPE_INT64:
86 mDefaultValue.u.i64 = defaultValue;
87 break;
88 case MTP_TYPE_UINT64:
89 mDefaultValue.u.u64 = defaultValue;
90 break;
91 default:
92 MTPE("unknown type %04X in MtpProperty::MtpProperty", type);
93 }
94 }
95}
96
97MtpProperty::~MtpProperty() {
98 if (mType == MTP_TYPE_STR) {
99 // free all strings
100 free(mDefaultValue.str);
101 free(mCurrentValue.str);
102 free(mMinimumValue.str);
103 free(mMaximumValue.str);
104 if (mDefaultArrayValues) {
105 for (int i = 0; i < mDefaultArrayLength; i++)
106 free(mDefaultArrayValues[i].str);
107 }
108 if (mCurrentArrayValues) {
109 for (int i = 0; i < mCurrentArrayLength; i++)
110 free(mCurrentArrayValues[i].str);
111 }
112 if (mEnumValues) {
113 for (int i = 0; i < mEnumLength; i++)
114 free(mEnumValues[i].str);
115 }
116 }
117 delete[] mDefaultArrayValues;
118 delete[] mCurrentArrayValues;
119 delete[] mEnumValues;
120}
121
122void MtpProperty::read(MtpDataPacket& packet) {
123 mCode = packet.getUInt16();
124 bool deviceProp = isDeviceProperty();
125 mType = packet.getUInt16();
126 mWriteable = (packet.getUInt8() == 1);
127 switch (mType) {
128 case MTP_TYPE_AINT8:
129 case MTP_TYPE_AUINT8:
130 case MTP_TYPE_AINT16:
131 case MTP_TYPE_AUINT16:
132 case MTP_TYPE_AINT32:
133 case MTP_TYPE_AUINT32:
134 case MTP_TYPE_AINT64:
135 case MTP_TYPE_AUINT64:
136 case MTP_TYPE_AINT128:
137 case MTP_TYPE_AUINT128:
138 mDefaultArrayValues = readArrayValues(packet, mDefaultArrayLength);
139 if (deviceProp)
140 mCurrentArrayValues = readArrayValues(packet, mCurrentArrayLength);
141 break;
142 default:
143 readValue(packet, mDefaultValue);
144 if (deviceProp)
145 readValue(packet, mCurrentValue);
146 }
147 if (!deviceProp)
148 mGroupCode = packet.getUInt32();
149 mFormFlag = packet.getUInt8();
150
151 if (mFormFlag == kFormRange) {
152 readValue(packet, mMinimumValue);
153 readValue(packet, mMaximumValue);
154 readValue(packet, mStepSize);
155 } else if (mFormFlag == kFormEnum) {
156 mEnumLength = packet.getUInt16();
157 mEnumValues = new MtpPropertyValue[mEnumLength];
158 for (int i = 0; i < mEnumLength; i++)
159 readValue(packet, mEnumValues[i]);
160 }
161}
162
163void MtpProperty::write(MtpDataPacket& packet) {
164 bool deviceProp = isDeviceProperty();
165
166 packet.putUInt16(mCode);
167 packet.putUInt16(mType);
168 packet.putUInt8(mWriteable ? 1 : 0);
169
170 switch (mType) {
171 case MTP_TYPE_AINT8:
172 case MTP_TYPE_AUINT8:
173 case MTP_TYPE_AINT16:
174 case MTP_TYPE_AUINT16:
175 case MTP_TYPE_AINT32:
176 case MTP_TYPE_AUINT32:
177 case MTP_TYPE_AINT64:
178 case MTP_TYPE_AUINT64:
179 case MTP_TYPE_AINT128:
180 case MTP_TYPE_AUINT128:
181 writeArrayValues(packet, mDefaultArrayValues, mDefaultArrayLength);
182 if (deviceProp)
183 writeArrayValues(packet, mCurrentArrayValues, mCurrentArrayLength);
184 break;
185 default:
186 writeValue(packet, mDefaultValue);
187 if (deviceProp)
188 writeValue(packet, mCurrentValue);
189 }
190 packet.putUInt32(mGroupCode);
191 if (!deviceProp)
192 packet.putUInt8(mFormFlag);
193 if (mFormFlag == kFormRange) {
194 writeValue(packet, mMinimumValue);
195 writeValue(packet, mMaximumValue);
196 writeValue(packet, mStepSize);
197 } else if (mFormFlag == kFormEnum) {
198 packet.putUInt16(mEnumLength);
199 for (int i = 0; i < mEnumLength; i++)
200 writeValue(packet, mEnumValues[i]);
201 }
202}
203
204void MtpProperty::setDefaultValue(const uint16_t* string) {
205 free(mDefaultValue.str);
206 if (string) {
207 MtpStringBuffer buffer(string);
208 mDefaultValue.str = strdup(buffer);
209 }
210 else
211 mDefaultValue.str = NULL;
212}
213
214void MtpProperty::setCurrentValue(const uint16_t* string) {
215 free(mCurrentValue.str);
216 if (string) {
217 MtpStringBuffer buffer(string);
218 mCurrentValue.str = strdup(buffer);
219 }
220 else
221 mCurrentValue.str = NULL;
222}
223
224void MtpProperty::setFormRange(int min, int max, int step) {
225 mFormFlag = kFormRange;
226 switch (mType) {
227 case MTP_TYPE_INT8:
228 mMinimumValue.u.i8 = min;
229 mMaximumValue.u.i8 = max;
230 mStepSize.u.i8 = step;
231 break;
232 case MTP_TYPE_UINT8:
233 mMinimumValue.u.u8 = min;
234 mMaximumValue.u.u8 = max;
235 mStepSize.u.u8 = step;
236 break;
237 case MTP_TYPE_INT16:
238 mMinimumValue.u.i16 = min;
239 mMaximumValue.u.i16 = max;
240 mStepSize.u.i16 = step;
241 break;
242 case MTP_TYPE_UINT16:
243 mMinimumValue.u.u16 = min;
244 mMaximumValue.u.u16 = max;
245 mStepSize.u.u16 = step;
246 break;
247 case MTP_TYPE_INT32:
248 mMinimumValue.u.i32 = min;
249 mMaximumValue.u.i32 = max;
250 mStepSize.u.i32 = step;
251 break;
252 case MTP_TYPE_UINT32:
253 mMinimumValue.u.u32 = min;
254 mMaximumValue.u.u32 = max;
255 mStepSize.u.u32 = step;
256 break;
257 case MTP_TYPE_INT64:
258 mMinimumValue.u.i64 = min;
259 mMaximumValue.u.i64 = max;
260 mStepSize.u.i64 = step;
261 break;
262 case MTP_TYPE_UINT64:
263 mMinimumValue.u.u64 = min;
264 mMaximumValue.u.u64 = max;
265 mStepSize.u.u64 = step;
266 break;
267 default:
268 MTPE("unsupported type for MtpProperty::setRange");
269 break;
270 }
271}
272
273void MtpProperty::setFormEnum(const int* values, int count) {
274 mFormFlag = kFormEnum;
275 delete[] mEnumValues;
276 mEnumValues = new MtpPropertyValue[count];
277 mEnumLength = count;
278
279 for (int i = 0; i < count; i++) {
280 int value = *values++;
281 switch (mType) {
282 case MTP_TYPE_INT8:
283 mEnumValues[i].u.i8 = value;
284 break;
285 case MTP_TYPE_UINT8:
286 mEnumValues[i].u.u8 = value;
287 break;
288 case MTP_TYPE_INT16:
289 mEnumValues[i].u.i16 = value;
290 break;
291 case MTP_TYPE_UINT16:
292 mEnumValues[i].u.u16 = value;
293 break;
294 case MTP_TYPE_INT32:
295 mEnumValues[i].u.i32 = value;
296 break;
297 case MTP_TYPE_UINT32:
298 mEnumValues[i].u.u32 = value;
299 break;
300 case MTP_TYPE_INT64:
301 mEnumValues[i].u.i64 = value;
302 break;
303 case MTP_TYPE_UINT64:
304 mEnumValues[i].u.u64 = value;
305 break;
306 default:
307 MTPE("unsupported type for MtpProperty::setEnum");
308 break;
309 }
310 }
311}
312
313void MtpProperty::setFormDateTime() {
314 mFormFlag = kFormDateTime;
315}
316
317void MtpProperty::print() {
318 MtpString buffer;
319 bool deviceProp = isDeviceProperty();
320 if (deviceProp)
321 MTPI(" %s (%04X)", MtpDebug::getDevicePropCodeName(mCode), mCode);
322 else
323 MTPI(" %s (%04X)", MtpDebug::getObjectPropCodeName(mCode), mCode);
324 MTPI(" type %04X", mType);
325 MTPI(" writeable %s", (mWriteable ? "true" : "false"));
326 buffer = " default value: ";
327 print(mDefaultValue, buffer);
328 MTPI("%s", (const char *)buffer);
329 if (deviceProp) {
330 buffer = " current value: ";
331 print(mCurrentValue, buffer);
332 MTPI("%s", (const char *)buffer);
333 }
334 switch (mFormFlag) {
335 case kFormNone:
336 break;
337 case kFormRange:
338 buffer = " Range (";
339 print(mMinimumValue, buffer);
340 buffer += ", ";
341 print(mMaximumValue, buffer);
342 buffer += ", ";
343 print(mStepSize, buffer);
344 buffer += ")";
345 MTPI("%s", (const char *)buffer);
346 break;
347 case kFormEnum:
348 buffer = " Enum { ";
349 for (int i = 0; i < mEnumLength; i++) {
350 print(mEnumValues[i], buffer);
351 buffer += " ";
352 }
353 buffer += "}";
354 MTPI("%s", (const char *)buffer);
355 break;
356 case kFormDateTime:
357 MTPI(" DateTime\n");
358 break;
359 default:
360 MTPI(" form %d\n", mFormFlag);
361 break;
362 }
363}
364
365void MtpProperty::print(MtpPropertyValue& value, MtpString& buffer) {
366 switch (mType) {
367 case MTP_TYPE_INT8:
368 buffer.appendFormat("%d", value.u.i8);
369 break;
370 case MTP_TYPE_UINT8:
371 buffer.appendFormat("%d", value.u.u8);
372 break;
373 case MTP_TYPE_INT16:
374 buffer.appendFormat("%d", value.u.i16);
375 break;
376 case MTP_TYPE_UINT16:
377 buffer.appendFormat("%d", value.u.u16);
378 break;
379 case MTP_TYPE_INT32:
380 buffer.appendFormat("%d", value.u.i32);
381 break;
382 case MTP_TYPE_UINT32:
383 buffer.appendFormat("%d", value.u.u32);
384 break;
385 case MTP_TYPE_INT64:
386 buffer.appendFormat("%lld", value.u.i64);
387 break;
388 case MTP_TYPE_UINT64:
389 buffer.appendFormat("%lld", value.u.u64);
390 break;
391 case MTP_TYPE_INT128:
392 buffer.appendFormat("%08X%08X%08X%08X", value.u.i128[0], value.u.i128[1],
393 value.u.i128[2], value.u.i128[3]);
394 break;
395 case MTP_TYPE_UINT128:
396 buffer.appendFormat("%08X%08X%08X%08X", value.u.u128[0], value.u.u128[1],
397 value.u.u128[2], value.u.u128[3]);
398 break;
399 case MTP_TYPE_STR:
400 buffer.appendFormat("%s", value.str);
401 break;
402 default:
403 MTPE("unsupported type for MtpProperty::print\n");
404 break;
405 }
406}
407
408void MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) {
409 MtpStringBuffer stringBuffer;
410
411 switch (mType) {
412 case MTP_TYPE_INT8:
413 case MTP_TYPE_AINT8:
414 value.u.i8 = packet.getInt8();
415 break;
416 case MTP_TYPE_UINT8:
417 case MTP_TYPE_AUINT8:
418 value.u.u8 = packet.getUInt8();
419 break;
420 case MTP_TYPE_INT16:
421 case MTP_TYPE_AINT16:
422 value.u.i16 = packet.getInt16();
423 break;
424 case MTP_TYPE_UINT16:
425 case MTP_TYPE_AUINT16:
426 value.u.u16 = packet.getUInt16();
427 break;
428 case MTP_TYPE_INT32:
429 case MTP_TYPE_AINT32:
430 value.u.i32 = packet.getInt32();
431 break;
432 case MTP_TYPE_UINT32:
433 case MTP_TYPE_AUINT32:
434 value.u.u32 = packet.getUInt32();
435 break;
436 case MTP_TYPE_INT64:
437 case MTP_TYPE_AINT64:
438 value.u.i64 = packet.getInt64();
439 break;
440 case MTP_TYPE_UINT64:
441 case MTP_TYPE_AUINT64:
442 value.u.u64 = packet.getUInt64();
443 break;
444 case MTP_TYPE_INT128:
445 case MTP_TYPE_AINT128:
446 packet.getInt128(value.u.i128);
447 break;
448 case MTP_TYPE_UINT128:
449 case MTP_TYPE_AUINT128:
450 packet.getUInt128(value.u.u128);
451 break;
452 case MTP_TYPE_STR:
453 packet.getString(stringBuffer);
454 value.str = strdup(stringBuffer);
455 break;
456 default:
457 MTPE("unknown type %04X in MtpProperty::readValue", mType);
458 }
459}
460
461void MtpProperty::writeValue(MtpDataPacket& packet, MtpPropertyValue& value) {
462 MtpStringBuffer stringBuffer;
463
464 switch (mType) {
465 case MTP_TYPE_INT8:
466 case MTP_TYPE_AINT8:
467 packet.putInt8(value.u.i8);
468 break;
469 case MTP_TYPE_UINT8:
470 case MTP_TYPE_AUINT8:
471 packet.putUInt8(value.u.u8);
472 break;
473 case MTP_TYPE_INT16:
474 case MTP_TYPE_AINT16:
475 packet.putInt16(value.u.i16);
476 break;
477 case MTP_TYPE_UINT16:
478 case MTP_TYPE_AUINT16:
479 packet.putUInt16(value.u.u16);
480 break;
481 case MTP_TYPE_INT32:
482 case MTP_TYPE_AINT32:
483 packet.putInt32(value.u.i32);
484 break;
485 case MTP_TYPE_UINT32:
486 case MTP_TYPE_AUINT32:
487 packet.putUInt32(value.u.u32);
488 break;
489 case MTP_TYPE_INT64:
490 case MTP_TYPE_AINT64:
491 packet.putInt64(value.u.i64);
492 break;
493 case MTP_TYPE_UINT64:
494 case MTP_TYPE_AUINT64:
495 packet.putUInt64(value.u.u64);
496 break;
497 case MTP_TYPE_INT128:
498 case MTP_TYPE_AINT128:
499 packet.putInt128(value.u.i128);
500 break;
501 case MTP_TYPE_UINT128:
502 case MTP_TYPE_AUINT128:
503 packet.putUInt128(value.u.u128);
504 break;
505 case MTP_TYPE_STR:
506 if (value.str)
507 packet.putString(value.str);
508 else
509 packet.putEmptyString();
510 break;
511 default:
512 MTPE("unknown type %04X in MtpProperty::writeValue", mType);
513 }
514}
515
516MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, int& length) {
517 length = packet.getUInt32();
518 if (length == 0)
519 return NULL;
520 MtpPropertyValue* result = new MtpPropertyValue[length];
521 for (int i = 0; i < length; i++)
522 readValue(packet, result[i]);
523 return result;
524}
525
526void MtpProperty::writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, int length) {
527 packet.putUInt32(length);
528 for (int i = 0; i < length; i++)
529 writeValue(packet, values[i]);
530}
531