Remove the mmap usage. Do not use memory buffer to hold the whole file.

This commit is contained in:
codestation
2014-01-05 00:41:22 -04:30
parent 9784332bae
commit a0d9e03d17
4 changed files with 79 additions and 37 deletions

View File

@@ -22,6 +22,11 @@
#include <QDebug> #include <QDebug>
#include <QHostInfo> #include <QHostInfo>
DeviceCapability::DeviceCapability() :
vita_info()
{
}
bool DeviceCapability::exchangeInfo(vita_device_t *device) bool DeviceCapability::exchangeInfo(vita_device_t *device)
{ {
if(VitaMTP_GetVitaInfo(device, &vita_info) != PTP_RC_OK) { if(VitaMTP_GetVitaInfo(device, &vita_info) != PTP_RC_OK) {

View File

@@ -25,7 +25,7 @@
class DeviceCapability class DeviceCapability
{ {
public: public:
explicit DeviceCapability() {} explicit DeviceCapability();
~DeviceCapability(); ~DeviceCapability();
bool exchangeInfo(vita_device_t *device); bool exchangeInfo(vita_device_t *device);

View File

@@ -29,6 +29,7 @@
#include <inttypes.h> #include <inttypes.h>
Database *CmaEvent::db = NULL; Database *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}; metadata_t CmaEvent::g_thumbmeta = {0, 0, 0, NULL, NULL, 0, 0, 0, Thumbnail, {{17, 240, 136, 0, 1, 1.0f, 2}}, NULL};
@@ -149,20 +150,30 @@ void CmaEvent::processEvent()
quint16 CmaEvent::processAllObjects(CMAObject *parent, quint32 handle) quint16 CmaEvent::processAllObjects(CMAObject *parent, quint32 handle)
{ {
union { qDebug("Called %s, handle: %d, parent name: %s", Q_FUNC_INFO, handle, parent->metadata.name);
unsigned char *fileData;
uint32_t *handles;
} data;
metadata_t remote_meta; char *name;
unsigned int length; uint64_t size;
int dataType;
if(VitaMTP_GetObject(device, handle, &remote_meta, (void **)&data, &length) != PTP_RC_OK) { uint32_t *p_handles;
unsigned int p_len;
if(VitaMTP_GetObject_Info(device, handle, &name, &dataType) != PTP_RC_OK) {
qWarning("Cannot get object for handle %d", handle); qWarning("Cannot get object for handle %d", handle);
return PTP_RC_VITA_Invalid_Data; return PTP_RC_VITA_Invalid_Data;
} }
CMAObject *object = db->pathToObject(remote_meta.name, parent->metadata.ohfi); if(dataType & Folder) {
if(VitaMTP_GetObject_Folder(device, handle, &p_handles, &p_len) != PTP_RC_OK) {
qWarning("Cannot get folder handles for handle %d", handle);
return PTP_RC_VITA_Invalid_Data;
}
} else {
}
CMAObject *object = db->pathToObject(name, parent->metadata.ohfi);
if(object) { if(object) {
qDebug("Deleting %s", object->path.toStdString().c_str()); qDebug("Deleting %s", object->path.toStdString().c_str());
@@ -172,49 +183,48 @@ quint16 CmaEvent::processAllObjects(CMAObject *parent, quint32 handle)
QDir dir(parent->path); QDir dir(parent->path);
if(remote_meta.dataType & Folder) { if(dataType & Folder) {
if(!dir.mkpath(remote_meta.name)) { if(!dir.mkpath(name)) {
qWarning("Cannot create directory: %s", remote_meta.name); qWarning("Cannot create directory: %s", name);
free(data.fileData); free(name);
free(remote_meta.name);
return PTP_RC_VITA_Failed_Operate_Object; return PTP_RC_VITA_Failed_Operate_Object;
} }
} else { } else {
QFile file(dir.absoluteFilePath(remote_meta.name)); m_file = new QFile(dir.absoluteFilePath(name));
if(!file.open(QIODevice::WriteOnly)) { if(!m_file->open(QIODevice::WriteOnly)) {
qWarning("Cannot write to %s", remote_meta.name); qWarning("Cannot write to %s", name);
free(data.fileData); free(name);
free(remote_meta.name); delete m_file;
return PTP_RC_VITA_Invalid_Permission; return PTP_RC_VITA_Invalid_Permission;
} else { } else {
file.write((const char *)data.fileData, remote_meta.size); VitaMTP_GetObject_Callback(device, handle, &size, CmaEvent::writeCallback);
m_file->close();
delete m_file;
} }
} }
QFileInfo info(dir, remote_meta.name); QFileInfo info(dir, name);
object = new CMAObject(parent); object = new CMAObject(parent);
object->initObject(info); object->initObject(info);
object->metadata.handle = remote_meta.handle; object->metadata.handle = handle;
db->append(parent->metadata.ohfi, object); db->append(parent->metadata.ohfi, object);
free(remote_meta.name); free(name);
qDebug("Added object %s with OHFI %i to database", object->metadata.path, object->metadata.ohfi); qDebug("Added object %s with OHFI %i to database", object->metadata.path, object->metadata.ohfi);
if(remote_meta.dataType & Folder) { if(dataType & Folder) {
for(unsigned int i = 0; i < length; i++) { for(unsigned int i = 0; i < p_len; i++) {
quint16 ret = processAllObjects(object, data.handles[i]); quint16 ret = processAllObjects(object, p_handles[i]);
if(ret != PTP_RC_OK) { if(ret != PTP_RC_OK) {
qDebug("Deleteting object with OHFI %d", object->metadata.ohfi); qDebug("Deleteting object with OHFI %d", object->metadata.ohfi);
db->remove(object); db->remove(object);
free(data.fileData);
return ret; return ret;
} }
} }
} }
free(data.fileData);
return PTP_RC_OK; return PTP_RC_OK;
} }
@@ -405,15 +415,15 @@ void CmaEvent::vitaEventSendObject(vita_event_t *event, int eventId)
uint handle; uint handle;
do { do {
uchar *data = NULL;
len = object->metadata.size; len = object->metadata.size;
QFile file(object->path); m_file = new QFile(object->path);
// read the file to send if it's not a directory // 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 it is a directory, data and len are not used by VitaMTP
if(object->metadata.dataType & File) { if(object->metadata.dataType & File) {
if(!file.open(QIODevice::ReadOnly) || (data = file.map(0, file.size())) == NULL) { if(!m_file->open(QIODevice::ReadOnly)) {
qWarning("Failed to read %s", object->path.toStdString().c_str()); qWarning("Failed to read %s", object->path.toStdString().c_str());
delete m_file;
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Not_Exist_Object); VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Not_Exist_Object);
return; return;
} }
@@ -432,17 +442,19 @@ void CmaEvent::vitaEventSendObject(vita_event_t *event, int eventId)
qDebug("OHFI %d with handle 0x%08X", ohfi, parentHandle); qDebug("OHFI %d with handle 0x%08X", ohfi, parentHandle);
VitaMTP_RegisterCancelEventId(eventId); VitaMTP_RegisterCancelEventId(eventId);
quint16 ret = VitaMTP_SendObject(device, &parentHandle, &handle, &object->metadata, data); quint16 ret = VitaMTP_SendObject_Callback(device, &parentHandle, &handle, &object->metadata, &CmaEvent::readCallback);
if(ret != PTP_RC_OK) { if(ret != PTP_RC_OK) {
qWarning("Sending of %s failed. Code: %04X", object->metadata.name, ret); qWarning("Sending of %s failed. Code: %04X", object->metadata.name, ret);
file.unmap(data); m_file->close();
delete m_file;
return; return;
} }
object->metadata.handle = handle; object->metadata.handle = handle;
if(object->metadata.dataType & File) { if(object->metadata.dataType & File) {
file.unmap(data); m_file->close();
delete m_file;
} }
// break early if only a file needs to be sent // break early if only a file needs to be sent
@@ -686,7 +698,7 @@ void CmaEvent::vitaEventSendPartOfObject(vita_event_t *event, int eventId)
} else { } else {
file.seek(part_init.offset); file.seek(part_init.offset);
QByteArray data = file.read(part_init.size); 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("Sending %s at file offset %" PRIu64" for %" PRIu64" bytes", object->metadata.path, part_init.offset, part_init.size);
if(VitaMTP_SendPartOfObject(device, eventId, (unsigned char *)data.data(), data.size()) != PTP_RC_OK) { 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); qWarning("Failed to send part of object OHFI %d", part_init.ohfi);
@@ -813,7 +825,7 @@ void CmaEvent::vitaEventGetPartOfObject(vita_event_t *event, int eventId)
return; return;
} }
qDebug("Receiving %s at offset %"PRIu64" for %"PRIu64" bytes", object->metadata.path, part_init.offset, part_init.size); qDebug("Receiving %s at offset %" PRIu64" for %" PRIu64" bytes", object->metadata.path, part_init.offset, part_init.size);
QFile file(object->path); QFile file(object->path);
if(!file.open(QIODevice::ReadWrite)) { if(!file.open(QIODevice::ReadWrite)) {
@@ -823,7 +835,7 @@ void CmaEvent::vitaEventGetPartOfObject(vita_event_t *event, int eventId)
file.seek(part_init.offset); file.seek(part_init.offset);
file.write((const char *)data, part_init.size); file.write((const char *)data, part_init.size);
object->updateObjectSize(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); qDebug("Written %" PRIu64" bytes to %s at offset %" PRIu64, part_init.size, object->path.toStdString().c_str(), part_init.offset);
VitaMTP_ReportResult(device, eventId, PTP_RC_OK); VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
} }
@@ -900,3 +912,24 @@ void CmaEvent::vitaEventCheckExistance(vita_event_t *event, int eventId)
VitaMTP_ReportResult(device, eventId, PTP_RC_OK); VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
} }
int CmaEvent::readCallback(unsigned char *data, unsigned long wantlen, unsigned long *gotlen)
{
QByteArray qdata = m_file->read(wantlen);
*gotlen = qdata.size();
if(*gotlen) {
memcpy(data, qdata.constData(), qdata.size());
}
return PTP_RC_OK;
}
int CmaEvent::writeCallback(const unsigned char *data, unsigned long size, unsigned long *written)
{
int ret = m_file->write((const char *)data, size);
if(ret != -1) {
*written = ret;
ret = PTP_RC_OK;
}
return ret;
}

View File

@@ -61,6 +61,9 @@ private:
void vitaEventSendObjectMetadataItems(vita_event_t *event, int eventId); void vitaEventSendObjectMetadataItems(vita_event_t *event, int eventId);
void vitaEventSendNPAccountInfo(vita_event_t *event, int eventId); void vitaEventSendNPAccountInfo(vita_event_t *event, int eventId);
static int readCallback(unsigned char *data, unsigned long wantlen, unsigned long *gotlen);
static int writeCallback(const unsigned char *data, unsigned long size, unsigned long *written);
void processEvent(); void processEvent();
bool isActive(); bool isActive();
void setDevice(vita_device_t *device); void setDevice(vita_device_t *device);
@@ -75,6 +78,7 @@ private:
QSemaphore sema; QSemaphore sema;
static metadata_t g_thumbmeta; static metadata_t g_thumbmeta;
static QFile *m_file;
signals: signals:
void finishedEventLoop(); void finishedEventLoop();