MtpProperty.cpp revision dde372033b4da75ebde7ea2afdec1c1b86ab5a42
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 memset(&mDefaultValue, 0, sizeof(mDefaultValue)); 40 memset(&mCurrentValue, 0, sizeof(mCurrentValue)); 41 memset(&mMinimumValue, 0, sizeof(mMinimumValue)); 42 memset(&mMaximumValue, 0, sizeof(mMaximumValue)); 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.u.i8 = defaultValue; 70 break; 71 case MTP_TYPE_UINT8: 72 mDefaultValue.u.u8 = defaultValue; 73 break; 74 case MTP_TYPE_INT16: 75 mDefaultValue.u.i16 = defaultValue; 76 break; 77 case MTP_TYPE_UINT16: 78 mDefaultValue.u.u16 = defaultValue; 79 break; 80 case MTP_TYPE_INT32: 81 mDefaultValue.u.i32 = defaultValue; 82 break; 83 case MTP_TYPE_UINT32: 84 mDefaultValue.u.u32 = defaultValue; 85 break; 86 case MTP_TYPE_INT64: 87 mDefaultValue.u.i64 = defaultValue; 88 break; 89 case MTP_TYPE_UINT64: 90 mDefaultValue.u.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 bool deviceProp = isDeviceProperty(); 125 126 mCode = packet.getUInt16(); 127 mType = packet.getUInt16(); 128 mWriteable = (packet.getUInt8() == 1); 129 switch (mType) { 130 case MTP_TYPE_AINT8: 131 case MTP_TYPE_AUINT8: 132 case MTP_TYPE_AINT16: 133 case MTP_TYPE_AUINT16: 134 case MTP_TYPE_AINT32: 135 case MTP_TYPE_AUINT32: 136 case MTP_TYPE_AINT64: 137 case MTP_TYPE_AUINT64: 138 case MTP_TYPE_AINT128: 139 case MTP_TYPE_AUINT128: 140 mDefaultArrayValues = readArrayValues(packet, mDefaultArrayLength); 141 if (deviceProp) 142 mCurrentArrayValues = readArrayValues(packet, mCurrentArrayLength); 143 break; 144 default: 145 readValue(packet, mDefaultValue); 146 if (deviceProp) 147 readValue(packet, mCurrentValue); 148 } 149 if (!deviceProp) 150 mGroupCode = packet.getUInt32(); 151 mFormFlag = packet.getUInt8(); 152 153 if (mFormFlag == kFormRange) { 154 readValue(packet, mMinimumValue); 155 readValue(packet, mMaximumValue); 156 readValue(packet, mStepSize); 157 } else if (mFormFlag == kFormEnum) { 158 mEnumLength = packet.getUInt16(); 159 mEnumValues = new MtpPropertyValue[mEnumLength]; 160 for (int i = 0; i < mEnumLength; i++) 161 readValue(packet, mEnumValues[i]); 162 } 163} 164 165void MtpProperty::write(MtpDataPacket& packet) { 166 bool deviceProp = isDeviceProperty(); 167 168 packet.putUInt16(mCode); 169 packet.putUInt16(mType); 170 packet.putUInt8(mWriteable ? 1 : 0); 171 172 switch (mType) { 173 case MTP_TYPE_AINT8: 174 case MTP_TYPE_AUINT8: 175 case MTP_TYPE_AINT16: 176 case MTP_TYPE_AUINT16: 177 case MTP_TYPE_AINT32: 178 case MTP_TYPE_AUINT32: 179 case MTP_TYPE_AINT64: 180 case MTP_TYPE_AUINT64: 181 case MTP_TYPE_AINT128: 182 case MTP_TYPE_AUINT128: 183 writeArrayValues(packet, mDefaultArrayValues, mDefaultArrayLength); 184 if (deviceProp) 185 writeArrayValues(packet, mCurrentArrayValues, mCurrentArrayLength); 186 break; 187 default: 188 writeValue(packet, mDefaultValue); 189 if (deviceProp) 190 writeValue(packet, mCurrentValue); 191 } 192 packet.putUInt32(mGroupCode); 193 if (!deviceProp) 194 packet.putUInt8(mFormFlag); 195 if (mFormFlag == kFormRange) { 196 writeValue(packet, mMinimumValue); 197 writeValue(packet, mMaximumValue); 198 writeValue(packet, mStepSize); 199 } else if (mFormFlag == kFormEnum) { 200 packet.putUInt16(mEnumLength); 201 for (int i = 0; i < mEnumLength; i++) 202 writeValue(packet, mEnumValues[i]); 203 } 204} 205 206void MtpProperty::setDefaultValue(const uint16_t* string) { 207 free(mDefaultValue.str); 208 if (string) { 209 MtpStringBuffer buffer(string); 210 mDefaultValue.str = strdup(buffer); 211 } 212 else 213 mDefaultValue.str = NULL; 214} 215 216void MtpProperty::setCurrentValue(const uint16_t* string) { 217 free(mCurrentValue.str); 218 if (string) { 219 MtpStringBuffer buffer(string); 220 mCurrentValue.str = strdup(buffer); 221 } 222 else 223 mCurrentValue.str = NULL; 224} 225 226void MtpProperty::print() { 227 LOGV("MtpProperty %04X\n", mCode); 228 LOGV(" type %04X\n", mType); 229 LOGV(" writeable %s\n", (mWriteable ? "true" : "false")); 230} 231 232void MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) { 233 MtpStringBuffer stringBuffer; 234 235 switch (mType) { 236 case MTP_TYPE_INT8: 237 case MTP_TYPE_AINT8: 238 value.u.i8 = packet.getInt8(); 239 break; 240 case MTP_TYPE_UINT8: 241 case MTP_TYPE_AUINT8: 242 value.u.u8 = packet.getUInt8(); 243 break; 244 case MTP_TYPE_INT16: 245 case MTP_TYPE_AINT16: 246 value.u.i16 = packet.getInt16(); 247 break; 248 case MTP_TYPE_UINT16: 249 case MTP_TYPE_AUINT16: 250 value.u.u16 = packet.getUInt16(); 251 break; 252 case MTP_TYPE_INT32: 253 case MTP_TYPE_AINT32: 254 value.u.i32 = packet.getInt32(); 255 break; 256 case MTP_TYPE_UINT32: 257 case MTP_TYPE_AUINT32: 258 value.u.u32 = packet.getUInt32(); 259 break; 260 case MTP_TYPE_INT64: 261 case MTP_TYPE_AINT64: 262 value.u.i64 = packet.getInt64(); 263 break; 264 case MTP_TYPE_UINT64: 265 case MTP_TYPE_AUINT64: 266 value.u.u64 = packet.getUInt64(); 267 break; 268 case MTP_TYPE_INT128: 269 case MTP_TYPE_AINT128: 270 packet.getInt128(value.u.i128); 271 break; 272 case MTP_TYPE_UINT128: 273 case MTP_TYPE_AUINT128: 274 packet.getUInt128(value.u.u128); 275 break; 276 case MTP_TYPE_STR: 277 packet.getString(stringBuffer); 278 value.str = strdup(stringBuffer); 279 break; 280 default: 281 LOGE("unknown type %04X in MtpProperty::readValue", mType); 282 } 283} 284 285void MtpProperty::writeValue(MtpDataPacket& packet, MtpPropertyValue& value) { 286 MtpStringBuffer stringBuffer; 287 288 switch (mType) { 289 case MTP_TYPE_INT8: 290 case MTP_TYPE_AINT8: 291 packet.putInt8(value.u.i8); 292 break; 293 case MTP_TYPE_UINT8: 294 case MTP_TYPE_AUINT8: 295 packet.putUInt8(value.u.u8); 296 break; 297 case MTP_TYPE_INT16: 298 case MTP_TYPE_AINT16: 299 packet.putInt16(value.u.i16); 300 break; 301 case MTP_TYPE_UINT16: 302 case MTP_TYPE_AUINT16: 303 packet.putUInt16(value.u.u16); 304 break; 305 case MTP_TYPE_INT32: 306 case MTP_TYPE_AINT32: 307 packet.putInt32(value.u.i32); 308 break; 309 case MTP_TYPE_UINT32: 310 case MTP_TYPE_AUINT32: 311 packet.putUInt32(value.u.u32); 312 break; 313 case MTP_TYPE_INT64: 314 case MTP_TYPE_AINT64: 315 packet.putInt64(value.u.i64); 316 break; 317 case MTP_TYPE_UINT64: 318 case MTP_TYPE_AUINT64: 319 packet.putUInt64(value.u.u64); 320 break; 321 case MTP_TYPE_INT128: 322 case MTP_TYPE_AINT128: 323 packet.putInt128(value.u.i128); 324 break; 325 case MTP_TYPE_UINT128: 326 case MTP_TYPE_AUINT128: 327 packet.putUInt128(value.u.u128); 328 break; 329 case MTP_TYPE_STR: 330 if (value.str) 331 packet.putString(value.str); 332 else 333 packet.putEmptyString(); 334 break; 335 default: 336 LOGE("unknown type %04X in MtpProperty::writeValue", mType); 337 } 338} 339 340MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, int& length) { 341 length = packet.getUInt32(); 342 if (length == 0) 343 return NULL; 344 MtpPropertyValue* result = new MtpPropertyValue[length]; 345 for (int i = 0; i < length; i++) 346 readValue(packet, result[i]); 347 return result; 348} 349 350void MtpProperty::writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, int length) { 351 packet.putUInt32(length); 352 for (int i = 0; i < length; i++) 353 writeValue(packet, values[i]); 354} 355 356} // namespace android 357