MtpProperty.cpp revision e3e76c456baee122de6715ae280130abaddc906c
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 mGroupCode(0), 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(MtpPropertyCode propCode, 46 MtpDataType type, 47 bool writeable, 48 int defaultValue) 49 : mCode(propCode), 50 mType(type), 51 mWriteable(writeable), 52 mDefaultArrayLength(0), 53 mDefaultArrayValues(NULL), 54 mCurrentArrayLength(0), 55 mCurrentArrayValues(NULL), 56 mGroupCode(0), 57 mFormFlag(kFormNone), 58 mEnumLength(0), 59 mEnumValues(NULL) 60{ 61 memset(&mDefaultValue, 0, sizeof(mDefaultValue)); 62 memset(&mCurrentValue, 0, sizeof(mCurrentValue)); 63 memset(&mMinimumValue, 0, sizeof(mMinimumValue)); 64 memset(&mMaximumValue, 0, sizeof(mMaximumValue)); 65 66 if (defaultValue) { 67 switch (type) { 68 case MTP_TYPE_INT8: 69 mDefaultValue.i8 = defaultValue; 70 break; 71 case MTP_TYPE_UINT8: 72 mDefaultValue.u8 = defaultValue; 73 break; 74 case MTP_TYPE_INT16: 75 mDefaultValue.i16 = defaultValue; 76 break; 77 case MTP_TYPE_UINT16: 78 mDefaultValue.u16 = defaultValue; 79 break; 80 case MTP_TYPE_INT32: 81 mDefaultValue.i32 = defaultValue; 82 break; 83 case MTP_TYPE_UINT32: 84 mDefaultValue.u32 = defaultValue; 85 break; 86 case MTP_TYPE_INT64: 87 mDefaultValue.i64 = defaultValue; 88 break; 89 case MTP_TYPE_UINT64: 90 mDefaultValue.u64 = defaultValue; 91 break; 92 default: 93 LOGE("unknown type %04X in MtpProperty::MtpProperty", type); 94 } 95 } 96} 97 98MtpProperty::~MtpProperty() { 99 if (mType == MTP_TYPE_STR) { 100 // free all strings 101 free(mDefaultValue.str); 102 free(mCurrentValue.str); 103 free(mMinimumValue.str); 104 free(mMaximumValue.str); 105 if (mDefaultArrayValues) { 106 for (int i = 0; i < mDefaultArrayLength; i++) 107 free(mDefaultArrayValues[i].str); 108 } 109 if (mCurrentArrayValues) { 110 for (int i = 0; i < mCurrentArrayLength; i++) 111 free(mCurrentArrayValues[i].str); 112 } 113 if (mEnumValues) { 114 for (int i = 0; i < mEnumLength; i++) 115 free(mEnumValues[i].str); 116 } 117 } 118 delete[] mDefaultArrayValues; 119 delete[] mCurrentArrayValues; 120 delete[] mEnumValues; 121} 122 123void MtpProperty::read(MtpDataPacket& packet) { 124 125 mCode = packet.getUInt16(); 126 mType = packet.getUInt16(); 127 mWriteable = (packet.getUInt8() == 1); 128 switch (mType) { 129 case MTP_TYPE_AINT8: 130 case MTP_TYPE_AUINT8: 131 case MTP_TYPE_AINT16: 132 case MTP_TYPE_AUINT16: 133 case MTP_TYPE_AINT32: 134 case MTP_TYPE_AUINT32: 135 case MTP_TYPE_AINT64: 136 case MTP_TYPE_AUINT64: 137 case MTP_TYPE_AINT128: 138 case MTP_TYPE_AUINT128: 139 mDefaultArrayValues = readArrayValues(packet, mDefaultArrayLength); 140 mCurrentArrayValues = readArrayValues(packet, mCurrentArrayLength); 141 break; 142 default: 143 readValue(packet, mDefaultValue); 144 if (isDeviceProperty()) 145 readValue(packet, mCurrentValue); 146 } 147 mGroupCode = packet.getUInt32(); 148 mFormFlag = packet.getUInt8(); 149 150 if (mFormFlag == kFormRange) { 151 readValue(packet, mMinimumValue); 152 readValue(packet, mMaximumValue); 153 readValue(packet, mStepSize); 154 } else if (mFormFlag == kFormEnum) { 155 mEnumLength = packet.getUInt16(); 156 mEnumValues = new MtpPropertyValue[mEnumLength]; 157 for (int i = 0; i < mEnumLength; i++) 158 readValue(packet, mEnumValues[i]); 159 } 160} 161 162void MtpProperty::write(MtpDataPacket& packet) { 163 packet.putUInt16(mCode); 164 packet.putUInt16(mType); 165 packet.putUInt8(mWriteable ? 1 : 0); 166 167 switch (mType) { 168 case MTP_TYPE_AINT8: 169 case MTP_TYPE_AUINT8: 170 case MTP_TYPE_AINT16: 171 case MTP_TYPE_AUINT16: 172 case MTP_TYPE_AINT32: 173 case MTP_TYPE_AUINT32: 174 case MTP_TYPE_AINT64: 175 case MTP_TYPE_AUINT64: 176 case MTP_TYPE_AINT128: 177 case MTP_TYPE_AUINT128: 178 writeArrayValues(packet, mDefaultArrayValues, mDefaultArrayLength); 179 break; 180 default: 181 writeValue(packet, mDefaultValue); 182 } 183 packet.putUInt32(mGroupCode); 184 packet.putUInt8(mFormFlag); 185 if (mFormFlag == kFormRange) { 186 writeValue(packet, mMinimumValue); 187 writeValue(packet, mMaximumValue); 188 writeValue(packet, mStepSize); 189 } else if (mFormFlag == kFormEnum) { 190 packet.putUInt16(mEnumLength); 191 for (int i = 0; i < mEnumLength; i++) 192 writeValue(packet, mEnumValues[i]); 193 } 194} 195 196void MtpProperty::print() { 197 LOGV("MtpProperty %04X\n", mCode); 198 LOGV(" type %04X\n", mType); 199 LOGV(" writeable %s\n", (mWriteable ? "true" : "false")); 200} 201 202void MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) { 203 MtpStringBuffer stringBuffer; 204 205 switch (mType) { 206 case MTP_TYPE_INT8: 207 case MTP_TYPE_AINT8: 208 value.i8 = packet.getInt8(); 209 break; 210 case MTP_TYPE_UINT8: 211 case MTP_TYPE_AUINT8: 212 value.u8 = packet.getUInt8(); 213 break; 214 case MTP_TYPE_INT16: 215 case MTP_TYPE_AINT16: 216 value.i16 = packet.getInt16(); 217 break; 218 case MTP_TYPE_UINT16: 219 case MTP_TYPE_AUINT16: 220 value.u16 = packet.getUInt16(); 221 break; 222 case MTP_TYPE_INT32: 223 case MTP_TYPE_AINT32: 224 value.i32 = packet.getInt32(); 225 break; 226 case MTP_TYPE_UINT32: 227 case MTP_TYPE_AUINT32: 228 value.u32 = packet.getUInt32(); 229 break; 230 case MTP_TYPE_INT64: 231 case MTP_TYPE_AINT64: 232 value.i64 = packet.getInt64(); 233 break; 234 case MTP_TYPE_UINT64: 235 case MTP_TYPE_AUINT64: 236 value.u64 = packet.getUInt64(); 237 break; 238 case MTP_TYPE_INT128: 239 case MTP_TYPE_AINT128: 240 packet.getInt128(value.i128); 241 break; 242 case MTP_TYPE_UINT128: 243 case MTP_TYPE_AUINT128: 244 packet.getUInt128(value.u128); 245 break; 246 case MTP_TYPE_STR: 247 packet.getString(stringBuffer); 248 value.str = strdup(stringBuffer); 249 break; 250 default: 251 LOGE("unknown type %04X in MtpProperty::readValue", mType); 252 } 253} 254 255void MtpProperty::writeValue(MtpDataPacket& packet, MtpPropertyValue& value) { 256 MtpStringBuffer stringBuffer; 257 258 switch (mType) { 259 case MTP_TYPE_INT8: 260 case MTP_TYPE_AINT8: 261 packet.putInt8(value.i8); 262 break; 263 case MTP_TYPE_UINT8: 264 case MTP_TYPE_AUINT8: 265 packet.putUInt8(value.u8); 266 break; 267 case MTP_TYPE_INT16: 268 case MTP_TYPE_AINT16: 269 packet.putInt16(value.i16); 270 break; 271 case MTP_TYPE_UINT16: 272 case MTP_TYPE_AUINT16: 273 packet.putUInt16(value.u16); 274 break; 275 case MTP_TYPE_INT32: 276 case MTP_TYPE_AINT32: 277 packet.putInt32(value.i32); 278 break; 279 case MTP_TYPE_UINT32: 280 case MTP_TYPE_AUINT32: 281 packet.putUInt32(value.u32); 282 break; 283 case MTP_TYPE_INT64: 284 case MTP_TYPE_AINT64: 285 packet.putInt64(value.i64); 286 break; 287 case MTP_TYPE_UINT64: 288 case MTP_TYPE_AUINT64: 289 packet.putUInt64(value.u64); 290 break; 291 case MTP_TYPE_INT128: 292 case MTP_TYPE_AINT128: 293 packet.putInt128(value.i128); 294 break; 295 case MTP_TYPE_UINT128: 296 case MTP_TYPE_AUINT128: 297 packet.putUInt128(value.u128); 298 break; 299 case MTP_TYPE_STR: 300 if (value.str) 301 packet.putString(value.str); 302 else 303 packet.putEmptyString(); 304 break; 305 default: 306 LOGE("unknown type %04X in MtpProperty::writeValue", mType); 307 } 308} 309 310MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, int& length) { 311 length = packet.getUInt32(); 312 if (length == 0) 313 return NULL; 314 MtpPropertyValue* result = new MtpPropertyValue[length]; 315 for (int i = 0; i < length; i++) 316 readValue(packet, result[i]); 317 return result; 318} 319 320void MtpProperty::writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, int length) { 321 packet.putUInt32(length); 322 for (int i = 0; i < length; i++) 323 writeValue(packet, values[i]); 324} 325 326} // namespace android 327