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