MtpProperty.cpp revision 21ef7d0e70c5ad599bc2602cb484f8cd647055ca
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 19#include "MtpDataPacket.h" 20#include "MtpProperty.h" 21#include "MtpStringBuffer.h" 22#include "MtpUtils.h" 23 24namespace android { 25 26MtpProperty::MtpProperty() 27 : mCode(0), 28 mType(0), 29 mWriteable(false), 30 mDefaultArrayLength(0), 31 mDefaultArrayValues(NULL), 32 mCurrentArrayLength(0), 33 mCurrentArrayValues(NULL), 34 mFormFlag(kFormNone), 35 mEnumLength(0), 36 mEnumValues(NULL) 37{ 38 mDefaultValue.str = NULL; 39 mCurrentValue.str = NULL; 40 mMinimumValue.str = NULL; 41 mMaximumValue.str = NULL; 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 mFormFlag(kFormNone), 56 mEnumLength(0), 57 mEnumValues(NULL) 58{ 59 memset(&mDefaultValue, 0, sizeof(mDefaultValue)); 60 memset(&mCurrentValue, 0, sizeof(mCurrentValue)); 61 memset(&mMinimumValue, 0, sizeof(mMinimumValue)); 62 memset(&mMaximumValue, 0, sizeof(mMaximumValue)); 63 64 if (defaultValue) { 65 switch (type) { 66 case MTP_TYPE_INT8: 67 mDefaultValue.i8 = defaultValue; 68 break; 69 case MTP_TYPE_UINT8: 70 mDefaultValue.u8 = defaultValue; 71 break; 72 case MTP_TYPE_INT16: 73 mDefaultValue.i16 = defaultValue; 74 break; 75 case MTP_TYPE_UINT16: 76 mDefaultValue.u16 = defaultValue; 77 break; 78 case MTP_TYPE_INT32: 79 mDefaultValue.i32 = defaultValue; 80 break; 81 case MTP_TYPE_UINT32: 82 mDefaultValue.u32 = defaultValue; 83 break; 84 case MTP_TYPE_INT64: 85 mDefaultValue.i64 = defaultValue; 86 break; 87 case MTP_TYPE_UINT64: 88 mDefaultValue.u64 = defaultValue; 89 break; 90 default: 91 LOGE("unknown type %d in MtpProperty::MtpProperty", type); 92 } 93 } 94} 95 96MtpProperty::~MtpProperty() { 97 if (mType == MTP_TYPE_STR) { 98 // free all strings 99 free(mDefaultValue.str); 100 free(mCurrentValue.str); 101 free(mMinimumValue.str); 102 free(mMaximumValue.str); 103 if (mDefaultArrayValues) { 104 for (int i = 0; i < mDefaultArrayLength; i++) 105 free(mDefaultArrayValues[i].str); 106 } 107 if (mCurrentArrayValues) { 108 for (int i = 0; i < mCurrentArrayLength; i++) 109 free(mCurrentArrayValues[i].str); 110 } 111 if (mEnumValues) { 112 for (int i = 0; i < mEnumLength; i++) 113 free(mEnumValues[i].str); 114 } 115 } 116 delete[] mDefaultArrayValues; 117 delete[] mCurrentArrayValues; 118 delete[] mEnumValues; 119} 120 121void MtpProperty::read(MtpDataPacket& packet, bool deviceProp) { 122 MtpStringBuffer string; 123 124 mCode = packet.getUInt16(); 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 mCurrentArrayValues = readArrayValues(packet, mCurrentArrayLength); 140 break; 141 default: 142 readValue(packet, mDefaultValue); 143 if (deviceProp) 144 readValue(packet, mCurrentValue); 145 } 146 mFormFlag = packet.getUInt8(); 147 148 if (mFormFlag == kFormRange) { 149 readValue(packet, mMinimumValue); 150 readValue(packet, mMaximumValue); 151 readValue(packet, mStepSize); 152 } else if (mFormFlag == kFormEnum) { 153 mEnumLength = packet.getUInt16(); 154 mEnumValues = new MtpPropertyValue[mEnumLength]; 155 for (int i = 0; i < mEnumLength; i++) 156 readValue(packet, mEnumValues[i]); 157 } 158} 159 160// FIXME - only works for object properties 161void MtpProperty::write(MtpDataPacket& packet) { 162 packet.putUInt16(mCode); 163 packet.putUInt16(mType); 164 packet.putUInt8(mWriteable ? 1 : 0); 165 166 switch (mType) { 167 case MTP_TYPE_AINT8: 168 case MTP_TYPE_AUINT8: 169 case MTP_TYPE_AINT16: 170 case MTP_TYPE_AUINT16: 171 case MTP_TYPE_AINT32: 172 case MTP_TYPE_AUINT32: 173 case MTP_TYPE_AINT64: 174 case MTP_TYPE_AUINT64: 175 case MTP_TYPE_AINT128: 176 case MTP_TYPE_AUINT128: 177 writeArrayValues(packet, mDefaultArrayValues, mDefaultArrayLength); 178 break; 179 default: 180 writeValue(packet, mDefaultValue); 181 } 182 packet.putUInt8(mFormFlag); 183 if (mFormFlag == kFormRange) { 184 writeValue(packet, mMinimumValue); 185 writeValue(packet, mMaximumValue); 186 writeValue(packet, mStepSize); 187 } else if (mFormFlag == kFormEnum) { 188 packet.putUInt16(mEnumLength); 189 for (int i = 0; i < mEnumLength; i++) 190 writeValue(packet, mEnumValues[i]); 191 } 192} 193 194void MtpProperty::print() { 195 LOGD("MtpProperty %04X\n", mCode); 196 LOGD(" type %04X\n", mType); 197 LOGD(" writeable %s\n", (mWriteable ? "true" : "false")); 198} 199 200void MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) { 201 switch (mType) { 202 case MTP_TYPE_INT8: 203 value.i8 = packet.getInt8(); 204 break; 205 case MTP_TYPE_UINT8: 206 value.u8 = packet.getUInt8(); 207 break; 208 case MTP_TYPE_INT16: 209 value.i16 = packet.getInt16(); 210 break; 211 case MTP_TYPE_UINT16: 212 value.u16 = packet.getUInt16(); 213 break; 214 case MTP_TYPE_INT32: 215 value.i32 = packet.getInt32(); 216 break; 217 case MTP_TYPE_UINT32: 218 value.u32 = packet.getUInt32(); 219 break; 220 case MTP_TYPE_INT64: 221 value.i64 = packet.getInt64(); 222 break; 223 case MTP_TYPE_UINT64: 224 value.u64 = packet.getUInt64(); 225 break; 226 case MTP_TYPE_INT128: 227 packet.getInt128(value.i128); 228 break; 229 case MTP_TYPE_UINT128: 230 packet.getUInt128(value.u128); 231 break; 232 default: 233 LOGE("unknown type %d in MtpProperty::readValue", mType); 234 } 235} 236 237void MtpProperty::writeValue(MtpDataPacket& packet, MtpPropertyValue& value) { 238 switch (mType) { 239 case MTP_TYPE_INT8: 240 packet.putInt8(value.i8); 241 break; 242 case MTP_TYPE_UINT8: 243 packet.putUInt8(value.u8); 244 break; 245 case MTP_TYPE_INT16: 246 packet.putInt16(value.i16); 247 break; 248 case MTP_TYPE_UINT16: 249 packet.putUInt16(value.u16); 250 break; 251 case MTP_TYPE_INT32: 252 packet.putInt32(value.i32); 253 break; 254 case MTP_TYPE_UINT32: 255 packet.putUInt32(value.u32); 256 break; 257 case MTP_TYPE_INT64: 258 packet.putInt64(value.i64); 259 break; 260 case MTP_TYPE_UINT64: 261 packet.putUInt64(value.u64); 262 break; 263 case MTP_TYPE_INT128: 264 packet.putInt128(value.i128); 265 break; 266 case MTP_TYPE_UINT128: 267 packet.putUInt128(value.u128); 268 break; 269 default: 270 LOGE("unknown type %d in MtpProperty::readValue", mType); 271 } 272} 273 274MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, int& length) { 275 length = packet.getUInt32(); 276 if (length == 0) 277 return NULL; 278 MtpPropertyValue* result = new MtpPropertyValue[length]; 279 for (int i = 0; i < length; i++) 280 readValue(packet, result[i]); 281 return result; 282} 283 284void MtpProperty::writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, int length) { 285 packet.putUInt32(length); 286 for (int i = 0; i < length; i++) 287 writeValue(packet, values[i]); 288} 289 290} // namespace android 291