Remove the mmap usage. Do not use memory buffer to hold the whole file.
This commit is contained in:
@@ -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) {
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
@@ -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();
|
||||||
|
Reference in New Issue
Block a user