From b7ad2b13f4d3b98ef18d4151d743f5dfc4e887ee Mon Sep 17 00:00:00 2001 From: codestation Date: Tue, 28 Jan 2014 14:00:15 -0430 Subject: [PATCH] Create a unified base class to access the database. Moved the default database class to QListDB and disallow leaking CMAObjects outside this class. Rewrote QListDB and CMAEvent to use the new internal API. Moved the file format constants to the base database class. Moved the metadata loading methods to the base database class. --- qcma.pro | 6 +- src/avdecoder.cpp | 2 +- src/cmaclient.h | 1 - src/cmaevent.cpp | 269 +++++++++++++++----------------- src/cmaevent.h | 4 +- src/cmaobject.cpp | 49 +----- src/database.cpp | 101 ++++++++++++ src/database.h | 63 ++++++++ src/forms/backupmanagerform.cpp | 28 ++-- src/qlistdb.cpp | 223 ++++++++++++++++++-------- src/qlistdb.h | 52 +++--- src/sqlitedb.cpp | 9 +- src/sqlitedb.h | 6 +- src/utils.cpp | 50 ------ src/utils.h | 31 ---- 15 files changed, 514 insertions(+), 380 deletions(-) create mode 100644 src/database.cpp create mode 100644 src/database.h diff --git a/qcma.pro b/qcma.pro index 85c3f2a..84cf31c 100644 --- a/qcma.pro +++ b/qcma.pro @@ -40,7 +40,8 @@ SOURCES += src/main.cpp \ src/forms/configwidget.cpp \ src/forms/confirmdialog.cpp \ src/forms/pinform.cpp \ - src/forms/progressform.cpp + src/forms/progressform.cpp \ + src/database.cpp HEADERS += \ src/capability.h \ @@ -66,7 +67,8 @@ HEADERS += \ src/forms/configwidget.h \ src/forms/confirmdialog.h \ src/forms/pinform.h \ - src/forms/progressform.h + src/forms/progressform.h \ + src/database.h FORMS += \ src/forms/configwidget.ui \ diff --git a/src/avdecoder.cpp b/src/avdecoder.cpp index 2f70bff..bcaf1d0 100644 --- a/src/avdecoder.cpp +++ b/src/avdecoder.cpp @@ -19,7 +19,7 @@ #include "utils.h" #include "avdecoder.h" -#include "cmaobject.h" +#include "database.h" #include #include diff --git a/src/cmaclient.h b/src/cmaclient.h index 93bc550..02d8131 100644 --- a/src/cmaclient.h +++ b/src/cmaclient.h @@ -22,7 +22,6 @@ #include "qlistdb.h" #include "cmaevent.h" -#include "cmaobject.h" #include "cmabroadcast.h" #include diff --git a/src/cmaevent.cpp b/src/cmaevent.cpp index 1a7c8ba..8e0dc0e 100644 --- a/src/cmaevent.cpp +++ b/src/cmaevent.cpp @@ -25,14 +25,13 @@ #include #include #include +#include #include -#include - QListDB *CmaEvent::db = NULL; QFile *CmaEvent::m_file = NULL; -metadata_t CmaEvent::g_thumbmeta = {0, 0, 0, NULL, NULL, 0, 0, 0, Thumbnail, {{17, 240, 136, 0, 1, 1.0f, 2}}, NULL}; +static metadata_t g_thumbmeta = {0, 0, 0, NULL, NULL, 0, 0, 0, Thumbnail, {{17, 240, 136, 0, 1, 1.0f, 2}}, NULL}; CmaEvent::CmaEvent(vita_device_t *s_device) : device(s_device), is_active(true) @@ -149,15 +148,13 @@ void CmaEvent::processEvent() qDebug("Ended event, code: 0x%x, id: %d", t_event.Code, t_event.Param1); } -quint16 CmaEvent::processAllObjects(CMAObject *parent, quint32 handle) +quint16 CmaEvent::processAllObjects(metadata_t &parent_metadata, quint32 handle) { - qDebug("Called %s, handle: %d, parent name: %s", Q_FUNC_INFO, handle, parent->metadata.name); + qDebug("Called %s, handle: %d, parent name: %s", Q_FUNC_INFO, handle, parent_metadata.name); char *name; - int fileType = -1; int dataType; - - uint32_t *p_handles; + quint32 *p_handles; unsigned int p_len; if(VitaMTP_GetObject_Info(device, handle, &name, &dataType) != PTP_RC_OK) { @@ -174,15 +171,16 @@ quint16 CmaEvent::processAllObjects(CMAObject *parent, quint32 handle) } - CMAObject *object = db->pathToObject(name, parent->metadata.ohfi); + int ohfi = db->getPathId(name, parent_metadata.ohfi); + const QString fullpath = db->getAbsolutePath(ohfi); - if(object) { - qDebug("Deleting %s", object->path.toStdString().c_str()); - removeRecursively(object->path); - db->remove(object); + if(ohfi > 0) { + qDebug() << "Deleting" << fullpath; + removeRecursively(fullpath); + db->deleteEntry(ohfi); } - QDir dir(parent->path); + QDir dir(db->getAbsolutePath(parent_metadata.ohfi)); if(dataType & Folder) { if(!dir.mkpath(name)) { @@ -205,33 +203,26 @@ quint16 CmaEvent::processAllObjects(CMAObject *parent, quint32 handle) VitaMTP_GetObject_Callback(device, handle, &size, CmaEvent::writeCallback); m_file->close(); delete m_file; - - // get the root ohfi type - CMAObject *root_obj = parent; - while(root_obj->parent) { - root_obj = root_obj->parent; - } - - fileType = checkFileType(dir.absoluteFilePath(name), root_obj->metadata.ohfi); } } QFileInfo info(dir, name); - object = new CMAObject(parent); - object->initObject(info, fileType); - object->metadata.handle = handle; - db->append(parent->metadata.ohfi, object); + int new_ohfi = db->insertObjectEntry(info.absoluteFilePath(), parent_metadata.ohfi); free(name); - qDebug("Added object %s with OHFI %i to database", object->metadata.path, object->metadata.ohfi); + qDebug() << QString("Added object %1 with OHFI %2 to database").arg(info.absoluteFilePath(), QString::number(new_ohfi)); if(dataType & Folder) { + metadata_t folder_metadata; + db->getObjectMetadata(new_ohfi, folder_metadata); + folder_metadata.handle = handle; + for(unsigned int i = 0; i < p_len; i++) { - quint16 ret = processAllObjects(object, p_handles[i]); + quint16 ret = processAllObjects(folder_metadata, p_handles[i]); if(ret != PTP_RC_OK) { - qDebug("Deleteting object with OHFI %d", object->metadata.ohfi); - db->remove(object); + qDebug("Deleteting object with OHFI %d", new_ohfi); + db->deleteEntry(new_ohfi); return ret; } } @@ -253,15 +244,15 @@ void CmaEvent::vitaEventGetTreatObject(vita_event_t *event, int eventId) QMutexLocker locker(&db->mutex); - CMAObject *parent = db->ohfiToObject(treatObject.ohfiParent); + metadata_t metadata; - if(parent == NULL) { + if(!db->getObjectMetadata(treatObject.ohfiParent, metadata)) { qWarning("Cannot find parent OHFI %d", treatObject.ohfiParent); VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI); return; } - VitaMTP_ReportResult(device, eventId, processAllObjects(parent, treatObject.handle)); + VitaMTP_ReportResult(device, eventId, processAllObjects(metadata, treatObject.handle)); } void CmaEvent::vitaEventSendCopyConfirmationInfo(vita_event_t *event, int eventId) @@ -276,21 +267,20 @@ void CmaEvent::vitaEventSendCopyConfirmationInfo(vita_event_t *event, int eventI QMutexLocker locker(&db->mutex); - quint64 size = 0; + qint64 size; + qint64 total_size = 0; for(quint32 i = 0; i < info->count; i++) { - CMAObject *object; - - if((object = db->ohfiToObject(info->ohfi[i])) == NULL) { + if((size = db->getObjectSize(info->ohfi[i])) < 0) { qWarning("Cannot find OHFI %d", info->ohfi[i]); free(info); return; } - size += object->metadata.size; + total_size += size; } - if(VitaMTP_SendCopyConfirmationInfo(device, eventId, info, size) != PTP_RC_OK) { + if(VitaMTP_SendCopyConfirmationInfo(device, eventId, info, total_size) != PTP_RC_OK) { qWarning("Error sending copy confirmation"); } else { VitaMTP_ReportResult(device, eventId, PTP_RC_OK); @@ -311,19 +301,18 @@ void CmaEvent::vitaEventSendObjectMetadataItems(vita_event_t *event, int eventId QMutexLocker locker(&db->mutex); - CMAObject *object = db->ohfiToObject(ohfi); + metadata_t metadata; - if(object == NULL) { + if(!db->getObjectMetadata(ohfi, metadata)) { qWarning("Cannot find OHFI %d in database", ohfi); VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI); return; } - metadata_t *metadata = &object->metadata; - metadata->next_metadata = NULL; - qDebug("Sending metadata for OHFI %d (%s)", ohfi, metadata->path); + metadata.next_metadata = NULL; + qDebug("Sending metadata for OHFI %d (%s)", ohfi, metadata.path); - quint16 ret = VitaMTP_SendObjectMetadata(device, eventId, metadata); + quint16 ret = VitaMTP_SendObjectMetadata(device, eventId, &metadata); if(ret != PTP_RC_OK) { qWarning("Error sending metadata. Code: %04X", ret); } else { @@ -368,8 +357,8 @@ void CmaEvent::vitaEventSendNumOfObject(vita_event_t *event, int eventId) QMutexLocker locker(&db->mutex); - uint ohfi = event->Param2; - int items = db->filterObjects(ohfi, NULL); + int ohfi = event->Param2; + int items = db->childObjectCount(ohfi); if(VitaMTP_SendNumOfObject(device, eventId, items) != PTP_RC_OK) { qWarning("Error occured receiving object count for OHFI parent %d", ohfi); @@ -391,8 +380,9 @@ void CmaEvent::vitaEventSendObjectMetadata(vita_event_t *event, int eventId) } QMutexLocker locker(&db->mutex); - metadata_t *meta; - int count = db->filterObjects(browse.ohfiParent, &meta, browse.index, browse.numObjects); // if meta is null, will return empty XML + metadata_t *meta = NULL; + + int count = db->getObjectMetadatas(browse.ohfiParent, meta, browse.index, browse.numObjects); // if meta is null, will return empty XML qDebug("Sending %i metadata filtered objects for OHFI %d", count, browse.ohfiParent); if(VitaMTP_SendObjectMetadata(device, eventId, meta) != PTP_RC_OK) { // send all objects with OHFI parent @@ -412,29 +402,27 @@ void CmaEvent::vitaEventSendObject(vita_event_t *event, int eventId) qDebug("Searching object with OHFI %d", ohfi); - QListDB::find_data iters; - if(!db->find(ohfi, iters)) { + metadata_t *metadata = NULL; + if(!db->getObjectMetadatas(ohfi, metadata)) { qWarning("Failed to find OHFI %d", ohfi); VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI); return; } - unsigned long len = 0; - CMAObject *object = *iters.it; - CMAObject *start = object; - uint parentHandle = event->Param3; - bool send_folder = object->metadata.dataType & Folder; - uint handle; + metadata_t *start = metadata; + quint32 parentHandle = event->Param3; + bool send_folder = metadata->dataType & Folder; + quint32 handle; do { - len = object->metadata.size; - m_file = new QFile(object->path); + unsigned long len = metadata->size; + m_file = new QFile(db->getAbsolutePath(metadata->ohfi)); // read the file to send if it's not a directory // if it is a directory, data and len are not used by VitaMTP - if(object->metadata.dataType & File) { + if(metadata->dataType & File) { if(!m_file->open(QIODevice::ReadOnly)) { - qWarning("Failed to read %s", object->path.toStdString().c_str()); + qWarning() << "Failed to read" << m_file->fileName(); delete m_file; VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Not_Exist_Object); return; @@ -445,18 +433,20 @@ void CmaEvent::vitaEventSendObject(vita_event_t *event, int eventId) // we know the parent has to be before the current node // the first time this is called, parentHandle is left untouched - if(start != object) { - parentHandle = object->parent->metadata.handle; + if(start != metadata) { + metadata_t parent_metadata; + db->getObjectMetadata(metadata->ohfiParent, parent_metadata); + parentHandle = parent_metadata.handle; } // send the data over - qDebug("Sending %s of %lu bytes to device", object->metadata.name, len); + qDebug("Sending %s of %lu bytes to device", metadata->name, len); qDebug("OHFI %d with handle 0x%08X", ohfi, parentHandle); VitaMTP_RegisterCancelEventId(eventId); - quint16 ret = VitaMTP_SendObject_Callback(device, &parentHandle, &handle, &object->metadata, &CmaEvent::readCallback); + quint16 ret = VitaMTP_SendObject_Callback(device, &parentHandle, &handle, metadata, &CmaEvent::readCallback); if(ret != PTP_RC_OK) { - qWarning("Sending of %s failed. Code: %04X", object->metadata.name, ret); + qWarning("Sending of %s failed. Code: %04X", metadata->name, ret); if(ret == PTP_ERROR_CANCEL) { VitaMTP_ReportResult(device, eventId, PTP_RC_GeneralError); } @@ -465,9 +455,9 @@ void CmaEvent::vitaEventSendObject(vita_event_t *event, int eventId) return; } - object->metadata.handle = handle; + metadata->handle = handle; - if(object->metadata.dataType & File) { + if(metadata->dataType & File) { m_file->close(); delete m_file; } @@ -477,9 +467,9 @@ void CmaEvent::vitaEventSendObject(vita_event_t *event, int eventId) break; } - object = *++iters.it; + metadata = metadata->next_metadata; - } while(iters.it != iters.end && object->metadata.ohfiParent >= OHFI_OFFSET); // get everything under this "folder" + } while(metadata && metadata->ohfiParent >= OHFI_OFFSET); // get everything under this "folder" VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, handle); @@ -573,18 +563,19 @@ void CmaEvent::vitaEventSendObjectStatus(vita_event_t *event, int eventId) QMutexLocker locker(&db->mutex); - CMAObject *object = db->pathToObject(objectstatus.title, objectstatus.ohfiRoot); + int ohfi = db->getPathId(objectstatus.title, objectstatus.ohfiRoot); - if(object == NULL) { // not in database, don't return metadata + if(ohfi == 0) { // not in database, don't return metadata qDebug("Object %s not in database (OHFI: %i). Sending OK response for non-existence", objectstatus.title, objectstatus.ohfiRoot); VitaMTP_ReportResult(device, eventId, PTP_RC_OK); } else { - metadata_t *metadata = &object->metadata; - metadata->next_metadata = NULL; - qDebug("Sending metadata for OHFI %d", object->metadata.ohfi); + metadata_t metadata; + db->getObjectMetadata(ohfi, metadata); + metadata.next_metadata = NULL; + qDebug("Sending metadata for OHFI %d", ohfi); - if(VitaMTP_SendObjectMetadata(device, eventId, metadata) != PTP_RC_OK) { - qWarning("Error sending metadata for %d", object->metadata.ohfi); + if(VitaMTP_SendObjectMetadata(device, eventId, &metadata) != PTP_RC_OK) { + qWarning("Error sending metadata for %d", ohfi); } else { VitaMTP_ReportResult(device, eventId, PTP_RC_OK); } @@ -600,22 +591,25 @@ void CmaEvent::vitaEventSendObjectThumb(vita_event_t *event, int eventId) QMutexLocker locker(&db->mutex); int ohfi = event->Param2; - CMAObject *object = db->ohfiToObject(ohfi); + metadata_t metadata; - if(object == NULL) { + if(!db->getObjectMetadata(ohfi, metadata)) { qWarning("Cannot find OHFI %d in database.", ohfi); VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI); return; } - QByteArray data = getThumbnail(object->path, object->metadata.dataType, &g_thumbmeta); + QString fullpath = db->getAbsolutePath(ohfi); + QByteArray data = getThumbnail(fullpath, metadata.dataType, &g_thumbmeta); if(data.size() == 0) { - qWarning("Cannot find/read thumbnail for %s", object->path.toStdString().c_str()); + qWarning() << "Cannot find/read thumbnail for" << fullpath; VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_Data); return; } + //FIXME: remove this after fixing vitamtp + // workaround for the vitamtp locale bug char *locale = strdup(setlocale(LC_ALL, NULL)); setlocale(LC_ALL, "C"); @@ -638,17 +632,18 @@ void CmaEvent::vitaEventDeleteObject(vita_event_t *event, int eventId) QMutexLocker locker(&db->mutex); int ohfi = event->Param2; - CMAObject *object = db->ohfiToObject(ohfi); + metadata_t metadata; - if(object == NULL) { + if(!db->getObjectMetadata(ohfi, metadata)) { qWarning("OHFI %d not found", ohfi); VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI); return; } - qDebug("Deleting %s, OHFI: %i", object->metadata.path, object->metadata.ohfi); - removeRecursively(object->path); - db->remove(object); + QString fullpath = db->getAbsolutePath(ohfi); + qDebug() << QString("Deleting %1, OHFI: %2").arg(fullpath, QString::number(ohfi)); + removeRecursively(fullpath); + db->deleteEntry(ohfi); VitaMTP_ReportResult(device, eventId, PTP_RC_OK); } @@ -727,24 +722,26 @@ void CmaEvent::vitaEventSendPartOfObject(vita_event_t *event, int eventId) QMutexLocker locker(&db->mutex); - CMAObject *object = db->ohfiToObject(part_init.ohfi); + QString fullpath = db->getAbsolutePath(part_init.ohfi); - if(object == NULL) { + if(fullpath.isNull()) { qWarning("Cannot find object for OHFI %d", part_init.ohfi); VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_Context); return; } - QFile file(object->path); + QFile file(fullpath); if(!file.open(QIODevice::ReadOnly)) { - qWarning("Cannot read %s", object->path.toStdString().c_str()); + qWarning() << "Cannot read" << fullpath; VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Not_Exist_Object); return; } else { file.seek(part_init.offset); QByteArray data = file.read(part_init.size); - qDebug("Sending %s at file offset %" PRIu64" for %" PRIu64" bytes", object->metadata.path, part_init.offset, part_init.size); + qDebug() << QString("Sending %1 at file offset %2 for %3 bytes").arg( + fullpath, QString::number(part_init.offset), QString::number(part_init.size) + ); if(VitaMTP_SendPartOfObject(device, eventId, (unsigned char *)data.data(), data.size()) != PTP_RC_OK) { qWarning("Failed to send part of object OHFI %d", part_init.ohfi); @@ -767,10 +764,10 @@ void CmaEvent::vitaEventOperateObject(vita_event_t *event, int eventId) QMutexLocker locker(&db->mutex); - CMAObject *root = db->ohfiToObject(operateobject.ohfi); + QString fullpath = db->getAbsolutePath(operateobject.ohfi); // end for renaming only - if(root == NULL) { + if(fullpath.isNull()) { VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Not_Exist_Object); return; } @@ -779,64 +776,46 @@ void CmaEvent::vitaEventOperateObject(vita_event_t *event, int eventId) case VITA_OPERATE_CREATE_FOLDER: { qDebug("Operate command %d: Create folder %s", operateobject.cmd, operateobject.title); - QDir dir(root->path); + QDir dir(fullpath); if(!dir.mkdir(operateobject.title)) { qWarning("Unable to create temporary folder: %s", operateobject.title); VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Failed_Operate_Object); } else { - CMAObject *newobj = new CMAObject(root); - newobj->initObject(QFileInfo(dir, operateobject.title)); - db->append(operateobject.ohfi, newobj); - qDebug("Created folder %s with OHFI %d under parent %s", newobj->metadata.path, newobj->metadata.ohfi, root->metadata.path); - VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, newobj->metadata.ohfi); + int new_ohfi = db->insertObjectEntry(QDir(dir).absoluteFilePath(operateobject.title), operateobject.ohfi); + qDebug("Created folder %s with OHFI %d", operateobject.title, new_ohfi); + VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, new_ohfi); } break; } case VITA_OPERATE_CREATE_FILE: { qDebug("Operate command %d: Create file %s", operateobject.cmd, operateobject.title); - QFile file(root->path + QDir::separator() + operateobject.title); + QFile file(fullpath + QDir::separator() + operateobject.title); if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { qWarning("Unable to create temporary file: %s", operateobject.title); VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Failed_Operate_Object); } else { - CMAObject *newobj = new CMAObject(root); - newobj->initObject(file); - db->append(root->metadata.ohfi, newobj); - qDebug("Created file %s with OHFI %d under parent %s", newobj->metadata.path, newobj->metadata.ohfi, root->metadata.path); - VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, newobj->metadata.ohfi); + int new_ohfi = db->insertObjectEntry(file.fileName(), operateobject.ohfi); + //qDebug("Created file %s with OHFI %d under parent %s", newobj->metadata.path, new_ohfi, root->metadata.path); + VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, new_ohfi); } break; } case VITA_OPERATE_RENAME: { - qDebug("Operate command %d: Rename %s to %s", operateobject.cmd, root->metadata.name, operateobject.title); + //qDebug("Operate command %d: Rename %s to %s", operateobject.cmd, root->metadata.name, operateobject.title); - QString oldpath = root->path; - QString oldname = root->metadata.name; - - //rename the current object - root->rename(operateobject.title); - QListDB::find_data iters; - db->find(root->metadata.ohfi, iters); - - // rename the rest of the list only if has the renamed parent in some part of the chain - while(iters.it != iters.end) { - CMAObject *obj = *iters.it++; - - if(obj->hasParent(root)) { - obj->refreshPath(); - } - } + db->renameObject(operateobject.ohfi, operateobject.title); + QString newpath = db->getAbsolutePath(operateobject.ohfi); // rename in filesystem - if(!QFile(oldpath).rename(root->path)) { - qWarning("Unable to rename %s to %s", oldname.toStdString().c_str(), operateobject.title); + if(!QFile(fullpath).rename(newpath)) { + qWarning("Unable to rename %s to %s", fullpath.toLocal8Bit().constData(), operateobject.title); VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Failed_Operate_Object); break; } - qDebug("Renamed OHFI %d from %s to %s", root->metadata.ohfi, oldname.toStdString().c_str(), root->metadata.name); - VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, root->metadata.ohfi); + qDebug("Renamed OHFI %d from %s to %s", operateobject.ohfi, fullpath.toLocal8Bit().constData(), newpath.toLocal8Bit().constData()); + VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, operateobject.ohfi); break; } @@ -862,26 +841,32 @@ void CmaEvent::vitaEventGetPartOfObject(vita_event_t *event, int eventId) } QMutexLocker locker(&db->mutex); - CMAObject *object = db->ohfiToObject(part_init.ohfi); + QString fullpath = db->getAbsolutePath(part_init.ohfi); - if(object == NULL) { + if(fullpath.isNull()) { qWarning("Cannot find OHFI %d", part_init.ohfi); VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI); free(data); return; } - qDebug("Receiving %s at offset %" PRIu64" for %" PRIu64" bytes", object->metadata.path, part_init.offset, part_init.size); + qDebug() << QString("Receiving %1 at offset %2 for %3 bytes").arg( + fullpath, QString::number(part_init.offset), QString::number(part_init.size) + ); - QFile file(object->path); + QFile file(fullpath); if(!file.open(QIODevice::ReadWrite)) { - qWarning("Cannot write to file %s", object->path.toStdString().c_str()); + qWarning() << "Cannot write to file" << fullpath; VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_Permission); } else { file.seek(part_init.offset); file.write((const char *)data, part_init.size); - object->updateObjectSize(part_init.size); - qDebug("Written %" PRIu64" bytes to %s at offset %" PRIu64, part_init.size, object->path.toStdString().c_str(), part_init.offset); + db->setObjectSize(part_init.ohfi, part_init.size); + + qDebug() << QString("Written %1 bytes to %2 at offset %3").arg( + QString::number(part_init.size), fullpath, QString::number(part_init.offset) + ); + VitaMTP_ReportResult(device, eventId, PTP_RC_OK); } @@ -895,20 +880,20 @@ void CmaEvent::vitaEventSendStorageSize(vita_event_t *event, int eventId) QMutexLocker locker(&db->mutex); int ohfi = event->Param2; - CMAObject *object = db->ohfiToObject(ohfi); + QString fullpath = db->getAbsolutePath(ohfi); - if(object == NULL) { + if(fullpath.isNull()) { qWarning("Error: Cannot find OHFI %d", ohfi); VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI); return; } else { - QFile file(object->path); + QFile file(fullpath); if(!file.exists()) { // create the directory if doesn't exist so the query don't fail - qDebug("Creating %s", object->path.toStdString().c_str()); + qDebug() << "Creating" << fullpath; - if(!QDir(QDir::root()).mkpath(object->path)) { + if(!QDir(QDir::root()).mkpath(QDir(fullpath).absolutePath())) { qWarning("Create directory failed"); VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_Permission); return; @@ -919,7 +904,7 @@ void CmaEvent::vitaEventSendStorageSize(vita_event_t *event, int eventId) quint64 total; quint64 free; - if(!getDiskSpace(object->path, &free, &total)) { + if(!getDiskSpace(fullpath, &free, &total)) { qWarning("Cannot get disk space"); VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_Permission); return; @@ -948,12 +933,12 @@ void CmaEvent::vitaEventCheckExistance(vita_event_t *event, int eventId) QMutexLocker locker(&db->mutex); - CMAObject *object = db->pathToObject(existance.name, 0); + int ohfi = db->getPathId(existance.name, 0); - if(object == NULL) { + if(ohfi == 0) { VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Different_Object); } else { - VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_VITA_Same_Object, object->metadata.ohfi); + VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_VITA_Same_Object, ohfi); } VitaMTP_ReportResult(device, eventId, PTP_RC_OK); diff --git a/src/cmaevent.h b/src/cmaevent.h index 3ff4e92..3eb2b8f 100644 --- a/src/cmaevent.h +++ b/src/cmaevent.h @@ -20,7 +20,6 @@ #ifndef CMAEVENT_H #define CMAEVENT_H -#include "cmaobject.h" #include "qlistdb.h" #include "httpdownloader.h" @@ -42,7 +41,7 @@ public: static QListDB *db; private: - uint16_t processAllObjects(CMAObject *parent, uint32_t handle); + uint16_t processAllObjects(metadata_t &metadata, uint32_t handle); void vitaEventSendObject(vita_event_t *event, int eventId); void vitaEventSendObjectMetadata(vita_event_t *event, int eventId); void vitaEventSendNumOfObject(vita_event_t *event, int eventId); @@ -79,7 +78,6 @@ private: QMutex active; QSemaphore sema; - static metadata_t g_thumbmeta; static QFile *m_file; signals: diff --git a/src/cmaobject.cpp b/src/cmaobject.cpp index c6fc284..a7783bc 100644 --- a/src/cmaobject.cpp +++ b/src/cmaobject.cpp @@ -20,6 +20,7 @@ #include "cmaobject.h" #include "sforeader.h" #include "avdecoder.h" +#include "database.h" #include "utils.h" #include @@ -108,48 +109,6 @@ void CMAObject::loadSfoMetadata(const QString &path) } } -void CMAObject::loadMusicMetadata(const QString &path) -{ - AVDecoder decoder; - bool skipMetadata = QSettings().value("skipMetadata", false).toBool(); - - if(!skipMetadata && decoder.open(path)) { - decoder.getAudioMetadata(metadata); - } else { - metadata.data.music.album = strdup(parent->metadata.name ? parent->metadata.name : ""); - metadata.data.music.artist = strdup(""); - metadata.data.music.title = strdup(metadata.name); - } -} - -void CMAObject::loadVideoMetadata(const QString &path) -{ - AVDecoder decoder; - bool skipMetadata = QSettings().value("skipMetadata", false).toBool(); - - if(!skipMetadata && decoder.open(path)) { - decoder.getVideoMetadata(metadata); - } else { - metadata.data.video.title = strdup(metadata.name); - metadata.data.video.explanation = strdup(""); - metadata.data.video.copyright = strdup(""); - // default to H264 video codec - metadata.data.video.tracks->data.track_video.codecType = CODEC_TYPE_AVC; - } -} - -void CMAObject::loadPhotoMetadata(const QString &path) -{ - QImage img; - bool skipMetadata = QSettings().value("skipMetadata", false).toBool(); - - if(!skipMetadata && img.load(path)) { - metadata.data.photo.tracks->data.track_photo.width = img.width(); - metadata.data.photo.tracks->data.track_photo.height = img.height(); - } - metadata.data.photo.title = strdup(metadata.name); -} - void CMAObject::initObject(const QFileInfo &file, int file_type) { metadata.name = strdup(file.fileName().toUtf8().data()); @@ -181,7 +140,7 @@ void CMAObject::initObject(const QFileInfo &file, int file_type) metadata.data.music.tracks = new media_track(); metadata.data.music.tracks->type = VITA_TRACK_TYPE_AUDIO; metadata.data.music.tracks->data.track_photo.codecType = audio_list[file_type].file_codec; - loadMusicMetadata(file.absoluteFilePath()); + Database::loadMusicMetadata(file.absoluteFilePath(), metadata); } else if(MASK_SET(metadata.dataType, Video | File)) { metadata.data.video.fileName = strdup(metadata.name); metadata.data.video.dateTimeUpdated = file.created().toTime_t(); @@ -191,7 +150,7 @@ void CMAObject::initObject(const QFileInfo &file, int file_type) metadata.data.video.numTracks = 1; metadata.data.video.tracks = new media_track(); metadata.data.video.tracks->type = VITA_TRACK_TYPE_VIDEO; - loadVideoMetadata(file.absoluteFilePath()); + Database::loadVideoMetadata(file.absoluteFilePath(), metadata); } else if(MASK_SET(metadata.dataType, Photo | File)) { if(file_type < 0) { @@ -207,7 +166,7 @@ void CMAObject::initObject(const QFileInfo &file, int file_type) metadata.data.photo.tracks = new media_track(); metadata.data.photo.tracks->type = VITA_TRACK_TYPE_PHOTO; metadata.data.photo.tracks->data.track_photo.codecType = photo_list[file_type].file_codec; - loadPhotoMetadata(file.absoluteFilePath()); + Database::loadPhotoMetadata(file.absoluteFilePath(), metadata); } path = file.absoluteFilePath(); diff --git a/src/database.cpp b/src/database.cpp new file mode 100644 index 0000000..7c80720 --- /dev/null +++ b/src/database.cpp @@ -0,0 +1,101 @@ +#include "database.h" +#include "avdecoder.h" + +#include + +const file_type audio_list[] = { + {"mp3", FILE_FORMAT_MP3, CODEC_TYPE_MP3}, + {"mp4", FILE_FORMAT_MP4, CODEC_TYPE_AAC}, + {"wav", FILE_FORMAT_WAV, CODEC_TYPE_PCM} +}; + +const file_type photo_list[] = { + {"jpg", FILE_FORMAT_JPG, CODEC_TYPE_JPG}, + {"jpeg", FILE_FORMAT_JPG, CODEC_TYPE_JPG}, + {"png", FILE_FORMAT_PNG, CODEC_TYPE_PNG}, + {"tif", FILE_FORMAT_TIF, CODEC_TYPE_TIF}, + {"tiff", FILE_FORMAT_TIF, CODEC_TYPE_TIF}, + {"bmp", FILE_FORMAT_BMP, CODEC_TYPE_BMP}, + {"gif", FILE_FORMAT_GIF, CODEC_TYPE_GIF}, +}; + +const file_type video_list[] = { + {"mp4", FILE_FORMAT_MP4, 0} +}; + +Database::Database(QObject *parent) : + QObject(parent) +{ +} + +int Database::checkFileType(const QString path, int ohfi_root) +{ + switch(ohfi_root) { + case VITA_OHFI_MUSIC: + for(int i = 0, max = sizeof(audio_list) / sizeof(file_type); i < max; i++) { + if(path.endsWith(audio_list[i].file_ext, Qt::CaseInsensitive)) { + return i; + } + } + break; + case VITA_OHFI_PHOTO: + for(int i = 0, max = sizeof(photo_list) / sizeof(file_type); i< max; i++) { + if(path.endsWith(photo_list[i].file_ext, Qt::CaseInsensitive)) { + return i; + } + } + break; + case VITA_OHFI_VIDEO: + for(int i = 0, max = sizeof(video_list) / sizeof(file_type); i< max; i++) { + if(path.endsWith(video_list[i].file_ext, Qt::CaseInsensitive)) { + return i; + } + } + break; + default: + return 0; + } + return -1; +} + +void Database::loadMusicMetadata(const QString &path, metadata_t &metadata) +{ + AVDecoder decoder; + bool skipMetadata = QSettings().value("skipMetadata", false).toBool(); + + if(!skipMetadata && decoder.open(path)) { + decoder.getAudioMetadata(metadata); + } else { + metadata.data.music.album = strdup(""); + metadata.data.music.artist = strdup(""); + metadata.data.music.title = strdup(metadata.name); + } +} + +void Database::loadVideoMetadata(const QString &path, metadata_t &metadata) +{ + AVDecoder decoder; + bool skipMetadata = QSettings().value("skipMetadata", false).toBool(); + + if(!skipMetadata && decoder.open(path)) { + decoder.getVideoMetadata(metadata); + } else { + metadata.data.video.title = strdup(metadata.name); + metadata.data.video.explanation = strdup(""); + metadata.data.video.copyright = strdup(""); + // default to H264 video codec + metadata.data.video.tracks->data.track_video.codecType = CODEC_TYPE_AVC; + } +} + +void Database::loadPhotoMetadata(const QString &path, metadata_t &metadata) +{ + QImage img; + bool skipMetadata = QSettings().value("skipMetadata", false).toBool(); + + if(!skipMetadata && img.load(path)) { + metadata.data.photo.tracks->data.track_photo.width = img.width(); + metadata.data.photo.tracks->data.track_photo.height = img.height(); + } + metadata.data.photo.title = strdup(metadata.name); +} diff --git a/src/database.h b/src/database.h new file mode 100644 index 0000000..29daf8c --- /dev/null +++ b/src/database.h @@ -0,0 +1,63 @@ +#ifndef DATABASE_H +#define DATABASE_H + +#include +#include + +typedef struct { + const char *file_ext; + int file_format; + int file_codec; +} file_type; + +#define FILE_FORMAT_MP4 1 +#define FILE_FORMAT_WAV 2 +#define FILE_FORMAT_MP3 3 +#define FILE_FORMAT_JPG 4 +#define FILE_FORMAT_PNG 5 +#define FILE_FORMAT_GIF 6 +#define FILE_FORMAT_BMP 7 +#define FILE_FORMAT_TIF 8 + +#define CODEC_TYPE_MPEG4 2 +#define CODEC_TYPE_AVC 3 +#define CODEC_TYPE_MP3 12 +#define CODEC_TYPE_AAC 13 +#define CODEC_TYPE_PCM 15 +#define CODEC_TYPE_JPG 17 +#define CODEC_TYPE_PNG 18 +#define CODEC_TYPE_TIF 19 +#define CODEC_TYPE_BMP 20 +#define CODEC_TYPE_GIF 21 + +extern const file_type audio_list[3]; +extern const file_type photo_list[7]; +extern const file_type video_list[1]; + +class Database : public QObject +{ + Q_OBJECT +public: + explicit Database(QObject *parent = 0); + + virtual int childObjectCount(int parent_ohfi) = 0; + virtual bool deleteEntry(int ohfi, int root_ohfi = 0) = 0; + virtual QString getAbsolutePath(int ohfi) = 0; + virtual QString getRelativePath(int ohfi) = 0; + virtual bool getObjectMetadata(int ohfi, metadata_t &metadata) = 0; + virtual int getObjectMetadatas(int parent_ohfi, metadata_t *&metadata, int index = 0, int max_number = 0) = 0; + virtual qint64 getObjectSize(int ohfi) = 0; + virtual int getPathId(const char *name, int ohfi) = 0; + virtual int insertObjectEntry(const QString &path, int parent_ohfi) = 0; + virtual bool renameObject(int ohfi, const QString &name) = 0; + virtual void setObjectSize(int ohfi, qint64 size) = 0; + virtual int getRootId(int ohfi) = 0; + + static int checkFileType(const QString path, int ohfi_root); + static void loadMusicMetadata(const QString &path, metadata_t &metadata); + static void loadPhotoMetadata(const QString &path, metadata_t &metadata); + static void loadVideoMetadata(const QString &path, metadata_t &metadata); + +}; + +#endif // DATABASE_H diff --git a/src/forms/backupmanagerform.cpp b/src/forms/backupmanagerform.cpp index c5fb9ab..72c825b 100644 --- a/src/forms/backupmanagerform.cpp +++ b/src/forms/backupmanagerform.cpp @@ -66,12 +66,13 @@ void BackupManagerForm::removeEntry(BackupItem *item) QMutexLocker locker(&db->mutex); - CMAObject *obj = db->ohfiToObject(item->ohfi); - if(obj) { - obj->removeReferencedObject(); - db->remove(obj); + metadata meta; + if(db->getObjectMetadata(item->ohfi, meta)) { + setBackupUsage(db->getObjectSize(meta.ohfiParent)); } + db->deleteEntry(item->ohfi); + for(int i = 0; i < ui->tableWidget->rowCount(); ++i) { BackupItem *iter_item = static_cast(ui->tableWidget->cellWidget(i, 0)); if(iter_item == item) { @@ -79,11 +80,6 @@ void BackupManagerForm::removeEntry(BackupItem *item) break; } } - - obj = db->ohfiToObject(obj->metadata.ohfiParent); - if(obj) { - setBackupUsage(obj->metadata.size); - } } void BackupManagerForm::setBackupUsage(quint64 size) @@ -146,10 +142,9 @@ void BackupManagerForm::loadBackupListing(int index) db->mutex.lock(); - // get the item list + // get the item list metadata_t *meta; - int row_count = db->filterObjects(ohfi, &meta); - + int row_count = db->getObjectMetadatas(ohfi, meta); ui->tableWidget->setRowCount(row_count); // exit if there aren't any items @@ -167,13 +162,12 @@ void BackupManagerForm::loadBackupListing(int index) #else horiz_header->setResizeMode(QHeaderView::Stretch); #endif - CMAObject *obj = db->ohfiToObject(ohfi); - setBackupUsage(obj->metadata.size); - + setBackupUsage(db->getObjectSize(ohfi)); + QString path = db->getAbsolutePath(ohfi); QList item_list; while(meta) { - QString base_path = obj->path + QDir::separator() + meta->name; + QString base_path = path + QDir::separator() + meta->name; QString parent_path = sys_dir ? base_path + QDir::separator() + "sce_sys" : base_path; SfoReader reader; QString game_name; @@ -213,7 +207,7 @@ void BackupManagerForm::loadBackupListing(int index) item->setItemInfo(game_name, size, info); item->setItemIcon(QDir(parent_path).absoluteFilePath(sys_dir ? "icon0.png" : "ICON0.PNG"), img_width, ohfi == VITA_OHFI_PSMAPP); - item->setDirectory(obj->path + QDir::separator() + meta->name); + item->setDirectory(path + QDir::separator() + meta->name); item->resize(646, 68); item_list << item; diff --git a/src/qlistdb.cpp b/src/qlistdb.cpp index eff9f9a..0fc1a23 100644 --- a/src/qlistdb.cpp +++ b/src/qlistdb.cpp @@ -28,7 +28,8 @@ #include #include -QListDB::QListDB() : +QListDB::QListDB(QObject *parent) : + Database(parent), mutex(QMutex::Recursive) { QString uuid = QSettings().value("lastAccountId", "ffffffffffffffff").toString(); @@ -249,18 +250,18 @@ void QListDB::destroy() object_list.clear(); } -bool QListDB::removeInternal(root_list &list, const CMAObject *obj) +bool QListDB::removeInternal(root_list &list, int ohfi) { bool found = false; QList::iterator it = list.begin(); while(it != list.end()) { - if(!found && (*it) == obj) { + if(!found && (*it)->metadata.ohfi == ohfi) { // update the size of the parent objects (*it)->updateObjectSize(-(*it)->metadata.size); it = list.erase(it); found = true; - } else if(found && (*it)->metadata.ohfiParent == obj->metadata.ohfi) { + } else if(found && (*it)->metadata.ohfiParent == ohfi) { it = list.erase(it); } else { ++it; @@ -270,22 +271,6 @@ bool QListDB::removeInternal(root_list &list, const CMAObject *obj) return found; } -bool QListDB::remove(const CMAObject *obj, int ohfi_root) -{ - QMutexLocker locker(&mutex); - - if(ohfi_root) { - return removeInternal(object_list[ohfi_root], obj); - } else { - for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) { - if(removeInternal(*root, obj)) { - return true; - } - } - } - return false; -} - bool QListDB::lessThanComparator(const CMAObject *a, const CMAObject *b) { return a->metadata.ohfi < b->metadata.ohfi; @@ -326,23 +311,6 @@ bool QListDB::find(int ohfi, QListDB::find_data &data) return false; } -void QListDB::append(int parent_ohfi, CMAObject *object) -{ - QMutexLocker locker(&mutex); - CMAObject parent; - parent.setOhfi(parent_ohfi); - - for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) { - root_list *cat_list = &(*root); - root_list::const_iterator it = qBinaryFind(cat_list->begin(), cat_list->end(), &parent, QListDB::lessThanComparator); - - if(it != cat_list->end()) { - cat_list->append(object); - break; - } - } -} - CMAObject *QListDB::ohfiToObject(int ohfi) { QMutexLocker locker(&mutex); @@ -363,24 +331,6 @@ CMAObject *QListDB::pathToObjectInternal(const root_list &list, const char *path return NULL; } -CMAObject *QListDB::pathToObject(const char *path, int ohfiRoot) -{ - QMutexLocker locker(&mutex); - - for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) { - - if(ohfiRoot && (*root).first()->metadata.ohfi != ohfiRoot) { - continue; - } - CMAObject *obj = pathToObjectInternal(*root, path); - - if(obj) { - return obj; - } - } - return NULL; -} - int QListDB::acceptFilteredObject(const CMAObject *parent, const CMAObject *current, int type) { QMutexLocker locker(&mutex); @@ -421,10 +371,45 @@ void QListDB::dumpMetadataList(const metadata_t *p_head) } } -int QListDB::filterObjects(int ohfiParent, metadata_t **p_head, int index, int max_number) +bool QListDB::getObjectMetadata(int ohfi, metadata_t &metadata) { QMutexLocker locker(&mutex); - CMARootObject *parent = static_cast(ohfiToObject(ohfiParent)); + + CMAObject *obj = ohfiToObject(ohfi); + if(obj) { + //TODO: return the pointer instead of copying the struct + metadata = obj->metadata; + return true; + } + return false; +} + +int QListDB::childObjectCount(int parent_ohfi) +{ + metadata_t *metadata = NULL; + return getObjectMetadatas(parent_ohfi, metadata); +} + +bool QListDB::deleteEntry(int ohfi, int root_ohfi) +{ + QMutexLocker locker(&mutex); + + if(root_ohfi) { + return removeInternal(object_list[root_ohfi], ohfi); + } else { + for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) { + if(removeInternal(*root, ohfi)) { + return true; + } + } + } + return false; +} + +int QListDB::getObjectMetadatas(int parent_ohfi, metadata_t *&metadata, int index, int max_number) +{ + QMutexLocker locker(&mutex); + CMARootObject *parent = static_cast(ohfiToObject(parent_ohfi)); if(parent == NULL) { return 0; @@ -433,11 +418,11 @@ int QListDB::filterObjects(int ohfiParent, metadata_t **p_head, int index, int m int type = parent->metadata.type; if(parent->metadata.ohfi < OHFI_OFFSET && parent->filters) { // if we have filters - if(ohfiParent == parent->metadata.ohfi) { // if we are looking at root - return parent->getFilters(p_head); + if(parent_ohfi == parent->metadata.ohfi) { // if we are looking at root + return parent->getFilters(&metadata); } else { // we are looking at a filter for(int j = 0; j < parent->num_filters; j++) { - if(parent->filters[j].ohfi == ohfiParent) { + if(parent->filters[j].ohfi == parent_ohfi) { type = parent->filters[j].type; break; } @@ -472,9 +457,123 @@ int QListDB::filterObjects(int ohfiParent, metadata_t **p_head, int index, int m tail->next_metadata = NULL; - if(p_head != NULL) { - *p_head = temp.next_metadata; + if(metadata != NULL) { + metadata = temp.next_metadata; } return numObjects; } + +qint64 QListDB::getObjectSize(int ohfi) +{ + QMutexLocker locker(&mutex); + + CMAObject *obj = ohfiToObject(ohfi); + return obj ? obj->metadata.size : -1; +} + +int QListDB::getPathId(const char *name, int ohfi) +{ + QMutexLocker locker(&mutex); + + for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) { + + if(ohfi && (*root).first()->metadata.ohfi != ohfi) { + continue; + } + CMAObject *obj = pathToObjectInternal(*root, name); + + if(obj) { + return obj->metadata.ohfi; + } + } + return 0; +} + +int QListDB::insertObjectEntry(const QString &path, int parent_ohfi) +{ + QMutexLocker locker(&mutex); + + CMAObject *parent = ohfiToObject(parent_ohfi); + + for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) { + root_list *cat_list = &(*root); + root_list::const_iterator it = qBinaryFind(cat_list->begin(), cat_list->end(), parent, QListDB::lessThanComparator); + + if(it != cat_list->end()) { + CMAObject *newobj = new CMAObject(parent); + newobj->initObject(path); + cat_list->append(newobj); + return newobj->metadata.ohfi; + } + } + + return 0; +} + +QString QListDB::getAbsolutePath(int ohfi) +{ + QMutexLocker locker(&mutex); + CMAObject *obj = ohfiToObject(ohfi); + return obj ? obj->path : NULL; +} + +QString QListDB::getRelativePath(int ohfi) +{ + QMutexLocker locker(&mutex); + CMAObject *obj = ohfiToObject(ohfi); + return obj ? obj->metadata.path : NULL; +} + +bool QListDB::renameObject(int ohfi, const QString &name) +{ + QMutexLocker locker(&mutex); + + CMAObject *root = ohfiToObject(ohfi); + + if(!root) { + return false; + } + + //rename the current object + root->rename(name); + QListDB::find_data iters; + find(root->metadata.ohfi, iters); + + // rename the rest of the list only if has the renamed parent in some part of the chain + while(iters.it != iters.end) { + CMAObject *obj = *iters.it++; + + if(obj->hasParent(root)) { + obj->refreshPath(); + } + } + + return true; +} + +void QListDB::setObjectSize(int ohfi, qint64 size) +{ + QMutexLocker locker(&mutex); + CMAObject *obj = ohfiToObject(ohfi); + + if(obj) { + obj->updateObjectSize(size); + } +} + +int QListDB::getRootId(int ohfi) +{ + QMutexLocker locker(&mutex); + CMAObject *obj = ohfiToObject(ohfi); + + if(!obj) { + return 0; + } + + while(obj->parent) { + obj = obj->parent; + } + + return obj->metadata.ohfi; +} diff --git a/src/qlistdb.h b/src/qlistdb.h index edbb560..ac8144b 100644 --- a/src/qlistdb.h +++ b/src/qlistdb.h @@ -20,6 +20,7 @@ #ifndef QLISTDB_H #define QLISTDB_H +#include "database.h" #include "cmarootobject.h" #include @@ -30,51 +31,54 @@ #include -class QListDB : public QObject +class QListDB : public Database { Q_OBJECT public: + explicit QListDB(QObject *parent = 0); + ~QListDB(); + + bool reload(bool &prepared); + void setUUID(const QString uuid); + + int childObjectCount(int parent_ohfi); + bool deleteEntry(int ohfi, int root_ohfi = 0); + QString getAbsolutePath(int ohfi); + bool getObjectMetadata(int ohfi, metadata_t &metadata); + int getObjectMetadatas(int parent_ohfi, metadata_t *&metadata, int index = 0, int max_number = 0); + qint64 getObjectSize(int ohfi); + int getPathId(const char *name, int ohfi); + QString getRelativePath(int ohfi); + int getRootId(int ohfi); + int insertObjectEntry(const QString &path, int parent_ohfi); + bool renameObject(int ohfi, const QString &name); + void setObjectSize(int ohfi, qint64 size); + + QMutex mutex; + +private: typedef struct { QList::const_iterator it; QList::const_iterator end; } find_data; - explicit QListDB(); - ~QListDB(); - - bool reload(bool &prepared); - void setUUID(const QString uuid); - void addEntries(CMAObject *root); - CMAObject *ohfiToObject(int ohfi); - bool find(int ohfi, find_data &data); - void append(int parent_ohfi, CMAObject *object); - bool remove(const CMAObject *obj, int ohfi_root = 0); - int filterObjects(int ohfiParent, metadata_t **p_head, int index = 0, int max_number = 0); - CMAObject *pathToObject(const char *path, int ohfiRoot); - int acceptFilteredObject(const CMAObject *parent, const CMAObject *current, int type); - - QMutex mutex; - -private: typedef QList root_list; typedef QMap map_list; - static const QStringList audio_types; - static const QStringList image_types; - static const QStringList video_types; - - int create(); void destroy(); int scanRootDirectory(root_list &list,int ohfi_type); int recursiveScanRootDirectory(root_list &list, CMAObject *parent, int ohfi_type); bool hasFilter(const CMARootObject *object,int ohfi); - bool removeInternal(root_list &list, const CMAObject *obj); + bool removeInternal(root_list &list, int ohfi); bool findInternal(const root_list &list, int ohfi, find_data &data); CMAObject *getParent(CMAObject *last_dir, const QString ¤t_path); CMAObject *pathToObjectInternal(const root_list &list, const char *path); static bool lessThanComparator(const CMAObject *a, const CMAObject *b); void dumpMetadataList(const metadata_t *p_head); + bool find(int ohfi, find_data &data); + int acceptFilteredObject(const CMAObject *parent, const CMAObject *current, int type); + CMAObject *ohfiToObject(int ohfi); bool continueOperation(); // control variables diff --git a/src/sqlitedb.cpp b/src/sqlitedb.cpp index 6ba19af..3ac1592 100644 --- a/src/sqlitedb.cpp +++ b/src/sqlitedb.cpp @@ -115,7 +115,7 @@ static const char *trigger_list[] = { }; SQLiteDB::SQLiteDB(QObject *parent) : - QObject(parent) + Database(parent) { uuid = QSettings().value("lastAccountId", "ffffffffffffffff").toString(); } @@ -275,6 +275,13 @@ int SQLiteDB::recursiveScanRootDirectory(const QString &base_path, int parent, i return total_objects; } +bool SQLiteDB::getObjectMetadata(int ohfi, metadata_t &metadata) +{ + Q_UNUSED(ohfi); + Q_UNUSED(metadata); + return false; +} + int SQLiteDB::getPathId(const QString &path) { QSqlQuery query(QString("SELECT object_id from sources WHERE path = %1").arg(path)); diff --git a/src/sqlitedb.h b/src/sqlitedb.h index e2a42d6..e78329b 100644 --- a/src/sqlitedb.h +++ b/src/sqlitedb.h @@ -1,6 +1,8 @@ #ifndef SQLITEDB_H #define SQLITEDB_H +#include "database.h" + #include #include @@ -25,7 +27,7 @@ #define OBJECT_APPLICATION 0x00080000 -class SQLiteDB : public QObject +class SQLiteDB : public Database { Q_OBJECT public: @@ -51,6 +53,8 @@ public: uint insertSavedataEntry(const QString &path, int type, int parent); uint insertApplicationEntry(const QString &path, int type, int parent, int app_type); + bool getObjectMetadata(int ohfi, metadata_t &metadata); + private: int recursiveScanRootDirectory(const QString &base_path, int parent, int type); uint insertDirectoryEntry(const QString &path, int type, int parent); diff --git a/src/utils.cpp b/src/utils.cpp index 07e814d..22059f0 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -31,26 +31,6 @@ #include #endif -const file_type audio_list[] = { - {"mp3", FILE_FORMAT_MP3, CODEC_TYPE_MP3}, - {"mp4", FILE_FORMAT_MP4, CODEC_TYPE_AAC}, - {"wav", FILE_FORMAT_WAV, CODEC_TYPE_PCM} -}; - -const file_type photo_list[] = { - {"jpg", FILE_FORMAT_JPG, CODEC_TYPE_JPG}, - {"jpeg", FILE_FORMAT_JPG, CODEC_TYPE_JPG}, - {"png", FILE_FORMAT_PNG, CODEC_TYPE_PNG}, - {"tif", FILE_FORMAT_TIF, CODEC_TYPE_TIF}, - {"tiff", FILE_FORMAT_TIF, CODEC_TYPE_TIF}, - {"bmp", FILE_FORMAT_BMP, CODEC_TYPE_BMP}, - {"gif", FILE_FORMAT_GIF, CODEC_TYPE_GIF}, -}; - -const file_type video_list[] = { - {"mp4", FILE_FORMAT_MP4, 0} -}; - bool getDiskSpace(const QString &dir, quint64 *free, quint64 *total) { #ifdef Q_OS_WIN32 @@ -195,33 +175,3 @@ QString readable_size(quint64 size, bool use_gib) } return QString().setNum(size_f,'f',2) + " " + unit; } - -int checkFileType(const QString path, int ohfi_root) -{ - switch(ohfi_root) { - case VITA_OHFI_MUSIC: - for(int i = 0, max = sizeof(audio_list) / sizeof(file_type); i < max; i++) { - if(path.endsWith(audio_list[i].file_ext, Qt::CaseInsensitive)) { - return i; - } - } - break; - case VITA_OHFI_PHOTO: - for(int i = 0, max = sizeof(photo_list) / sizeof(file_type); i< max; i++) { - if(path.endsWith(photo_list[i].file_ext, Qt::CaseInsensitive)) { - return i; - } - } - break; - case VITA_OHFI_VIDEO: - for(int i = 0, max = sizeof(video_list) / sizeof(file_type); i< max; i++) { - if(path.endsWith(video_list[i].file_ext, Qt::CaseInsensitive)) { - return i; - } - } - break; - default: - return 0; - } - return -1; -} diff --git a/src/utils.h b/src/utils.h index 816a34f..8d8deba 100644 --- a/src/utils.h +++ b/src/utils.h @@ -26,36 +26,6 @@ #include -typedef struct { - const char *file_ext; - int file_format; - int file_codec; -} file_type; - -#define FILE_FORMAT_MP4 1 -#define FILE_FORMAT_WAV 2 -#define FILE_FORMAT_MP3 3 -#define FILE_FORMAT_JPG 4 -#define FILE_FORMAT_PNG 5 -#define FILE_FORMAT_GIF 6 -#define FILE_FORMAT_BMP 7 -#define FILE_FORMAT_TIF 8 - -#define CODEC_TYPE_MPEG4 2 -#define CODEC_TYPE_AVC 3 -#define CODEC_TYPE_MP3 12 -#define CODEC_TYPE_AAC 13 -#define CODEC_TYPE_PCM 15 -#define CODEC_TYPE_JPG 17 -#define CODEC_TYPE_PNG 18 -#define CODEC_TYPE_TIF 19 -#define CODEC_TYPE_BMP 20 -#define CODEC_TYPE_GIF 21 - -extern const file_type audio_list[3]; -extern const file_type photo_list[7]; -extern const file_type video_list[1]; - // Qt4 doesn't have public methods for Thread::*sleep #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) typedef QThread Sleeper; @@ -79,6 +49,5 @@ bool removeRecursively(const QString &dirName); QString readable_size(quint64 size, bool use_gib = false); bool getDiskSpace(const QString &dir, quint64 *free, quint64 *total); QByteArray getThumbnail(const QString &path, DataType type, metadata_t *metadata); -int checkFileType(const QString path, int ohfi_root); #endif // UTILS_H