MtpProperty.cpp revision 2bb8c0e7c4e4093f4161ff5e98cef51c87193859
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, bool deviceProp) { 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 (deviceProp) 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 162// FIXME - only works for object properties 163void MtpProperty::write(MtpDataPacket& packet) { 164 packet.putUInt16(mCode); 165 packet.putUInt16(mType); 166 packet.putUInt8(mWriteable ? 1 : 0); 167 168 switch (mType) { 169 case MTP_TYPE_AINT8: 170 case MTP_TYPE_AUINT8: 171 case MTP_TYPE_AINT16: 172 case MTP_TYPE_AUINT16: 173 case MTP_TYPE_AINT32: 174 case MTP_TYPE_AUINT32: 175 case MTP_TYPE_AINT64: 176 case MTP_TYPE_AUINT64: 177 case MTP_TYPE_AINT128: 178 case MTP_TYPE_AUINT128: 179 writeArrayValues(packet, mDefaultArrayValues, mDefaultArrayLength); 180 break; 181 default: 182 writeValue(packet, mDefaultValue); 183 } 184 packet.putUInt32(mGroupCode); 185 packet.putUInt8(mFormFlag); 186 if (mFormFlag == kFormRange) { 187 writeValue(packet, mMinimumValue); 188 writeValue(packet, mMaximumValue); 189 writeValue(packet, mStepSize); 190 } else if (mFormFlag == kFormEnum) { 191 packet.putUInt16(mEnumLength); 192 for (int i = 0; i < mEnumLength; i++) 193 writeValue(packet, mEnumValues[i]); 194 } 195} 196 197void MtpProperty::print() { 198 LOGV("MtpProperty %04X\n", mCode); 199 LOGV(" type %04X\n", mType); 200 LOGV(" writeable %s\n", (mWriteable ? "true" : "false")); 201} 202 203void MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) { 204 MtpStringBuffer stringBuffer; 205 206 switch (mType) { 207 case MTP_TYPE_INT8: 208 case MTP_TYPE_AINT8: 209 value.i8 = packet.getInt8(); 210 break; 211 case MTP_TYPE_UINT8: 212 case MTP_TYPE_AUINT8: 213 value.u8 = packet.getUInt8(); 214 break; 215 case MTP_TYPE_INT16: 216 case MTP_TYPE_AINT16: 217 value.i16 = packet.getInt16(); 218 break; 219 case MTP_TYPE_UINT16: 220 case MTP_TYPE_AUINT16: 221 value.u16 = packet.getUInt16(); 222 break; 223 case MTP_TYPE_INT32: 224 case MTP_TYPE_AINT32: 225 value.i32 = packet.getInt32(); 226 break; 227 case MTP_TYPE_UINT32: 228 case MTP_TYPE_AUINT32: 229 value.u32 = packet.getUInt32(); 230 break; 231 case MTP_TYPE_INT64: 232 case MTP_TYPE_AINT64: 233 value.i64 = packet.getInt64(); 234 break; 235 case MTP_TYPE_UINT64: 236 case MTP_TYPE_AUINT64: 237 value.u64 = packet.getUInt64(); 238 break; 239 case MTP_TYPE_INT128: 240 case MTP_TYPE_AINT128: 241 packet.getInt128(value.i128); 242 break; 243 case MTP_TYPE_UINT128: 244 case MTP_TYPE_AUINT128: 245 packet.getUInt128(value.u128); 246 break; 247 case MTP_TYPE_STR: 248 packet.getString(stringBuffer); 249 value.str = strdup(stringBuffer); 250 break; 251 default: 252 LOGE("unknown type %04X in MtpProperty::readValue", mType); 253 } 254} 255 256void MtpProperty::writeValue(MtpDataPacket& packet, MtpPropertyValue& value) { 257 MtpStringBuffer stringBuffer; 258 259 switch (mType) { 260 case MTP_TYPE_INT8: 261 case MTP_TYPE_AINT8: 262 packet.putInt8(value.i8); 263 break; 264 case MTP_TYPE_UINT8: 265 case MTP_TYPE_AUINT8: 266 packet.putUInt8(value.u8); 267 break; 268 case MTP_TYPE_INT16: 269 case MTP_TYPE_AINT16: 270 packet.putInt16(value.i16); 271 break; 272 case MTP_TYPE_UINT16: 273 case MTP_TYPE_AUINT16: 274 packet.putUInt16(value.u16); 275 break; 276 case MTP_TYPE_INT32: 277 case MTP_TYPE_AINT32: 278 packet.putInt32(value.i32); 279 break; 280 case MTP_TYPE_UINT32: 281 case MTP_TYPE_AUINT32: 282 packet.putUInt32(value.u32); 283 break; 284 case MTP_TYPE_INT64: 285 case MTP_TYPE_AINT64: 286 packet.putInt64(value.i64); 287 break; 288 case MTP_TYPE_UINT64: 289 case MTP_TYPE_AUINT64: 290 packet.putUInt64(value.u64); 291 break; 292 case MTP_TYPE_INT128: 293 case MTP_TYPE_AINT128: 294 packet.putInt128(value.i128); 295 break; 296 case MTP_TYPE_UINT128: 297 case MTP_TYPE_AUINT128: 298 packet.putUInt128(value.u128); 299 break; 300 case MTP_TYPE_STR: 301 if (value.str) 302 packet.putString(value.str); 303 else 304 packet.putEmptyString(); 305 break; 306 default: 307 LOGE("unknown type %04X in MtpProperty::writeValue", mType); 308 } 309} 310 311MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, int& length) { 312 length = packet.getUInt32(); 313 if (length == 0) 314 return NULL; 315 MtpPropertyValue* result = new MtpPropertyValue[length]; 316 for (int i = 0; i < length; i++) 317 readValue(packet, result[i]); 318 return result; 319} 320 321void MtpProperty::writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, int length) { 322 packet.putUInt32(length); 323 for (int i = 0; i < length; i++) 324 writeValue(packet, values[i]); 325} 326 327} // namespace android 328