MtpProperty.cpp revision a6c490b8b2d96ebaab632286029463f932ae3b6b
1/*
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
17#define LOG_TAG "MtpProperty"
18#include "utils/Log.h"
19
20#include "MtpDataPacket.h"
21#include "MtpProperty.h"
22#include "MtpStringBuffer.h"
23#include "MtpUtils.h"
24
25namespace android {
26
27MtpProperty::MtpProperty()
28    :   mCode(0),
29        mType(0),
30        mWriteable(false),
31        mDefaultArrayLength(0),
32        mDefaultArrayValues(NULL),
33        mCurrentArrayLength(0),
34        mCurrentArrayValues(NULL),
35        mFormFlag(kFormNone),
36        mEnumLength(0),
37        mEnumValues(NULL)
38{
39    mDefaultValue.str = NULL;
40    mCurrentValue.str = NULL;
41    mMinimumValue.str = NULL;
42    mMaximumValue.str = NULL;
43}
44
45MtpProperty::~MtpProperty() {
46    if (mType == MTP_TYPE_STR) {
47        // free all strings
48        free(mDefaultValue.str);
49        free(mCurrentValue.str);
50        free(mMinimumValue.str);
51        free(mMaximumValue.str);
52        if (mDefaultArrayValues) {
53            for (int i = 0; i < mDefaultArrayLength; i++)
54                free(mDefaultArrayValues[i].str);
55        }
56        if (mCurrentArrayValues) {
57            for (int i = 0; i < mCurrentArrayLength; i++)
58                free(mCurrentArrayValues[i].str);
59        }
60        if (mEnumValues) {
61            for (int i = 0; i < mEnumLength; i++)
62                free(mEnumValues[i].str);
63        }
64    }
65    delete[] mDefaultArrayValues;
66    delete[] mCurrentArrayValues;
67    delete[] mEnumValues;
68}
69
70void MtpProperty::read(MtpDataPacket& packet) {
71    MtpStringBuffer string;
72
73    mCode = packet.getUInt16();
74    mType = packet.getUInt16();
75    mWriteable = (packet.getUInt8() == 1);
76    switch (mType) {
77        case MTP_TYPE_AINT8:
78        case MTP_TYPE_AUINT8:
79        case MTP_TYPE_AINT16:
80        case MTP_TYPE_AUINT16:
81        case MTP_TYPE_AINT32:
82        case MTP_TYPE_AUINT32:
83        case MTP_TYPE_AINT64:
84        case MTP_TYPE_AUINT64:
85        case MTP_TYPE_AINT128:
86        case MTP_TYPE_AUINT128:
87            mDefaultArrayValues = readArrayValues(packet, mDefaultArrayLength);
88            mCurrentArrayValues = readArrayValues(packet, mCurrentArrayLength);
89            break;
90        default:
91            readValue(packet, mDefaultValue);
92            readValue(packet, mCurrentValue);
93    }
94    mFormFlag = packet.getUInt8();
95
96    if (mFormFlag == kFormRange) {
97            readValue(packet, mMinimumValue);
98            readValue(packet, mMaximumValue);
99            readValue(packet, mStepSize);
100    } else if (mFormFlag == kFormEnum) {
101        mEnumLength = packet.getUInt16();
102        mEnumValues = new MtpPropertyValue[mEnumLength];
103        for (int i = 0; i < mEnumLength; i++)
104            readValue(packet, mEnumValues[i]);
105    }
106}
107
108void MtpProperty::print() {
109    LOGD("MtpProperty %04X\n", mCode);
110    LOGD("    type %04X\n", mType);
111    LOGD("    writeable %s\n", (mWriteable ? "true" : "false"));
112}
113
114void MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) {
115    switch (mType) {
116        case MTP_TYPE_INT8:
117            value.i8 = packet.getInt8();
118            break;
119        case MTP_TYPE_UINT8:
120            value.u8 = packet.getUInt8();
121            break;
122        case MTP_TYPE_INT16:
123            value.i16 = packet.getInt16();
124            break;
125        case MTP_TYPE_UINT16:
126            value.u16 = packet.getUInt16();
127            break;
128        case MTP_TYPE_INT32:
129            value.i32 = packet.getInt32();
130            break;
131        case MTP_TYPE_UINT32:
132            value.u32 = packet.getUInt32();
133            break;
134        case MTP_TYPE_INT64:
135            value.i64 = packet.getInt64();
136            break;
137        case MTP_TYPE_UINT64:
138            value.u64 = packet.getUInt64();
139            break;
140        case MTP_TYPE_INT128:
141            packet.getInt128(value.i128);
142            break;
143        case MTP_TYPE_UINT128:
144            packet.getUInt128(value.u128);
145            break;
146        default:
147            fprintf(stderr, "unknown type %d in MtpProperty::readValue\n", mType);
148    }
149}
150
151MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, int& length) {
152    length = packet.getUInt32();
153    if (length == 0)
154        return NULL;
155    MtpPropertyValue* result = new MtpPropertyValue[length];
156    for (int i = 0; i < length; i++)
157        readValue(packet, result[i]);
158    return result;
159}
160
161}  // namespace android
162