| /* |
| * Copyright (C) 2010 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "MtpClient.h" |
| #include "MtpDevice.h" |
| #include "MtpDeviceInfo.h" |
| #include "MtpObjectInfo.h" |
| #include "MtpStorage.h" |
| #include "MtpUtils.h" |
| |
| #include "MtpFile.h" |
| |
| namespace android { |
| |
| MtpClient* MtpFile::sClient = NULL; |
| |
| MtpFile::MtpFile(MtpDevice* device) |
| : mDevice(device), |
| mStorage(0), |
| mHandle(0) |
| { |
| } |
| |
| MtpFile::MtpFile(MtpDevice* device, MtpStorageID storage) |
| : mDevice(device), |
| mStorage(storage), |
| mHandle(0) |
| { |
| } |
| |
| MtpFile::MtpFile(MtpDevice* device, MtpStorageID storage, MtpObjectHandle handle) |
| : mDevice(device), |
| mStorage(storage), |
| mHandle(handle) |
| { |
| } |
| |
| MtpFile::MtpFile(MtpFile* file) |
| : mDevice(file->mDevice), |
| mStorage(file->mStorage), |
| mHandle(file->mHandle) |
| { |
| } |
| |
| MtpFile::~MtpFile() { |
| } |
| |
| void MtpFile::print() { |
| if (mHandle) { |
| |
| } else if (mStorage) { |
| printf("%x\n", mStorage); |
| } else { |
| int id = mDevice->getID(); |
| MtpDeviceInfo* info = mDevice->getDeviceInfo(); |
| if (info) |
| printf("%d\t%s %s %s\n", id, info->mManufacturer, info->mModel, info->mSerial); |
| else |
| printf("%d\t(no device info available)\n", id); |
| delete info; |
| } |
| } |
| |
| MtpObjectInfo* MtpFile::getObjectInfo() { |
| return mDevice->getObjectInfo(mHandle); |
| } |
| |
| void MtpFile::list() { |
| if (mStorage) { |
| MtpObjectHandleList* handles = mDevice->getObjectHandles(mStorage, 0, |
| (mHandle ? mHandle : -1)); |
| if (handles) { |
| for (int i = 0; i < handles->size(); i++) { |
| MtpObjectHandle handle = (*handles)[i]; |
| MtpObjectInfo* info = mDevice->getObjectInfo(handle); |
| if (info) { |
| char modified[100]; |
| struct tm tm; |
| |
| gmtime_r(&info->mDateModified, &tm); |
| strftime(modified, sizeof(modified), "%a %b %e %H:%M:%S GMT %Y", &tm); |
| printf("%s Handle: %d Format: %04X Size: %d Modified: %s\n", |
| info->mName, handle, info->mFormat, info->mCompressedSize, modified); |
| delete info; |
| } |
| } |
| delete handles; |
| } |
| } else { |
| // list storage units for device |
| MtpStorageIDList* storageList = mDevice->getStorageIDs(); |
| for (int i = 0; i < storageList->size(); i++) { |
| MtpStorageID storageID = (*storageList)[i]; |
| printf("%x\n", storageID); |
| } |
| } |
| } |
| |
| void MtpFile::init(MtpClient* client) { |
| sClient = client; |
| } |
| |
| MtpFile* MtpFile::parsePath(MtpFile* base, char* path) { |
| MtpDevice* device = NULL; |
| MtpStorageID storage = 0; |
| MtpObjectHandle handle = 0; |
| |
| if (path[0] != '/' && base) { |
| device = base->mDevice; |
| storage = base->mStorage; |
| handle = base->mHandle; |
| } |
| |
| // parse an absolute path |
| if (path[0] == '/') |
| path++; |
| char* tok = strtok(path, "/"); |
| while (tok) { |
| if (storage) { |
| // find child of current handle |
| MtpObjectHandleList* handles = device->getObjectHandles(storage, 0, |
| (handle ? handle : -1)); |
| MtpObjectHandle childHandle = 0; |
| |
| if (handles) { |
| for (int i = 0; i < handles->size() && !childHandle; i++) { |
| MtpObjectHandle handle = (*handles)[i]; |
| MtpObjectInfo* info = device->getObjectInfo(handle); |
| if (info && !strcmp(tok, info->mName)) |
| childHandle = handle; |
| delete info; |
| } |
| delete handles; |
| } |
| if (childHandle) |
| handle = childHandle; |
| else |
| return NULL; |
| } else if (device) { |
| unsigned int id; |
| // find storage for the device |
| if (sscanf(tok, "%x", &id) == 1) { |
| MtpStorageIDList* storageList = device->getStorageIDs(); |
| bool found = false; |
| for (int i = 0; i < storageList->size(); i++) { |
| if ((*storageList)[i] == id) { |
| found = true; |
| break; |
| } |
| } |
| if (found) |
| storage = id; |
| else |
| return NULL; |
| } |
| } else { |
| // find device |
| unsigned int id; |
| if (sscanf(tok, "%d", &id) == 1) |
| device = sClient->getDevice(id); |
| if (!device) |
| return NULL; |
| } |
| |
| tok = strtok(NULL, "/"); |
| } |
| |
| if (device) |
| return new MtpFile(device, storage, handle); |
| else |
| return NULL; |
| } |
| |
| } |